authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-25 16:30:40-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-25 16:30:40-05:00
logf33bf48af7d9c99d532864f8a6c3f695ad5bbd21
treefa39bd6b654178e653d06e1c79f22ad1d29cd526
parent64365bc5d7b1e2c507806ee8976acc3479ad7862
parent416a547cdb8dbbf3d2e7ce32132f0a25f2a8607e
signaturelock-open Commit is signed but in an unrecognized format.

Merge remote-tracking branch 'origin/master' into llvm10


173 files changed, 8079 insertions(+), 8445 deletions(-)

CMakeLists.txt+59-39
...@@ -240,8 +240,8 @@ find_package(Threads)...@@ -240,8 +240,8 @@ find_package(Threads)
240# CMake doesn't let us create an empty executable, so we hang on to this one separately.240# CMake doesn't let us create an empty executable, so we hang on to this one separately.
241set(ZIG_MAIN_SRC "${CMAKE_SOURCE_DIR}/src/main.cpp")241set(ZIG_MAIN_SRC "${CMAKE_SOURCE_DIR}/src/main.cpp")
242242
243# This is our shim which will be replaced by libuserland written in Zig.243# This is our shim which will be replaced by libstage2 written in Zig.
244set(ZIG0_SHIM_SRC "${CMAKE_SOURCE_DIR}/src/userland.cpp")244set(ZIG0_SHIM_SRC "${CMAKE_SOURCE_DIR}/src/stage2.cpp")
245245
246if(ZIG_ENABLE_MEM_PROFILE)246if(ZIG_ENABLE_MEM_PROFILE)
247 set(ZIG_SOURCES_MEM_PROFILE "${CMAKE_SOURCE_DIR}/src/mem_profile.cpp")247 set(ZIG_SOURCES_MEM_PROFILE "${CMAKE_SOURCE_DIR}/src/mem_profile.cpp")
...@@ -263,7 +263,6 @@ set(ZIG_SOURCES...@@ -263,7 +263,6 @@ set(ZIG_SOURCES
263 "${CMAKE_SOURCE_DIR}/src/heap.cpp"263 "${CMAKE_SOURCE_DIR}/src/heap.cpp"
264 "${CMAKE_SOURCE_DIR}/src/ir.cpp"264 "${CMAKE_SOURCE_DIR}/src/ir.cpp"
265 "${CMAKE_SOURCE_DIR}/src/ir_print.cpp"265 "${CMAKE_SOURCE_DIR}/src/ir_print.cpp"
266 "${CMAKE_SOURCE_DIR}/src/libc_installation.cpp"
267 "${CMAKE_SOURCE_DIR}/src/link.cpp"266 "${CMAKE_SOURCE_DIR}/src/link.cpp"
268 "${CMAKE_SOURCE_DIR}/src/mem.cpp"267 "${CMAKE_SOURCE_DIR}/src/mem.cpp"
269 "${CMAKE_SOURCE_DIR}/src/os.cpp"268 "${CMAKE_SOURCE_DIR}/src/os.cpp"
...@@ -377,27 +376,27 @@ set_target_properties(opt_c_util PROPERTIES...@@ -377,27 +376,27 @@ set_target_properties(opt_c_util PROPERTIES
377 COMPILE_FLAGS "${OPTIMIZED_C_FLAGS}"376 COMPILE_FLAGS "${OPTIMIZED_C_FLAGS}"
378)377)
379378
380add_library(compiler STATIC ${ZIG_SOURCES})379add_library(zigcompiler STATIC ${ZIG_SOURCES})
381set_target_properties(compiler PROPERTIES380set_target_properties(zigcompiler PROPERTIES
382 COMPILE_FLAGS ${EXE_CFLAGS}381 COMPILE_FLAGS ${EXE_CFLAGS}
383 LINK_FLAGS ${EXE_LDFLAGS}382 LINK_FLAGS ${EXE_LDFLAGS}
384)383)
385target_link_libraries(compiler LINK_PUBLIC384target_link_libraries(zigcompiler LINK_PUBLIC
386 zig_cpp385 zig_cpp
387 opt_c_util386 opt_c_util
388 ${SOFTFLOAT_LIBRARIES}387 ${SOFTFLOAT_LIBRARIES}
389 ${CMAKE_THREAD_LIBS_INIT}388 ${CMAKE_THREAD_LIBS_INIT}
390)389)
391if(NOT MSVC)390if(NOT MSVC)
392 target_link_libraries(compiler LINK_PUBLIC ${LIBXML2})391 target_link_libraries(zigcompiler LINK_PUBLIC ${LIBXML2})
393endif()392endif()
394393
395if(ZIG_DIA_GUIDS_LIB)394if(ZIG_DIA_GUIDS_LIB)
396 target_link_libraries(compiler LINK_PUBLIC ${ZIG_DIA_GUIDS_LIB})395 target_link_libraries(zigcompiler LINK_PUBLIC ${ZIG_DIA_GUIDS_LIB})
397endif()396endif()
398397
399if(MSVC OR MINGW)398if(MSVC OR MINGW)
400 target_link_libraries(compiler LINK_PUBLIC version)399 target_link_libraries(zigcompiler LINK_PUBLIC version)
401endif()400endif()
402401
403add_executable(zig0 "${ZIG_MAIN_SRC}" "${ZIG0_SHIM_SRC}")402add_executable(zig0 "${ZIG_MAIN_SRC}" "${ZIG0_SHIM_SRC}")
...@@ -405,40 +404,43 @@ set_target_properties(zig0 PROPERTIES...@@ -405,40 +404,43 @@ set_target_properties(zig0 PROPERTIES
405 COMPILE_FLAGS ${EXE_CFLAGS}404 COMPILE_FLAGS ${EXE_CFLAGS}
406 LINK_FLAGS ${EXE_LDFLAGS}405 LINK_FLAGS ${EXE_LDFLAGS}
407)406)
408target_link_libraries(zig0 compiler)407target_link_libraries(zig0 zigcompiler)
409408
410if(MSVC)409if(MSVC)
411 set(LIBUSERLAND "${CMAKE_BINARY_DIR}/userland.lib")410 set(LIBSTAGE2 "${CMAKE_BINARY_DIR}/zigstage2.lib")
412else()411else()
413 set(LIBUSERLAND "${CMAKE_BINARY_DIR}/libuserland.a")412 set(LIBSTAGE2 "${CMAKE_BINARY_DIR}/libzigstage2.a")
414endif()413endif()
415if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")414if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
416 set(LIBUSERLAND_RELEASE_MODE "false")415 set(LIBSTAGE2_RELEASE_ARG "")
417else()416else()
418 set(LIBUSERLAND_RELEASE_MODE "true")417 set(LIBSTAGE2_RELEASE_ARG --release-fast --strip)
418endif()
419if(WIN32)
420 set(LIBSTAGE2_WINDOWS_ARGS "-lntdll")
421else()
422 set(LIBSTAGE2_WINDOWS_ARGS "")
419endif()423endif()
420424
421set(BUILD_LIBUSERLAND_ARGS "build"425set(BUILD_LIBSTAGE2_ARGS "build-lib"
426 "src-self-hosted/stage2.zig"
427 -mcpu=baseline
428 --name zigstage2
422 --override-lib-dir "${CMAKE_SOURCE_DIR}/lib"429 --override-lib-dir "${CMAKE_SOURCE_DIR}/lib"
423 "-Doutput-dir=${CMAKE_BINARY_DIR}"430 --cache on
424 "-Drelease=${LIBUSERLAND_RELEASE_MODE}"431 --output-dir "${CMAKE_BINARY_DIR}"
425 "-Dlib-files-only"432 ${LIBSTAGE2_RELEASE_ARG}
426 --prefix "${CMAKE_INSTALL_PREFIX}"433 --disable-gen-h
427 libuserland434 --bundle-compiler-rt
435 -fPIC
436 -lc
437 ${LIBSTAGE2_WINDOWS_ARGS}
428)438)
429439
430# When using Visual Studio build system generator we default to libuserland install.440add_custom_target(zig_build_libstage2 ALL
431if(MSVC)441 COMMAND zig0 ${BUILD_LIBSTAGE2_ARGS}
432 set(ZIG_SKIP_INSTALL_LIB_FILES off CACHE BOOL "Disable copying lib/ files to install prefix")
433 if(NOT ZIG_SKIP_INSTALL_LIB_FILES)
434 set(BUILD_LIBUSERLAND_ARGS ${BUILD_LIBUSERLAND_ARGS} install)
435 endif()
436endif()
437
438add_custom_target(zig_build_libuserland ALL
439 COMMAND zig0 ${BUILD_LIBUSERLAND_ARGS}
440 DEPENDS zig0442 DEPENDS zig0
441 BYPRODUCTS "${LIBUSERLAND}"443 BYPRODUCTS "${LIBSTAGE2}"
442 WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"444 WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
443)445)
444add_executable(zig "${ZIG_MAIN_SRC}")446add_executable(zig "${ZIG_MAIN_SRC}")
...@@ -447,22 +449,40 @@ set_target_properties(zig PROPERTIES...@@ -447,22 +449,40 @@ set_target_properties(zig PROPERTIES
447 COMPILE_FLAGS ${EXE_CFLAGS}449 COMPILE_FLAGS ${EXE_CFLAGS}
448 LINK_FLAGS ${EXE_LDFLAGS}450 LINK_FLAGS ${EXE_LDFLAGS}
449)451)
450target_link_libraries(zig compiler "${LIBUSERLAND}")452target_link_libraries(zig zigcompiler "${LIBSTAGE2}")
451if(MSVC)453if(MSVC)
452 target_link_libraries(zig ntdll.lib)454 target_link_libraries(zig ntdll.lib)
453elseif(MINGW) 455elseif(MINGW)
454 target_link_libraries(zig ntdll)456 target_link_libraries(zig ntdll)
455endif()457endif()
456add_dependencies(zig zig_build_libuserland)458add_dependencies(zig zig_build_libstage2)
457459
458install(TARGETS zig DESTINATION bin)460install(TARGETS zig DESTINATION bin)
459461
460# CODE has no effect with Visual Studio build system generator.462set(ZIG_INSTALL_ARGS "build"
461if(NOT MSVC)463 --override-lib-dir "${CMAKE_SOURCE_DIR}/lib"
462 get_target_property(zig0_BINARY_DIR zig0 BINARY_DIR)464 "-Dlib-files-only"
463 install(CODE "set(zig0_EXE \"${zig0_BINARY_DIR}/zig0\")")465 --prefix "${CMAKE_INSTALL_PREFIX}"
464 install(CODE "set(INSTALL_LIBUSERLAND_ARGS \"${BUILD_LIBUSERLAND_ARGS}\" install)")466 install
465 install(CODE "set(BUILD_LIBUSERLAND_ARGS \"${BUILD_LIBUSERLAND_ARGS}\")")467)
468
469# CODE has no effect with Visual Studio build system generator, therefore
470# when using Visual Studio build system generator we resort to running
471# `zig build install` during the build phase.
472if(MSVC)
473 set(ZIG_SKIP_INSTALL_LIB_FILES off CACHE BOOL
474 "Windows-only: Disable copying lib/ files to install prefix during the build phase")
475 if(NOT ZIG_SKIP_INSTALL_LIB_FILES)
476 add_custom_target(zig_install_lib_files ALL
477 COMMAND zig ${ZIG_INSTALL_ARGS}
478 DEPENDS zig
479 WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
480 )
481 endif()
482else()
483 get_target_property(zig_BINARY_DIR zig BINARY_DIR)
484 install(CODE "set(zig_EXE \"${zig_BINARY_DIR}/zig\")")
485 install(CODE "set(ZIG_INSTALL_ARGS \"${ZIG_INSTALL_ARGS}\")")
466 install(CODE "set(CMAKE_SOURCE_DIR \"${CMAKE_SOURCE_DIR}\")")486 install(CODE "set(CMAKE_SOURCE_DIR \"${CMAKE_SOURCE_DIR}\")")
467 install(SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/cmake/install.cmake)487 install(SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/cmake/install.cmake)
468endif()488endif()
build.zig+1-28
...@@ -65,8 +65,6 @@ pub fn build(b: *Builder) !void {...@@ -65,8 +65,6 @@ pub fn build(b: *Builder) !void {
65 try configureStage2(b, test_stage2, ctx);65 try configureStage2(b, test_stage2, ctx);
66 try configureStage2(b, exe, ctx);66 try configureStage2(b, exe, ctx);
6767
68 addLibUserlandStep(b, mode);
69
70 const skip_release = b.option(bool, "skip-release", "Main test suite skips release builds") orelse false;68 const skip_release = b.option(bool, "skip-release", "Main test suite skips release builds") orelse false;
71 const skip_release_small = b.option(bool, "skip-release-small", "Main test suite skips release-small builds") orelse skip_release;69 const skip_release_small = b.option(bool, "skip-release-small", "Main test suite skips release-small builds") orelse skip_release;
72 const skip_release_fast = b.option(bool, "skip-release-fast", "Main test suite skips release-fast builds") orelse skip_release;70 const skip_release_fast = b.option(bool, "skip-release-fast", "Main test suite skips release-fast builds") orelse skip_release;
...@@ -176,7 +174,7 @@ fn dependOnLib(b: *Builder, lib_exe_obj: var, dep: LibraryDep) void {...@@ -176,7 +174,7 @@ fn dependOnLib(b: *Builder, lib_exe_obj: var, dep: LibraryDep) void {
176}174}
177175
178fn fileExists(filename: []const u8) !bool {176fn fileExists(filename: []const u8) !bool {
179 fs.File.access(filename) catch |err| switch (err) {177 fs.cwd().access(filename, .{}) catch |err| switch (err) {
180 error.FileNotFound => return false,178 error.FileNotFound => return false,
181 else => return err,179 else => return err,
182 };180 };
...@@ -379,28 +377,3 @@ const Context = struct {...@@ -379,28 +377,3 @@ const Context = struct {
379 dia_guids_lib: []const u8,377 dia_guids_lib: []const u8,
380 llvm: LibraryDep,378 llvm: LibraryDep,
381};379};
382
383fn addLibUserlandStep(b: *Builder, mode: builtin.Mode) void {
384 const artifact = b.addStaticLibrary("userland", "src-self-hosted/stage1.zig");
385 artifact.disable_gen_h = true;
386 artifact.bundle_compiler_rt = true;
387 artifact.setTarget(builtin.arch, builtin.os, builtin.abi);
388 artifact.setBuildMode(mode);
389 artifact.force_pic = true;
390 if (mode != .Debug) {
391 artifact.strip = true;
392 }
393 artifact.linkSystemLibrary("c");
394 if (builtin.os == .windows) {
395 artifact.linkSystemLibrary("ntdll");
396 }
397 const libuserland_step = b.step("libuserland", "Build the userland compiler library for use in stage1");
398 libuserland_step.dependOn(&artifact.step);
399
400 const output_dir = b.option(
401 []const u8,
402 "output-dir",
403 "For libuserland step, where to put the output",
404 ) orelse return;
405 artifact.setOutputDir(output_dir);
406}
ci/srht/freebsd_script+7-24
...@@ -34,38 +34,21 @@ release/bin/zig build test-behavior...@@ -34,38 +34,21 @@ release/bin/zig build test-behavior
34# release/bin/zig build test-std34# release/bin/zig build test-std
3535
36release/bin/zig build test-compiler-rt36release/bin/zig build test-compiler-rt
3737release/bin/zig build test-compare-output
38# This test is disabled because it triggers "out of memory" on the sr.ht CI service.38release/bin/zig build test-standalone
39# See https://github.com/ziglang/zig/issues/3210
40# release/bin/zig build test-compare-output
41
42# This test is disabled because it triggers "out of memory" on the sr.ht CI service.
43# See https://github.com/ziglang/zig/issues/3210
44# release/bin/zig build test-standalone
45
46release/bin/zig build test-stack-traces39release/bin/zig build test-stack-traces
47release/bin/zig build test-cli40release/bin/zig build test-cli
48release/bin/zig build test-asm-link41release/bin/zig build test-asm-link
49release/bin/zig build test-runtime-safety42release/bin/zig build test-runtime-safety
5043release/bin/zig build test-translate-c
51# This test is disabled because it triggers "out of memory" on the sr.ht CI service.44release/bin/zig build test-run-translated-c
52# See https://github.com/ziglang/zig/issues/3210
53# release/bin/zig build test-translate-c
54
55release/bin/zig build test-gen-h45release/bin/zig build test-gen-h
5646release/bin/zig build test-compile-errors
57# This test is disabled because it triggers "out of memory" on the sr.ht CI service.47release/bin/zig build docs
58# See https://github.com/ziglang/zig/issues/3210
59# release/bin/zig build test-compile-errors
60
61# This test is disabled because it triggers "out of memory" on the sr.ht CI service.
62# See https://github.com/ziglang/zig/issues/3210
63# release/bin/zig build docs
6448
65if [ -f ~/.s3cfg ]; then49if [ -f ~/.s3cfg ]; then
66 mv ../LICENSE release/50 mv ../LICENSE release/
67 # Enable when `release/bin/zig build docs` passes without "out of memory" or failures51 mv ../zig-cache/langref.html release/
68 #mv ../zig-cache/langref.html release/
69 mv release/bin/zig release/52 mv release/bin/zig release/
70 rmdir release/bin53 rmdir release/bin
7154
cmake/install.cmake+6-6
...@@ -1,16 +1,16 @@...@@ -1,16 +1,16 @@
1message("-- Installing: ${CMAKE_INSTALL_PREFIX}/lib")1message("-- Installing: ${CMAKE_INSTALL_PREFIX}/lib")
22
3if(NOT EXISTS ${zig0_EXE})3if(NOT EXISTS ${zig_EXE})
4 message("::")4 message("::")
5 message(":: ERROR: Executable not found")5 message(":: ERROR: Executable not found")
6 message(":: (execute_process)")6 message(":: (execute_process)")
7 message("::")7 message("::")
8 message(":: executable: ${zig0_EXE}")8 message(":: executable: ${zig_EXE}")
9 message("::")9 message("::")
10 message(FATAL_ERROR)10 message(FATAL_ERROR)
11endif()11endif()
1212
13execute_process(COMMAND ${zig0_EXE} ${INSTALL_LIBUSERLAND_ARGS}13execute_process(COMMAND ${zig_EXE} ${ZIG_INSTALL_ARGS}
14 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}14 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
15 RESULT_VARIABLE _result15 RESULT_VARIABLE _result
16)16)
...@@ -19,11 +19,11 @@ if(_result)...@@ -19,11 +19,11 @@ if(_result)
19 message(":: ERROR: ${_result}")19 message(":: ERROR: ${_result}")
20 message(":: (execute_process)")20 message(":: (execute_process)")
2121
22 string(REPLACE ";" " " s_INSTALL_LIBUSERLAND_ARGS "${INSTALL_LIBUSERLAND_ARGS}")22 string(REPLACE ";" " " s_INSTALL_LIBSTAGE2_ARGS "${ZIG_INSTALL_ARGS}")
23 message("::")23 message("::")
24 message(":: argv: ${zig0_EXE} ${s_INSTALL_LIBUSERLAND_ARGS} install")24 message(":: argv: ${zig_EXE} ${s_INSTALL_LIBSTAGE2_ARGS}")
2525
26 set(_args ${zig0_EXE} ${INSTALL_LIBUSERLAND_ARGS})26 set(_args ${zig_EXE} ${ZIG_INSTALL_ARGS})
27 list(LENGTH _args _len)27 list(LENGTH _args _len)
28 math(EXPR _len "${_len} - 1")28 math(EXPR _len "${_len} - 1")
29 message("::")29 message("::")
doc/langref.html.in+23-153
...@@ -550,7 +550,7 @@ pub fn main() void {...@@ -550,7 +550,7 @@ pub fn main() void {
550 {#syntax#}i7{#endsyntax#} refers to a signed 7-bit integer. The maximum allowed bit-width of an550 {#syntax#}i7{#endsyntax#} refers to a signed 7-bit integer. The maximum allowed bit-width of an
551 integer type is {#syntax#}65535{#endsyntax#}.551 integer type is {#syntax#}65535{#endsyntax#}.
552 </p>552 </p>
553 {#see_also|Integers|Floats|void|Errors|@IntType#}553 {#see_also|Integers|Floats|void|Errors|@Type#}
554 {#header_close#}554 {#header_close#}
555 {#header_open|Primitive Values#}555 {#header_open|Primitive Values#}
556 <div class="table-wrapper">556 <div class="table-wrapper">
...@@ -2025,7 +2025,8 @@ test "volatile" {...@@ -2025,7 +2025,8 @@ test "volatile" {
2025 conversions are not possible.2025 conversions are not possible.
2026 </p>2026 </p>
2027 {#code_begin|test#}2027 {#code_begin|test#}
2028const assert = @import("std").debug.assert;2028const std = @import("std");
2029const assert = std.debug.assert;
20292030
2030test "pointer casting" {2031test "pointer casting" {
2031 const bytes align(@alignOf(u32)) = [_]u8{ 0x12, 0x12, 0x12, 0x12 };2032 const bytes align(@alignOf(u32)) = [_]u8{ 0x12, 0x12, 0x12, 0x12 };
...@@ -2034,7 +2035,7 @@ test "pointer casting" {...@@ -2034,7 +2035,7 @@ test "pointer casting" {
20342035
2035 // Even this example is contrived - there are better ways to do the above than2036 // Even this example is contrived - there are better ways to do the above than
2036 // pointer casting. For example, using a slice narrowing cast:2037 // pointer casting. For example, using a slice narrowing cast:
2037 const u32_value = @bytesToSlice(u32, bytes[0..])[0];2038 const u32_value = std.mem.bytesAsSlice(u32, bytes[0..])[0];
2038 assert(u32_value == 0x12121212);2039 assert(u32_value == 0x12121212);
20392040
2040 // And even another way, the most straightforward way to do it:2041 // And even another way, the most straightforward way to do it:
...@@ -2114,16 +2115,16 @@ test "function alignment" {...@@ -2114,16 +2115,16 @@ test "function alignment" {
2114 {#link|safety check|Incorrect Pointer Alignment#}:2115 {#link|safety check|Incorrect Pointer Alignment#}:
2115 </p>2116 </p>
2116 {#code_begin|test_safety|incorrect alignment#}2117 {#code_begin|test_safety|incorrect alignment#}
2117const assert = @import("std").debug.assert;2118const std = @import("std");
21182119
2119test "pointer alignment safety" {2120test "pointer alignment safety" {
2120 var array align(4) = [_]u32{ 0x11111111, 0x11111111 };2121 var array align(4) = [_]u32{ 0x11111111, 0x11111111 };
2121 const bytes = @sliceToBytes(array[0..]);2122 const bytes = std.mem.sliceAsBytes(array[0..]);
2122 assert(foo(bytes) == 0x11111111);2123 std.debug.assert(foo(bytes) == 0x11111111);
2123}2124}
2124fn foo(bytes: []u8) u32 {2125fn foo(bytes: []u8) u32 {
2125 const slice4 = bytes[1..5];2126 const slice4 = bytes[1..5];
2126 const int_slice = @bytesToSlice(u32, @alignCast(4, slice4));2127 const int_slice = std.mem.bytesAsSlice(u32, @alignCast(4, slice4));
2127 return int_slice[0];2128 return int_slice[0];
2128}2129}
2129 {#code_end#}2130 {#code_end#}
...@@ -2249,7 +2250,7 @@ test "slice widening" {...@@ -2249,7 +2250,7 @@ test "slice widening" {
2249 // Zig supports slice widening and slice narrowing. Cast a slice of u82250 // Zig supports slice widening and slice narrowing. Cast a slice of u8
2250 // to a slice of anything else, and Zig will perform the length conversion.2251 // to a slice of anything else, and Zig will perform the length conversion.
2251 const array align(@alignOf(u32)) = [_]u8{ 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13 };2252 const array align(@alignOf(u32)) = [_]u8{ 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13 };
2252 const slice = @bytesToSlice(u32, array[0..]);2253 const slice = mem.bytesAsSlice(u32, array[0..]);
2253 assert(slice.len == 2);2254 assert(slice.len == 2);
2254 assert(slice[0] == 0x12121212);2255 assert(slice[0] == 0x12121212);
2255 assert(slice[1] == 0x13131313);2256 assert(slice[1] == 0x13131313);
...@@ -2809,14 +2810,10 @@ test "@TagType" {...@@ -2809,14 +2810,10 @@ test "@TagType" {
2809 assert(@TagType(Small) == u2);2810 assert(@TagType(Small) == u2);
2810}2811}
28112812
2812// @memberCount tells how many fields an enum has:2813// @typeInfo tells us the field count and the fields names:
2813test "@memberCount" {2814test "@typeInfo" {
2814 assert(@memberCount(Small) == 4);2815 assert(@typeInfo(Small).Enum.fields.len == 4);
2815}2816 assert(mem.eql(u8, @typeInfo(Small).Enum.fields[1].name, "Two"));
2816
2817// @memberName tells the name of a field in an enum:
2818test "@memberName" {
2819 assert(mem.eql(u8, @memberName(Small, 1), "Two"));
2820}2817}
28212818
2822// @tagName gives a []const u8 representation of an enum value:2819// @tagName gives a []const u8 representation of an enum value:
...@@ -2824,7 +2821,7 @@ test "@tagName" {...@@ -2824,7 +2821,7 @@ test "@tagName" {
2824 assert(mem.eql(u8, @tagName(Small.Three), "Three"));2821 assert(mem.eql(u8, @tagName(Small.Three), "Three"));
2825}2822}
2826 {#code_end#}2823 {#code_end#}
2827 {#see_also|@memberName|@memberCount|@tagName|@sizeOf#}2824 {#see_also|@typeInfo|@tagName|@sizeOf#}
28282825
2829 {#header_open|extern enum#}2826 {#header_open|extern enum#}
2830 <p>2827 <p>
...@@ -5186,7 +5183,6 @@ test "coercion of zero bit types" {...@@ -5186,7 +5183,6 @@ test "coercion of zero bit types" {
5186 <li>{#link|@bitCast#} - change type but maintain bit representation</li>5183 <li>{#link|@bitCast#} - change type but maintain bit representation</li>
5187 <li>{#link|@alignCast#} - make a pointer have more alignment</li>5184 <li>{#link|@alignCast#} - make a pointer have more alignment</li>
5188 <li>{#link|@boolToInt#} - convert true to 1 and false to 0</li>5185 <li>{#link|@boolToInt#} - convert true to 1 and false to 0</li>
5189 <li>{#link|@bytesToSlice#} - convert a slice of bytes to a slice of another type</li>
5190 <li>{#link|@enumToInt#} - obtain the integer tag value of an enum or tagged union</li>5186 <li>{#link|@enumToInt#} - obtain the integer tag value of an enum or tagged union</li>
5191 <li>{#link|@errSetCast#} - convert to a smaller error set</li>5187 <li>{#link|@errSetCast#} - convert to a smaller error set</li>
5192 <li>{#link|@errorToInt#} - obtain the integer value of an error code</li>5188 <li>{#link|@errorToInt#} - obtain the integer value of an error code</li>
...@@ -5199,7 +5195,6 @@ test "coercion of zero bit types" {...@@ -5199,7 +5195,6 @@ test "coercion of zero bit types" {
5199 <li>{#link|@intToPtr#} - convert an address to a pointer</li>5195 <li>{#link|@intToPtr#} - convert an address to a pointer</li>
5200 <li>{#link|@ptrCast#} - convert between pointer types</li>5196 <li>{#link|@ptrCast#} - convert between pointer types</li>
5201 <li>{#link|@ptrToInt#} - obtain the address of a pointer</li>5197 <li>{#link|@ptrToInt#} - obtain the address of a pointer</li>
5202 <li>{#link|@sliceToBytes#} - convert a slice of anything to a slice of bytes</li>
5203 <li>{#link|@truncate#} - convert between integer types, chopping off bits</li>5198 <li>{#link|@truncate#} - convert between integer types, chopping off bits</li>
5204 </ul>5199 </ul>
5205 {#header_close#}5200 {#header_close#}
...@@ -6672,18 +6667,6 @@ comptime {...@@ -6672,18 +6667,6 @@ comptime {
6672 </p>6667 </p>
6673 {#see_also|Alignment#}6668 {#see_also|Alignment#}
6674 {#header_close#}6669 {#header_close#}
6675 {#header_open|@ArgType#}
6676 <pre>{#syntax#}@ArgType(comptime T: type, comptime n: usize) type{#endsyntax#}</pre>
6677 <p>
6678 This builtin function takes a function type and returns the type of the parameter at index {#syntax#}n{#endsyntax#}.
6679 </p>
6680 <p>
6681 {#syntax#}T{#endsyntax#} must be a function type.
6682 </p>
6683 <p>
6684 Note: This function is deprecated. Use {#link|@typeInfo#} instead.
6685 </p>
6686 {#header_close#}
66876670
6688 {#header_open|@as#}6671 {#header_open|@as#}
6689 <pre>{#syntax#}@as(comptime T: type, expression) T{#endsyntax#}</pre>6672 <pre>{#syntax#}@as(comptime T: type, expression) T{#endsyntax#}</pre>
...@@ -6817,7 +6800,7 @@ async fn func(y: *i32) void {...@@ -6817,7 +6800,7 @@ async fn func(y: *i32) void {
6817 Asserts that {#syntax#}@sizeOf(@TypeOf(value)) == @sizeOf(DestType){#endsyntax#}.6800 Asserts that {#syntax#}@sizeOf(@TypeOf(value)) == @sizeOf(DestType){#endsyntax#}.
6818 </p>6801 </p>
6819 <p>6802 <p>
6820 Asserts that {#syntax#}@typeId(DestType) != @import("builtin").TypeId.Pointer{#endsyntax#}. Use {#syntax#}@ptrCast{#endsyntax#} or {#syntax#}@intToPtr{#endsyntax#} if you need this.6803 Asserts that {#syntax#}@typeInfo(DestType) != .Pointer{#endsyntax#}. Use {#syntax#}@ptrCast{#endsyntax#} or {#syntax#}@intToPtr{#endsyntax#} if you need this.
6821 </p>6804 </p>
6822 <p>6805 <p>
6823 Can be used for these things for example:6806 Can be used for these things for example:
...@@ -6929,18 +6912,6 @@ async fn func(y: *i32) void {...@@ -6929,18 +6912,6 @@ async fn func(y: *i32) void {
6929 {#see_also|@bitOffsetOf#}6912 {#see_also|@bitOffsetOf#}
6930 {#header_close#}6913 {#header_close#}
69316914
6932 {#header_open|@bytesToSlice#}
6933 <pre>{#syntax#}@bytesToSlice(comptime Element: type, bytes: []u8) []Element{#endsyntax#}</pre>
6934 <p>
6935 Converts a slice of bytes or array of bytes into a slice of {#syntax#}Element{#endsyntax#}.
6936 The resulting slice has the same {#link|pointer|Pointers#} properties as the parameter.
6937 </p>
6938 <p>
6939 Attempting to convert a number of bytes with a length that does not evenly divide into a slice of
6940 elements results in safety-protected {#link|Undefined Behavior#}.
6941 </p>
6942 {#header_close#}
6943
6944 {#header_open|@call#}6915 {#header_open|@call#}
6945 <pre>{#syntax#}@call(options: std.builtin.CallOptions, function: var, args: var) var{#endsyntax#}</pre>6916 <pre>{#syntax#}@call(options: std.builtin.CallOptions, function: var, args: var) var{#endsyntax#}</pre>
6946 <p>6917 <p>
...@@ -7248,7 +7219,7 @@ test "main" {...@@ -7248,7 +7219,7 @@ test "main" {
7248 <p>7219 <p>
7249 Floored division. Rounds toward negative infinity. For unsigned integers it is7220 Floored division. Rounds toward negative infinity. For unsigned integers it is
7250 the same as {#syntax#}numerator / denominator{#endsyntax#}. Caller guarantees {#syntax#}denominator != 0{#endsyntax#} and7221 the same as {#syntax#}numerator / denominator{#endsyntax#}. Caller guarantees {#syntax#}denominator != 0{#endsyntax#} and
7251 {#syntax#}!(@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1){#endsyntax#}.7222 {#syntax#}!(@typeInfo(T) == .Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1){#endsyntax#}.
7252 </p>7223 </p>
7253 <ul>7224 <ul>
7254 <li>{#syntax#}@divFloor(-5, 3) == -2{#endsyntax#}</li>7225 <li>{#syntax#}@divFloor(-5, 3) == -2{#endsyntax#}</li>
...@@ -7262,7 +7233,7 @@ test "main" {...@@ -7262,7 +7233,7 @@ test "main" {
7262 <p>7233 <p>
7263 Truncated division. Rounds toward zero. For unsigned integers it is7234 Truncated division. Rounds toward zero. For unsigned integers it is
7264 the same as {#syntax#}numerator / denominator{#endsyntax#}. Caller guarantees {#syntax#}denominator != 0{#endsyntax#} and7235 the same as {#syntax#}numerator / denominator{#endsyntax#}. Caller guarantees {#syntax#}denominator != 0{#endsyntax#} and
7265 {#syntax#}!(@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1){#endsyntax#}.7236 {#syntax#}!(@typeInfo(T) == .Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1){#endsyntax#}.
7266 </p>7237 </p>
7267 <ul>7238 <ul>
7268 <li>{#syntax#}@divTrunc(-5, 3) == -1{#endsyntax#}</li>7239 <li>{#syntax#}@divTrunc(-5, 3) == -1{#endsyntax#}</li>
...@@ -7320,7 +7291,7 @@ test "main" {...@@ -7320,7 +7291,7 @@ test "main" {
7320 {#header_close#}7291 {#header_close#}
73217292
7322 {#header_open|@errorToInt#}7293 {#header_open|@errorToInt#}
7323 <pre>{#syntax#}@errorToInt(err: var) @IntType(false, @sizeOf(anyerror) * 8){#endsyntax#}</pre>7294 <pre>{#syntax#}@errorToInt(err: var) std.meta.IntType(false, @sizeOf(anyerror) * 8){#endsyntax#}</pre>
7324 <p>7295 <p>
7325 Supports the following types:7296 Supports the following types:
7326 </p>7297 </p>
...@@ -7365,7 +7336,7 @@ comptime {...@@ -7365,7 +7336,7 @@ comptime {
7365 @export(internalName, .{ .name = "foo", .linkage = .Strong });7336 @export(internalName, .{ .name = "foo", .linkage = .Strong });
7366}7337}
73677338
7368extern fn internalName() void {}7339fn internalName() callconv(.C) void {}
7369 {#code_end#}7340 {#code_end#}
7370 <p>This is equivalent to:</p>7341 <p>This is equivalent to:</p>
7371 {#code_begin|obj#}7342 {#code_begin|obj#}
...@@ -7614,7 +7585,7 @@ test "@hasDecl" {...@@ -7614,7 +7585,7 @@ test "@hasDecl" {
7614 {#header_close#}7585 {#header_close#}
76157586
7616 {#header_open|@intToError#}7587 {#header_open|@intToError#}
7617 <pre>{#syntax#}@intToError(value: @IntType(false, @sizeOf(anyerror) * 8)) anyerror{#endsyntax#}</pre>7588 <pre>{#syntax#}@intToError(value: std.meta.IntType(false, @sizeOf(anyerror) * 8)) anyerror{#endsyntax#}</pre>
7618 <p>7589 <p>
7619 Converts from the integer representation of an error into {#link|The Global Error Set#} type.7590 Converts from the integer representation of an error into {#link|The Global Error Set#} type.
7620 </p>7591 </p>
...@@ -7647,44 +7618,6 @@ test "@hasDecl" {...@@ -7647,44 +7618,6 @@ test "@hasDecl" {
7647 </p>7618 </p>
7648 {#header_close#}7619 {#header_close#}
76497620
7650 {#header_open|@IntType#}
7651 <pre>{#syntax#}@IntType(comptime is_signed: bool, comptime bit_count: u16) type{#endsyntax#}</pre>
7652 <p>
7653 This function returns an integer type with the given signness and bit count. The maximum
7654 bit count for an integer type is {#syntax#}65535{#endsyntax#}.
7655 </p>
7656 <p>
7657 Deprecated. Use {#link|@Type#}.
7658 </p>
7659 {#header_close#}
7660
7661 {#header_open|@memberCount#}
7662 <pre>{#syntax#}@memberCount(comptime T: type) comptime_int{#endsyntax#}</pre>
7663 <p>
7664 This function returns the number of members in a struct, enum, or union type.
7665 </p>
7666 <p>
7667 The result is a compile time constant.
7668 </p>
7669 <p>
7670 It does not include functions, variables, or constants.
7671 </p>
7672 {#header_close#}
7673 {#header_open|@memberName#}
7674 <pre>{#syntax#}@memberName(comptime T: type, comptime index: usize) [N]u8{#endsyntax#}</pre>
7675 <p>Returns the field name of a struct, union, or enum.</p>
7676 <p>
7677 The result is a compile time constant.
7678 </p>
7679 <p>
7680 It does not include functions, variables, or constants.
7681 </p>
7682 {#header_close#}
7683 {#header_open|@memberType#}
7684 <pre>{#syntax#}@memberType(comptime T: type, comptime index: usize) type{#endsyntax#}</pre>
7685 <p>Returns the field type of a struct or union.</p>
7686 {#header_close#}
7687
7688 {#header_open|@memcpy#}7621 {#header_open|@memcpy#}
7689 <pre>{#syntax#}@memcpy(noalias dest: [*]u8, noalias source: [*]const u8, byte_count: usize){#endsyntax#}</pre>7622 <pre>{#syntax#}@memcpy(noalias dest: [*]u8, noalias source: [*]const u8, byte_count: usize){#endsyntax#}</pre>
7690 <p>7623 <p>
...@@ -8067,14 +8000,6 @@ test "@setRuntimeSafety" {...@@ -8067,14 +8000,6 @@ test "@setRuntimeSafety" {
8067 {#see_also|@bitSizeOf|@typeInfo#}8000 {#see_also|@bitSizeOf|@typeInfo#}
8068 {#header_close#}8001 {#header_close#}
80698002
8070 {#header_open|@sliceToBytes#}
8071 <pre>{#syntax#}@sliceToBytes(value: var) []u8{#endsyntax#}</pre>
8072 <p>
8073 Converts a slice or array to a slice of {#syntax#}u8{#endsyntax#}. The resulting slice has the same
8074 {#link|pointer|Pointers#} properties as the parameter.
8075 </p>
8076 {#header_close#}
8077
8078 {#header_open|@splat#}8003 {#header_open|@splat#}
8079 <pre>{#syntax#}@splat(comptime len: u32, scalar: var) @Vector(len, @TypeOf(scalar)){#endsyntax#}</pre>8004 <pre>{#syntax#}@splat(comptime len: u32, scalar: var) @Vector(len, @TypeOf(scalar)){#endsyntax#}</pre>
8080 <p>8005 <p>
...@@ -8388,43 +8313,6 @@ test "integer truncation" {...@@ -8388,43 +8313,6 @@ test "integer truncation" {
8388 <li>{#link|struct#}</li>8313 <li>{#link|struct#}</li>
8389 </ul>8314 </ul>
8390 {#header_close#}8315 {#header_close#}
8391
8392 {#header_open|@typeId#}
8393 <pre>{#syntax#}@typeId(comptime T: type) @import("builtin").TypeId{#endsyntax#}</pre>
8394 <p>
8395 Returns which kind of type something is. Possible values:
8396 </p>
8397 {#code_begin|syntax#}
8398pub const TypeId = enum {
8399 Type,
8400 Void,
8401 Bool,
8402 NoReturn,
8403 Int,
8404 Float,
8405 Pointer,
8406 Array,
8407 Struct,
8408 ComptimeFloat,
8409 ComptimeInt,
8410 Undefined,
8411 Null,
8412 Optional,
8413 ErrorUnion,
8414 ErrorSet,
8415 Enum,
8416 Union,
8417 Fn,
8418 BoundFn,
8419 Opaque,
8420 Frame,
8421 AnyFrame,
8422 Vector,
8423 EnumLiteral,
8424};
8425 {#code_end#}
8426 {#header_close#}
8427
8428 {#header_open|@typeInfo#}8316 {#header_open|@typeInfo#}
8429 <pre>{#syntax#}@typeInfo(comptime T: type) @import("std").builtin.TypeInfo{#endsyntax#}</pre>8317 <pre>{#syntax#}@typeInfo(comptime T: type) @import("std").builtin.TypeInfo{#endsyntax#}</pre>
8430 <p>8318 <p>
...@@ -8885,25 +8773,6 @@ pub fn main() void {...@@ -8885,25 +8773,6 @@ pub fn main() void {
8885 var b: u32 = 3;8773 var b: u32 = 3;
8886 var c = @divExact(a, b);8774 var c = @divExact(a, b);
8887 std.debug.warn("value: {}\n", .{c});8775 std.debug.warn("value: {}\n", .{c});
8888}
8889 {#code_end#}
8890 {#header_close#}
8891 {#header_open|Slice Widen Remainder#}
8892 <p>At compile-time:</p>
8893 {#code_begin|test_err|unable to convert#}
8894comptime {
8895 var bytes = [5]u8{ 1, 2, 3, 4, 5 };
8896 var slice = @bytesToSlice(u32, bytes[0..]);
8897}
8898 {#code_end#}
8899 <p>At runtime:</p>
8900 {#code_begin|exe_err#}
8901const std = @import("std");
8902
8903pub fn main() void {
8904 var bytes = [5]u8{ 1, 2, 3, 4, 5 };
8905 var slice = @bytesToSlice(u32, bytes[0..]);
8906 std.debug.warn("value: {}\n", .{slice[0]});
8907}8776}
8908 {#code_end#}8777 {#code_end#}
8909 {#header_close#}8778 {#header_close#}
...@@ -9085,14 +8954,15 @@ comptime {...@@ -9085,14 +8954,15 @@ comptime {
9085 {#code_end#}8954 {#code_end#}
9086 <p>At runtime:</p>8955 <p>At runtime:</p>
9087 {#code_begin|exe_err#}8956 {#code_begin|exe_err#}
8957const mem = @import("std").mem;
9088pub fn main() !void {8958pub fn main() !void {
9089 var array align(4) = [_]u32{ 0x11111111, 0x11111111 };8959 var array align(4) = [_]u32{ 0x11111111, 0x11111111 };
9090 const bytes = @sliceToBytes(array[0..]);8960 const bytes = mem.sliceAsBytes(array[0..]);
9091 if (foo(bytes) != 0x11111111) return error.Wrong;8961 if (foo(bytes) != 0x11111111) return error.Wrong;
9092}8962}
9093fn foo(bytes: []u8) u32 {8963fn foo(bytes: []u8) u32 {
9094 const slice4 = bytes[1..5];8964 const slice4 = bytes[1..5];
9095 const int_slice = @bytesToSlice(u32, @alignCast(4, slice4));8965 const int_slice = mem.bytesAsSlice(u32, @alignCast(4, slice4));
9096 return int_slice[0];8966 return int_slice[0];
9097}8967}
9098 {#code_end#}8968 {#code_end#}
lib/std/array_list.zig+25
...@@ -188,6 +188,14 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {...@@ -188,6 +188,14 @@ pub fn AlignedArrayList(comptime T: type, comptime alignment: ?u29) type {
188 self.len += items.len;188 self.len += items.len;
189 }189 }
190190
191 /// Append a value to the list `n` times. Allocates more memory
192 /// as necessary.
193 pub fn appendNTimes(self: *Self, value: T, n: usize) !void {
194 const old_len = self.len;
195 try self.resize(self.len + n);
196 mem.set(T, self.items[old_len..self.len], value);
197 }
198
191 /// Adjust the list's length to `new_len`. Doesn't initialize199 /// Adjust the list's length to `new_len`. Doesn't initialize
192 /// added items if any.200 /// added items if any.
193 pub fn resize(self: *Self, new_len: usize) !void {201 pub fn resize(self: *Self, new_len: usize) !void {
...@@ -311,6 +319,23 @@ test "std.ArrayList.basic" {...@@ -311,6 +319,23 @@ test "std.ArrayList.basic" {
311 testing.expect(list.pop() == 33);319 testing.expect(list.pop() == 33);
312}320}
313321
322test "std.ArrayList.appendNTimes" {
323 var list = ArrayList(i32).init(testing.allocator);
324 defer list.deinit();
325
326 try list.appendNTimes(2, 10);
327 testing.expectEqual(@as(usize, 10), list.len);
328 for (list.toSlice()) |element| {
329 testing.expectEqual(@as(i32, 2), element);
330 }
331}
332
333test "std.ArrayList.appendNTimes with failing allocator" {
334 var list = ArrayList(i32).init(testing.failing_allocator);
335 defer list.deinit();
336 testing.expectError(error.OutOfMemory, list.appendNTimes(2, 10));
337}
338
314test "std.ArrayList.orderedRemove" {339test "std.ArrayList.orderedRemove" {
315 var list = ArrayList(i32).init(testing.allocator);340 var list = ArrayList(i32).init(testing.allocator);
316 defer list.deinit();341 defer list.deinit();
lib/std/buffer.zig+12
...@@ -147,6 +147,10 @@ pub const Buffer = struct {...@@ -147,6 +147,10 @@ pub const Buffer = struct {
147 try self.resize(m.len);147 try self.resize(m.len);
148 mem.copy(u8, self.list.toSlice(), m);148 mem.copy(u8, self.list.toSlice(), m);
149 }149 }
150
151 pub fn print(self: *Buffer, comptime fmt: []const u8, args: var) !void {
152 return std.fmt.format(self, error{OutOfMemory}, Buffer.append, fmt, args);
153 }
150};154};
151155
152test "simple Buffer" {156test "simple Buffer" {
...@@ -190,3 +194,11 @@ test "Buffer.initCapacity" {...@@ -190,3 +194,11 @@ test "Buffer.initCapacity" {
190 testing.expect(buf.capacity() == old_cap);194 testing.expect(buf.capacity() == old_cap);
191 testing.expect(mem.eql(u8, buf.toSliceConst(), "hello"));195 testing.expect(mem.eql(u8, buf.toSliceConst(), "hello"));
192}196}
197
198test "Buffer.print" {
199 var buf = try Buffer.init(testing.allocator, "");
200 defer buf.deinit();
201
202 try buf.print("Hello {} the {}", .{ 2, "world" });
203 testing.expect(buf.eql("Hello 2 the world"));
204}
lib/std/build.zig+35-158
...@@ -27,9 +27,6 @@ pub const Builder = struct {...@@ -27,9 +27,6 @@ pub const Builder = struct {
27 install_tls: TopLevelStep,27 install_tls: TopLevelStep,
28 uninstall_tls: TopLevelStep,28 uninstall_tls: TopLevelStep,
29 allocator: *Allocator,29 allocator: *Allocator,
30 native_system_lib_paths: ArrayList([]const u8),
31 native_system_include_dirs: ArrayList([]const u8),
32 native_system_rpaths: ArrayList([]const u8),
33 user_input_options: UserInputOptionsMap,30 user_input_options: UserInputOptionsMap,
34 available_options_map: AvailableOptionsMap,31 available_options_map: AvailableOptionsMap,
35 available_options_list: ArrayList(AvailableOption),32 available_options_list: ArrayList(AvailableOption),
...@@ -41,6 +38,7 @@ pub const Builder = struct {...@@ -41,6 +38,7 @@ pub const Builder = struct {
41 verbose_ir: bool,38 verbose_ir: bool,
42 verbose_llvm_ir: bool,39 verbose_llvm_ir: bool,
43 verbose_cimport: bool,40 verbose_cimport: bool,
41 verbose_llvm_cpu_features: bool,
44 invalid_user_input: bool,42 invalid_user_input: bool,
45 zig_exe: []const u8,43 zig_exe: []const u8,
46 default_step: *Step,44 default_step: *Step,
...@@ -137,11 +135,9 @@ pub const Builder = struct {...@@ -137,11 +135,9 @@ pub const Builder = struct {
137 .verbose_ir = false,135 .verbose_ir = false,
138 .verbose_llvm_ir = false,136 .verbose_llvm_ir = false,
139 .verbose_cimport = false,137 .verbose_cimport = false,
138 .verbose_llvm_cpu_features = false,
140 .invalid_user_input = false,139 .invalid_user_input = false,
141 .allocator = allocator,140 .allocator = allocator,
142 .native_system_lib_paths = ArrayList([]const u8).init(allocator),
143 .native_system_include_dirs = ArrayList([]const u8).init(allocator),
144 .native_system_rpaths = ArrayList([]const u8).init(allocator),
145 .user_input_options = UserInputOptionsMap.init(allocator),141 .user_input_options = UserInputOptionsMap.init(allocator),
146 .available_options_map = AvailableOptionsMap.init(allocator),142 .available_options_map = AvailableOptionsMap.init(allocator),
147 .available_options_list = ArrayList(AvailableOption).init(allocator),143 .available_options_list = ArrayList(AvailableOption).init(allocator),
...@@ -172,15 +168,11 @@ pub const Builder = struct {...@@ -172,15 +168,11 @@ pub const Builder = struct {
172 };168 };
173 try self.top_level_steps.append(&self.install_tls);169 try self.top_level_steps.append(&self.install_tls);
174 try self.top_level_steps.append(&self.uninstall_tls);170 try self.top_level_steps.append(&self.uninstall_tls);
175 self.detectNativeSystemPaths();
176 self.default_step = &self.install_tls.step;171 self.default_step = &self.install_tls.step;
177 return self;172 return self;
178 }173 }
179174
180 pub fn destroy(self: *Builder) void {175 pub fn destroy(self: *Builder) void {
181 self.native_system_lib_paths.deinit();
182 self.native_system_include_dirs.deinit();
183 self.native_system_rpaths.deinit();
184 self.env_map.deinit();176 self.env_map.deinit();
185 self.top_level_steps.deinit();177 self.top_level_steps.deinit();
186 self.allocator.destroy(self);178 self.allocator.destroy(self);
...@@ -347,18 +339,6 @@ pub const Builder = struct {...@@ -347,18 +339,6 @@ pub const Builder = struct {
347 };339 };
348 }340 }
349341
350 pub fn addNativeSystemIncludeDir(self: *Builder, path: []const u8) void {
351 self.native_system_include_dirs.append(path) catch unreachable;
352 }
353
354 pub fn addNativeSystemRPath(self: *Builder, path: []const u8) void {
355 self.native_system_rpaths.append(path) catch unreachable;
356 }
357
358 pub fn addNativeSystemLibPath(self: *Builder, path: []const u8) void {
359 self.native_system_lib_paths.append(path) catch unreachable;
360 }
361
362 pub fn make(self: *Builder, step_names: []const []const u8) !void {342 pub fn make(self: *Builder, step_names: []const []const u8) !void {
363 try self.makePath(self.cache_root);343 try self.makePath(self.cache_root);
364344
...@@ -433,87 +413,6 @@ pub const Builder = struct {...@@ -433,87 +413,6 @@ pub const Builder = struct {
433 return error.InvalidStepName;413 return error.InvalidStepName;
434 }414 }
435415
436 fn detectNativeSystemPaths(self: *Builder) void {
437 var is_nixos = false;
438 if (process.getEnvVarOwned(self.allocator, "NIX_CFLAGS_COMPILE")) |nix_cflags_compile| {
439 is_nixos = true;
440 var it = mem.tokenize(nix_cflags_compile, " ");
441 while (true) {
442 const word = it.next() orelse break;
443 if (mem.eql(u8, word, "-isystem")) {
444 const include_path = it.next() orelse {
445 warn("Expected argument after -isystem in NIX_CFLAGS_COMPILE\n", .{});
446 break;
447 };
448 self.addNativeSystemIncludeDir(include_path);
449 } else {
450 warn("Unrecognized C flag from NIX_CFLAGS_COMPILE: {}\n", .{word});
451 break;
452 }
453 }
454 } else |err| {
455 assert(err == error.EnvironmentVariableNotFound);
456 }
457 if (process.getEnvVarOwned(self.allocator, "NIX_LDFLAGS")) |nix_ldflags| {
458 is_nixos = true;
459 var it = mem.tokenize(nix_ldflags, " ");
460 while (true) {
461 const word = it.next() orelse break;
462 if (mem.eql(u8, word, "-rpath")) {
463 const rpath = it.next() orelse {
464 warn("Expected argument after -rpath in NIX_LDFLAGS\n", .{});
465 break;
466 };
467 self.addNativeSystemRPath(rpath);
468 } else if (word.len > 2 and word[0] == '-' and word[1] == 'L') {
469 const lib_path = word[2..];
470 self.addNativeSystemLibPath(lib_path);
471 } else {
472 warn("Unrecognized C flag from NIX_LDFLAGS: {}\n", .{word});
473 break;
474 }
475 }
476 } else |err| {
477 assert(err == error.EnvironmentVariableNotFound);
478 }
479 if (is_nixos) return;
480 switch (builtin.os) {
481 .windows => {},
482 else => {
483 const triple = (Target{
484 .Cross = CrossTarget{
485 .arch = builtin.arch,
486 .os = builtin.os,
487 .abi = builtin.abi,
488 .cpu_features = builtin.cpu_features,
489 },
490 }).linuxTriple(self.allocator);
491
492 // TODO: $ ld --verbose | grep SEARCH_DIR
493 // the output contains some paths that end with lib64, maybe include them too?
494 // also, what is the best possible order of things?
495
496 self.addNativeSystemIncludeDir("/usr/local/include");
497 self.addNativeSystemLibPath("/usr/local/lib");
498 self.addNativeSystemLibPath("/usr/local/lib64");
499
500 self.addNativeSystemIncludeDir(self.fmt("/usr/include/{}", .{triple}));
501 self.addNativeSystemLibPath(self.fmt("/usr/lib/{}", .{triple}));
502
503 self.addNativeSystemIncludeDir("/usr/include");
504 self.addNativeSystemLibPath("/lib");
505 self.addNativeSystemLibPath("/lib64");
506 self.addNativeSystemLibPath("/usr/lib");
507 self.addNativeSystemLibPath("/usr/lib64");
508
509 // example: on a 64-bit debian-based linux distro, with zlib installed from apt:
510 // zlib.h is in /usr/include (added above)
511 // libz.so.1 is in /lib/x86_64-linux-gnu (added here)
512 self.addNativeSystemLibPath(self.fmt("/lib/{}", .{triple}));
513 },
514 }
515 }
516
517 pub fn option(self: *Builder, comptime T: type, name: []const u8, description: []const u8) ?T {416 pub fn option(self: *Builder, comptime T: type, name: []const u8, description: []const u8) ?T {
518 const type_id = comptime typeToEnum(T);417 const type_id = comptime typeToEnum(T);
519 const available_option = AvailableOption{418 const available_option = AvailableOption{
...@@ -638,7 +537,7 @@ pub const Builder = struct {...@@ -638,7 +537,7 @@ pub const Builder = struct {
638 return Target.Native;537 return Target.Native;
639 } else {538 } else {
640 const target_str = self.option([]const u8, "target", "the target to build for") orelse return Target.Native;539 const target_str = self.option([]const u8, "target", "the target to build for") orelse return Target.Native;
641 return Target.parse(target_str) catch unreachable; // TODO better error message for bad target540 return Target.parse(.{ .arch_os_abi = target_str }) catch unreachable; // TODO better error message for bad target
642 }541 }
643 }542 }
644543
...@@ -710,13 +609,13 @@ pub const Builder = struct {...@@ -710,13 +609,13 @@ pub const Builder = struct {
710 }609 }
711610
712 fn typeToEnum(comptime T: type) TypeId {611 fn typeToEnum(comptime T: type) TypeId {
713 return switch (@typeId(T)) {612 return switch (@typeInfo(T)) {
714 builtin.TypeId.Int => TypeId.Int,613 .Int => .Int,
715 builtin.TypeId.Float => TypeId.Float,614 .Float => .Float,
716 builtin.TypeId.Bool => TypeId.Bool,615 .Bool => .Bool,
717 else => switch (T) {616 else => switch (T) {
718 []const u8 => TypeId.String,617 []const u8 => .String,
719 []const []const u8 => TypeId.List,618 []const []const u8 => .List,
720 else => @compileError("Unsupported type: " ++ @typeName(T)),619 else => @compileError("Unsupported type: " ++ @typeName(T)),
721 },620 },
722 };621 };
...@@ -728,11 +627,11 @@ pub const Builder = struct {...@@ -728,11 +627,11 @@ pub const Builder = struct {
728627
729 pub fn typeIdName(id: TypeId) []const u8 {628 pub fn typeIdName(id: TypeId) []const u8 {
730 return switch (id) {629 return switch (id) {
731 TypeId.Bool => "bool",630 .Bool => "bool",
732 TypeId.Int => "int",631 .Int => "int",
733 TypeId.Float => "float",632 .Float => "float",
734 TypeId.String => "string",633 .String => "string",
735 TypeId.List => "list",634 .List => "list",
736 };635 };
737 }636 }
738637
...@@ -1155,6 +1054,9 @@ pub const LibExeObjStep = struct {...@@ -1155,6 +1054,9 @@ pub const LibExeObjStep = struct {
1155 frameworks: BufSet,1054 frameworks: BufSet,
1156 verbose_link: bool,1055 verbose_link: bool,
1157 verbose_cc: bool,1056 verbose_cc: bool,
1057 emit_llvm_ir: bool = false,
1058 emit_asm: bool = false,
1059 emit_bin: bool = true,
1158 disable_gen_h: bool,1060 disable_gen_h: bool,
1159 bundle_compiler_rt: bool,1061 bundle_compiler_rt: bool,
1160 disable_stack_probing: bool,1062 disable_stack_probing: bool,
...@@ -1182,7 +1084,6 @@ pub const LibExeObjStep = struct {...@@ -1182,7 +1084,6 @@ pub const LibExeObjStep = struct {
1182 include_dirs: ArrayList(IncludeDir),1084 include_dirs: ArrayList(IncludeDir),
1183 c_macros: ArrayList([]const u8),1085 c_macros: ArrayList([]const u8),
1184 output_dir: ?[]const u8,1086 output_dir: ?[]const u8,
1185 need_system_paths: bool,
1186 is_linking_libc: bool = false,1087 is_linking_libc: bool = false,
1187 vcpkg_bin_path: ?[]const u8 = null,1088 vcpkg_bin_path: ?[]const u8 = null,
11881089
...@@ -1320,7 +1221,6 @@ pub const LibExeObjStep = struct {...@@ -1320,7 +1221,6 @@ pub const LibExeObjStep = struct {
1320 .disable_stack_probing = false,1221 .disable_stack_probing = false,
1321 .disable_sanitize_c = false,1222 .disable_sanitize_c = false,
1322 .output_dir = null,1223 .output_dir = null,
1323 .need_system_paths = false,
1324 .single_threaded = false,1224 .single_threaded = false,
1325 .installed_path = null,1225 .installed_path = null,
1326 .install_step = null,1226 .install_step = null,
...@@ -1496,7 +1396,6 @@ pub const LibExeObjStep = struct {...@@ -1496,7 +1396,6 @@ pub const LibExeObjStep = struct {
1496 /// Prefer to use `linkSystemLibrary` instead.1396 /// Prefer to use `linkSystemLibrary` instead.
1497 pub fn linkSystemLibraryName(self: *LibExeObjStep, name: []const u8) void {1397 pub fn linkSystemLibraryName(self: *LibExeObjStep, name: []const u8) void {
1498 self.link_objects.append(LinkObject{ .SystemLib = self.builder.dupe(name) }) catch unreachable;1398 self.link_objects.append(LinkObject{ .SystemLib = self.builder.dupe(name) }) catch unreachable;
1499 self.need_system_paths = true;
1500 }1399 }
15011400
1502 /// This links against a system library, exclusively using pkg-config to find the library.1401 /// This links against a system library, exclusively using pkg-config to find the library.
...@@ -1940,6 +1839,11 @@ pub const LibExeObjStep = struct {...@@ -1940,6 +1839,11 @@ pub const LibExeObjStep = struct {
1940 if (builder.verbose_llvm_ir) zig_args.append("--verbose-llvm-ir") catch unreachable;1839 if (builder.verbose_llvm_ir) zig_args.append("--verbose-llvm-ir") catch unreachable;
1941 if (builder.verbose_link or self.verbose_link) zig_args.append("--verbose-link") catch unreachable;1840 if (builder.verbose_link or self.verbose_link) zig_args.append("--verbose-link") catch unreachable;
1942 if (builder.verbose_cc or self.verbose_cc) zig_args.append("--verbose-cc") catch unreachable;1841 if (builder.verbose_cc or self.verbose_cc) zig_args.append("--verbose-cc") catch unreachable;
1842 if (builder.verbose_llvm_cpu_features) zig_args.append("--verbose-llvm-cpu-features") catch unreachable;
1843
1844 if (self.emit_llvm_ir) try zig_args.append("-femit-llvm-ir");
1845 if (self.emit_asm) try zig_args.append("-femit-asm");
1846 if (!self.emit_bin) try zig_args.append("-fno-emit-bin");
19431847
1944 if (self.strip) {1848 if (self.strip) {
1945 try zig_args.append("--strip");1849 try zig_args.append("--strip");
...@@ -2008,43 +1912,33 @@ pub const LibExeObjStep = struct {...@@ -2008,43 +1912,33 @@ pub const LibExeObjStep = struct {
2008 try zig_args.append(self.target.zigTriple(builder.allocator) catch unreachable);1912 try zig_args.append(self.target.zigTriple(builder.allocator) catch unreachable);
20091913
2010 const all_features = self.target.getArch().allFeaturesList();1914 const all_features = self.target.getArch().allFeaturesList();
2011 var populated_cpu_features = cross.cpu_features.cpu.features;1915 var populated_cpu_features = cross.cpu.model.features;
2012 if (self.target.getArch().subArchFeature()) |sub_arch_index| {
2013 populated_cpu_features.addFeature(sub_arch_index);
2014 }
2015 populated_cpu_features.populateDependencies(all_features);1916 populated_cpu_features.populateDependencies(all_features);
20161917
2017 if (populated_cpu_features.eql(cross.cpu_features.features)) {1918 if (populated_cpu_features.eql(cross.cpu.features)) {
2018 // The CPU name alone is sufficient.1919 // The CPU name alone is sufficient.
2019 // If it is the baseline CPU, no command line args are required.1920 // If it is the baseline CPU, no command line args are required.
2020 if (cross.cpu_features.cpu != self.target.getArch().getBaselineCpuFeatures().cpu) {1921 if (cross.cpu.model != Target.Cpu.baseline(self.target.getArch()).model) {
2021 try zig_args.append("-target-cpu");1922 try zig_args.append("-mcpu");
2022 try zig_args.append(cross.cpu_features.cpu.name);1923 try zig_args.append(cross.cpu.model.name);
2023 }1924 }
2024 } else {1925 } else {
2025 try zig_args.append("-target-cpu");1926 var mcpu_buffer = try std.Buffer.init(builder.allocator, "-mcpu=");
2026 try zig_args.append(cross.cpu_features.cpu.name);1927 try mcpu_buffer.append(cross.cpu.model.name);
20271928
2028 try zig_args.append("-target-feature");
2029 var feature_str_buffer = try std.Buffer.initSize(builder.allocator, 0);
2030 for (all_features) |feature, i_usize| {1929 for (all_features) |feature, i_usize| {
2031 const i = @intCast(Target.Cpu.Feature.Set.Index, i_usize);1930 const i = @intCast(Target.Cpu.Feature.Set.Index, i_usize);
2032 const in_cpu_set = populated_cpu_features.isEnabled(i);1931 const in_cpu_set = populated_cpu_features.isEnabled(i);
2033 const in_actual_set = cross.cpu_features.features.isEnabled(i);1932 const in_actual_set = cross.cpu.features.isEnabled(i);
2034 if (in_cpu_set and !in_actual_set) {1933 if (in_cpu_set and !in_actual_set) {
2035 try feature_str_buffer.appendByte('-');1934 try mcpu_buffer.appendByte('-');
2036 try feature_str_buffer.append(feature.name);1935 try mcpu_buffer.append(feature.name);
2037 try feature_str_buffer.appendByte(',');
2038 } else if (!in_cpu_set and in_actual_set) {1936 } else if (!in_cpu_set and in_actual_set) {
2039 try feature_str_buffer.appendByte('+');1937 try mcpu_buffer.appendByte('+');
2040 try feature_str_buffer.append(feature.name);1938 try mcpu_buffer.append(feature.name);
2041 try feature_str_buffer.appendByte(',');
2042 }1939 }
2043 }1940 }
2044 if (mem.endsWith(u8, feature_str_buffer.toSliceConst(), ",")) {1941 try zig_args.append(mcpu_buffer.toSliceConst());
2045 feature_str_buffer.shrink(feature_str_buffer.len() - 1);
2046 }
2047 try zig_args.append(feature_str_buffer.toSliceConst());
2048 }1942 }
2049 },1943 },
2050 }1944 }
...@@ -2152,23 +2046,6 @@ pub const LibExeObjStep = struct {...@@ -2152,23 +2046,6 @@ pub const LibExeObjStep = struct {
2152 try zig_args.append(lib_path);2046 try zig_args.append(lib_path);
2153 }2047 }
21542048
2155 if (self.need_system_paths and self.target == Target.Native) {
2156 for (builder.native_system_include_dirs.toSliceConst()) |include_path| {
2157 zig_args.append("-isystem") catch unreachable;
2158 zig_args.append(builder.pathFromRoot(include_path)) catch unreachable;
2159 }
2160
2161 for (builder.native_system_rpaths.toSliceConst()) |rpath| {
2162 zig_args.append("-rpath") catch unreachable;
2163 zig_args.append(rpath) catch unreachable;
2164 }
2165
2166 for (builder.native_system_lib_paths.toSliceConst()) |lib_path| {
2167 zig_args.append("--library-path") catch unreachable;
2168 zig_args.append(lib_path) catch unreachable;
2169 }
2170 }
2171
2172 for (self.c_macros.toSliceConst()) |c_macro| {2049 for (self.c_macros.toSliceConst()) |c_macro| {
2173 try zig_args.append("-D");2050 try zig_args.append("-D");
2174 try zig_args.append(c_macro);2051 try zig_args.append(c_macro);
lib/std/builtin.zig+2-5
...@@ -6,8 +6,8 @@ pub const Target = std.Target;...@@ -6,8 +6,8 @@ pub const Target = std.Target;
6/// Deprecated: use `std.Target.Os`.6/// Deprecated: use `std.Target.Os`.
7pub const Os = std.Target.Os;7pub const Os = std.Target.Os;
88
9/// Deprecated: use `std.Target.Arch`.9/// Deprecated: use `std.Target.Cpu.Arch`.
10pub const Arch = std.Target.Arch;10pub const Arch = std.Target.Cpu.Arch;
1111
12/// Deprecated: use `std.Target.Abi`.12/// Deprecated: use `std.Target.Abi`.
13pub const Abi = std.Target.Abi;13pub const Abi = std.Target.Abi;
...@@ -18,9 +18,6 @@ pub const ObjectFormat = std.Target.ObjectFormat;...@@ -18,9 +18,6 @@ pub const ObjectFormat = std.Target.ObjectFormat;
18/// Deprecated: use `std.Target.SubSystem`.18/// Deprecated: use `std.Target.SubSystem`.
19pub const SubSystem = std.Target.SubSystem;19pub const SubSystem = std.Target.SubSystem;
2020
21/// Deprecated: use `std.Target.CpuFeatures`.
22pub const CpuFeatures = std.Target.CpuFeatures;
23
24/// Deprecated: use `std.Target.Cpu`.21/// Deprecated: use `std.Target.Cpu`.
25pub const Cpu = std.Target.Cpu;22pub const Cpu = std.Target.Cpu;
2623
lib/std/c.zig+3
...@@ -62,6 +62,8 @@ pub fn versionCheck(glibc_version: builtin.Version) type {...@@ -62,6 +62,8 @@ pub fn versionCheck(glibc_version: builtin.Version) type {
62 };62 };
63}63}
6464
65pub extern "c" var environ: [*:null]?[*:0]u8;
66
65pub extern "c" fn fopen(filename: [*:0]const u8, modes: [*:0]const u8) ?*FILE;67pub extern "c" fn fopen(filename: [*:0]const u8, modes: [*:0]const u8) ?*FILE;
66pub extern "c" fn fclose(stream: *FILE) c_int;68pub extern "c" fn fclose(stream: *FILE) c_int;
67pub extern "c" fn fwrite(ptr: [*]const u8, size_of_type: usize, item_count: usize, stream: *FILE) usize;69pub extern "c" fn fwrite(ptr: [*]const u8, size_of_type: usize, item_count: usize, stream: *FILE) usize;
...@@ -96,6 +98,7 @@ pub extern "c" fn getcwd(buf: [*]u8, size: usize) ?[*]u8;...@@ -96,6 +98,7 @@ pub extern "c" fn getcwd(buf: [*]u8, size: usize) ?[*]u8;
96pub extern "c" fn waitpid(pid: c_int, stat_loc: *c_uint, options: c_uint) c_int;98pub extern "c" fn waitpid(pid: c_int, stat_loc: *c_uint, options: c_uint) c_int;
97pub extern "c" fn fork() c_int;99pub extern "c" fn fork() c_int;
98pub extern "c" fn access(path: [*:0]const u8, mode: c_uint) c_int;100pub extern "c" fn access(path: [*:0]const u8, mode: c_uint) c_int;
101pub extern "c" fn faccessat(dirfd: fd_t, path: [*:0]const u8, mode: c_uint, flags: c_uint) c_int;
99pub extern "c" fn pipe(fds: *[2]fd_t) c_int;102pub extern "c" fn pipe(fds: *[2]fd_t) c_int;
100pub extern "c" fn pipe2(fds: *[2]fd_t, flags: u32) c_int;103pub extern "c" fn pipe2(fds: *[2]fd_t, flags: u32) c_int;
101pub extern "c" fn mkdir(path: [*:0]const u8, mode: c_uint) c_int;104pub extern "c" fn mkdir(path: [*:0]const u8, mode: c_uint) c_int;
lib/std/c/tokenizer.zig+2
...@@ -616,6 +616,7 @@ pub const Tokenizer = struct {...@@ -616,6 +616,7 @@ pub const Tokenizer = struct {
616 },616 },
617 .BackSlash => switch (c) {617 .BackSlash => switch (c) {
618 '\n' => {618 '\n' => {
619 result.start = self.index + 1;
619 state = .Start;620 state = .Start;
620 },621 },
621 '\r' => {622 '\r' => {
...@@ -631,6 +632,7 @@ pub const Tokenizer = struct {...@@ -631,6 +632,7 @@ pub const Tokenizer = struct {
631 },632 },
632 .BackSlashCr => switch (c) {633 .BackSlashCr => switch (c) {
633 '\n' => {634 '\n' => {
635 result.start = self.index + 1;
634 state = .Start;636 state = .Start;
635 },637 },
636 else => {638 else => {
lib/std/child_process.zig+40-16
...@@ -48,7 +48,10 @@ pub const ChildProcess = struct {...@@ -48,7 +48,10 @@ pub const ChildProcess = struct {
48 cwd: ?[]const u8,48 cwd: ?[]const u8,
4949
50 err_pipe: if (builtin.os == .windows) void else [2]os.fd_t,50 err_pipe: if (builtin.os == .windows) void else [2]os.fd_t,
51 llnode: if (builtin.os == .windows) void else TailQueue(*ChildProcess).Node,51
52 expand_arg0: Arg0Expand,
53
54 pub const Arg0Expand = os.Arg0Expand;
5255
53 pub const SpawnError = error{56 pub const SpawnError = error{
54 OutOfMemory,57 OutOfMemory,
...@@ -90,7 +93,6 @@ pub const ChildProcess = struct {...@@ -90,7 +93,6 @@ pub const ChildProcess = struct {
90 .handle = undefined,93 .handle = undefined,
91 .thread_handle = undefined,94 .thread_handle = undefined,
92 .err_pipe = undefined,95 .err_pipe = undefined,
93 .llnode = undefined,
94 .term = null,96 .term = null,
95 .env_map = null,97 .env_map = null,
96 .cwd = null,98 .cwd = null,
...@@ -102,6 +104,7 @@ pub const ChildProcess = struct {...@@ -102,6 +104,7 @@ pub const ChildProcess = struct {
102 .stdin_behavior = StdIo.Inherit,104 .stdin_behavior = StdIo.Inherit,
103 .stdout_behavior = StdIo.Inherit,105 .stdout_behavior = StdIo.Inherit,
104 .stderr_behavior = StdIo.Inherit,106 .stderr_behavior = StdIo.Inherit,
107 .expand_arg0 = .no_expand,
105 };108 };
106 errdefer allocator.destroy(child);109 errdefer allocator.destroy(child);
107 return child;110 return child;
...@@ -174,34 +177,56 @@ pub const ChildProcess = struct {...@@ -174,34 +177,56 @@ pub const ChildProcess = struct {
174177
175 /// Spawns a child process, waits for it, collecting stdout and stderr, and then returns.178 /// Spawns a child process, waits for it, collecting stdout and stderr, and then returns.
176 /// If it succeeds, the caller owns result.stdout and result.stderr memory.179 /// If it succeeds, the caller owns result.stdout and result.stderr memory.
180 /// TODO deprecate in favor of exec2
177 pub fn exec(181 pub fn exec(
178 allocator: *mem.Allocator,182 allocator: *mem.Allocator,
179 argv: []const []const u8,183 argv: []const []const u8,
180 cwd: ?[]const u8,184 cwd: ?[]const u8,
181 env_map: ?*const BufMap,185 env_map: ?*const BufMap,
182 max_output_size: usize,186 max_output_bytes: usize,
183 ) !ExecResult {187 ) !ExecResult {
184 const child = try ChildProcess.init(argv, allocator);188 return exec2(.{
189 .allocator = allocator,
190 .argv = argv,
191 .cwd = cwd,
192 .env_map = env_map,
193 .max_output_bytes = max_output_bytes,
194 });
195 }
196
197 /// Spawns a child process, waits for it, collecting stdout and stderr, and then returns.
198 /// If it succeeds, the caller owns result.stdout and result.stderr memory.
199 /// TODO rename to exec
200 pub fn exec2(args: struct {
201 allocator: *mem.Allocator,
202 argv: []const []const u8,
203 cwd: ?[]const u8 = null,
204 env_map: ?*const BufMap = null,
205 max_output_bytes: usize = 50 * 1024,
206 expand_arg0: Arg0Expand = .no_expand,
207 }) !ExecResult {
208 const child = try ChildProcess.init(args.argv, args.allocator);
185 defer child.deinit();209 defer child.deinit();
186210
187 child.stdin_behavior = ChildProcess.StdIo.Ignore;211 child.stdin_behavior = .Ignore;
188 child.stdout_behavior = ChildProcess.StdIo.Pipe;212 child.stdout_behavior = .Pipe;
189 child.stderr_behavior = ChildProcess.StdIo.Pipe;213 child.stderr_behavior = .Pipe;
190 child.cwd = cwd;214 child.cwd = args.cwd;
191 child.env_map = env_map;215 child.env_map = args.env_map;
216 child.expand_arg0 = args.expand_arg0;
192217
193 try child.spawn();218 try child.spawn();
194219
195 var stdout = Buffer.initNull(allocator);220 var stdout = Buffer.initNull(args.allocator);
196 var stderr = Buffer.initNull(allocator);221 var stderr = Buffer.initNull(args.allocator);
197 defer Buffer.deinit(&stdout);222 defer Buffer.deinit(&stdout);
198 defer Buffer.deinit(&stderr);223 defer Buffer.deinit(&stderr);
199224
200 var stdout_file_in_stream = child.stdout.?.inStream();225 var stdout_file_in_stream = child.stdout.?.inStream();
201 var stderr_file_in_stream = child.stderr.?.inStream();226 var stderr_file_in_stream = child.stderr.?.inStream();
202227
203 try stdout_file_in_stream.stream.readAllBuffer(&stdout, max_output_size);228 try stdout_file_in_stream.stream.readAllBuffer(&stdout, args.max_output_bytes);
204 try stderr_file_in_stream.stream.readAllBuffer(&stderr, max_output_size);229 try stderr_file_in_stream.stream.readAllBuffer(&stderr, args.max_output_bytes);
205230
206 return ExecResult{231 return ExecResult{
207 .term = try child.wait(),232 .term = try child.wait(),
...@@ -420,7 +445,7 @@ pub const ChildProcess = struct {...@@ -420,7 +445,7 @@ pub const ChildProcess = struct {
420 os.setreuid(uid, uid) catch |err| forkChildErrReport(err_pipe[1], err);445 os.setreuid(uid, uid) catch |err| forkChildErrReport(err_pipe[1], err);
421 }446 }
422447
423 const err = os.execvpe(self.allocator, self.argv, env_map);448 const err = os.execvpe_expandArg0(self.allocator, self.expand_arg0, self.argv, env_map);
424 forkChildErrReport(err_pipe[1], err);449 forkChildErrReport(err_pipe[1], err);
425 }450 }
426451
...@@ -453,7 +478,6 @@ pub const ChildProcess = struct {...@@ -453,7 +478,6 @@ pub const ChildProcess = struct {
453478
454 self.pid = pid;479 self.pid = pid;
455 self.err_pipe = err_pipe;480 self.err_pipe = err_pipe;
456 self.llnode = TailQueue(*ChildProcess).Node.init(self);
457 self.term = null;481 self.term = null;
458482
459 if (self.stdin_behavior == StdIo.Pipe) {483 if (self.stdin_behavior == StdIo.Pipe) {
...@@ -827,7 +851,7 @@ fn forkChildErrReport(fd: i32, err: ChildProcess.SpawnError) noreturn {...@@ -827,7 +851,7 @@ fn forkChildErrReport(fd: i32, err: ChildProcess.SpawnError) noreturn {
827 os.exit(1);851 os.exit(1);
828}852}
829853
830const ErrInt = @IntType(false, @sizeOf(anyerror) * 8);854const ErrInt = std.meta.IntType(false, @sizeOf(anyerror) * 8);
831855
832fn writeIntFd(fd: i32, value: ErrInt) !void {856fn writeIntFd(fd: i32, value: ErrInt) !void {
833 const file = File{857 const file = File{
lib/std/crypto.zig+31
...@@ -57,3 +57,34 @@ test "crypto" {...@@ -57,3 +57,34 @@ test "crypto" {
57 _ = @import("crypto/sha3.zig");57 _ = @import("crypto/sha3.zig");
58 _ = @import("crypto/x25519.zig");58 _ = @import("crypto/x25519.zig");
59}59}
60
61test "issue #4532: no index out of bounds" {
62 const types = [_]type{
63 Md5,
64 Sha1,
65 Sha224,
66 Sha256,
67 Sha384,
68 Sha512,
69 Blake2s224,
70 Blake2s256,
71 Blake2b384,
72 Blake2b512,
73 };
74
75 inline for (types) |Hasher| {
76 var block = [_]u8{'#'} ** Hasher.block_length;
77 var out1: [Hasher.digest_length]u8 = undefined;
78 var out2: [Hasher.digest_length]u8 = undefined;
79
80 var h = Hasher.init();
81 h.update(block[0..]);
82 h.final(out1[0..]);
83 h.reset();
84 h.update(block[0..1]);
85 h.update(block[1..]);
86 h.final(out2[0..]);
87
88 std.testing.expectEqual(out1, out2);
89 }
90}
lib/std/crypto/blake2.zig+2-2
...@@ -94,7 +94,7 @@ fn Blake2s(comptime out_len: usize) type {...@@ -94,7 +94,7 @@ fn Blake2s(comptime out_len: usize) type {
94 var off: usize = 0;94 var off: usize = 0;
9595
96 // Partial buffer exists from previous update. Copy into buffer then hash.96 // Partial buffer exists from previous update. Copy into buffer then hash.
97 if (d.buf_len != 0 and d.buf_len + b.len > 64) {97 if (d.buf_len != 0 and d.buf_len + b.len >= 64) {
98 off += 64 - d.buf_len;98 off += 64 - d.buf_len;
99 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);99 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
100 d.t += 64;100 d.t += 64;
...@@ -331,7 +331,7 @@ fn Blake2b(comptime out_len: usize) type {...@@ -331,7 +331,7 @@ fn Blake2b(comptime out_len: usize) type {
331 var off: usize = 0;331 var off: usize = 0;
332332
333 // Partial buffer exists from previous update. Copy into buffer then hash.333 // Partial buffer exists from previous update. Copy into buffer then hash.
334 if (d.buf_len != 0 and d.buf_len + b.len > 128) {334 if (d.buf_len != 0 and d.buf_len + b.len >= 128) {
335 off += 128 - d.buf_len;335 off += 128 - d.buf_len;
336 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);336 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
337 d.t += 128;337 d.t += 128;
lib/std/crypto/gimli.zig+2-2
...@@ -24,11 +24,11 @@ pub const State = struct {...@@ -24,11 +24,11 @@ pub const State = struct {
24 const Self = @This();24 const Self = @This();
2525
26 pub fn toSlice(self: *Self) []u8 {26 pub fn toSlice(self: *Self) []u8 {
27 return @sliceToBytes(self.data[0..]);27 return mem.sliceAsBytes(self.data[0..]);
28 }28 }
2929
30 pub fn toSliceConst(self: *Self) []const u8 {30 pub fn toSliceConst(self: *Self) []const u8 {
31 return @sliceToBytes(self.data[0..]);31 return mem.sliceAsBytes(self.data[0..]);
32 }32 }
3333
34 pub fn permute(self: *Self) void {34 pub fn permute(self: *Self) void {
lib/std/crypto/md5.zig+1-1
...@@ -63,7 +63,7 @@ pub const Md5 = struct {...@@ -63,7 +63,7 @@ pub const Md5 = struct {
63 var off: usize = 0;63 var off: usize = 0;
6464
65 // Partial buffer exists from previous update. Copy into buffer then hash.65 // Partial buffer exists from previous update. Copy into buffer then hash.
66 if (d.buf_len != 0 and d.buf_len + b.len > 64) {66 if (d.buf_len != 0 and d.buf_len + b.len >= 64) {
67 off += 64 - d.buf_len;67 off += 64 - d.buf_len;
68 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);68 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
6969
lib/std/crypto/sha1.zig+1-1
...@@ -61,7 +61,7 @@ pub const Sha1 = struct {...@@ -61,7 +61,7 @@ pub const Sha1 = struct {
61 var off: usize = 0;61 var off: usize = 0;
6262
63 // Partial buffer exists from previous update. Copy into buffer then hash.63 // Partial buffer exists from previous update. Copy into buffer then hash.
64 if (d.buf_len != 0 and d.buf_len + b.len > 64) {64 if (d.buf_len != 0 and d.buf_len + b.len >= 64) {
65 off += 64 - d.buf_len;65 off += 64 - d.buf_len;
66 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);66 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
6767
lib/std/crypto/sha2.zig+2-2
...@@ -116,7 +116,7 @@ fn Sha2_32(comptime params: Sha2Params32) type {...@@ -116,7 +116,7 @@ fn Sha2_32(comptime params: Sha2Params32) type {
116 var off: usize = 0;116 var off: usize = 0;
117117
118 // Partial buffer exists from previous update. Copy into buffer then hash.118 // Partial buffer exists from previous update. Copy into buffer then hash.
119 if (d.buf_len != 0 and d.buf_len + b.len > 64) {119 if (d.buf_len != 0 and d.buf_len + b.len >= 64) {
120 off += 64 - d.buf_len;120 off += 64 - d.buf_len;
121 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);121 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
122122
...@@ -458,7 +458,7 @@ fn Sha2_64(comptime params: Sha2Params64) type {...@@ -458,7 +458,7 @@ fn Sha2_64(comptime params: Sha2Params64) type {
458 var off: usize = 0;458 var off: usize = 0;
459459
460 // Partial buffer exists from previous update. Copy into buffer then hash.460 // Partial buffer exists from previous update. Copy into buffer then hash.
461 if (d.buf_len != 0 and d.buf_len + b.len > 128) {461 if (d.buf_len != 0 and d.buf_len + b.len >= 128) {
462 off += 128 - d.buf_len;462 off += 128 - d.buf_len;
463 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);463 mem.copy(u8, d.buf[d.buf_len..], b[0..off]);
464464
lib/std/cstr.zig+1-1
...@@ -72,7 +72,7 @@ pub const NullTerminated2DArray = struct {...@@ -72,7 +72,7 @@ pub const NullTerminated2DArray = struct {
72 errdefer allocator.free(buf);72 errdefer allocator.free(buf);
7373
74 var write_index = index_size;74 var write_index = index_size;
75 const index_buf = @bytesToSlice(?[*]u8, buf);75 const index_buf = mem.bytesAsSlice(?[*]u8, buf);
7676
77 var i: usize = 0;77 var i: usize = 0;
78 for (slices) |slice| {78 for (slices) |slice| {
lib/std/debug/leb128.zig+6-6
...@@ -2,7 +2,7 @@ const std = @import("std");...@@ -2,7 +2,7 @@ const std = @import("std");
2const testing = std.testing;2const testing = std.testing;
33
4pub fn readULEB128(comptime T: type, in_stream: var) !T {4pub fn readULEB128(comptime T: type, in_stream: var) !T {
5 const ShiftT = @IntType(false, std.math.log2(T.bit_count));5 const ShiftT = std.meta.IntType(false, std.math.log2(T.bit_count));
66
7 var result: T = 0;7 var result: T = 0;
8 var shift: usize = 0;8 var shift: usize = 0;
...@@ -27,7 +27,7 @@ pub fn readULEB128(comptime T: type, in_stream: var) !T {...@@ -27,7 +27,7 @@ pub fn readULEB128(comptime T: type, in_stream: var) !T {
27}27}
2828
29pub fn readULEB128Mem(comptime T: type, ptr: *[*]const u8) !T {29pub fn readULEB128Mem(comptime T: type, ptr: *[*]const u8) !T {
30 const ShiftT = @IntType(false, std.math.log2(T.bit_count));30 const ShiftT = std.meta.IntType(false, std.math.log2(T.bit_count));
3131
32 var result: T = 0;32 var result: T = 0;
33 var shift: usize = 0;33 var shift: usize = 0;
...@@ -55,8 +55,8 @@ pub fn readULEB128Mem(comptime T: type, ptr: *[*]const u8) !T {...@@ -55,8 +55,8 @@ pub fn readULEB128Mem(comptime T: type, ptr: *[*]const u8) !T {
55}55}
5656
57pub fn readILEB128(comptime T: type, in_stream: var) !T {57pub fn readILEB128(comptime T: type, in_stream: var) !T {
58 const UT = @IntType(false, T.bit_count);58 const UT = std.meta.IntType(false, T.bit_count);
59 const ShiftT = @IntType(false, std.math.log2(T.bit_count));59 const ShiftT = std.meta.IntType(false, std.math.log2(T.bit_count));
6060
61 var result: UT = 0;61 var result: UT = 0;
62 var shift: usize = 0;62 var shift: usize = 0;
...@@ -87,8 +87,8 @@ pub fn readILEB128(comptime T: type, in_stream: var) !T {...@@ -87,8 +87,8 @@ pub fn readILEB128(comptime T: type, in_stream: var) !T {
87}87}
8888
89pub fn readILEB128Mem(comptime T: type, ptr: *[*]const u8) !T {89pub fn readILEB128Mem(comptime T: type, ptr: *[*]const u8) !T {
90 const UT = @IntType(false, T.bit_count);90 const UT = std.meta.IntType(false, T.bit_count);
91 const ShiftT = @IntType(false, std.math.log2(T.bit_count));91 const ShiftT = std.meta.IntType(false, std.math.log2(T.bit_count));
9292
93 var result: UT = 0;93 var result: UT = 0;
94 var shift: usize = 0;94 var shift: usize = 0;
lib/std/event.zig+2
...@@ -1,6 +1,7 @@...@@ -1,6 +1,7 @@
1pub const Channel = @import("event/channel.zig").Channel;1pub const Channel = @import("event/channel.zig").Channel;
2pub const Future = @import("event/future.zig").Future;2pub const Future = @import("event/future.zig").Future;
3pub const Group = @import("event/group.zig").Group;3pub const Group = @import("event/group.zig").Group;
4pub const Batch = @import("event/batch.zig").Batch;
4pub const Lock = @import("event/lock.zig").Lock;5pub const Lock = @import("event/lock.zig").Lock;
5pub const Locked = @import("event/locked.zig").Locked;6pub const Locked = @import("event/locked.zig").Locked;
6pub const RwLock = @import("event/rwlock.zig").RwLock;7pub const RwLock = @import("event/rwlock.zig").RwLock;
...@@ -11,6 +12,7 @@ test "import event tests" {...@@ -11,6 +12,7 @@ test "import event tests" {
11 _ = @import("event/channel.zig");12 _ = @import("event/channel.zig");
12 _ = @import("event/future.zig");13 _ = @import("event/future.zig");
13 _ = @import("event/group.zig");14 _ = @import("event/group.zig");
15 _ = @import("event/batch.zig");
14 _ = @import("event/lock.zig");16 _ = @import("event/lock.zig");
15 _ = @import("event/locked.zig");17 _ = @import("event/locked.zig");
16 _ = @import("event/rwlock.zig");18 _ = @import("event/rwlock.zig");
lib/std/event/batch.zig created+139
...@@ -0,0 +1,139 @@
1const std = @import("../std.zig");
2const testing = std.testing;
3
4/// Performs multiple async functions in parallel, without heap allocation.
5/// Async function frames are managed externally to this abstraction, and
6/// passed in via the `add` function. Once all the jobs are added, call `wait`.
7/// This API is *not* thread-safe. The object must be accessed from one thread at
8/// a time, however, it need not be the same thread.
9pub fn Batch(
10 /// The return value for each job.
11 /// If a job slot was re-used due to maxed out concurrency, then its result
12 /// value will be overwritten. The values can be accessed with the `results` field.
13 comptime Result: type,
14 /// How many jobs to run in parallel.
15 comptime max_jobs: comptime_int,
16 /// Controls whether the `add` and `wait` functions will be async functions.
17 comptime async_behavior: enum {
18 /// Observe the value of `std.io.is_async` to decide whether `add`
19 /// and `wait` will be async functions. Asserts that the jobs do not suspend when
20 /// `std.io.mode == .blocking`. This is a generally safe assumption, and the
21 /// usual recommended option for this parameter.
22 auto_async,
23
24 /// Always uses the `noasync` keyword when using `await` on the jobs,
25 /// making `add` and `wait` non-async functions. Asserts that the jobs do not suspend.
26 never_async,
27
28 /// `add` and `wait` use regular `await` keyword, making them async functions.
29 always_async,
30 },
31) type {
32 return struct {
33 jobs: [max_jobs]Job,
34 next_job_index: usize,
35 collected_result: CollectedResult,
36
37 const Job = struct {
38 frame: ?anyframe->Result,
39 result: Result,
40 };
41
42 const Self = @This();
43
44 const CollectedResult = switch (@typeInfo(Result)) {
45 .ErrorUnion => Result,
46 else => void,
47 };
48
49 const async_ok = switch (async_behavior) {
50 .auto_async => std.io.is_async,
51 .never_async => false,
52 .always_async => true,
53 };
54
55 pub fn init() Self {
56 return Self{
57 .jobs = [1]Job{
58 .{
59 .frame = null,
60 .result = undefined,
61 },
62 } ** max_jobs,
63 .next_job_index = 0,
64 .collected_result = {},
65 };
66 }
67
68 /// Add a frame to the Batch. If all jobs are in-flight, then this function
69 /// waits until one completes.
70 /// This function is *not* thread-safe. It must be called from one thread at
71 /// a time, however, it need not be the same thread.
72 /// TODO: "select" language feature to use the next available slot, rather than
73 /// awaiting the next index.
74 pub fn add(self: *Self, frame: anyframe->Result) void {
75 const job = &self.jobs[self.next_job_index];
76 self.next_job_index = (self.next_job_index + 1) % max_jobs;
77 if (job.frame) |existing| {
78 job.result = if (async_ok) await existing else noasync await existing;
79 if (CollectedResult != void) {
80 job.result catch |err| {
81 self.collected_result = err;
82 };
83 }
84 }
85 job.frame = frame;
86 }
87
88 /// Wait for all the jobs to complete.
89 /// Safe to call any number of times.
90 /// If `Result` is an error union, this function returns the last error that occurred, if any.
91 /// Unlike the `results` field, the return value of `wait` will report any error that occurred;
92 /// hitting max parallelism will not compromise the result.
93 /// This function is *not* thread-safe. It must be called from one thread at
94 /// a time, however, it need not be the same thread.
95 pub fn wait(self: *Self) CollectedResult {
96 for (self.jobs) |*job| if (job.frame) |f| {
97 job.result = if (async_ok) await f else noasync await f;
98 if (CollectedResult != void) {
99 job.result catch |err| {
100 self.collected_result = err;
101 };
102 }
103 job.frame = null;
104 };
105 return self.collected_result;
106 }
107 };
108}
109
110test "std.event.Batch" {
111 var count: usize = 0;
112 var batch = Batch(void, 2, .auto_async).init();
113 batch.add(&async sleepALittle(&count));
114 batch.add(&async increaseByTen(&count));
115 batch.wait();
116 testing.expect(count == 11);
117
118 var another = Batch(anyerror!void, 2, .auto_async).init();
119 another.add(&async somethingElse());
120 another.add(&async doSomethingThatFails());
121 testing.expectError(error.ItBroke, another.wait());
122}
123
124fn sleepALittle(count: *usize) void {
125 std.time.sleep(1 * std.time.millisecond);
126 _ = @atomicRmw(usize, count, .Add, 1, .SeqCst);
127}
128
129fn increaseByTen(count: *usize) void {
130 var i: usize = 0;
131 while (i < 10) : (i += 1) {
132 _ = @atomicRmw(usize, count, .Add, 1, .SeqCst);
133 }
134}
135
136fn doSomethingThatFails() anyerror!void {}
137fn somethingElse() anyerror!void {
138 return error.ItBroke;
139}
lib/std/event/group.zig+5
...@@ -5,6 +5,11 @@ const testing = std.testing;...@@ -5,6 +5,11 @@ const testing = std.testing;
5const Allocator = std.mem.Allocator;5const Allocator = std.mem.Allocator;
66
7/// ReturnType must be `void` or `E!void`7/// ReturnType must be `void` or `E!void`
8/// TODO This API was created back with the old design of async/await, when calling any
9/// async function required an allocator. There is an ongoing experiment to transition
10/// all uses of this API to the simpler and more resource-aware `std.event.Batch` API.
11/// If the transition goes well, all usages of `Group` will be gone, and this API
12/// will be deleted.
8pub fn Group(comptime ReturnType: type) type {13pub fn Group(comptime ReturnType: type) type {
9 return struct {14 return struct {
10 frame_stack: Stack,15 frame_stack: Stack,
lib/std/event/loop.zig+13-12
...@@ -12,15 +12,18 @@ const maxInt = std.math.maxInt;...@@ -12,15 +12,18 @@ const maxInt = std.math.maxInt;
12const Thread = std.Thread;12const Thread = std.Thread;
1313
14pub const Loop = struct {14pub const Loop = struct {
15 allocator: *mem.Allocator,
16 next_tick_queue: std.atomic.Queue(anyframe),15 next_tick_queue: std.atomic.Queue(anyframe),
17 os_data: OsData,16 os_data: OsData,
18 final_resume_node: ResumeNode,17 final_resume_node: ResumeNode,
19 pending_event_count: usize,18 pending_event_count: usize,
20 extra_threads: []*Thread,19 extra_threads: []*Thread,
2120
22 // pre-allocated eventfds. all permanently active.21 /// For resources that have the same lifetime as the `Loop`.
23 // this is how we send promises to be resumed on other threads.22 /// This is only used by `Loop` for the thread pool and associated resources.
23 arena: std.heap.ArenaAllocator,
24
25 /// Pre-allocated eventfds. All permanently active.
26 /// This is how `Loop` sends promises to be resumed on other threads.
24 available_eventfd_resume_nodes: std.atomic.Stack(ResumeNode.EventFd),27 available_eventfd_resume_nodes: std.atomic.Stack(ResumeNode.EventFd),
25 eventfd_resume_nodes: []std.atomic.Stack(ResumeNode.EventFd).Node,28 eventfd_resume_nodes: []std.atomic.Stack(ResumeNode.EventFd).Node,
2629
...@@ -127,11 +130,9 @@ pub const Loop = struct {...@@ -127,11 +130,9 @@ pub const Loop = struct {
127 /// Thread count is the total thread count. The thread pool size will be130 /// Thread count is the total thread count. The thread pool size will be
128 /// max(thread_count - 1, 0)131 /// max(thread_count - 1, 0)
129 pub fn initThreadPool(self: *Loop, thread_count: usize) !void {132 pub fn initThreadPool(self: *Loop, thread_count: usize) !void {
130 // TODO: https://github.com/ziglang/zig/issues/3539
131 const allocator = std.heap.page_allocator;
132 self.* = Loop{133 self.* = Loop{
134 .arena = std.heap.ArenaAllocator.init(std.heap.page_allocator),
133 .pending_event_count = 1,135 .pending_event_count = 1,
134 .allocator = allocator,
135 .os_data = undefined,136 .os_data = undefined,
136 .next_tick_queue = std.atomic.Queue(anyframe).init(),137 .next_tick_queue = std.atomic.Queue(anyframe).init(),
137 .extra_threads = undefined,138 .extra_threads = undefined,
...@@ -143,17 +144,17 @@ pub const Loop = struct {...@@ -143,17 +144,17 @@ pub const Loop = struct {
143 .overlapped = ResumeNode.overlapped_init,144 .overlapped = ResumeNode.overlapped_init,
144 },145 },
145 };146 };
147 errdefer self.arena.deinit();
148
146 // We need at least one of these in case the fs thread wants to use onNextTick149 // We need at least one of these in case the fs thread wants to use onNextTick
147 const extra_thread_count = thread_count - 1;150 const extra_thread_count = thread_count - 1;
148 const resume_node_count = std.math.max(extra_thread_count, 1);151 const resume_node_count = std.math.max(extra_thread_count, 1);
149 self.eventfd_resume_nodes = try self.allocator.alloc(152 self.eventfd_resume_nodes = try self.arena.allocator.alloc(
150 std.atomic.Stack(ResumeNode.EventFd).Node,153 std.atomic.Stack(ResumeNode.EventFd).Node,
151 resume_node_count,154 resume_node_count,
152 );155 );
153 errdefer self.allocator.free(self.eventfd_resume_nodes);
154156
155 self.extra_threads = try self.allocator.alloc(*Thread, extra_thread_count);157 self.extra_threads = try self.arena.allocator.alloc(*Thread, extra_thread_count);
156 errdefer self.allocator.free(self.extra_threads);
157158
158 try self.initOsData(extra_thread_count);159 try self.initOsData(extra_thread_count);
159 errdefer self.deinitOsData();160 errdefer self.deinitOsData();
...@@ -161,7 +162,8 @@ pub const Loop = struct {...@@ -161,7 +162,8 @@ pub const Loop = struct {
161162
162 pub fn deinit(self: *Loop) void {163 pub fn deinit(self: *Loop) void {
163 self.deinitOsData();164 self.deinitOsData();
164 self.allocator.free(self.extra_threads);165 self.arena.deinit();
166 self.* = undefined;
165 }167 }
166168
167 const InitOsDataError = os.EpollCreateError || mem.Allocator.Error || os.EventFdError ||169 const InitOsDataError = os.EpollCreateError || mem.Allocator.Error || os.EventFdError ||
...@@ -407,7 +409,6 @@ pub const Loop = struct {...@@ -407,7 +409,6 @@ pub const Loop = struct {
407 noasync os.close(self.os_data.final_eventfd);409 noasync os.close(self.os_data.final_eventfd);
408 while (self.available_eventfd_resume_nodes.pop()) |node| noasync os.close(node.data.eventfd);410 while (self.available_eventfd_resume_nodes.pop()) |node| noasync os.close(node.data.eventfd);
409 noasync os.close(self.os_data.epollfd);411 noasync os.close(self.os_data.epollfd);
410 self.allocator.free(self.eventfd_resume_nodes);
411 },412 },
412 .macosx, .freebsd, .netbsd, .dragonfly => {413 .macosx, .freebsd, .netbsd, .dragonfly => {
413 noasync os.close(self.os_data.kqfd);414 noasync os.close(self.os_data.kqfd);
lib/std/fifo.zig+4-4
...@@ -101,7 +101,7 @@ pub fn LinearFifo(...@@ -101,7 +101,7 @@ pub fn LinearFifo(
101 }101 }
102 }102 }
103 { // set unused area to undefined103 { // set unused area to undefined
104 const unused = @sliceToBytes(self.buf[self.count..]);104 const unused = mem.sliceAsBytes(self.buf[self.count..]);
105 @memset(unused.ptr, undefined, unused.len);105 @memset(unused.ptr, undefined, unused.len);
106 }106 }
107 }107 }
...@@ -166,12 +166,12 @@ pub fn LinearFifo(...@@ -166,12 +166,12 @@ pub fn LinearFifo(
166 { // set old range to undefined. Note: may be wrapped around166 { // set old range to undefined. Note: may be wrapped around
167 const slice = self.readableSliceMut(0);167 const slice = self.readableSliceMut(0);
168 if (slice.len >= count) {168 if (slice.len >= count) {
169 const unused = @sliceToBytes(slice[0..count]);169 const unused = mem.sliceAsBytes(slice[0..count]);
170 @memset(unused.ptr, undefined, unused.len);170 @memset(unused.ptr, undefined, unused.len);
171 } else {171 } else {
172 const unused = @sliceToBytes(slice[0..]);172 const unused = mem.sliceAsBytes(slice[0..]);
173 @memset(unused.ptr, undefined, unused.len);173 @memset(unused.ptr, undefined, unused.len);
174 const unused2 = @sliceToBytes(self.readableSliceMut(slice.len)[0 .. count - slice.len]);174 const unused2 = mem.sliceAsBytes(self.readableSliceMut(slice.len)[0 .. count - slice.len]);
175 @memset(unused2.ptr, undefined, unused2.len);175 @memset(unused2.ptr, undefined, unused2.len);
176 }176 }
177 }177 }
lib/std/fmt.zig+12-12
...@@ -82,7 +82,7 @@ pub fn format(...@@ -82,7 +82,7 @@ pub fn format(
82 comptime fmt: []const u8,82 comptime fmt: []const u8,
83 args: var,83 args: var,
84) Errors!void {84) Errors!void {
85 const ArgSetType = @IntType(false, 32);85 const ArgSetType = u32;
86 if (@typeInfo(@TypeOf(args)) != .Struct) {86 if (@typeInfo(@TypeOf(args)) != .Struct) {
87 @compileError("Expected tuple or struct argument, found " ++ @typeName(@TypeOf(args)));87 @compileError("Expected tuple or struct argument, found " ++ @typeName(@TypeOf(args)));
88 }88 }
...@@ -405,7 +405,7 @@ pub fn formatType(...@@ -405,7 +405,7 @@ pub fn formatType(
405 try format(context, Errors, output, "@{x}", .{@ptrToInt(&value)});405 try format(context, Errors, output, "@{x}", .{@ptrToInt(&value)});
406 }406 }
407 },407 },
408 .Struct => {408 .Struct => |StructT| {
409 if (comptime std.meta.trait.hasFn("format")(T)) {409 if (comptime std.meta.trait.hasFn("format")(T)) {
410 return value.format(fmt, options, context, Errors, output);410 return value.format(fmt, options, context, Errors, output);
411 }411 }
...@@ -416,27 +416,28 @@ pub fn formatType(...@@ -416,27 +416,28 @@ pub fn formatType(
416 }416 }
417 comptime var field_i = 0;417 comptime var field_i = 0;
418 try output(context, "{");418 try output(context, "{");
419 inline while (field_i < @memberCount(T)) : (field_i += 1) {419 inline for (StructT.fields) |f| {
420 if (field_i == 0) {420 if (field_i == 0) {
421 try output(context, " .");421 try output(context, " .");
422 } else {422 } else {
423 try output(context, ", .");423 try output(context, ", .");
424 }424 }
425 try output(context, @memberName(T, field_i));425 try output(context, f.name);
426 try output(context, " = ");426 try output(context, " = ");
427 try formatType(@field(value, @memberName(T, field_i)), fmt, options, context, Errors, output, max_depth - 1);427 try formatType(@field(value, f.name), fmt, options, context, Errors, output, max_depth - 1);
428 field_i += 1;
428 }429 }
429 try output(context, " }");430 try output(context, " }");
430 },431 },
431 .Pointer => |ptr_info| switch (ptr_info.size) {432 .Pointer => |ptr_info| switch (ptr_info.size) {
432 .One => switch (@typeInfo(ptr_info.child)) {433 .One => switch (@typeInfo(ptr_info.child)) {
433 builtin.TypeId.Array => |info| {434 .Array => |info| {
434 if (info.child == u8) {435 if (info.child == u8) {
435 return formatText(value, fmt, options, context, Errors, output);436 return formatText(value, fmt, options, context, Errors, output);
436 }437 }
437 return format(context, Errors, output, "{}@{x}", .{ @typeName(T.Child), @ptrToInt(value) });438 return format(context, Errors, output, "{}@{x}", .{ @typeName(T.Child), @ptrToInt(value) });
438 },439 },
439 builtin.TypeId.Enum, builtin.TypeId.Union, builtin.TypeId.Struct => {440 .Enum, .Union, .Struct => {
440 return formatType(value.*, fmt, options, context, Errors, output, max_depth);441 return formatType(value.*, fmt, options, context, Errors, output, max_depth);
441 },442 },
442 else => return format(context, Errors, output, "{}@{x}", .{ @typeName(T.Child), @ptrToInt(value) }),443 else => return format(context, Errors, output, "{}@{x}", .{ @typeName(T.Child), @ptrToInt(value) }),
...@@ -509,7 +510,7 @@ fn formatValue(...@@ -509,7 +510,7 @@ fn formatValue(
509 }510 }
510511
511 const T = @TypeOf(value);512 const T = @TypeOf(value);
512 switch (@typeId(T)) {513 switch (@typeInfo(T)) {
513 .Float => return formatFloatValue(value, fmt, options, context, Errors, output),514 .Float => return formatFloatValue(value, fmt, options, context, Errors, output),
514 .Int, .ComptimeInt => return formatIntValue(value, fmt, options, context, Errors, output),515 .Int, .ComptimeInt => return formatIntValue(value, fmt, options, context, Errors, output),
515 .Bool => return output(context, if (value) "true" else "false"),516 .Bool => return output(context, if (value) "true" else "false"),
...@@ -757,8 +758,6 @@ pub fn formatFloatDecimal(...@@ -757,8 +758,6 @@ pub fn formatFloatDecimal(
757 } else {758 } else {
758 try output(context, ".0");759 try output(context, ".0");
759 }760 }
760 } else {
761 try output(context, "0");
762 }761 }
763762
764 return;763 return;
...@@ -945,7 +944,7 @@ fn formatIntSigned(...@@ -945,7 +944,7 @@ fn formatIntSigned(
945 .fill = options.fill,944 .fill = options.fill,
946 };945 };
947946
948 const uint = @IntType(false, @TypeOf(value).bit_count);947 const uint = std.meta.IntType(false, @TypeOf(value).bit_count);
949 if (value < 0) {948 if (value < 0) {
950 const minus_sign: u8 = '-';949 const minus_sign: u8 = '-';
951 try output(context, @as(*const [1]u8, &minus_sign)[0..]);950 try output(context, @as(*const [1]u8, &minus_sign)[0..]);
...@@ -973,7 +972,7 @@ fn formatIntUnsigned(...@@ -973,7 +972,7 @@ fn formatIntUnsigned(
973 assert(base >= 2);972 assert(base >= 2);
974 var buf: [math.max(@TypeOf(value).bit_count, 1)]u8 = undefined;973 var buf: [math.max(@TypeOf(value).bit_count, 1)]u8 = undefined;
975 const min_int_bits = comptime math.max(@TypeOf(value).bit_count, @TypeOf(base).bit_count);974 const min_int_bits = comptime math.max(@TypeOf(value).bit_count, @TypeOf(base).bit_count);
976 const MinInt = @IntType(@TypeOf(value).is_signed, min_int_bits);975 const MinInt = std.meta.IntType(@TypeOf(value).is_signed, min_int_bits);
977 var a: MinInt = value;976 var a: MinInt = value;
978 var index: usize = buf.len;977 var index: usize = buf.len;
979978
...@@ -1399,6 +1398,7 @@ test "float.special" {...@@ -1399,6 +1398,7 @@ test "float.special" {
13991398
1400test "float.decimal" {1399test "float.decimal" {
1401 try testFmt("f64: 152314000000000000000000000000", "f64: {d}", .{@as(f64, 1.52314e+29)});1400 try testFmt("f64: 152314000000000000000000000000", "f64: {d}", .{@as(f64, 1.52314e+29)});
1401 try testFmt("f32: 0", "f32: {d}", .{@as(f32, 0.0)});
1402 try testFmt("f32: 1.1", "f32: {d:.1}", .{@as(f32, 1.1234)});1402 try testFmt("f32: 1.1", "f32: {d:.1}", .{@as(f32, 1.1234)});
1403 try testFmt("f32: 1234.57", "f32: {d:.2}", .{@as(f32, 1234.567)});1403 try testFmt("f32: 1234.57", "f32: {d:.2}", .{@as(f32, 1234.567)});
1404 // -11.1234 is converted to f64 -11.12339... internally (errol3() function takes f64).1404 // -11.1234 is converted to f64 -11.12339... internally (errol3() function takes f64).
lib/std/fmt/parse_float.zig+1-1
...@@ -389,7 +389,7 @@ test "fmt.parseFloat" {...@@ -389,7 +389,7 @@ test "fmt.parseFloat" {
389 const epsilon = 1e-7;389 const epsilon = 1e-7;
390390
391 inline for ([_]type{ f16, f32, f64, f128 }) |T| {391 inline for ([_]type{ f16, f32, f64, f128 }) |T| {
392 const Z = @IntType(false, T.bit_count);392 const Z = std.meta.IntType(false, T.bit_count);
393393
394 testing.expectError(error.InvalidCharacter, parseFloat(T, ""));394 testing.expectError(error.InvalidCharacter, parseFloat(T, ""));
395 testing.expectError(error.InvalidCharacter, parseFloat(T, " 1"));395 testing.expectError(error.InvalidCharacter, parseFloat(T, " 1"));
lib/std/fs.zig+52-7
...@@ -96,7 +96,6 @@ pub fn updateFile(source_path: []const u8, dest_path: []const u8) !PrevStatus {...@@ -96,7 +96,6 @@ pub fn updateFile(source_path: []const u8, dest_path: []const u8) !PrevStatus {
96/// atime, and mode of the source file so that the next call to `updateFile` will not need a copy.96/// atime, and mode of the source file so that the next call to `updateFile` will not need a copy.
97/// Returns the previous status of the file before updating.97/// Returns the previous status of the file before updating.
98/// If any of the directories do not exist for dest_path, they are created.98/// If any of the directories do not exist for dest_path, they are created.
99/// TODO https://github.com/ziglang/zig/issues/2885
100pub fn updateFileMode(source_path: []const u8, dest_path: []const u8, mode: ?File.Mode) !PrevStatus {99pub fn updateFileMode(source_path: []const u8, dest_path: []const u8, mode: ?File.Mode) !PrevStatus {
101 const my_cwd = cwd();100 const my_cwd = cwd();
102101
...@@ -818,6 +817,13 @@ pub const Dir = struct {...@@ -818,6 +817,13 @@ pub const Dir = struct {
818 ) File.OpenError!File {817 ) File.OpenError!File {
819 const w = os.windows;818 const w = os.windows;
820819
820 if (sub_path_w[0] == '.' and sub_path_w[1] == 0) {
821 return error.IsDir;
822 }
823 if (sub_path_w[0] == '.' and sub_path_w[1] == '.' and sub_path_w[2] == 0) {
824 return error.IsDir;
825 }
826
821 var result = File{827 var result = File{
822 .handle = undefined,828 .handle = undefined,
823 .io_mode = .blocking,829 .io_mode = .blocking,
...@@ -839,12 +845,6 @@ pub const Dir = struct {...@@ -839,12 +845,6 @@ pub const Dir = struct {
839 .SecurityDescriptor = null,845 .SecurityDescriptor = null,
840 .SecurityQualityOfService = null,846 .SecurityQualityOfService = null,
841 };847 };
842 if (sub_path_w[0] == '.' and sub_path_w[1] == 0) {
843 return error.IsDir;
844 }
845 if (sub_path_w[0] == '.' and sub_path_w[1] == '.' and sub_path_w[2] == 0) {
846 return error.IsDir;
847 }
848 var io: w.IO_STATUS_BLOCK = undefined;848 var io: w.IO_STATUS_BLOCK = undefined;
849 const rc = w.ntdll.NtCreateFile(849 const rc = w.ntdll.NtCreateFile(
850 &result.handle,850 &result.handle,
...@@ -864,6 +864,7 @@ pub const Dir = struct {...@@ -864,6 +864,7 @@ pub const Dir = struct {
864 .OBJECT_NAME_INVALID => unreachable,864 .OBJECT_NAME_INVALID => unreachable,
865 .OBJECT_NAME_NOT_FOUND => return error.FileNotFound,865 .OBJECT_NAME_NOT_FOUND => return error.FileNotFound,
866 .OBJECT_PATH_NOT_FOUND => return error.FileNotFound,866 .OBJECT_PATH_NOT_FOUND => return error.FileNotFound,
867 .NO_MEDIA_IN_DEVICE => return error.NoDevice,
867 .INVALID_PARAMETER => unreachable,868 .INVALID_PARAMETER => unreachable,
868 .SHARING_VIOLATION => return error.SharingViolation,869 .SHARING_VIOLATION => return error.SharingViolation,
869 .ACCESS_DENIED => return error.AccessDenied,870 .ACCESS_DENIED => return error.AccessDenied,
...@@ -1323,6 +1324,50 @@ pub const Dir = struct {...@@ -1323,6 +1324,50 @@ pub const Dir = struct {
1323 defer file.close();1324 defer file.close();
1324 try file.write(data);1325 try file.write(data);
1325 }1326 }
1327
1328 pub const AccessError = os.AccessError;
1329
1330 /// Test accessing `path`.
1331 /// `path` is UTF8-encoded.
1332 /// Be careful of Time-Of-Check-Time-Of-Use race conditions when using this function.
1333 /// For example, instead of testing if a file exists and then opening it, just
1334 /// open it and handle the error for file not found.
1335 pub fn access(self: Dir, sub_path: []const u8, flags: File.OpenFlags) AccessError!void {
1336 if (builtin.os == .windows) {
1337 const sub_path_w = try os.windows.sliceToPrefixedFileW(sub_path);
1338 return self.accessW(&sub_path_w, flags);
1339 }
1340 const path_c = try os.toPosixPath(sub_path);
1341 return self.accessZ(&path_c, flags);
1342 }
1343
1344 /// Same as `access` except the path parameter is null-terminated.
1345 pub fn accessZ(self: Dir, sub_path: [*:0]const u8, flags: File.OpenFlags) AccessError!void {
1346 if (builtin.os == .windows) {
1347 const sub_path_w = try os.windows.cStrToPrefixedFileW(sub_path);
1348 return self.accessW(&sub_path_w, flags);
1349 }
1350 const os_mode = if (flags.write and flags.read)
1351 @as(u32, os.R_OK | os.W_OK)
1352 else if (flags.write)
1353 @as(u32, os.W_OK)
1354 else
1355 @as(u32, os.F_OK);
1356 const result = if (need_async_thread)
1357 std.event.Loop.instance.?.faccessatZ(self.fd, sub_path, os_mode)
1358 else
1359 os.faccessatZ(self.fd, sub_path, os_mode, 0);
1360 return result;
1361 }
1362
1363 /// Same as `access` except asserts the target OS is Windows and the path parameter is
1364 /// * WTF-16 encoded
1365 /// * null-terminated
1366 /// * NtDll prefixed
1367 /// TODO currently this ignores `flags`.
1368 pub fn accessW(self: Dir, sub_path_w: [*:0]const u16, flags: File.OpenFlags) AccessError!void {
1369 return os.faccessatW(self.fd, sub_path_w, 0, 0);
1370 }
1326};1371};
13271372
1328/// Returns an handle to the current working directory that is open for traversal.1373/// Returns an handle to the current working directory that is open for traversal.
lib/std/fs/file.zig-25
...@@ -60,31 +60,6 @@ pub const File = struct {...@@ -60,31 +60,6 @@ pub const File = struct {
60 mode: Mode = default_mode,60 mode: Mode = default_mode,
61 };61 };
6262
63 /// Test for the existence of `path`.
64 /// `path` is UTF8-encoded.
65 /// In general it is recommended to avoid this function. For example,
66 /// instead of testing if a file exists and then opening it, just
67 /// open it and handle the error for file not found.
68 /// TODO: deprecate this and move it to `std.fs.Dir`.
69 /// TODO: integrate with async I/O
70 pub fn access(path: []const u8) !void {
71 return os.access(path, os.F_OK);
72 }
73
74 /// Same as `access` except the parameter is null-terminated.
75 /// TODO: deprecate this and move it to `std.fs.Dir`.
76 /// TODO: integrate with async I/O
77 pub fn accessC(path: [*:0]const u8) !void {
78 return os.accessC(path, os.F_OK);
79 }
80
81 /// Same as `access` except the parameter is null-terminated UTF16LE-encoded.
82 /// TODO: deprecate this and move it to `std.fs.Dir`.
83 /// TODO: integrate with async I/O
84 pub fn accessW(path: [*:0]const u16) !void {
85 return os.accessW(path, os.F_OK);
86 }
87
88 /// Upon success, the stream is in an uninitialized state. To continue using it,63 /// Upon success, the stream is in an uninitialized state. To continue using it,
89 /// you must use the open() function.64 /// you must use the open() function.
90 pub fn close(self: File) void {65 pub fn close(self: File) void {
lib/std/fs/watch.zig+1-1
...@@ -26,7 +26,7 @@ fn eqlString(a: []const u16, b: []const u16) bool {...@@ -26,7 +26,7 @@ fn eqlString(a: []const u16, b: []const u16) bool {
26}26}
2727
28fn hashString(s: []const u16) u32 {28fn hashString(s: []const u16) u32 {
29 return @truncate(u32, std.hash.Wyhash.hash(0, @sliceToBytes(s)));29 return @truncate(u32, std.hash.Wyhash.hash(0, mem.sliceAsBytes(s)));
30}30}
3131
32const WatchEventError = error{32const WatchEventError = error{
lib/std/hash/auto_hash.zig+1-1
...@@ -93,7 +93,7 @@ pub fn hash(hasher: var, key: var, comptime strat: HashStrategy) void {...@@ -93,7 +93,7 @@ pub fn hash(hasher: var, key: var, comptime strat: HashStrategy) void {
93 // TODO Check if the situation is better after #561 is resolved.93 // TODO Check if the situation is better after #561 is resolved.
94 .Int => @call(.{ .modifier = .always_inline }, hasher.update, .{std.mem.asBytes(&key)}),94 .Int => @call(.{ .modifier = .always_inline }, hasher.update, .{std.mem.asBytes(&key)}),
9595
96 .Float => |info| hash(hasher, @bitCast(@IntType(false, info.bits), key), strat),96 .Float => |info| hash(hasher, @bitCast(std.meta.IntType(false, info.bits), key), strat),
9797
98 .Bool => hash(hasher, @boolToInt(key), strat),98 .Bool => hash(hasher, @boolToInt(key), strat),
99 .Enum => hash(hasher, @enumToInt(key), strat),99 .Enum => hash(hasher, @enumToInt(key), strat),
lib/std/hash/wyhash.zig+1-1
...@@ -10,7 +10,7 @@ const primes = [_]u64{...@@ -10,7 +10,7 @@ const primes = [_]u64{
10};10};
1111
12fn read_bytes(comptime bytes: u8, data: []const u8) u64 {12fn read_bytes(comptime bytes: u8, data: []const u8) u64 {
13 const T = @IntType(false, 8 * bytes);13 const T = std.meta.IntType(false, 8 * bytes);
14 return mem.readIntSliceLittle(T, data[0..bytes]);14 return mem.readIntSliceLittle(T, data[0..bytes]);
15}15}
1616
lib/std/heap.zig+4-4
...@@ -283,14 +283,14 @@ const WasmPageAllocator = struct {...@@ -283,14 +283,14 @@ const WasmPageAllocator = struct {
283283
284 fn getBit(self: FreeBlock, idx: usize) PageStatus {284 fn getBit(self: FreeBlock, idx: usize) PageStatus {
285 const bit_offset = 0;285 const bit_offset = 0;
286 return @intToEnum(PageStatus, Io.get(@sliceToBytes(self.data), idx, bit_offset));286 return @intToEnum(PageStatus, Io.get(mem.sliceAsBytes(self.data), idx, bit_offset));
287 }287 }
288288
289 fn setBits(self: FreeBlock, start_idx: usize, len: usize, val: PageStatus) void {289 fn setBits(self: FreeBlock, start_idx: usize, len: usize, val: PageStatus) void {
290 const bit_offset = 0;290 const bit_offset = 0;
291 var i: usize = 0;291 var i: usize = 0;
292 while (i < len) : (i += 1) {292 while (i < len) : (i += 1) {
293 Io.set(@sliceToBytes(self.data), start_idx + i, bit_offset, @enumToInt(val));293 Io.set(mem.sliceAsBytes(self.data), start_idx + i, bit_offset, @enumToInt(val));
294 }294 }
295 }295 }
296296
...@@ -552,7 +552,7 @@ pub const ArenaAllocator = struct {...@@ -552,7 +552,7 @@ pub const ArenaAllocator = struct {
552 if (len >= actual_min_size) break;552 if (len >= actual_min_size) break;
553 }553 }
554 const buf = try self.child_allocator.alignedAlloc(u8, @alignOf(BufNode), len);554 const buf = try self.child_allocator.alignedAlloc(u8, @alignOf(BufNode), len);
555 const buf_node_slice = @bytesToSlice(BufNode, buf[0..@sizeOf(BufNode)]);555 const buf_node_slice = mem.bytesAsSlice(BufNode, buf[0..@sizeOf(BufNode)]);
556 const buf_node = &buf_node_slice[0];556 const buf_node = &buf_node_slice[0];
557 buf_node.* = BufNode{557 buf_node.* = BufNode{
558 .data = buf,558 .data = buf,
...@@ -1015,7 +1015,7 @@ fn testAllocatorLargeAlignment(allocator: *mem.Allocator) mem.Allocator.Error!vo...@@ -1015,7 +1015,7 @@ fn testAllocatorLargeAlignment(allocator: *mem.Allocator) mem.Allocator.Error!vo
1015 // very near usize?1015 // very near usize?
1016 if (mem.page_size << 2 > maxInt(usize)) return;1016 if (mem.page_size << 2 > maxInt(usize)) return;
10171017
1018 const USizeShift = @IntType(false, std.math.log2(usize.bit_count));1018 const USizeShift = std.meta.IntType(false, std.math.log2(usize.bit_count));
1019 const large_align = @as(u29, mem.page_size << 2);1019 const large_align = @as(u29, mem.page_size << 2);
10201020
1021 var align_mask: usize = undefined;1021 var align_mask: usize = undefined;
lib/std/io.zig+94-219
...@@ -121,76 +121,37 @@ pub fn BufferedInStreamCustom(comptime buffer_size: usize, comptime Error: type)...@@ -121,76 +121,37 @@ pub fn BufferedInStreamCustom(comptime buffer_size: usize, comptime Error: type)
121121
122 unbuffered_in_stream: *Stream,122 unbuffered_in_stream: *Stream,
123123
124 buffer: [buffer_size]u8,124 const FifoType = std.fifo.LinearFifo(u8, std.fifo.LinearFifoBufferType{ .Static = buffer_size });
125 start_index: usize,125 fifo: FifoType,
126 end_index: usize,
127126
128 pub fn init(unbuffered_in_stream: *Stream) Self {127 pub fn init(unbuffered_in_stream: *Stream) Self {
129 return Self{128 return Self{
130 .unbuffered_in_stream = unbuffered_in_stream,129 .unbuffered_in_stream = unbuffered_in_stream,
131 .buffer = undefined,130 .fifo = FifoType.init(),
132
133 // Initialize these two fields to buffer_size so that
134 // in `readFn` we treat the state as being able to read
135 // more from the unbuffered stream. If we set them to 0
136 // and 0, the code would think we already hit EOF.
137 .start_index = buffer_size,
138 .end_index = buffer_size,
139
140 .stream = Stream{ .readFn = readFn },131 .stream = Stream{ .readFn = readFn },
141 };132 };
142 }133 }
143134
144 fn readFn(in_stream: *Stream, dest: []u8) !usize {135 fn readFn(in_stream: *Stream, dest: []u8) !usize {
145 const self = @fieldParentPtr(Self, "stream", in_stream);136 const self = @fieldParentPtr(Self, "stream", in_stream);
146
147 // Hot path for one byte reads
148 if (dest.len == 1 and self.end_index > self.start_index) {
149 dest[0] = self.buffer[self.start_index];
150 self.start_index += 1;
151 return 1;
152 }
153
154 var dest_index: usize = 0;137 var dest_index: usize = 0;
155 while (true) {138 while (dest_index < dest.len) {
156 const dest_space = dest.len - dest_index;139 const written = self.fifo.read(dest[dest_index..]);
157 if (dest_space == 0) {140 if (written == 0) {
158 return dest_index;141 // fifo empty, fill it
159 }142 const writable = self.fifo.writableSlice(0);
160 const amt_buffered = self.end_index - self.start_index;143 assert(writable.len > 0);
161 if (amt_buffered == 0) {144 const n = try self.unbuffered_in_stream.read(writable);
162 assert(self.end_index <= buffer_size);145 if (n == 0) {
163 // Make sure the last read actually gave us some data
164 if (self.end_index == 0) {
165 // reading from the unbuffered stream returned nothing146 // reading from the unbuffered stream returned nothing
166 // so we have nothing left to read.147 // so we have nothing left to read.
167 return dest_index;148 return dest_index;
168 }149 }
169 // we can read more data from the unbuffered stream150 self.fifo.update(n);
170 if (dest_space < buffer_size) {
171 self.start_index = 0;
172 self.end_index = try self.unbuffered_in_stream.read(self.buffer[0..]);
173
174 // Shortcut
175 if (self.end_index >= dest_space) {
176 mem.copy(u8, dest[dest_index..], self.buffer[0..dest_space]);
177 self.start_index = dest_space;
178 return dest.len;
179 }
180 } else {
181 // asking for so much data that buffering is actually less efficient.
182 // forward the request directly to the unbuffered stream
183 const amt_read = try self.unbuffered_in_stream.read(dest[dest_index..]);
184 return dest_index + amt_read;
185 }
186 }151 }
187152 dest_index += written;
188 const copy_amount = math.min(dest_space, amt_buffered);
189 const copy_end_index = self.start_index + copy_amount;
190 mem.copy(u8, dest[dest_index..], self.buffer[self.start_index..copy_end_index]);
191 self.start_index = copy_end_index;
192 dest_index += copy_amount;
193 }153 }
154 return dest.len;
194 }155 }
195 };156 };
196}157}
...@@ -235,7 +196,7 @@ test "io.BufferedInStream" {...@@ -235,7 +196,7 @@ test "io.BufferedInStream" {
235196
236/// Creates a stream which supports 'un-reading' data, so that it can be read again.197/// Creates a stream which supports 'un-reading' data, so that it can be read again.
237/// This makes look-ahead style parsing much easier.198/// This makes look-ahead style parsing much easier.
238pub fn PeekStream(comptime buffer_size: usize, comptime InStreamError: type) type {199pub fn PeekStream(comptime buffer_type: std.fifo.LinearFifoBufferType, comptime InStreamError: type) type {
239 return struct {200 return struct {
240 const Self = @This();201 const Self = @This();
241 pub const Error = InStreamError;202 pub const Error = InStreamError;
...@@ -244,57 +205,57 @@ pub fn PeekStream(comptime buffer_size: usize, comptime InStreamError: type) typ...@@ -244,57 +205,57 @@ pub fn PeekStream(comptime buffer_size: usize, comptime InStreamError: type) typ
244 stream: Stream,205 stream: Stream,
245 base: *Stream,206 base: *Stream,
246207
247 // Right now the look-ahead space is statically allocated, but a version with dynamic allocation208 const FifoType = std.fifo.LinearFifo(u8, buffer_type);
248 // is not too difficult to derive from this.209 fifo: FifoType,
249 buffer: [buffer_size]u8,210
250 index: usize,211 pub usingnamespace switch (buffer_type) {
251 at_end: bool,212 .Static => struct {
252213 pub fn init(base: *Stream) Self {
253 pub fn init(base: *Stream) Self {214 return .{
254 return Self{215 .base = base,
255 .base = base,216 .fifo = FifoType.init(),
256 .buffer = undefined,217 .stream = Stream{ .readFn = readFn },
257 .index = 0,218 };
258 .at_end = false,219 }
259 .stream = Stream{ .readFn = readFn },220 },
260 };221 .Slice => struct {
261 }222 pub fn init(base: *Stream, buf: []u8) Self {
223 return .{
224 .base = base,
225 .fifo = FifoType.init(buf),
226 .stream = Stream{ .readFn = readFn },
227 };
228 }
229 },
230 .Dynamic => struct {
231 pub fn init(base: *Stream, allocator: *mem.Allocator) Self {
232 return .{
233 .base = base,
234 .fifo = FifoType.init(allocator),
235 .stream = Stream{ .readFn = readFn },
236 };
237 }
238 },
239 };
262240
263 pub fn putBackByte(self: *Self, byte: u8) void {241 pub fn putBackByte(self: *Self, byte: u8) !void {
264 self.buffer[self.index] = byte;242 try self.putBack(&[_]u8{byte});
265 self.index += 1;
266 }243 }
267244
268 pub fn putBack(self: *Self, bytes: []const u8) void {245 pub fn putBack(self: *Self, bytes: []const u8) !void {
269 var pos = bytes.len;246 try self.fifo.unget(bytes);
270 while (pos != 0) {
271 pos -= 1;
272 self.putBackByte(bytes[pos]);
273 }
274 }247 }
275248
276 fn readFn(in_stream: *Stream, dest: []u8) Error!usize {249 fn readFn(in_stream: *Stream, dest: []u8) Error!usize {
277 const self = @fieldParentPtr(Self, "stream", in_stream);250 const self = @fieldParentPtr(Self, "stream", in_stream);
278251
279 // copy over anything putBack()'d252 // copy over anything putBack()'d
280 var pos: usize = 0;253 var dest_index = self.fifo.read(dest);
281 while (pos < dest.len and self.index != 0) {254 if (dest_index == dest.len) return dest_index;
282 dest[pos] = self.buffer[self.index - 1];
283 self.index -= 1;
284 pos += 1;
285 }
286
287 if (pos == dest.len or self.at_end) {
288 return pos;
289 }
290255
291 // ask the backing stream for more256 // ask the backing stream for more
292 const left = dest.len - pos;257 dest_index += try self.base.read(dest[dest_index..]);
293 const read = try self.base.read(dest[pos..]);258 return dest_index;
294 assert(read <= left);
295
296 self.at_end = (read < left);
297 return pos + read;
298 }259 }
299 };260 };
300}261}
...@@ -376,7 +337,7 @@ pub fn BitInStream(endian: builtin.Endian, comptime Error: type) type {...@@ -376,7 +337,7 @@ pub fn BitInStream(endian: builtin.Endian, comptime Error: type) type {
376 assert(u_bit_count >= bits);337 assert(u_bit_count >= bits);
377 break :bc if (u_bit_count <= u8_bit_count) u8_bit_count else u_bit_count;338 break :bc if (u_bit_count <= u8_bit_count) u8_bit_count else u_bit_count;
378 };339 };
379 const Buf = @IntType(false, buf_bit_count);340 const Buf = std.meta.IntType(false, buf_bit_count);
380 const BufShift = math.Log2Int(Buf);341 const BufShift = math.Log2Int(Buf);
381342
382 out_bits.* = @as(usize, 0);343 out_bits.* = @as(usize, 0);
...@@ -607,52 +568,33 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize, comptime OutStreamEr...@@ -607,52 +568,33 @@ pub fn BufferedOutStreamCustom(comptime buffer_size: usize, comptime OutStreamEr
607568
608 unbuffered_out_stream: *Stream,569 unbuffered_out_stream: *Stream,
609570
610 buffer: [buffer_size]u8,571 const FifoType = std.fifo.LinearFifo(u8, std.fifo.LinearFifoBufferType{ .Static = buffer_size });
611 index: usize,572 fifo: FifoType,
612573
613 pub fn init(unbuffered_out_stream: *Stream) Self {574 pub fn init(unbuffered_out_stream: *Stream) Self {
614 return Self{575 return Self{
615 .unbuffered_out_stream = unbuffered_out_stream,576 .unbuffered_out_stream = unbuffered_out_stream,
616 .buffer = undefined,577 .fifo = FifoType.init(),
617 .index = 0,
618 .stream = Stream{ .writeFn = writeFn },578 .stream = Stream{ .writeFn = writeFn },
619 };579 };
620 }580 }
621581
622 pub fn flush(self: *Self) !void {582 pub fn flush(self: *Self) !void {
623 try self.unbuffered_out_stream.write(self.buffer[0..self.index]);583 while (true) {
624 self.index = 0;584 const slice = self.fifo.readableSlice(0);
585 if (slice.len == 0) break;
586 try self.unbuffered_out_stream.write(slice);
587 self.fifo.discard(slice.len);
588 }
625 }589 }
626590
627 fn writeFn(out_stream: *Stream, bytes: []const u8) Error!void {591 fn writeFn(out_stream: *Stream, bytes: []const u8) Error!void {
628 const self = @fieldParentPtr(Self, "stream", out_stream);592 const self = @fieldParentPtr(Self, "stream", out_stream);
629593 if (bytes.len >= self.fifo.writableLength()) {
630 if (bytes.len == 1) {
631 // This is not required logic but a shorter path
632 // for single byte writes
633 self.buffer[self.index] = bytes[0];
634 self.index += 1;
635 if (self.index == buffer_size) {
636 try self.flush();
637 }
638 return;
639 } else if (bytes.len >= self.buffer.len) {
640 try self.flush();594 try self.flush();
641 return self.unbuffered_out_stream.write(bytes);595 return self.unbuffered_out_stream.write(bytes);
642 }596 }
643 var src_index: usize = 0;597 self.fifo.writeAssumeCapacity(bytes);
644
645 while (src_index < bytes.len) {
646 const dest_space_left = self.buffer.len - self.index;
647 const copy_amt = math.min(dest_space_left, bytes.len - src_index);
648 mem.copy(u8, self.buffer[self.index..], bytes[src_index .. src_index + copy_amt]);
649 self.index += copy_amt;
650 assert(self.index <= self.buffer.len);
651 if (self.index == self.buffer.len) {
652 try self.flush();
653 }
654 src_index += copy_amt;
655 }
656 }598 }
657 };599 };
658}600}
...@@ -717,7 +659,7 @@ pub fn BitOutStream(endian: builtin.Endian, comptime Error: type) type {...@@ -717,7 +659,7 @@ pub fn BitOutStream(endian: builtin.Endian, comptime Error: type) type {
717 assert(u_bit_count >= bits);659 assert(u_bit_count >= bits);
718 break :bc if (u_bit_count <= u8_bit_count) u8_bit_count else u_bit_count;660 break :bc if (u_bit_count <= u8_bit_count) u8_bit_count else u_bit_count;
719 };661 };
720 const Buf = @IntType(false, buf_bit_count);662 const Buf = std.meta.IntType(false, buf_bit_count);
721 const BufShift = math.Log2Int(Buf);663 const BufShift = math.Log2Int(Buf);
722664
723 const buf_value = @intCast(Buf, value);665 const buf_value = @intCast(Buf, value);
...@@ -848,73 +790,6 @@ pub const BufferedAtomicFile = struct {...@@ -848,73 +790,6 @@ pub const BufferedAtomicFile = struct {
848 }790 }
849};791};
850792
851pub fn readLine(buf: *std.Buffer) ![]u8 {
852 var stdin_stream = getStdIn().inStream();
853 return readLineFrom(&stdin_stream.stream, buf);
854}
855
856/// Reads all characters until the next newline into buf, and returns
857/// a slice of the characters read (excluding the newline character(s)).
858pub fn readLineFrom(stream: var, buf: *std.Buffer) ![]u8 {
859 const start = buf.len();
860 while (true) {
861 const byte = try stream.readByte();
862 switch (byte) {
863 '\r' => {
864 // trash the following \n
865 _ = try stream.readByte();
866 return buf.toSlice()[start..];
867 },
868 '\n' => return buf.toSlice()[start..],
869 else => try buf.appendByte(byte),
870 }
871 }
872}
873
874test "io.readLineFrom" {
875 var buf = try std.Buffer.initSize(testing.allocator, 0);
876 defer buf.deinit();
877 var mem_stream = SliceInStream.init(
878 \\Line 1
879 \\Line 22
880 \\Line 333
881 );
882 const stream = &mem_stream.stream;
883
884 testing.expectEqualSlices(u8, "Line 1", try readLineFrom(stream, &buf));
885 testing.expectEqualSlices(u8, "Line 22", try readLineFrom(stream, &buf));
886 testing.expectError(error.EndOfStream, readLineFrom(stream, &buf));
887 testing.expectEqualSlices(u8, "Line 1Line 22Line 333", buf.toSlice());
888}
889
890pub fn readLineSlice(slice: []u8) ![]u8 {
891 var stdin_stream = getStdIn().inStream();
892 return readLineSliceFrom(&stdin_stream.stream, slice);
893}
894
895/// Reads all characters until the next newline into slice, and returns
896/// a slice of the characters read (excluding the newline character(s)).
897pub fn readLineSliceFrom(stream: var, slice: []u8) ![]u8 {
898 // We cannot use Buffer.fromOwnedSlice, as it wants to append a null byte
899 // after taking ownership, which would always require an allocation.
900 var buf = std.Buffer{ .list = std.ArrayList(u8).fromOwnedSlice(testing.failing_allocator, slice) };
901 try buf.resize(0);
902 return try readLineFrom(stream, &buf);
903}
904
905test "io.readLineSliceFrom" {
906 var buf: [7]u8 = undefined;
907 var mem_stream = SliceInStream.init(
908 \\Line 1
909 \\Line 22
910 \\Line 333
911 );
912 const stream = &mem_stream.stream;
913
914 testing.expectEqualSlices(u8, "Line 1", try readLineSliceFrom(stream, buf[0..]));
915 testing.expectError(error.OutOfMemory, readLineSliceFrom(stream, buf[0..]));
916}
917
918pub const Packing = enum {793pub const Packing = enum {
919 /// Pack data to byte alignment794 /// Pack data to byte alignment
920 Byte,795 Byte,
...@@ -956,12 +831,12 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,...@@ -956,12 +831,12 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
956831
957 //@BUG: inferred error issue. See: #1386832 //@BUG: inferred error issue. See: #1386
958 fn deserializeInt(self: *Self, comptime T: type) (Error || error{EndOfStream})!T {833 fn deserializeInt(self: *Self, comptime T: type) (Error || error{EndOfStream})!T {
959 comptime assert(trait.is(builtin.TypeId.Int)(T) or trait.is(builtin.TypeId.Float)(T));834 comptime assert(trait.is(.Int)(T) or trait.is(.Float)(T));
960835
961 const u8_bit_count = 8;836 const u8_bit_count = 8;
962 const t_bit_count = comptime meta.bitCount(T);837 const t_bit_count = comptime meta.bitCount(T);
963838
964 const U = @IntType(false, t_bit_count);839 const U = std.meta.IntType(false, t_bit_count);
965 const Log2U = math.Log2Int(U);840 const Log2U = math.Log2Int(U);
966 const int_size = (U.bit_count + 7) / 8;841 const int_size = (U.bit_count + 7) / 8;
967842
...@@ -976,7 +851,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,...@@ -976,7 +851,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
976851
977 if (int_size == 1) {852 if (int_size == 1) {
978 if (t_bit_count == 8) return @bitCast(T, buffer[0]);853 if (t_bit_count == 8) return @bitCast(T, buffer[0]);
979 const PossiblySignedByte = @IntType(T.is_signed, 8);854 const PossiblySignedByte = std.meta.IntType(T.is_signed, 8);
980 return @truncate(T, @bitCast(PossiblySignedByte, buffer[0]));855 return @truncate(T, @bitCast(PossiblySignedByte, buffer[0]));
981 }856 }
982857
...@@ -1005,9 +880,9 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,...@@ -1005,9 +880,9 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
1005 /// Deserializes data into the type pointed to by `ptr`880 /// Deserializes data into the type pointed to by `ptr`
1006 pub fn deserializeInto(self: *Self, ptr: var) !void {881 pub fn deserializeInto(self: *Self, ptr: var) !void {
1007 const T = @TypeOf(ptr);882 const T = @TypeOf(ptr);
1008 comptime assert(trait.is(builtin.TypeId.Pointer)(T));883 comptime assert(trait.is(.Pointer)(T));
1009884
1010 if (comptime trait.isSlice(T) or comptime trait.isPtrTo(builtin.TypeId.Array)(T)) {885 if (comptime trait.isSlice(T) or comptime trait.isPtrTo(.Array)(T)) {
1011 for (ptr) |*v|886 for (ptr) |*v|
1012 try self.deserializeInto(v);887 try self.deserializeInto(v);
1013 return;888 return;
...@@ -1016,7 +891,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,...@@ -1016,7 +891,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
1016 comptime assert(trait.isSingleItemPtr(T));891 comptime assert(trait.isSingleItemPtr(T));
1017892
1018 const C = comptime meta.Child(T);893 const C = comptime meta.Child(T);
1019 const child_type_id = @typeId(C);894 const child_type_id = @typeInfo(C);
1020895
1021 //custom deserializer: fn(self: *Self, deserializer: var) !void896 //custom deserializer: fn(self: *Self, deserializer: var) !void
1022 if (comptime trait.hasFn("deserialize")(C)) return C.deserialize(ptr, self);897 if (comptime trait.hasFn("deserialize")(C)) return C.deserialize(ptr, self);
...@@ -1027,10 +902,10 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,...@@ -1027,10 +902,10 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
1027 }902 }
1028903
1029 switch (child_type_id) {904 switch (child_type_id) {
1030 builtin.TypeId.Void => return,905 .Void => return,
1031 builtin.TypeId.Bool => ptr.* = (try self.deserializeInt(u1)) > 0,906 .Bool => ptr.* = (try self.deserializeInt(u1)) > 0,
1032 builtin.TypeId.Float, builtin.TypeId.Int => ptr.* = try self.deserializeInt(C),907 .Float, .Int => ptr.* = try self.deserializeInt(C),
1033 builtin.TypeId.Struct => {908 .Struct => {
1034 const info = @typeInfo(C).Struct;909 const info = @typeInfo(C).Struct;
1035910
1036 inline for (info.fields) |*field_info| {911 inline for (info.fields) |*field_info| {
...@@ -1040,7 +915,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,...@@ -1040,7 +915,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
1040 if (FieldType == void or FieldType == u0) continue;915 if (FieldType == void or FieldType == u0) continue;
1041916
1042 //it doesn't make any sense to read pointers917 //it doesn't make any sense to read pointers
1043 if (comptime trait.is(builtin.TypeId.Pointer)(FieldType)) {918 if (comptime trait.is(.Pointer)(FieldType)) {
1044 @compileError("Will not " ++ "read field " ++ name ++ " of struct " ++919 @compileError("Will not " ++ "read field " ++ name ++ " of struct " ++
1045 @typeName(C) ++ " because it " ++ "is of pointer-type " ++920 @typeName(C) ++ " because it " ++ "is of pointer-type " ++
1046 @typeName(FieldType) ++ ".");921 @typeName(FieldType) ++ ".");
...@@ -1049,7 +924,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,...@@ -1049,7 +924,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
1049 try self.deserializeInto(&@field(ptr, name));924 try self.deserializeInto(&@field(ptr, name));
1050 }925 }
1051 },926 },
1052 builtin.TypeId.Union => {927 .Union => {
1053 const info = @typeInfo(C).Union;928 const info = @typeInfo(C).Union;
1054 if (info.tag_type) |TagType| {929 if (info.tag_type) |TagType| {
1055 //we avoid duplicate iteration over the enum tags930 //we avoid duplicate iteration over the enum tags
...@@ -1073,7 +948,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,...@@ -1073,7 +948,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
1073 @compileError("Cannot meaningfully deserialize " ++ @typeName(C) ++948 @compileError("Cannot meaningfully deserialize " ++ @typeName(C) ++
1074 " because it is an untagged union. Use a custom deserialize().");949 " because it is an untagged union. Use a custom deserialize().");
1075 },950 },
1076 builtin.TypeId.Optional => {951 .Optional => {
1077 const OC = comptime meta.Child(C);952 const OC = comptime meta.Child(C);
1078 const exists = (try self.deserializeInt(u1)) > 0;953 const exists = (try self.deserializeInt(u1)) > 0;
1079 if (!exists) {954 if (!exists) {
...@@ -1085,7 +960,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,...@@ -1085,7 +960,7 @@ pub fn Deserializer(comptime endian: builtin.Endian, comptime packing: Packing,
1085 const val_ptr = &ptr.*.?;960 const val_ptr = &ptr.*.?;
1086 try self.deserializeInto(val_ptr);961 try self.deserializeInto(val_ptr);
1087 },962 },
1088 builtin.TypeId.Enum => {963 .Enum => {
1089 var value = try self.deserializeInt(@TagType(C));964 var value = try self.deserializeInt(@TagType(C));
1090 ptr.* = try meta.intToEnum(C, value);965 ptr.* = try meta.intToEnum(C, value);
1091 },966 },
...@@ -1134,12 +1009,12 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co...@@ -1134,12 +1009,12 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co
11341009
1135 fn serializeInt(self: *Self, value: var) Error!void {1010 fn serializeInt(self: *Self, value: var) Error!void {
1136 const T = @TypeOf(value);1011 const T = @TypeOf(value);
1137 comptime assert(trait.is(builtin.TypeId.Int)(T) or trait.is(builtin.TypeId.Float)(T));1012 comptime assert(trait.is(.Int)(T) or trait.is(.Float)(T));
11381013
1139 const t_bit_count = comptime meta.bitCount(T);1014 const t_bit_count = comptime meta.bitCount(T);
1140 const u8_bit_count = comptime meta.bitCount(u8);1015 const u8_bit_count = comptime meta.bitCount(u8);
11411016
1142 const U = @IntType(false, t_bit_count);1017 const U = std.meta.IntType(false, t_bit_count);
1143 const Log2U = math.Log2Int(U);1018 const Log2U = math.Log2Int(U);
1144 const int_size = (U.bit_count + 7) / 8;1019 const int_size = (U.bit_count + 7) / 8;
11451020
...@@ -1183,11 +1058,11 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co...@@ -1183,11 +1058,11 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co
1183 return;1058 return;
1184 }1059 }
11851060
1186 switch (@typeId(T)) {1061 switch (@typeInfo(T)) {
1187 builtin.TypeId.Void => return,1062 .Void => return,
1188 builtin.TypeId.Bool => try self.serializeInt(@as(u1, @boolToInt(value))),1063 .Bool => try self.serializeInt(@as(u1, @boolToInt(value))),
1189 builtin.TypeId.Float, builtin.TypeId.Int => try self.serializeInt(value),1064 .Float, .Int => try self.serializeInt(value),
1190 builtin.TypeId.Struct => {1065 .Struct => {
1191 const info = @typeInfo(T);1066 const info = @typeInfo(T);
11921067
1193 inline for (info.Struct.fields) |*field_info| {1068 inline for (info.Struct.fields) |*field_info| {
...@@ -1197,7 +1072,7 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co...@@ -1197,7 +1072,7 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co
1197 if (FieldType == void or FieldType == u0) continue;1072 if (FieldType == void or FieldType == u0) continue;
11981073
1199 //It doesn't make sense to write pointers1074 //It doesn't make sense to write pointers
1200 if (comptime trait.is(builtin.TypeId.Pointer)(FieldType)) {1075 if (comptime trait.is(.Pointer)(FieldType)) {
1201 @compileError("Will not " ++ "serialize field " ++ name ++1076 @compileError("Will not " ++ "serialize field " ++ name ++
1202 " of struct " ++ @typeName(T) ++ " because it " ++1077 " of struct " ++ @typeName(T) ++ " because it " ++
1203 "is of pointer-type " ++ @typeName(FieldType) ++ ".");1078 "is of pointer-type " ++ @typeName(FieldType) ++ ".");
...@@ -1205,7 +1080,7 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co...@@ -1205,7 +1080,7 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co
1205 try self.serialize(@field(value, name));1080 try self.serialize(@field(value, name));
1206 }1081 }
1207 },1082 },
1208 builtin.TypeId.Union => {1083 .Union => {
1209 const info = @typeInfo(T).Union;1084 const info = @typeInfo(T).Union;
1210 if (info.tag_type) |TagType| {1085 if (info.tag_type) |TagType| {
1211 const active_tag = meta.activeTag(value);1086 const active_tag = meta.activeTag(value);
...@@ -1226,7 +1101,7 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co...@@ -1226,7 +1101,7 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co
1226 @compileError("Cannot meaningfully serialize " ++ @typeName(T) ++1101 @compileError("Cannot meaningfully serialize " ++ @typeName(T) ++
1227 " because it is an untagged union. Use a custom serialize().");1102 " because it is an untagged union. Use a custom serialize().");
1228 },1103 },
1229 builtin.TypeId.Optional => {1104 .Optional => {
1230 if (value == null) {1105 if (value == null) {
1231 try self.serializeInt(@as(u1, @boolToInt(false)));1106 try self.serializeInt(@as(u1, @boolToInt(false)));
1232 return;1107 return;
...@@ -1237,10 +1112,10 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co...@@ -1237,10 +1112,10 @@ pub fn Serializer(comptime endian: builtin.Endian, comptime packing: Packing, co
1237 const val_ptr = &value.?;1112 const val_ptr = &value.?;
1238 try self.serialize(val_ptr.*);1113 try self.serialize(val_ptr.*);
1239 },1114 },
1240 builtin.TypeId.Enum => {1115 .Enum => {
1241 try self.serializeInt(@enumToInt(value));1116 try self.serializeInt(@enumToInt(value));
1242 },1117 },
1243 else => @compileError("Cannot serialize " ++ @tagName(@typeId(T)) ++ " types (unimplemented)."),1118 else => @compileError("Cannot serialize " ++ @tagName(@typeInfo(T)) ++ " types (unimplemented)."),
1244 }1119 }
1245 }1120 }
1246 };1121 };
lib/std/io/in_stream.zig+1-1
...@@ -235,7 +235,7 @@ pub fn InStream(comptime ReadError: type) type {...@@ -235,7 +235,7 @@ pub fn InStream(comptime ReadError: type) type {
235 // Only extern and packed structs have defined in-memory layout.235 // Only extern and packed structs have defined in-memory layout.
236 comptime assert(@typeInfo(T).Struct.layout != builtin.TypeInfo.ContainerLayout.Auto);236 comptime assert(@typeInfo(T).Struct.layout != builtin.TypeInfo.ContainerLayout.Auto);
237 var res: [1]T = undefined;237 var res: [1]T = undefined;
238 try self.readNoEof(@sliceToBytes(res[0..]));238 try self.readNoEof(mem.sliceAsBytes(res[0..]));
239 return res[0];239 return res[0];
240 }240 }
241241
lib/std/io/test.zig+13-11
...@@ -5,6 +5,7 @@ const meta = std.meta;...@@ -5,6 +5,7 @@ const meta = std.meta;
5const trait = std.trait;5const trait = std.trait;
6const DefaultPrng = std.rand.DefaultPrng;6const DefaultPrng = std.rand.DefaultPrng;
7const expect = std.testing.expect;7const expect = std.testing.expect;
8const expectEqual = std.testing.expectEqual;
8const expectError = std.testing.expectError;9const expectError = std.testing.expectError;
9const mem = std.mem;10const mem = std.mem;
10const fs = std.fs;11const fs = std.fs;
...@@ -44,8 +45,8 @@ test "write a file, read it, then delete it" {...@@ -44,8 +45,8 @@ test "write a file, read it, then delete it" {
44 defer file.close();45 defer file.close();
4546
46 const file_size = try file.getEndPos();47 const file_size = try file.getEndPos();
47 const expected_file_size = "begin".len + data.len + "end".len;48 const expected_file_size: u64 = "begin".len + data.len + "end".len;
48 expect(file_size == expected_file_size);49 expectEqual(expected_file_size, file_size);
4950
50 var file_in_stream = file.inStream();51 var file_in_stream = file.inStream();
51 var buf_stream = io.BufferedInStream(File.ReadError).init(&file_in_stream.stream);52 var buf_stream = io.BufferedInStream(File.ReadError).init(&file_in_stream.stream);
...@@ -93,12 +94,12 @@ test "SliceInStream" {...@@ -93,12 +94,12 @@ test "SliceInStream" {
93test "PeekStream" {94test "PeekStream" {
94 const bytes = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8 };95 const bytes = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8 };
95 var ss = io.SliceInStream.init(&bytes);96 var ss = io.SliceInStream.init(&bytes);
96 var ps = io.PeekStream(2, io.SliceInStream.Error).init(&ss.stream);97 var ps = io.PeekStream(.{ .Static = 2 }, io.SliceInStream.Error).init(&ss.stream);
9798
98 var dest: [4]u8 = undefined;99 var dest: [4]u8 = undefined;
99100
100 ps.putBackByte(9);101 try ps.putBackByte(9);
101 ps.putBackByte(10);102 try ps.putBackByte(10);
102103
103 var read = try ps.stream.read(dest[0..4]);104 var read = try ps.stream.read(dest[0..4]);
104 expect(read == 4);105 expect(read == 4);
...@@ -114,8 +115,8 @@ test "PeekStream" {...@@ -114,8 +115,8 @@ test "PeekStream" {
114 expect(read == 2);115 expect(read == 2);
115 expect(mem.eql(u8, dest[0..2], bytes[6..8]));116 expect(mem.eql(u8, dest[0..2], bytes[6..8]));
116117
117 ps.putBackByte(11);118 try ps.putBackByte(11);
118 ps.putBackByte(12);119 try ps.putBackByte(12);
119120
120 read = try ps.stream.read(dest[0..4]);121 read = try ps.stream.read(dest[0..4]);
121 expect(read == 2);122 expect(read == 2);
...@@ -317,6 +318,7 @@ test "BitStreams with File Stream" {...@@ -317,6 +318,7 @@ test "BitStreams with File Stream" {
317}318}
318319
319fn testIntSerializerDeserializer(comptime endian: builtin.Endian, comptime packing: io.Packing) !void {320fn testIntSerializerDeserializer(comptime endian: builtin.Endian, comptime packing: io.Packing) !void {
321 @setEvalBranchQuota(1500);
320 //@NOTE: if this test is taking too long, reduce the maximum tested bitsize322 //@NOTE: if this test is taking too long, reduce the maximum tested bitsize
321 const max_test_bitsize = 128;323 const max_test_bitsize = 128;
322324
...@@ -340,8 +342,8 @@ fn testIntSerializerDeserializer(comptime endian: builtin.Endian, comptime packi...@@ -340,8 +342,8 @@ fn testIntSerializerDeserializer(comptime endian: builtin.Endian, comptime packi
340342
341 comptime var i = 0;343 comptime var i = 0;
342 inline while (i <= max_test_bitsize) : (i += 1) {344 inline while (i <= max_test_bitsize) : (i += 1) {
343 const U = @IntType(false, i);345 const U = std.meta.IntType(false, i);
344 const S = @IntType(true, i);346 const S = std.meta.IntType(true, i);
345 try serializer.serializeInt(@as(U, i));347 try serializer.serializeInt(@as(U, i));
346 if (i != 0) try serializer.serializeInt(@as(S, -1)) else try serializer.serialize(@as(S, 0));348 if (i != 0) try serializer.serializeInt(@as(S, -1)) else try serializer.serialize(@as(S, 0));
347 }349 }
...@@ -349,8 +351,8 @@ fn testIntSerializerDeserializer(comptime endian: builtin.Endian, comptime packi...@@ -349,8 +351,8 @@ fn testIntSerializerDeserializer(comptime endian: builtin.Endian, comptime packi
349351
350 i = 0;352 i = 0;
351 inline while (i <= max_test_bitsize) : (i += 1) {353 inline while (i <= max_test_bitsize) : (i += 1) {
352 const U = @IntType(false, i);354 const U = std.meta.IntType(false, i);
353 const S = @IntType(true, i);355 const S = std.meta.IntType(true, i);
354 const x = try deserializer.deserializeInt(U);356 const x = try deserializer.deserializeInt(U);
355 const y = try deserializer.deserializeInt(S);357 const y = try deserializer.deserializeInt(S);
356 expect(x == @as(U, i));358 expect(x == @as(U, i));
lib/std/json.zig+822-3
...@@ -19,6 +19,74 @@ const StringEscapes = union(enum) {...@@ -19,6 +19,74 @@ const StringEscapes = union(enum) {
19 },19 },
20};20};
2121
22/// Checks to see if a string matches what it would be as a json-encoded string
23/// Assumes that `encoded` is a well-formed json string
24fn encodesTo(decoded: []const u8, encoded: []const u8) bool {
25 var i: usize = 0;
26 var j: usize = 0;
27 while (i < decoded.len) {
28 if (j >= encoded.len) return false;
29 if (encoded[j] != '\\') {
30 if (decoded[i] != encoded[j]) return false;
31 j += 1;
32 i += 1;
33 } else {
34 const escape_type = encoded[j + 1];
35 if (escape_type != 'u') {
36 const t: u8 = switch (escape_type) {
37 '\\' => '\\',
38 '/' => '/',
39 'n' => '\n',
40 'r' => '\r',
41 't' => '\t',
42 'f' => 12,
43 'b' => 8,
44 '"' => '"',
45 else => unreachable,
46 };
47 if (decoded[i] != t) return false;
48 j += 2;
49 i += 1;
50 } else {
51 var codepoint = std.fmt.parseInt(u21, encoded[j + 2 .. j + 6], 16) catch unreachable;
52 j += 6;
53 if (codepoint >= 0xD800 and codepoint < 0xDC00) {
54 // surrogate pair
55 assert(encoded[j] == '\\');
56 assert(encoded[j + 1] == 'u');
57 const low_surrogate = std.fmt.parseInt(u21, encoded[j + 2 .. j + 6], 16) catch unreachable;
58 codepoint = 0x10000 + (((codepoint & 0x03ff) << 10) | (low_surrogate & 0x03ff));
59 j += 6;
60 }
61 var buf: [4]u8 = undefined;
62 const len = std.unicode.utf8Encode(codepoint, &buf) catch unreachable;
63 if (i + len > decoded.len) return false;
64 if (!mem.eql(u8, decoded[i .. i + len], buf[0..len])) return false;
65 i += len;
66 }
67 }
68 }
69 assert(i == decoded.len);
70 assert(j == encoded.len);
71 return true;
72}
73
74test "encodesTo" {
75 // same
76 testing.expectEqual(true, encodesTo("false", "false"));
77 // totally different
78 testing.expectEqual(false, encodesTo("false", "true"));
79 // differnt lengths
80 testing.expectEqual(false, encodesTo("false", "other"));
81 // with escape
82 testing.expectEqual(true, encodesTo("\\", "\\\\"));
83 testing.expectEqual(true, encodesTo("with\nescape", "with\\nescape"));
84 // with unicode
85 testing.expectEqual(true, encodesTo("ą", "\\u0105"));
86 testing.expectEqual(true, encodesTo("😂", "\\ud83d\\ude02"));
87 testing.expectEqual(true, encodesTo("withąunicode😂", "with\\u0105unicode\\ud83d\\ude02"));
88}
89
22/// A single token slice into the parent string.90/// A single token slice into the parent string.
23///91///
24/// Use `token.slice()` on the input at the current position to get the current slice.92/// Use `token.slice()` on the input at the current position to get the current slice.
...@@ -1026,10 +1094,8 @@ pub const TokenStream = struct {...@@ -1026,10 +1094,8 @@ pub const TokenStream = struct {
10261094
1027 pub fn next(self: *TokenStream) Error!?Token {1095 pub fn next(self: *TokenStream) Error!?Token {
1028 if (self.token) |token| {1096 if (self.token) |token| {
1029 // TODO: Audit this pattern once #2915 is closed
1030 const copy = token;
1031 self.token = null;1097 self.token = null;
1032 return copy;1098 return token;
1033 }1099 }
10341100
1035 var t1: ?Token = undefined;1101 var t1: ?Token = undefined;
...@@ -1203,6 +1269,493 @@ pub const Value = union(enum) {...@@ -1203,6 +1269,493 @@ pub const Value = union(enum) {
1203 }1269 }
1204};1270};
12051271
1272pub const ParseOptions = struct {
1273 allocator: ?*Allocator = null,
1274
1275 /// Behaviour when a duplicate field is encountered.
1276 duplicate_field_behavior: enum {
1277 UseFirst,
1278 Error,
1279 UseLast,
1280 } = .Error,
1281};
1282
1283fn parseInternal(comptime T: type, token: Token, tokens: *TokenStream, options: ParseOptions) !T {
1284 switch (@typeInfo(T)) {
1285 .Bool => {
1286 return switch (token) {
1287 .True => true,
1288 .False => false,
1289 else => error.UnexpectedToken,
1290 };
1291 },
1292 .Float, .ComptimeFloat => {
1293 const numberToken = switch (token) {
1294 .Number => |n| n,
1295 else => return error.UnexpectedToken,
1296 };
1297 return try std.fmt.parseFloat(T, numberToken.slice(tokens.slice, tokens.i - 1));
1298 },
1299 .Int, .ComptimeInt => {
1300 const numberToken = switch (token) {
1301 .Number => |n| n,
1302 else => return error.UnexpectedToken,
1303 };
1304 if (!numberToken.is_integer) return error.UnexpectedToken;
1305 return try std.fmt.parseInt(T, numberToken.slice(tokens.slice, tokens.i - 1), 10);
1306 },
1307 .Optional => |optionalInfo| {
1308 if (token == .Null) {
1309 return null;
1310 } else {
1311 return try parseInternal(optionalInfo.child, token, tokens, options);
1312 }
1313 },
1314 .Enum => |enumInfo| {
1315 switch (token) {
1316 .Number => |numberToken| {
1317 if (!numberToken.is_integer) return error.UnexpectedToken;
1318 const n = try std.fmt.parseInt(enumInfo.tag_type, numberToken.slice(tokens.slice, tokens.i - 1), 10);
1319 return try std.meta.intToEnum(T, n);
1320 },
1321 .String => |stringToken| {
1322 const source_slice = stringToken.slice(tokens.slice, tokens.i - 1);
1323 switch (stringToken.escapes) {
1324 .None => return std.meta.stringToEnum(T, source_slice) orelse return error.InvalidEnumTag,
1325 .Some => {
1326 inline for (enumInfo.fields) |field| {
1327 if (field.name.len == stringToken.decodedLength() and encodesTo(field.name, source_slice)) {
1328 return @field(T, field.name);
1329 }
1330 }
1331 return error.InvalidEnumTag;
1332 },
1333 }
1334 },
1335 else => return error.UnexpectedToken,
1336 }
1337 },
1338 .Union => |unionInfo| {
1339 if (unionInfo.tag_type) |_| {
1340 // try each of the union fields until we find one that matches
1341 inline for (unionInfo.fields) |u_field| {
1342 if (parseInternal(u_field.field_type, token, tokens, options)) |value| {
1343 return @unionInit(T, u_field.name, value);
1344 } else |err| {
1345 // Bubble up error.OutOfMemory
1346 // Parsing some types won't have OutOfMemory in their
1347 // error-sets, for the condition to be valid, merge it in.
1348 if (@as(@TypeOf(err) || error{OutOfMemory}, err) == error.OutOfMemory) return err;
1349 // otherwise continue through the `inline for`
1350 }
1351 }
1352 return error.NoUnionMembersMatched;
1353 } else {
1354 @compileError("Unable to parse into untagged union '" ++ @typeName(T) ++ "'");
1355 }
1356 },
1357 .Struct => |structInfo| {
1358 switch (token) {
1359 .ObjectBegin => {},
1360 else => return error.UnexpectedToken,
1361 }
1362 var r: T = undefined;
1363 var fields_seen = [_]bool{false} ** structInfo.fields.len;
1364 errdefer {
1365 inline for (structInfo.fields) |field, i| {
1366 if (fields_seen[i]) {
1367 parseFree(field.field_type, @field(r, field.name), options);
1368 }
1369 }
1370 }
1371
1372 while (true) {
1373 switch ((try tokens.next()) orelse return error.UnexpectedEndOfJson) {
1374 .ObjectEnd => break,
1375 .String => |stringToken| {
1376 const key_source_slice = stringToken.slice(tokens.slice, tokens.i - 1);
1377 var found = false;
1378 inline for (structInfo.fields) |field, i| {
1379 // TODO: using switches here segfault the compiler (#2727?)
1380 if ((stringToken.escapes == .None and mem.eql(u8, field.name, key_source_slice)) or (stringToken.escapes == .Some and (field.name.len == stringToken.decodedLength() and encodesTo(field.name, key_source_slice)))) {
1381 // if (switch (stringToken.escapes) {
1382 // .None => mem.eql(u8, field.name, key_source_slice),
1383 // .Some => (field.name.len == stringToken.decodedLength() and encodesTo(field.name, key_source_slice)),
1384 // }) {
1385 if (fields_seen[i]) {
1386 // switch (options.duplicate_field_behavior) {
1387 // .UseFirst => {},
1388 // .Error => {},
1389 // .UseLast => {},
1390 // }
1391 if (options.duplicate_field_behavior == .UseFirst) {
1392 break;
1393 } else if (options.duplicate_field_behavior == .Error) {
1394 return error.DuplicateJSONField;
1395 } else if (options.duplicate_field_behavior == .UseLast) {
1396 parseFree(field.field_type, @field(r, field.name), options);
1397 }
1398 }
1399 @field(r, field.name) = try parse(field.field_type, tokens, options);
1400 fields_seen[i] = true;
1401 found = true;
1402 break;
1403 }
1404 }
1405 if (!found) return error.UnknownField;
1406 },
1407 else => return error.UnexpectedToken,
1408 }
1409 }
1410 inline for (structInfo.fields) |field, i| {
1411 if (!fields_seen[i]) {
1412 if (field.default_value) |default| {
1413 @field(r, field.name) = default;
1414 } else {
1415 return error.MissingField;
1416 }
1417 }
1418 }
1419 return r;
1420 },
1421 .Array => |arrayInfo| {
1422 switch (token) {
1423 .ArrayBegin => {
1424 var r: T = undefined;
1425 var i: usize = 0;
1426 errdefer {
1427 while (true) : (i -= 1) {
1428 parseFree(arrayInfo.child, r[i], options);
1429 if (i == 0) break;
1430 }
1431 }
1432 while (i < r.len) : (i += 1) {
1433 r[i] = try parse(arrayInfo.child, tokens, options);
1434 }
1435 const tok = (try tokens.next()) orelse return error.UnexpectedEndOfJson;
1436 switch (tok) {
1437 .ArrayEnd => {},
1438 else => return error.UnexpectedToken,
1439 }
1440 return r;
1441 },
1442 .String => |stringToken| {
1443 if (arrayInfo.child != u8) return error.UnexpectedToken;
1444 var r: T = undefined;
1445 const source_slice = stringToken.slice(tokens.slice, tokens.i - 1);
1446 switch (stringToken.escapes) {
1447 .None => mem.copy(u8, &r, source_slice),
1448 .Some => try unescapeString(&r, source_slice),
1449 }
1450 return r;
1451 },
1452 else => return error.UnexpectedToken,
1453 }
1454 },
1455 .Pointer => |ptrInfo| {
1456 const allocator = options.allocator orelse return error.AllocatorRequired;
1457 switch (ptrInfo.size) {
1458 .One => {
1459 const r: T = allocator.create(ptrInfo.child);
1460 r.* = try parseInternal(ptrInfo.child, token, tokens, options);
1461 return r;
1462 },
1463 .Slice => {
1464 switch (token) {
1465 .ArrayBegin => {
1466 var arraylist = std.ArrayList(ptrInfo.child).init(allocator);
1467 errdefer {
1468 while (arraylist.popOrNull()) |v| {
1469 parseFree(ptrInfo.child, v, options);
1470 }
1471 arraylist.deinit();
1472 }
1473
1474 while (true) {
1475 const tok = (try tokens.next()) orelse return error.UnexpectedEndOfJson;
1476 switch (tok) {
1477 .ArrayEnd => break,
1478 else => {},
1479 }
1480
1481 try arraylist.ensureCapacity(arraylist.len + 1);
1482 const v = try parseInternal(ptrInfo.child, tok, tokens, options);
1483 arraylist.appendAssumeCapacity(v);
1484 }
1485 return arraylist.toOwnedSlice();
1486 },
1487 .String => |stringToken| {
1488 if (ptrInfo.child != u8) return error.UnexpectedToken;
1489 const source_slice = stringToken.slice(tokens.slice, tokens.i - 1);
1490 switch (stringToken.escapes) {
1491 .None => return mem.dupe(allocator, u8, source_slice),
1492 .Some => |some_escapes| {
1493 const output = try allocator.alloc(u8, stringToken.decodedLength());
1494 errdefer allocator.free(output);
1495 try unescapeString(output, source_slice);
1496 return output;
1497 },
1498 }
1499 },
1500 else => return error.UnexpectedToken,
1501 }
1502 },
1503 else => @compileError("Unable to parse into type '" ++ @typeName(T) ++ "'"),
1504 }
1505 },
1506 else => @compileError("Unable to parse into type '" ++ @typeName(T) ++ "'"),
1507 }
1508 unreachable;
1509}
1510
1511pub fn parse(comptime T: type, tokens: *TokenStream, options: ParseOptions) !T {
1512 const token = (try tokens.next()) orelse return error.UnexpectedEndOfJson;
1513 return parseInternal(T, token, tokens, options);
1514}
1515
1516/// Releases resources created by `parse`.
1517/// Should be called with the same type and `ParseOptions` that were passed to `parse`
1518pub fn parseFree(comptime T: type, value: T, options: ParseOptions) void {
1519 switch (@typeInfo(T)) {
1520 .Bool, .Float, .ComptimeFloat, .Int, .ComptimeInt, .Enum => {},
1521 .Optional => {
1522 if (value) |v| {
1523 return parseFree(@TypeOf(v), v, options);
1524 }
1525 },
1526 .Union => |unionInfo| {
1527 if (unionInfo.tag_type) |UnionTagType| {
1528 inline for (unionInfo.fields) |u_field| {
1529 if (@enumToInt(@as(UnionTagType, value)) == u_field.enum_field.?.value) {
1530 parseFree(u_field.field_type, @field(value, u_field.name), options);
1531 break;
1532 }
1533 }
1534 } else {
1535 unreachable;
1536 }
1537 },
1538 .Struct => |structInfo| {
1539 inline for (structInfo.fields) |field| {
1540 parseFree(field.field_type, @field(value, field.name), options);
1541 }
1542 },
1543 .Array => |arrayInfo| {
1544 for (value) |v| {
1545 parseFree(arrayInfo.child, v, options);
1546 }
1547 },
1548 .Pointer => |ptrInfo| {
1549 const allocator = options.allocator orelse unreachable;
1550 switch (ptrInfo.size) {
1551 .One => {
1552 parseFree(ptrInfo.child, value.*, options);
1553 allocator.destroy(v);
1554 },
1555 .Slice => {
1556 for (value) |v| {
1557 parseFree(ptrInfo.child, v, options);
1558 }
1559 allocator.free(value);
1560 },
1561 else => unreachable,
1562 }
1563 },
1564 else => unreachable,
1565 }
1566}
1567
1568test "parse" {
1569 testing.expectEqual(false, try parse(bool, &TokenStream.init("false"), ParseOptions{}));
1570 testing.expectEqual(true, try parse(bool, &TokenStream.init("true"), ParseOptions{}));
1571 testing.expectEqual(@as(u1, 1), try parse(u1, &TokenStream.init("1"), ParseOptions{}));
1572 testing.expectError(error.Overflow, parse(u1, &TokenStream.init("50"), ParseOptions{}));
1573 testing.expectEqual(@as(u64, 42), try parse(u64, &TokenStream.init("42"), ParseOptions{}));
1574 testing.expectEqual(@as(f64, 42), try parse(f64, &TokenStream.init("42.0"), ParseOptions{}));
1575 testing.expectEqual(@as(?bool, null), try parse(?bool, &TokenStream.init("null"), ParseOptions{}));
1576 testing.expectEqual(@as(?bool, true), try parse(?bool, &TokenStream.init("true"), ParseOptions{}));
1577
1578 testing.expectEqual(@as([3]u8, "foo".*), try parse([3]u8, &TokenStream.init("\"foo\""), ParseOptions{}));
1579 testing.expectEqual(@as([3]u8, "foo".*), try parse([3]u8, &TokenStream.init("[102, 111, 111]"), ParseOptions{}));
1580}
1581
1582test "parse into enum" {
1583 const T = extern enum {
1584 Foo = 42,
1585 Bar,
1586 @"with\\escape",
1587 };
1588 testing.expectEqual(@as(T, .Foo), try parse(T, &TokenStream.init("\"Foo\""), ParseOptions{}));
1589 testing.expectEqual(@as(T, .Foo), try parse(T, &TokenStream.init("42"), ParseOptions{}));
1590 testing.expectEqual(@as(T, .@"with\\escape"), try parse(T, &TokenStream.init("\"with\\\\escape\""), ParseOptions{}));
1591 testing.expectError(error.InvalidEnumTag, parse(T, &TokenStream.init("5"), ParseOptions{}));
1592 testing.expectError(error.InvalidEnumTag, parse(T, &TokenStream.init("\"Qux\""), ParseOptions{}));
1593}
1594
1595test "parse into that allocates a slice" {
1596 testing.expectError(error.AllocatorRequired, parse([]u8, &TokenStream.init("\"foo\""), ParseOptions{}));
1597
1598 const options = ParseOptions{ .allocator = testing.allocator };
1599 {
1600 const r = try parse([]u8, &TokenStream.init("\"foo\""), options);
1601 defer parseFree([]u8, r, options);
1602 testing.expectEqualSlices(u8, "foo", r);
1603 }
1604 {
1605 const r = try parse([]u8, &TokenStream.init("[102, 111, 111]"), options);
1606 defer parseFree([]u8, r, options);
1607 testing.expectEqualSlices(u8, "foo", r);
1608 }
1609 {
1610 const r = try parse([]u8, &TokenStream.init("\"with\\\\escape\""), options);
1611 defer parseFree([]u8, r, options);
1612 testing.expectEqualSlices(u8, "with\\escape", r);
1613 }
1614}
1615
1616test "parse into tagged union" {
1617 {
1618 const T = union(enum) {
1619 int: i32,
1620 float: f64,
1621 string: []const u8,
1622 };
1623 testing.expectEqual(T{ .float = 1.5 }, try parse(T, &TokenStream.init("1.5"), ParseOptions{}));
1624 }
1625
1626 { // if union matches string member, fails with NoUnionMembersMatched rather than AllocatorRequired
1627 // Note that this behaviour wasn't necessarily by design, but was
1628 // what fell out of the implementation and may result in interesting
1629 // API breakage if changed
1630 const T = union(enum) {
1631 int: i32,
1632 float: f64,
1633 string: []const u8,
1634 };
1635 testing.expectError(error.NoUnionMembersMatched, parse(T, &TokenStream.init("\"foo\""), ParseOptions{}));
1636 }
1637
1638 { // failing allocations should be bubbled up instantly without trying next member
1639 var fail_alloc = testing.FailingAllocator.init(testing.allocator, 0);
1640 const options = ParseOptions{ .allocator = &fail_alloc.allocator };
1641 const T = union(enum) {
1642 // both fields here match the input
1643 string: []const u8,
1644 array: [3]u8,
1645 };
1646 testing.expectError(error.OutOfMemory, parse(T, &TokenStream.init("[1,2,3]"), options));
1647 }
1648
1649 {
1650 // if multiple matches possible, takes first option
1651 const T = union(enum) {
1652 x: u8,
1653 y: u8,
1654 };
1655 testing.expectEqual(T{ .x = 42 }, try parse(T, &TokenStream.init("42"), ParseOptions{}));
1656 }
1657}
1658
1659test "parseFree descends into tagged union" {
1660 // tagged unions are broken on arm64: https://github.com/ziglang/zig/issues/4492
1661 if (std.builtin.arch == .aarch64) return error.SkipZigTest;
1662
1663 var fail_alloc = testing.FailingAllocator.init(testing.allocator, 1);
1664 const options = ParseOptions{ .allocator = &fail_alloc.allocator };
1665 const T = union(enum) {
1666 int: i32,
1667 float: f64,
1668 string: []const u8,
1669 };
1670 // use a string with unicode escape so we know result can't be a reference to global constant
1671 const r = try parse(T, &TokenStream.init("\"with\\u0105unicode\""), options);
1672 testing.expectEqual(@TagType(T).string, @as(@TagType(T), r));
1673 testing.expectEqualSlices(u8, "withąunicode", r.string);
1674 testing.expectEqual(@as(usize, 0), fail_alloc.deallocations);
1675 parseFree(T, r, options);
1676 testing.expectEqual(@as(usize, 1), fail_alloc.deallocations);
1677}
1678
1679test "parse into struct with no fields" {
1680 const T = struct {};
1681 testing.expectEqual(T{}, try parse(T, &TokenStream.init("{}"), ParseOptions{}));
1682}
1683
1684test "parse into struct with misc fields" {
1685 @setEvalBranchQuota(10000);
1686 const options = ParseOptions{ .allocator = testing.allocator };
1687 const T = struct {
1688 int: i64,
1689 float: f64,
1690 @"with\\escape": bool,
1691 @"withąunicode😂": bool,
1692 language: []const u8,
1693 optional: ?bool,
1694 default_field: i32 = 42,
1695 static_array: [3]f64,
1696 dynamic_array: []f64,
1697
1698 const Bar = struct {
1699 nested: []const u8,
1700 };
1701 complex: Bar,
1702
1703 const Baz = struct {
1704 foo: []const u8,
1705 };
1706 veryComplex: []Baz,
1707
1708 const Union = union(enum) {
1709 x: u8,
1710 float: f64,
1711 string: []const u8,
1712 };
1713 a_union: Union,
1714 };
1715 const r = try parse(T, &TokenStream.init(
1716 \\{
1717 \\ "int": 420,
1718 \\ "float": 3.14,
1719 \\ "with\\escape": true,
1720 \\ "with\u0105unicode\ud83d\ude02": false,
1721 \\ "language": "zig",
1722 \\ "optional": null,
1723 \\ "static_array": [66.6, 420.420, 69.69],
1724 \\ "dynamic_array": [66.6, 420.420, 69.69],
1725 \\ "complex": {
1726 \\ "nested": "zig"
1727 \\ },
1728 \\ "veryComplex": [
1729 \\ {
1730 \\ "foo": "zig"
1731 \\ }, {
1732 \\ "foo": "rocks"
1733 \\ }
1734 \\ ],
1735 \\ "a_union": 100000
1736 \\}
1737 ), options);
1738 defer parseFree(T, r, options);
1739 testing.expectEqual(@as(i64, 420), r.int);
1740 testing.expectEqual(@as(f64, 3.14), r.float);
1741 testing.expectEqual(true, r.@"with\\escape");
1742 testing.expectEqual(false, r.@"withąunicode😂");
1743 testing.expectEqualSlices(u8, "zig", r.language);
1744 testing.expectEqual(@as(?bool, null), r.optional);
1745 testing.expectEqual(@as(i32, 42), r.default_field);
1746 testing.expectEqual(@as(f64, 66.6), r.static_array[0]);
1747 testing.expectEqual(@as(f64, 420.420), r.static_array[1]);
1748 testing.expectEqual(@as(f64, 69.69), r.static_array[2]);
1749 testing.expectEqual(@as(usize, 3), r.dynamic_array.len);
1750 testing.expectEqual(@as(f64, 66.6), r.dynamic_array[0]);
1751 testing.expectEqual(@as(f64, 420.420), r.dynamic_array[1]);
1752 testing.expectEqual(@as(f64, 69.69), r.dynamic_array[2]);
1753 testing.expectEqualSlices(u8, r.complex.nested, "zig");
1754 testing.expectEqualSlices(u8, "zig", r.veryComplex[0].foo);
1755 testing.expectEqualSlices(u8, "rocks", r.veryComplex[1].foo);
1756 testing.expectEqual(T.Union{ .float = 100000 }, r.a_union);
1757}
1758
1206/// A non-stream JSON parser which constructs a tree of Value's.1759/// A non-stream JSON parser which constructs a tree of Value's.
1207pub const Parser = struct {1760pub const Parser = struct {
1208 allocator: *Allocator,1761 allocator: *Allocator,
...@@ -1688,3 +2241,269 @@ test "string copy option" {...@@ -1688,3 +2241,269 @@ test "string copy option" {
1688 }2241 }
1689 testing.expect(found_nocopy);2242 testing.expect(found_nocopy);
1690}2243}
2244
2245pub const StringifyOptions = struct {
2246 // TODO: indentation options?
2247 // TODO: make escaping '/' in strings optional?
2248 // TODO: allow picking if []u8 is string or array?
2249};
2250
2251pub fn stringify(
2252 value: var,
2253 options: StringifyOptions,
2254 context: var,
2255 comptime Errors: type,
2256 comptime output: fn (@TypeOf(context), []const u8) Errors!void,
2257) Errors!void {
2258 const T = @TypeOf(value);
2259 switch (@typeInfo(T)) {
2260 .Float, .ComptimeFloat => {
2261 return std.fmt.formatFloatScientific(value, std.fmt.FormatOptions{}, context, Errors, output);
2262 },
2263 .Int, .ComptimeInt => {
2264 return std.fmt.formatIntValue(value, "", std.fmt.FormatOptions{}, context, Errors, output);
2265 },
2266 .Bool => {
2267 return output(context, if (value) "true" else "false");
2268 },
2269 .Optional => {
2270 if (value) |payload| {
2271 return try stringify(payload, options, context, Errors, output);
2272 } else {
2273 return output(context, "null");
2274 }
2275 },
2276 .Enum => {
2277 if (comptime std.meta.trait.hasFn("jsonStringify")(T)) {
2278 return value.jsonStringify(options, context, Errors, output);
2279 }
2280
2281 @compileError("Unable to stringify enum '" ++ @typeName(T) ++ "'");
2282 },
2283 .Union => {
2284 if (comptime std.meta.trait.hasFn("jsonStringify")(T)) {
2285 return value.jsonStringify(options, context, Errors, output);
2286 }
2287
2288 const info = @typeInfo(T).Union;
2289 if (info.tag_type) |UnionTagType| {
2290 inline for (info.fields) |u_field| {
2291 if (@enumToInt(@as(UnionTagType, value)) == u_field.enum_field.?.value) {
2292 return try stringify(@field(value, u_field.name), options, context, Errors, output);
2293 }
2294 }
2295 } else {
2296 @compileError("Unable to stringify untagged union '" ++ @typeName(T) ++ "'");
2297 }
2298 },
2299 .Struct => |S| {
2300 if (comptime std.meta.trait.hasFn("jsonStringify")(T)) {
2301 return value.jsonStringify(options, context, Errors, output);
2302 }
2303
2304 try output(context, "{");
2305 comptime var field_output = false;
2306 inline for (S.fields) |Field, field_i| {
2307 // don't include void fields
2308 if (Field.field_type == void) continue;
2309
2310 if (!field_output) {
2311 field_output = true;
2312 } else {
2313 try output(context, ",");
2314 }
2315
2316 try stringify(Field.name, options, context, Errors, output);
2317 try output(context, ":");
2318 try stringify(@field(value, Field.name), options, context, Errors, output);
2319 }
2320 try output(context, "}");
2321 return;
2322 },
2323 .Pointer => |ptr_info| switch (ptr_info.size) {
2324 .One => {
2325 // TODO: avoid loops?
2326 return try stringify(value.*, options, context, Errors, output);
2327 },
2328 // TODO: .Many when there is a sentinel (waiting for https://github.com/ziglang/zig/pull/3972)
2329 .Slice => {
2330 if (ptr_info.child == u8 and std.unicode.utf8ValidateSlice(value)) {
2331 try output(context, "\"");
2332 var i: usize = 0;
2333 while (i < value.len) : (i += 1) {
2334 switch (value[i]) {
2335 // normal ascii characters
2336 0x20...0x21, 0x23...0x2E, 0x30...0x5B, 0x5D...0x7F => try output(context, value[i .. i + 1]),
2337 // control characters with short escapes
2338 '\\' => try output(context, "\\\\"),
2339 '\"' => try output(context, "\\\""),
2340 '/' => try output(context, "\\/"),
2341 0x8 => try output(context, "\\b"),
2342 0xC => try output(context, "\\f"),
2343 '\n' => try output(context, "\\n"),
2344 '\r' => try output(context, "\\r"),
2345 '\t' => try output(context, "\\t"),
2346 else => {
2347 const ulen = std.unicode.utf8ByteSequenceLength(value[i]) catch unreachable;
2348 const codepoint = std.unicode.utf8Decode(value[i .. i + ulen]) catch unreachable;
2349 if (codepoint <= 0xFFFF) {
2350 // If the character is in the Basic Multilingual Plane (U+0000 through U+FFFF),
2351 // then it may be represented as a six-character sequence: a reverse solidus, followed
2352 // by the lowercase letter u, followed by four hexadecimal digits that encode the character's code point.
2353 try output(context, "\\u");
2354 try std.fmt.formatIntValue(codepoint, "x", std.fmt.FormatOptions{ .width = 4, .fill = '0' }, context, Errors, output);
2355 } else {
2356 // To escape an extended character that is not in the Basic Multilingual Plane,
2357 // the character is represented as a 12-character sequence, encoding the UTF-16 surrogate pair.
2358 const high = @intCast(u16, (codepoint - 0x10000) >> 10) + 0xD800;
2359 const low = @intCast(u16, codepoint & 0x3FF) + 0xDC00;
2360 try output(context, "\\u");
2361 try std.fmt.formatIntValue(high, "x", std.fmt.FormatOptions{ .width = 4, .fill = '0' }, context, Errors, output);
2362 try output(context, "\\u");
2363 try std.fmt.formatIntValue(low, "x", std.fmt.FormatOptions{ .width = 4, .fill = '0' }, context, Errors, output);
2364 }
2365 i += ulen - 1;
2366 },
2367 }
2368 }
2369 try output(context, "\"");
2370 return;
2371 }
2372
2373 try output(context, "[");
2374 for (value) |x, i| {
2375 if (i != 0) {
2376 try output(context, ",");
2377 }
2378 try stringify(x, options, context, Errors, output);
2379 }
2380 try output(context, "]");
2381 return;
2382 },
2383 else => @compileError("Unable to stringify type '" ++ @typeName(T) ++ "'"),
2384 },
2385 .Array => |info| {
2386 return try stringify(value[0..], options, context, Errors, output);
2387 },
2388 else => @compileError("Unable to stringify type '" ++ @typeName(T) ++ "'"),
2389 }
2390 unreachable;
2391}
2392
2393fn teststringify(expected: []const u8, value: var) !void {
2394 const TestStringifyContext = struct {
2395 expected_remaining: []const u8,
2396 fn testStringifyWrite(context: *@This(), bytes: []const u8) !void {
2397 if (context.expected_remaining.len < bytes.len) {
2398 std.debug.warn(
2399 \\====== expected this output: =========
2400 \\{}
2401 \\======== instead found this: =========
2402 \\{}
2403 \\======================================
2404 , .{
2405 context.expected_remaining,
2406 bytes,
2407 });
2408 return error.TooMuchData;
2409 }
2410 if (!mem.eql(u8, context.expected_remaining[0..bytes.len], bytes)) {
2411 std.debug.warn(
2412 \\====== expected this output: =========
2413 \\{}
2414 \\======== instead found this: =========
2415 \\{}
2416 \\======================================
2417 , .{
2418 context.expected_remaining[0..bytes.len],
2419 bytes,
2420 });
2421 return error.DifferentData;
2422 }
2423 context.expected_remaining = context.expected_remaining[bytes.len..];
2424 }
2425 };
2426 var buf: [100]u8 = undefined;
2427 var context = TestStringifyContext{ .expected_remaining = expected };
2428 try stringify(value, StringifyOptions{}, &context, error{
2429 TooMuchData,
2430 DifferentData,
2431 }, TestStringifyContext.testStringifyWrite);
2432 if (context.expected_remaining.len > 0) return error.NotEnoughData;
2433}
2434
2435test "stringify basic types" {
2436 try teststringify("false", false);
2437 try teststringify("true", true);
2438 try teststringify("null", @as(?u8, null));
2439 try teststringify("null", @as(?*u32, null));
2440 try teststringify("42", 42);
2441 try teststringify("4.2e+01", 42.0);
2442 try teststringify("42", @as(u8, 42));
2443 try teststringify("42", @as(u128, 42));
2444 try teststringify("4.2e+01", @as(f32, 42));
2445 try teststringify("4.2e+01", @as(f64, 42));
2446}
2447
2448test "stringify string" {
2449 try teststringify("\"hello\"", "hello");
2450 try teststringify("\"with\\nescapes\\r\"", "with\nescapes\r");
2451 try teststringify("\"with unicode\\u0001\"", "with unicode\u{1}");
2452 try teststringify("\"with unicode\\u0080\"", "with unicode\u{80}");
2453 try teststringify("\"with unicode\\u00ff\"", "with unicode\u{FF}");
2454 try teststringify("\"with unicode\\u0100\"", "with unicode\u{100}");
2455 try teststringify("\"with unicode\\u0800\"", "with unicode\u{800}");
2456 try teststringify("\"with unicode\\u8000\"", "with unicode\u{8000}");
2457 try teststringify("\"with unicode\\ud799\"", "with unicode\u{D799}");
2458 try teststringify("\"with unicode\\ud800\\udc00\"", "with unicode\u{10000}");
2459 try teststringify("\"with unicode\\udbff\\udfff\"", "with unicode\u{10FFFF}");
2460}
2461
2462test "stringify tagged unions" {
2463 try teststringify("42", union(enum) {
2464 Foo: u32,
2465 Bar: bool,
2466 }{ .Foo = 42 });
2467}
2468
2469test "stringify struct" {
2470 try teststringify("{\"foo\":42}", struct {
2471 foo: u32,
2472 }{ .foo = 42 });
2473}
2474
2475test "stringify struct with void field" {
2476 try teststringify("{\"foo\":42}", struct {
2477 foo: u32,
2478 bar: void = {},
2479 }{ .foo = 42 });
2480}
2481
2482test "stringify array of structs" {
2483 const MyStruct = struct {
2484 foo: u32,
2485 };
2486 try teststringify("[{\"foo\":42},{\"foo\":100},{\"foo\":1000}]", [_]MyStruct{
2487 MyStruct{ .foo = 42 },
2488 MyStruct{ .foo = 100 },
2489 MyStruct{ .foo = 1000 },
2490 });
2491}
2492
2493test "stringify struct with custom stringifier" {
2494 try teststringify("[\"something special\",42]", struct {
2495 foo: u32,
2496 const Self = @This();
2497 pub fn jsonStringify(
2498 value: Self,
2499 options: StringifyOptions,
2500 context: var,
2501 comptime Errors: type,
2502 comptime output: fn (@TypeOf(context), []const u8) Errors!void,
2503 ) !void {
2504 try output(context, "[\"something special\",");
2505 try stringify(42, options, context, Errors, output);
2506 try output(context, "]");
2507 }
2508 }{ .foo = 42 });
2509}
lib/std/math.zig+26-28
...@@ -1,6 +1,4 @@...@@ -1,6 +1,4 @@
1const builtin = @import("builtin");
2const std = @import("std.zig");1const std = @import("std.zig");
3const TypeId = builtin.TypeId;
4const assert = std.debug.assert;2const assert = std.debug.assert;
5const testing = std.testing;3const testing = std.testing;
64
...@@ -89,7 +87,7 @@ pub const snan = @import("math/nan.zig").snan;...@@ -89,7 +87,7 @@ pub const snan = @import("math/nan.zig").snan;
89pub const inf = @import("math/inf.zig").inf;87pub const inf = @import("math/inf.zig").inf;
9088
91pub fn approxEq(comptime T: type, x: T, y: T, epsilon: T) bool {89pub fn approxEq(comptime T: type, x: T, y: T, epsilon: T) bool {
92 assert(@typeId(T) == TypeId.Float);90 assert(@typeInfo(T) == .Float);
93 return fabs(x - y) < epsilon;91 return fabs(x - y) < epsilon;
94}92}
9593
...@@ -198,7 +196,7 @@ test "" {...@@ -198,7 +196,7 @@ test "" {
198}196}
199197
200pub fn floatMantissaBits(comptime T: type) comptime_int {198pub fn floatMantissaBits(comptime T: type) comptime_int {
201 assert(@typeId(T) == builtin.TypeId.Float);199 assert(@typeInfo(T) == .Float);
202200
203 return switch (T.bit_count) {201 return switch (T.bit_count) {
204 16 => 10,202 16 => 10,
...@@ -211,7 +209,7 @@ pub fn floatMantissaBits(comptime T: type) comptime_int {...@@ -211,7 +209,7 @@ pub fn floatMantissaBits(comptime T: type) comptime_int {
211}209}
212210
213pub fn floatExponentBits(comptime T: type) comptime_int {211pub fn floatExponentBits(comptime T: type) comptime_int {
214 assert(@typeId(T) == builtin.TypeId.Float);212 assert(@typeInfo(T) == .Float);
215213
216 return switch (T.bit_count) {214 return switch (T.bit_count) {
217 16 => 5,215 16 => 5,
...@@ -446,7 +444,7 @@ pub fn Log2Int(comptime T: type) type {...@@ -446,7 +444,7 @@ pub fn Log2Int(comptime T: type) type {
446 count += 1;444 count += 1;
447 }445 }
448446
449 return @IntType(false, count);447 return std.meta.IntType(false, count);
450}448}
451449
452pub fn IntFittingRange(comptime from: comptime_int, comptime to: comptime_int) type {450pub fn IntFittingRange(comptime from: comptime_int, comptime to: comptime_int) type {
...@@ -462,7 +460,7 @@ pub fn IntFittingRange(comptime from: comptime_int, comptime to: comptime_int) t...@@ -462,7 +460,7 @@ pub fn IntFittingRange(comptime from: comptime_int, comptime to: comptime_int) t
462 if (is_signed) {460 if (is_signed) {
463 magnitude_bits += 1;461 magnitude_bits += 1;
464 }462 }
465 return @IntType(is_signed, magnitude_bits);463 return std.meta.IntType(is_signed, magnitude_bits);
466}464}
467465
468test "math.IntFittingRange" {466test "math.IntFittingRange" {
...@@ -526,7 +524,7 @@ fn testOverflow() void {...@@ -526,7 +524,7 @@ fn testOverflow() void {
526524
527pub fn absInt(x: var) !@TypeOf(x) {525pub fn absInt(x: var) !@TypeOf(x) {
528 const T = @TypeOf(x);526 const T = @TypeOf(x);
529 comptime assert(@typeId(T) == builtin.TypeId.Int); // must pass an integer to absInt527 comptime assert(@typeInfo(T) == .Int); // must pass an integer to absInt
530 comptime assert(T.is_signed); // must pass a signed integer to absInt528 comptime assert(T.is_signed); // must pass a signed integer to absInt
531529
532 if (x == minInt(@TypeOf(x))) {530 if (x == minInt(@TypeOf(x))) {
...@@ -560,7 +558,7 @@ fn testAbsFloat() void {...@@ -560,7 +558,7 @@ fn testAbsFloat() void {
560pub fn divTrunc(comptime T: type, numerator: T, denominator: T) !T {558pub fn divTrunc(comptime T: type, numerator: T, denominator: T) !T {
561 @setRuntimeSafety(false);559 @setRuntimeSafety(false);
562 if (denominator == 0) return error.DivisionByZero;560 if (denominator == 0) return error.DivisionByZero;
563 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == minInt(T) and denominator == -1) return error.Overflow;561 if (@typeInfo(T) == .Int and T.is_signed and numerator == minInt(T) and denominator == -1) return error.Overflow;
564 return @divTrunc(numerator, denominator);562 return @divTrunc(numerator, denominator);
565}563}
566564
...@@ -581,7 +579,7 @@ fn testDivTrunc() void {...@@ -581,7 +579,7 @@ fn testDivTrunc() void {
581pub fn divFloor(comptime T: type, numerator: T, denominator: T) !T {579pub fn divFloor(comptime T: type, numerator: T, denominator: T) !T {
582 @setRuntimeSafety(false);580 @setRuntimeSafety(false);
583 if (denominator == 0) return error.DivisionByZero;581 if (denominator == 0) return error.DivisionByZero;
584 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == minInt(T) and denominator == -1) return error.Overflow;582 if (@typeInfo(T) == .Int and T.is_signed and numerator == minInt(T) and denominator == -1) return error.Overflow;
585 return @divFloor(numerator, denominator);583 return @divFloor(numerator, denominator);
586}584}
587585
...@@ -602,7 +600,7 @@ fn testDivFloor() void {...@@ -602,7 +600,7 @@ fn testDivFloor() void {
602pub fn divExact(comptime T: type, numerator: T, denominator: T) !T {600pub fn divExact(comptime T: type, numerator: T, denominator: T) !T {
603 @setRuntimeSafety(false);601 @setRuntimeSafety(false);
604 if (denominator == 0) return error.DivisionByZero;602 if (denominator == 0) return error.DivisionByZero;
605 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == minInt(T) and denominator == -1) return error.Overflow;603 if (@typeInfo(T) == .Int and T.is_signed and numerator == minInt(T) and denominator == -1) return error.Overflow;
606 const result = @divTrunc(numerator, denominator);604 const result = @divTrunc(numerator, denominator);
607 if (result * denominator != numerator) return error.UnexpectedRemainder;605 if (result * denominator != numerator) return error.UnexpectedRemainder;
608 return result;606 return result;
...@@ -676,13 +674,13 @@ pub fn absCast(x: var) t: {...@@ -676,13 +674,13 @@ pub fn absCast(x: var) t: {
676 if (@TypeOf(x) == comptime_int) {674 if (@TypeOf(x) == comptime_int) {
677 break :t comptime_int;675 break :t comptime_int;
678 } else {676 } else {
679 break :t @IntType(false, @TypeOf(x).bit_count);677 break :t std.meta.IntType(false, @TypeOf(x).bit_count);
680 }678 }
681} {679} {
682 if (@TypeOf(x) == comptime_int) {680 if (@TypeOf(x) == comptime_int) {
683 return if (x < 0) -x else x;681 return if (x < 0) -x else x;
684 }682 }
685 const uint = @IntType(false, @TypeOf(x).bit_count);683 const uint = std.meta.IntType(false, @TypeOf(x).bit_count);
686 if (x >= 0) return @intCast(uint, x);684 if (x >= 0) return @intCast(uint, x);
687685
688 return @intCast(uint, -(x + 1)) + 1;686 return @intCast(uint, -(x + 1)) + 1;
...@@ -703,10 +701,10 @@ test "math.absCast" {...@@ -703,10 +701,10 @@ test "math.absCast" {
703701
704/// Returns the negation of the integer parameter.702/// Returns the negation of the integer parameter.
705/// Result is a signed integer.703/// Result is a signed integer.
706pub fn negateCast(x: var) !@IntType(true, @TypeOf(x).bit_count) {704pub fn negateCast(x: var) !std.meta.IntType(true, @TypeOf(x).bit_count) {
707 if (@TypeOf(x).is_signed) return negate(x);705 if (@TypeOf(x).is_signed) return negate(x);
708706
709 const int = @IntType(true, @TypeOf(x).bit_count);707 const int = std.meta.IntType(true, @TypeOf(x).bit_count);
710 if (x > -minInt(int)) return error.Overflow;708 if (x > -minInt(int)) return error.Overflow;
711709
712 if (x == -minInt(int)) return minInt(int);710 if (x == -minInt(int)) return minInt(int);
...@@ -727,8 +725,8 @@ test "math.negateCast" {...@@ -727,8 +725,8 @@ test "math.negateCast" {
727/// Cast an integer to a different integer type. If the value doesn't fit,725/// Cast an integer to a different integer type. If the value doesn't fit,
728/// return an error.726/// return an error.
729pub fn cast(comptime T: type, x: var) (error{Overflow}!T) {727pub fn cast(comptime T: type, x: var) (error{Overflow}!T) {
730 comptime assert(@typeId(T) == builtin.TypeId.Int); // must pass an integer728 comptime assert(@typeInfo(T) == .Int); // must pass an integer
731 comptime assert(@typeId(@TypeOf(x)) == builtin.TypeId.Int); // must pass an integer729 comptime assert(@typeInfo(@TypeOf(x)) == .Int); // must pass an integer
732 if (maxInt(@TypeOf(x)) > maxInt(T) and x > maxInt(T)) {730 if (maxInt(@TypeOf(x)) > maxInt(T) and x > maxInt(T)) {
733 return error.Overflow;731 return error.Overflow;
734 } else if (minInt(@TypeOf(x)) < minInt(T) and x < minInt(T)) {732 } else if (minInt(@TypeOf(x)) < minInt(T) and x < minInt(T)) {
...@@ -792,11 +790,11 @@ fn testFloorPowerOfTwo() void {...@@ -792,11 +790,11 @@ fn testFloorPowerOfTwo() void {
792/// Returns the next power of two (if the value is not already a power of two).790/// Returns the next power of two (if the value is not already a power of two).
793/// Only unsigned integers can be used. Zero is not an allowed input.791/// Only unsigned integers can be used. Zero is not an allowed input.
794/// Result is a type with 1 more bit than the input type.792/// Result is a type with 1 more bit than the input type.
795pub fn ceilPowerOfTwoPromote(comptime T: type, value: T) @IntType(T.is_signed, T.bit_count + 1) {793pub fn ceilPowerOfTwoPromote(comptime T: type, value: T) std.meta.IntType(T.is_signed, T.bit_count + 1) {
796 comptime assert(@typeId(T) == builtin.TypeId.Int);794 comptime assert(@typeInfo(T) == .Int);
797 comptime assert(!T.is_signed);795 comptime assert(!T.is_signed);
798 assert(value != 0);796 assert(value != 0);
799 comptime const PromotedType = @IntType(T.is_signed, T.bit_count + 1);797 comptime const PromotedType = std.meta.IntType(T.is_signed, T.bit_count + 1);
800 comptime const shiftType = std.math.Log2Int(PromotedType);798 comptime const shiftType = std.math.Log2Int(PromotedType);
801 return @as(PromotedType, 1) << @intCast(shiftType, T.bit_count - @clz(T, value - 1));799 return @as(PromotedType, 1) << @intCast(shiftType, T.bit_count - @clz(T, value - 1));
802}800}
...@@ -805,9 +803,9 @@ pub fn ceilPowerOfTwoPromote(comptime T: type, value: T) @IntType(T.is_signed, T...@@ -805,9 +803,9 @@ pub fn ceilPowerOfTwoPromote(comptime T: type, value: T) @IntType(T.is_signed, T
805/// Only unsigned integers can be used. Zero is not an allowed input.803/// Only unsigned integers can be used. Zero is not an allowed input.
806/// If the value doesn't fit, returns an error.804/// If the value doesn't fit, returns an error.
807pub fn ceilPowerOfTwo(comptime T: type, value: T) (error{Overflow}!T) {805pub fn ceilPowerOfTwo(comptime T: type, value: T) (error{Overflow}!T) {
808 comptime assert(@typeId(T) == builtin.TypeId.Int);806 comptime assert(@typeInfo(T) == .Int);
809 comptime assert(!T.is_signed);807 comptime assert(!T.is_signed);
810 comptime const PromotedType = @IntType(T.is_signed, T.bit_count + 1);808 comptime const PromotedType = std.meta.IntType(T.is_signed, T.bit_count + 1);
811 comptime const overflowBit = @as(PromotedType, 1) << T.bit_count;809 comptime const overflowBit = @as(PromotedType, 1) << T.bit_count;
812 var x = ceilPowerOfTwoPromote(T, value);810 var x = ceilPowerOfTwoPromote(T, value);
813 if (overflowBit & x != 0) {811 if (overflowBit & x != 0) {
...@@ -878,10 +876,10 @@ test "std.math.log2_int_ceil" {...@@ -878,10 +876,10 @@ test "std.math.log2_int_ceil" {
878876
879pub fn lossyCast(comptime T: type, value: var) T {877pub fn lossyCast(comptime T: type, value: var) T {
880 switch (@typeInfo(@TypeOf(value))) {878 switch (@typeInfo(@TypeOf(value))) {
881 builtin.TypeId.Int => return @intToFloat(T, value),879 .Int => return @intToFloat(T, value),
882 builtin.TypeId.Float => return @floatCast(T, value),880 .Float => return @floatCast(T, value),
883 builtin.TypeId.ComptimeInt => return @as(T, value),881 .ComptimeInt => return @as(T, value),
884 builtin.TypeId.ComptimeFloat => return @as(T, value),882 .ComptimeFloat => return @as(T, value),
885 else => @compileError("bad type"),883 else => @compileError("bad type"),
886 }884 }
887}885}
...@@ -949,8 +947,8 @@ test "max value type" {...@@ -949,8 +947,8 @@ test "max value type" {
949 testing.expect(x == 2147483647);947 testing.expect(x == 2147483647);
950}948}
951949
952pub fn mulWide(comptime T: type, a: T, b: T) @IntType(T.is_signed, T.bit_count * 2) {950pub fn mulWide(comptime T: type, a: T, b: T) std.meta.IntType(T.is_signed, T.bit_count * 2) {
953 const ResultInt = @IntType(T.is_signed, T.bit_count * 2);951 const ResultInt = std.meta.IntType(T.is_signed, T.bit_count * 2);
954 return @as(ResultInt, a) * @as(ResultInt, b);952 return @as(ResultInt, a) * @as(ResultInt, b);
955}953}
956954
lib/std/math/big/int.zig+7-10
...@@ -1,5 +1,4 @@...@@ -1,5 +1,4 @@
1const std = @import("../../std.zig");1const std = @import("../../std.zig");
2const builtin = @import("builtin");
3const debug = std.debug;2const debug = std.debug;
4const testing = std.testing;3const testing = std.testing;
5const math = std.math;4const math = std.math;
...@@ -9,10 +8,8 @@ const ArrayList = std.ArrayList;...@@ -9,10 +8,8 @@ const ArrayList = std.ArrayList;
9const maxInt = std.math.maxInt;8const maxInt = std.math.maxInt;
10const minInt = std.math.minInt;9const minInt = std.math.minInt;
1110
12const TypeId = builtin.TypeId;
13
14pub const Limb = usize;11pub const Limb = usize;
15pub const DoubleLimb = @IntType(false, 2 * Limb.bit_count);12pub const DoubleLimb = std.meta.IntType(false, 2 * Limb.bit_count);
16pub const Log2Limb = math.Log2Int(Limb);13pub const Log2Limb = math.Log2Int(Limb);
1714
18comptime {15comptime {
...@@ -270,8 +267,8 @@ pub const Int = struct {...@@ -270,8 +267,8 @@ pub const Int = struct {
270 const T = @TypeOf(value);267 const T = @TypeOf(value);
271268
272 switch (@typeInfo(T)) {269 switch (@typeInfo(T)) {
273 TypeId.Int => |info| {270 .Int => |info| {
274 const UT = if (T.is_signed) @IntType(false, T.bit_count - 1) else T;271 const UT = if (T.is_signed) std.meta.IntType(false, T.bit_count - 1) else T;
275272
276 try self.ensureCapacity(@sizeOf(UT) / @sizeOf(Limb));273 try self.ensureCapacity(@sizeOf(UT) / @sizeOf(Limb));
277 self.metadata = 0;274 self.metadata = 0;
...@@ -294,7 +291,7 @@ pub const Int = struct {...@@ -294,7 +291,7 @@ pub const Int = struct {
294 }291 }
295 }292 }
296 },293 },
297 TypeId.ComptimeInt => {294 .ComptimeInt => {
298 comptime var w_value = if (value < 0) -value else value;295 comptime var w_value = if (value < 0) -value else value;
299296
300 const req_limbs = @divFloor(math.log2(w_value), Limb.bit_count) + 1;297 const req_limbs = @divFloor(math.log2(w_value), Limb.bit_count) + 1;
...@@ -332,9 +329,9 @@ pub const Int = struct {...@@ -332,9 +329,9 @@ pub const Int = struct {
332 ///329 ///
333 /// Returns an error if self cannot be narrowed into the requested type without truncation.330 /// Returns an error if self cannot be narrowed into the requested type without truncation.
334 pub fn to(self: Int, comptime T: type) ConvertError!T {331 pub fn to(self: Int, comptime T: type) ConvertError!T {
335 switch (@typeId(T)) {332 switch (@typeInfo(T)) {
336 TypeId.Int => {333 .Int => {
337 const UT = @IntType(false, T.bit_count);334 const UT = std.meta.IntType(false, T.bit_count);
338335
339 if (self.bitCountTwosComp() > T.bit_count) {336 if (self.bitCountTwosComp() > T.bit_count) {
340 return error.TargetTooSmall;337 return error.TargetTooSmall;
lib/std/math/big/rational.zig+6-9
...@@ -1,5 +1,4 @@...@@ -1,5 +1,4 @@
1const std = @import("../../std.zig");1const std = @import("../../std.zig");
2const builtin = @import("builtin");
3const debug = std.debug;2const debug = std.debug;
4const math = std.math;3const math = std.math;
5const mem = std.mem;4const mem = std.mem;
...@@ -7,8 +6,6 @@ const testing = std.testing;...@@ -7,8 +6,6 @@ const testing = std.testing;
7const Allocator = mem.Allocator;6const Allocator = mem.Allocator;
8const ArrayList = std.ArrayList;7const ArrayList = std.ArrayList;
98
10const TypeId = builtin.TypeId;
11
12const bn = @import("int.zig");9const bn = @import("int.zig");
13const Limb = bn.Limb;10const Limb = bn.Limb;
14const DoubleLimb = bn.DoubleLimb;11const DoubleLimb = bn.DoubleLimb;
...@@ -129,9 +126,9 @@ pub const Rational = struct {...@@ -129,9 +126,9 @@ pub const Rational = struct {
129 /// completely represent the provided float.126 /// completely represent the provided float.
130 pub fn setFloat(self: *Rational, comptime T: type, f: T) !void {127 pub fn setFloat(self: *Rational, comptime T: type, f: T) !void {
131 // Translated from golang.go/src/math/big/rat.go.128 // Translated from golang.go/src/math/big/rat.go.
132 debug.assert(@typeId(T) == builtin.TypeId.Float);129 debug.assert(@typeInfo(T) == .Float);
133130
134 const UnsignedIntType = @IntType(false, T.bit_count);131 const UnsignedIntType = std.meta.IntType(false, T.bit_count);
135 const f_bits = @bitCast(UnsignedIntType, f);132 const f_bits = @bitCast(UnsignedIntType, f);
136133
137 const exponent_bits = math.floatExponentBits(T);134 const exponent_bits = math.floatExponentBits(T);
...@@ -187,10 +184,10 @@ pub const Rational = struct {...@@ -187,10 +184,10 @@ pub const Rational = struct {
187 pub fn toFloat(self: Rational, comptime T: type) !T {184 pub fn toFloat(self: Rational, comptime T: type) !T {
188 // Translated from golang.go/src/math/big/rat.go.185 // Translated from golang.go/src/math/big/rat.go.
189 // TODO: Indicate whether the result is not exact.186 // TODO: Indicate whether the result is not exact.
190 debug.assert(@typeId(T) == builtin.TypeId.Float);187 debug.assert(@typeInfo(T) == .Float);
191188
192 const fsize = T.bit_count;189 const fsize = T.bit_count;
193 const BitReprType = @IntType(false, T.bit_count);190 const BitReprType = std.meta.IntType(false, T.bit_count);
194191
195 const msize = math.floatMantissaBits(T);192 const msize = math.floatMantissaBits(T);
196 const msize1 = msize + 1;193 const msize1 = msize + 1;
...@@ -465,7 +462,7 @@ pub const Rational = struct {...@@ -465,7 +462,7 @@ pub const Rational = struct {
465 }462 }
466};463};
467464
468const SignedDoubleLimb = @IntType(true, DoubleLimb.bit_count);465const SignedDoubleLimb = std.meta.IntType(true, DoubleLimb.bit_count);
469466
470fn gcd(rma: *Int, x: Int, y: Int) !void {467fn gcd(rma: *Int, x: Int, y: Int) !void {
471 rma.assertWritable();468 rma.assertWritable();
...@@ -653,7 +650,7 @@ test "big.rational gcd one large" {...@@ -653,7 +650,7 @@ test "big.rational gcd one large" {
653}650}
654651
655fn extractLowBits(a: Int, comptime T: type) T {652fn extractLowBits(a: Int, comptime T: type) T {
656 testing.expect(@typeId(T) == builtin.TypeId.Int);653 testing.expect(@typeInfo(T) == .Int);
657654
658 if (T.bit_count <= Limb.bit_count) {655 if (T.bit_count <= Limb.bit_count) {
659 return @truncate(T, a.limbs[0]);656 return @truncate(T, a.limbs[0]);
lib/std/math/cos.zig+1-1
...@@ -44,7 +44,7 @@ const pi4c = 2.69515142907905952645E-15;...@@ -44,7 +44,7 @@ const pi4c = 2.69515142907905952645E-15;
44const m4pi = 1.273239544735162542821171882678754627704620361328125;44const m4pi = 1.273239544735162542821171882678754627704620361328125;
4545
46fn cos_(comptime T: type, x_: T) T {46fn cos_(comptime T: type, x_: T) T {
47 const I = @IntType(true, T.bit_count);47 const I = std.meta.IntType(true, T.bit_count);
4848
49 var x = x_;49 var x = x_;
50 if (math.isNan(x) or math.isInf(x)) {50 if (math.isNan(x) or math.isInf(x)) {
lib/std/math/ln.zig+5-7
...@@ -7,8 +7,6 @@...@@ -7,8 +7,6 @@
7const std = @import("../std.zig");7const std = @import("../std.zig");
8const math = std.math;8const math = std.math;
9const expect = std.testing.expect;9const expect = std.testing.expect;
10const builtin = @import("builtin");
11const TypeId = builtin.TypeId;
1210
13/// Returns the natural logarithm of x.11/// Returns the natural logarithm of x.
14///12///
...@@ -19,21 +17,21 @@ const TypeId = builtin.TypeId;...@@ -19,21 +17,21 @@ const TypeId = builtin.TypeId;
19/// - ln(nan) = nan17/// - ln(nan) = nan
20pub fn ln(x: var) @TypeOf(x) {18pub fn ln(x: var) @TypeOf(x) {
21 const T = @TypeOf(x);19 const T = @TypeOf(x);
22 switch (@typeId(T)) {20 switch (@typeInfo(T)) {
23 TypeId.ComptimeFloat => {21 .ComptimeFloat => {
24 return @as(comptime_float, ln_64(x));22 return @as(comptime_float, ln_64(x));
25 },23 },
26 TypeId.Float => {24 .Float => {
27 return switch (T) {25 return switch (T) {
28 f32 => ln_32(x),26 f32 => ln_32(x),
29 f64 => ln_64(x),27 f64 => ln_64(x),
30 else => @compileError("ln not implemented for " ++ @typeName(T)),28 else => @compileError("ln not implemented for " ++ @typeName(T)),
31 };29 };
32 },30 },
33 TypeId.ComptimeInt => {31 .ComptimeInt => {
34 return @as(comptime_int, math.floor(ln_64(@as(f64, x))));32 return @as(comptime_int, math.floor(ln_64(@as(f64, x))));
35 },33 },
36 TypeId.Int => {34 .Int => {
37 return @as(T, math.floor(ln_64(@as(f64, x))));35 return @as(T, math.floor(ln_64(@as(f64, x))));
38 },36 },
39 else => @compileError("ln not implemented for " ++ @typeName(T)),37 else => @compileError("ln not implemented for " ++ @typeName(T)),
lib/std/math/log.zig+6-8
...@@ -6,8 +6,6 @@...@@ -6,8 +6,6 @@
66
7const std = @import("../std.zig");7const std = @import("../std.zig");
8const math = std.math;8const math = std.math;
9const builtin = @import("builtin");
10const TypeId = builtin.TypeId;
11const expect = std.testing.expect;9const expect = std.testing.expect;
1210
13/// Returns the logarithm of x for the provided base.11/// Returns the logarithm of x for the provided base.
...@@ -16,24 +14,24 @@ pub fn log(comptime T: type, base: T, x: T) T {...@@ -16,24 +14,24 @@ pub fn log(comptime T: type, base: T, x: T) T {
16 return math.log2(x);14 return math.log2(x);
17 } else if (base == 10) {15 } else if (base == 10) {
18 return math.log10(x);16 return math.log10(x);
19 } else if ((@typeId(T) == TypeId.Float or @typeId(T) == TypeId.ComptimeFloat) and base == math.e) {17 } else if ((@typeInfo(T) == .Float or @typeInfo(T) == .ComptimeFloat) and base == math.e) {
20 return math.ln(x);18 return math.ln(x);
21 }19 }
2220
23 const float_base = math.lossyCast(f64, base);21 const float_base = math.lossyCast(f64, base);
24 switch (@typeId(T)) {22 switch (@typeInfo(T)) {
25 TypeId.ComptimeFloat => {23 .ComptimeFloat => {
26 return @as(comptime_float, math.ln(@as(f64, x)) / math.ln(float_base));24 return @as(comptime_float, math.ln(@as(f64, x)) / math.ln(float_base));
27 },25 },
28 TypeId.ComptimeInt => {26 .ComptimeInt => {
29 return @as(comptime_int, math.floor(math.ln(@as(f64, x)) / math.ln(float_base)));27 return @as(comptime_int, math.floor(math.ln(@as(f64, x)) / math.ln(float_base)));
30 },28 },
31 builtin.TypeId.Int => {29 .Int => {
32 // TODO implement integer log without using float math30 // TODO implement integer log without using float math
33 return @floatToInt(T, math.floor(math.ln(@intToFloat(f64, x)) / math.ln(float_base)));31 return @floatToInt(T, math.floor(math.ln(@intToFloat(f64, x)) / math.ln(float_base)));
34 },32 },
3533
36 builtin.TypeId.Float => {34 .Float => {
37 switch (T) {35 switch (T) {
38 f32 => return @floatCast(f32, math.ln(@as(f64, x)) / math.ln(float_base)),36 f32 => return @floatCast(f32, math.ln(@as(f64, x)) / math.ln(float_base)),
39 f64 => return math.ln(x) / math.ln(float_base),37 f64 => return math.ln(x) / math.ln(float_base),
lib/std/math/log10.zig+5-7
...@@ -7,8 +7,6 @@...@@ -7,8 +7,6 @@
7const std = @import("../std.zig");7const std = @import("../std.zig");
8const math = std.math;8const math = std.math;
9const testing = std.testing;9const testing = std.testing;
10const builtin = @import("builtin");
11const TypeId = builtin.TypeId;
12const maxInt = std.math.maxInt;10const maxInt = std.math.maxInt;
1311
14/// Returns the base-10 logarithm of x.12/// Returns the base-10 logarithm of x.
...@@ -20,21 +18,21 @@ const maxInt = std.math.maxInt;...@@ -20,21 +18,21 @@ const maxInt = std.math.maxInt;
20/// - log10(nan) = nan18/// - log10(nan) = nan
21pub fn log10(x: var) @TypeOf(x) {19pub fn log10(x: var) @TypeOf(x) {
22 const T = @TypeOf(x);20 const T = @TypeOf(x);
23 switch (@typeId(T)) {21 switch (@typeInfo(T)) {
24 TypeId.ComptimeFloat => {22 .ComptimeFloat => {
25 return @as(comptime_float, log10_64(x));23 return @as(comptime_float, log10_64(x));
26 },24 },
27 TypeId.Float => {25 .Float => {
28 return switch (T) {26 return switch (T) {
29 f32 => log10_32(x),27 f32 => log10_32(x),
30 f64 => log10_64(x),28 f64 => log10_64(x),
31 else => @compileError("log10 not implemented for " ++ @typeName(T)),29 else => @compileError("log10 not implemented for " ++ @typeName(T)),
32 };30 };
33 },31 },
34 TypeId.ComptimeInt => {32 .ComptimeInt => {
35 return @as(comptime_int, math.floor(log10_64(@as(f64, x))));33 return @as(comptime_int, math.floor(log10_64(@as(f64, x))));
36 },34 },
37 TypeId.Int => {35 .Int => {
38 return @floatToInt(T, math.floor(log10_64(@intToFloat(f64, x))));36 return @floatToInt(T, math.floor(log10_64(@intToFloat(f64, x))));
39 },37 },
40 else => @compileError("log10 not implemented for " ++ @typeName(T)),38 else => @compileError("log10 not implemented for " ++ @typeName(T)),
lib/std/math/log2.zig+5-7
...@@ -7,8 +7,6 @@...@@ -7,8 +7,6 @@
7const std = @import("../std.zig");7const std = @import("../std.zig");
8const math = std.math;8const math = std.math;
9const expect = std.testing.expect;9const expect = std.testing.expect;
10const builtin = @import("builtin");
11const TypeId = builtin.TypeId;
12const maxInt = std.math.maxInt;10const maxInt = std.math.maxInt;
1311
14/// Returns the base-2 logarithm of x.12/// Returns the base-2 logarithm of x.
...@@ -20,18 +18,18 @@ const maxInt = std.math.maxInt;...@@ -20,18 +18,18 @@ const maxInt = std.math.maxInt;
20/// - log2(nan) = nan18/// - log2(nan) = nan
21pub fn log2(x: var) @TypeOf(x) {19pub fn log2(x: var) @TypeOf(x) {
22 const T = @TypeOf(x);20 const T = @TypeOf(x);
23 switch (@typeId(T)) {21 switch (@typeInfo(T)) {
24 TypeId.ComptimeFloat => {22 .ComptimeFloat => {
25 return @as(comptime_float, log2_64(x));23 return @as(comptime_float, log2_64(x));
26 },24 },
27 TypeId.Float => {25 .Float => {
28 return switch (T) {26 return switch (T) {
29 f32 => log2_32(x),27 f32 => log2_32(x),
30 f64 => log2_64(x),28 f64 => log2_64(x),
31 else => @compileError("log2 not implemented for " ++ @typeName(T)),29 else => @compileError("log2 not implemented for " ++ @typeName(T)),
32 };30 };
33 },31 },
34 TypeId.ComptimeInt => comptime {32 .ComptimeInt => comptime {
35 var result = 0;33 var result = 0;
36 var x_shifted = x;34 var x_shifted = x;
37 while (b: {35 while (b: {
...@@ -40,7 +38,7 @@ pub fn log2(x: var) @TypeOf(x) {...@@ -40,7 +38,7 @@ pub fn log2(x: var) @TypeOf(x) {
40 }) : (result += 1) {}38 }) : (result += 1) {}
41 return result;39 return result;
42 },40 },
43 TypeId.Int => {41 .Int => {
44 return math.log2_int(T, x);42 return math.log2_int(T, x);
45 },43 },
46 else => @compileError("log2 not implemented for " ++ @typeName(T)),44 else => @compileError("log2 not implemented for " ++ @typeName(T)),
lib/std/math/pow.zig+1-1
...@@ -145,7 +145,7 @@ pub fn pow(comptime T: type, x: T, y: T) T {...@@ -145,7 +145,7 @@ pub fn pow(comptime T: type, x: T, y: T) T {
145 var xe = r2.exponent;145 var xe = r2.exponent;
146 var x1 = r2.significand;146 var x1 = r2.significand;
147147
148 var i = @floatToInt(@IntType(true, T.bit_count), yi);148 var i = @floatToInt(std.meta.IntType(true, T.bit_count), yi);
149 while (i != 0) : (i >>= 1) {149 while (i != 0) : (i >>= 1) {
150 const overflow_shift = math.floatExponentBits(T) + 1;150 const overflow_shift = math.floatExponentBits(T) + 1;
151 if (xe < -(1 << overflow_shift) or (1 << overflow_shift) < xe) {151 if (xe < -(1 << overflow_shift) or (1 << overflow_shift) < xe) {
lib/std/math/sin.zig+1-1
...@@ -45,7 +45,7 @@ const pi4c = 2.69515142907905952645E-15;...@@ -45,7 +45,7 @@ const pi4c = 2.69515142907905952645E-15;
45const m4pi = 1.273239544735162542821171882678754627704620361328125;45const m4pi = 1.273239544735162542821171882678754627704620361328125;
4646
47fn sin_(comptime T: type, x_: T) T {47fn sin_(comptime T: type, x_: T) T {
48 const I = @IntType(true, T.bit_count);48 const I = std.meta.IntType(true, T.bit_count);
4949
50 var x = x_;50 var x = x_;
51 if (x == 0 or math.isNan(x)) {51 if (x == 0 or math.isNan(x)) {
lib/std/math/sqrt.zig+3-3
...@@ -31,7 +31,7 @@ pub fn sqrt(x: var) Sqrt(@TypeOf(x)) {...@@ -31,7 +31,7 @@ pub fn sqrt(x: var) Sqrt(@TypeOf(x)) {
31 }31 }
32}32}
3333
34fn sqrt_int(comptime T: type, value: T) @IntType(false, T.bit_count / 2) {34fn sqrt_int(comptime T: type, value: T) std.meta.IntType(false, T.bit_count / 2) {
35 var op = value;35 var op = value;
36 var res: T = 0;36 var res: T = 0;
37 var one: T = 1 << (T.bit_count - 2);37 var one: T = 1 << (T.bit_count - 2);
...@@ -50,7 +50,7 @@ fn sqrt_int(comptime T: type, value: T) @IntType(false, T.bit_count / 2) {...@@ -50,7 +50,7 @@ fn sqrt_int(comptime T: type, value: T) @IntType(false, T.bit_count / 2) {
50 one >>= 2;50 one >>= 2;
51 }51 }
5252
53 const ResultType = @IntType(false, T.bit_count / 2);53 const ResultType = std.meta.IntType(false, T.bit_count / 2);
54 return @intCast(ResultType, res);54 return @intCast(ResultType, res);
55}55}
5656
...@@ -66,7 +66,7 @@ test "math.sqrt_int" {...@@ -66,7 +66,7 @@ test "math.sqrt_int" {
66/// Returns the return type `sqrt` will return given an operand of type `T`.66/// Returns the return type `sqrt` will return given an operand of type `T`.
67pub fn Sqrt(comptime T: type) type {67pub fn Sqrt(comptime T: type) type {
68 return switch (@typeInfo(T)) {68 return switch (@typeInfo(T)) {
69 .Int => |int| @IntType(false, int.bits / 2),69 .Int => |int| std.meta.IntType(false, int.bits / 2),
70 else => T,70 else => T,
71 };71 };
72}72}
lib/std/math/tan.zig+1-1
...@@ -38,7 +38,7 @@ const pi4c = 2.69515142907905952645E-15;...@@ -38,7 +38,7 @@ const pi4c = 2.69515142907905952645E-15;
38const m4pi = 1.273239544735162542821171882678754627704620361328125;38const m4pi = 1.273239544735162542821171882678754627704620361328125;
3939
40fn tan_(comptime T: type, x_: T) T {40fn tan_(comptime T: type, x_: T) T {
41 const I = @IntType(true, T.bit_count);41 const I = std.meta.IntType(true, T.bit_count);
4242
43 var x = x_;43 var x = x_;
44 if (x == 0 or math.isNan(x)) {44 if (x == 0 or math.isNan(x)) {
lib/std/mem.zig+287-18
...@@ -132,7 +132,7 @@ pub const Allocator = struct {...@@ -132,7 +132,7 @@ pub const Allocator = struct {
132 // their own frame with @Frame(func).132 // their own frame with @Frame(func).
133 return @intToPtr([*]T, @ptrToInt(byte_slice.ptr))[0..n];133 return @intToPtr([*]T, @ptrToInt(byte_slice.ptr))[0..n];
134 } else {134 } else {
135 return @bytesToSlice(T, @alignCast(a, byte_slice));135 return mem.bytesAsSlice(T, @alignCast(a, byte_slice));
136 }136 }
137 }137 }
138138
...@@ -173,7 +173,7 @@ pub const Allocator = struct {...@@ -173,7 +173,7 @@ pub const Allocator = struct {
173 return @as([*]align(new_alignment) T, undefined)[0..0];173 return @as([*]align(new_alignment) T, undefined)[0..0];
174 }174 }
175175
176 const old_byte_slice = @sliceToBytes(old_mem);176 const old_byte_slice = mem.sliceAsBytes(old_mem);
177 const byte_count = math.mul(usize, @sizeOf(T), new_n) catch return Error.OutOfMemory;177 const byte_count = math.mul(usize, @sizeOf(T), new_n) catch return Error.OutOfMemory;
178 // Note: can't set shrunk memory to undefined as memory shouldn't be modified on realloc failure178 // Note: can't set shrunk memory to undefined as memory shouldn't be modified on realloc failure
179 const byte_slice = try self.reallocFn(self, old_byte_slice, Slice.alignment, byte_count, new_alignment);179 const byte_slice = try self.reallocFn(self, old_byte_slice, Slice.alignment, byte_count, new_alignment);
...@@ -181,7 +181,7 @@ pub const Allocator = struct {...@@ -181,7 +181,7 @@ pub const Allocator = struct {
181 if (new_n > old_mem.len) {181 if (new_n > old_mem.len) {
182 @memset(byte_slice.ptr + old_byte_slice.len, undefined, byte_slice.len - old_byte_slice.len);182 @memset(byte_slice.ptr + old_byte_slice.len, undefined, byte_slice.len - old_byte_slice.len);
183 }183 }
184 return @bytesToSlice(T, @alignCast(new_alignment, byte_slice));184 return mem.bytesAsSlice(T, @alignCast(new_alignment, byte_slice));
185 }185 }
186186
187 /// Prefer calling realloc to shrink if you can tolerate failure, such as187 /// Prefer calling realloc to shrink if you can tolerate failure, such as
...@@ -221,18 +221,18 @@ pub const Allocator = struct {...@@ -221,18 +221,18 @@ pub const Allocator = struct {
221 // new_n <= old_mem.len and the multiplication didn't overflow for that operation.221 // new_n <= old_mem.len and the multiplication didn't overflow for that operation.
222 const byte_count = @sizeOf(T) * new_n;222 const byte_count = @sizeOf(T) * new_n;
223223
224 const old_byte_slice = @sliceToBytes(old_mem);224 const old_byte_slice = mem.sliceAsBytes(old_mem);
225 @memset(old_byte_slice.ptr + byte_count, undefined, old_byte_slice.len - byte_count);225 @memset(old_byte_slice.ptr + byte_count, undefined, old_byte_slice.len - byte_count);
226 const byte_slice = self.shrinkFn(self, old_byte_slice, Slice.alignment, byte_count, new_alignment);226 const byte_slice = self.shrinkFn(self, old_byte_slice, Slice.alignment, byte_count, new_alignment);
227 assert(byte_slice.len == byte_count);227 assert(byte_slice.len == byte_count);
228 return @bytesToSlice(T, @alignCast(new_alignment, byte_slice));228 return mem.bytesAsSlice(T, @alignCast(new_alignment, byte_slice));
229 }229 }
230230
231 /// Free an array allocated with `alloc`. To free a single item,231 /// Free an array allocated with `alloc`. To free a single item,
232 /// see `destroy`.232 /// see `destroy`.
233 pub fn free(self: *Allocator, memory: var) void {233 pub fn free(self: *Allocator, memory: var) void {
234 const Slice = @typeInfo(@TypeOf(memory)).Pointer;234 const Slice = @typeInfo(@TypeOf(memory)).Pointer;
235 const bytes = @sliceToBytes(memory);235 const bytes = mem.sliceAsBytes(memory);
236 const bytes_len = bytes.len + if (Slice.sentinel != null) @sizeOf(Slice.child) else 0;236 const bytes_len = bytes.len + if (Slice.sentinel != null) @sizeOf(Slice.child) else 0;
237 if (bytes_len == 0) return;237 if (bytes_len == 0) return;
238 const non_const_ptr = @intToPtr([*]u8, @ptrToInt(bytes.ptr));238 const non_const_ptr = @intToPtr([*]u8, @ptrToInt(bytes.ptr));
...@@ -276,18 +276,67 @@ pub fn set(comptime T: type, dest: []T, value: T) void {...@@ -276,18 +276,67 @@ pub fn set(comptime T: type, dest: []T, value: T) void {
276 d.* = value;276 d.* = value;
277}277}
278278
279/// Generally, Zig users are encouraged to explicitly initialize all fields of a struct explicitly rather than using this function.
280/// However, it is recognized that there are sometimes use cases for initializing all fields to a "zero" value. For example, when
281/// interfacing with a C API where this practice is more common and relied upon. If you are performing code review and see this
282/// function used, examine closely - it may be a code smell.
279/// Zero initializes the type.283/// Zero initializes the type.
280/// This can be used to zero initialize a C-struct.284/// This can be used to zero initialize a any type for which it makes sense. Structs will be initialized recursively.
281pub fn zeroes(comptime T: type) T {285pub fn zeroes(comptime T: type) T {
282 if (@sizeOf(T) == 0) return T{};286 switch (@typeInfo(T)) {
283287 .ComptimeInt, .Int, .ComptimeFloat, .Float => {
284 if (comptime meta.containerLayout(T) != .Extern) {288 return @as(T, 0);
285 @compileError("TODO: Currently this only works for extern types");289 },
290 .Enum, .EnumLiteral => {
291 return @intToEnum(T, 0);
292 },
293 .Void => {
294 return {};
295 },
296 .Bool => {
297 return false;
298 },
299 .Optional, .Null => {
300 return null;
301 },
302 .Struct => |struct_info| {
303 if (@sizeOf(T) == 0) return T{};
304 if (comptime meta.containerLayout(T) == .Extern) {
305 var item: T = undefined;
306 @memset(@ptrCast([*]u8, &item), 0, @sizeOf(T));
307 return item;
308 } else {
309 var structure: T = undefined;
310 inline for (struct_info.fields) |field| {
311 @field(structure, field.name) = zeroes(@TypeOf(@field(structure, field.name)));
312 }
313 return structure;
314 }
315 },
316 .Pointer => |ptr_info| {
317 switch (ptr_info.size) {
318 .Slice => {
319 return &[_]ptr_info.child{};
320 },
321 .C => {
322 return null;
323 },
324 .One, .Many => {
325 @compileError("Can't set a non nullable pointer to zero.");
326 },
327 }
328 },
329 .Array => |info| {
330 var array: T = undefined;
331 for (array) |*element| {
332 element.* = zeroes(info.child);
333 }
334 return array;
335 },
336 .Vector, .ErrorUnion, .ErrorSet, .Union, .Fn, .BoundFn, .Type, .NoReturn, .Undefined, .Opaque, .Frame, .AnyFrame, => {
337 @compileError("Can't set a "++ @typeName(T) ++" to zero.");
338 },
286 }339 }
287
288 var item: T = undefined;
289 @memset(@ptrCast([*]u8, &item), 0, @sizeOf(T));
290 return item;
291}340}
292341
293test "mem.zeroes" {342test "mem.zeroes" {
...@@ -301,6 +350,62 @@ test "mem.zeroes" {...@@ -301,6 +350,62 @@ test "mem.zeroes" {
301350
302 testing.expect(a.x == 0);351 testing.expect(a.x == 0);
303 testing.expect(a.y == 10);352 testing.expect(a.y == 10);
353
354 const ZigStruct = struct {
355 const IntegralTypes = struct {
356 integer_0: i0,
357 integer_8: i8,
358 integer_16: i16,
359 integer_32: i32,
360 integer_64: i64,
361 integer_128: i128,
362 unsigned_0: u0,
363 unsigned_8: u8,
364 unsigned_16: u16,
365 unsigned_32: u32,
366 unsigned_64: u64,
367 unsigned_128: u128,
368
369 float_32: f32,
370 float_64: f64,
371 };
372
373 integral_types: IntegralTypes,
374
375 const Pointers = struct {
376 optional: ?*u8,
377 c_pointer: [*c]u8,
378 slice: []u8,
379 };
380 pointers: Pointers,
381
382 array: [2]u32,
383 optional_int: ?u8,
384 empty: void,
385 };
386
387 const b = zeroes(ZigStruct);
388 testing.expectEqual(@as(i8, 0), b.integral_types.integer_0);
389 testing.expectEqual(@as(i8, 0), b.integral_types.integer_8);
390 testing.expectEqual(@as(i16, 0), b.integral_types.integer_16);
391 testing.expectEqual(@as(i32, 0), b.integral_types.integer_32);
392 testing.expectEqual(@as(i64, 0), b.integral_types.integer_64);
393 testing.expectEqual(@as(i128, 0), b.integral_types.integer_128);
394 testing.expectEqual(@as(u8, 0), b.integral_types.unsigned_0);
395 testing.expectEqual(@as(u8, 0), b.integral_types.unsigned_8);
396 testing.expectEqual(@as(u16, 0), b.integral_types.unsigned_16);
397 testing.expectEqual(@as(u32, 0), b.integral_types.unsigned_32);
398 testing.expectEqual(@as(u64, 0), b.integral_types.unsigned_64);
399 testing.expectEqual(@as(u128, 0), b.integral_types.unsigned_128);
400 testing.expectEqual(@as(f32, 0), b.integral_types.float_32);
401 testing.expectEqual(@as(f64, 0), b.integral_types.float_64);
402 testing.expectEqual(@as(?*u8, null), b.pointers.optional);
403 testing.expectEqual(@as([*c]u8, null), b.pointers.c_pointer);
404 testing.expectEqual(@as([]u8, &[_]u8{}), b.pointers.slice);
405 for (b.array) |e| {
406 testing.expectEqual(@as(u32, 0), e);
407 }
408 testing.expectEqual(@as(?u8, null), b.optional_int);
304}409}
305410
306pub fn secureZero(comptime T: type, s: []T) void {411pub fn secureZero(comptime T: type, s: []T) void {
...@@ -387,13 +492,21 @@ pub fn allEqual(comptime T: type, slice: []const T, scalar: T) bool {...@@ -387,13 +492,21 @@ pub fn allEqual(comptime T: type, slice: []const T, scalar: T) bool {
387 return true;492 return true;
388}493}
389494
390/// Copies ::m to newly allocated memory. Caller is responsible to free it.495/// Copies `m` to newly allocated memory. Caller owns the memory.
391pub fn dupe(allocator: *Allocator, comptime T: type, m: []const T) ![]T {496pub fn dupe(allocator: *Allocator, comptime T: type, m: []const T) ![]T {
392 const new_buf = try allocator.alloc(T, m.len);497 const new_buf = try allocator.alloc(T, m.len);
393 copy(T, new_buf, m);498 copy(T, new_buf, m);
394 return new_buf;499 return new_buf;
395}500}
396501
502/// Copies `m` to newly allocated memory, with a null-terminated element. Caller owns the memory.
503pub fn dupeZ(allocator: *Allocator, comptime T: type, m: []const T) ![:0]T {
504 const new_buf = try allocator.alloc(T, m.len + 1);
505 copy(T, new_buf, m);
506 new_buf[m.len] = 0;
507 return new_buf[0..m.len :0];
508}
509
397/// Remove values from the beginning of a slice.510/// Remove values from the beginning of a slice.
398pub fn trimLeft(comptime T: type, slice: []const T, values_to_strip: []const T) []const T {511pub fn trimLeft(comptime T: type, slice: []const T, values_to_strip: []const T) []const T {
399 var begin: usize = 0;512 var begin: usize = 0;
...@@ -700,7 +813,7 @@ pub fn writeIntSliceLittle(comptime T: type, buffer: []u8, value: T) void {...@@ -700,7 +813,7 @@ pub fn writeIntSliceLittle(comptime T: type, buffer: []u8, value: T) void {
700 assert(buffer.len >= @divExact(T.bit_count, 8));813 assert(buffer.len >= @divExact(T.bit_count, 8));
701814
702 // TODO I want to call writeIntLittle here but comptime eval facilities aren't good enough815 // TODO I want to call writeIntLittle here but comptime eval facilities aren't good enough
703 const uint = @IntType(false, T.bit_count);816 const uint = std.meta.IntType(false, T.bit_count);
704 var bits = @truncate(uint, value);817 var bits = @truncate(uint, value);
705 for (buffer) |*b| {818 for (buffer) |*b| {
706 b.* = @truncate(u8, bits);819 b.* = @truncate(u8, bits);
...@@ -717,7 +830,7 @@ pub fn writeIntSliceBig(comptime T: type, buffer: []u8, value: T) void {...@@ -717,7 +830,7 @@ pub fn writeIntSliceBig(comptime T: type, buffer: []u8, value: T) void {
717 assert(buffer.len >= @divExact(T.bit_count, 8));830 assert(buffer.len >= @divExact(T.bit_count, 8));
718831
719 // TODO I want to call writeIntBig here but comptime eval facilities aren't good enough832 // TODO I want to call writeIntBig here but comptime eval facilities aren't good enough
720 const uint = @IntType(false, T.bit_count);833 const uint = std.meta.IntType(false, T.bit_count);
721 var bits = @truncate(uint, value);834 var bits = @truncate(uint, value);
722 var index: usize = buffer.len;835 var index: usize = buffer.len;
723 while (index != 0) {836 while (index != 0) {
...@@ -1478,6 +1591,162 @@ test "bytesToValue" {...@@ -1478,6 +1591,162 @@ test "bytesToValue" {
1478 testing.expect(deadbeef == @as(u32, 0xDEADBEEF));1591 testing.expect(deadbeef == @as(u32, 0xDEADBEEF));
1479}1592}
14801593
1594//TODO copy also is_volatile, etc. I tried to use @typeInfo, modify child type, use @Type, but ran into issues.
1595fn BytesAsSliceReturnType(comptime T: type, comptime bytesType: type) type {
1596 if (!(trait.isSlice(bytesType) and meta.Child(bytesType) == u8) and !(trait.isPtrTo(.Array)(bytesType) and meta.Child(meta.Child(bytesType)) == u8)) {
1597 @compileError("expected []u8 or *[_]u8, passed " ++ @typeName(bytesType));
1598 }
1599
1600 if (trait.isPtrTo(.Array)(bytesType) and @typeInfo(meta.Child(bytesType)).Array.len % @sizeOf(T) != 0) {
1601 @compileError("number of bytes in " ++ @typeName(bytesType) ++ " is not divisible by size of " ++ @typeName(T));
1602 }
1603
1604 const alignment = meta.alignment(bytesType);
1605
1606 return if (trait.isConstPtr(bytesType)) []align(alignment) const T else []align(alignment) T;
1607}
1608
1609pub fn bytesAsSlice(comptime T: type, bytes: var) BytesAsSliceReturnType(T, @TypeOf(bytes)) {
1610 const bytesSlice = if (comptime trait.isPtrTo(.Array)(@TypeOf(bytes))) bytes[0..] else bytes;
1611
1612 // let's not give an undefined pointer to @ptrCast
1613 // it may be equal to zero and fail a null check
1614 if (bytesSlice.len == 0) {
1615 return &[0]T{};
1616 }
1617
1618 const bytesType = @TypeOf(bytesSlice);
1619 const alignment = comptime meta.alignment(bytesType);
1620
1621 const castTarget = if (comptime trait.isConstPtr(bytesType)) [*]align(alignment) const T else [*]align(alignment) T;
1622
1623 return @ptrCast(castTarget, bytesSlice.ptr)[0..@divExact(bytes.len, @sizeOf(T))];
1624}
1625
1626test "bytesAsSlice" {
1627 const bytes = [_]u8{ 0xDE, 0xAD, 0xBE, 0xEF };
1628 const slice = bytesAsSlice(u16, bytes[0..]);
1629 testing.expect(slice.len == 2);
1630 testing.expect(bigToNative(u16, slice[0]) == 0xDEAD);
1631 testing.expect(bigToNative(u16, slice[1]) == 0xBEEF);
1632}
1633
1634test "bytesAsSlice keeps pointer alignment" {
1635 var bytes = [_]u8{ 0x01, 0x02, 0x03, 0x04 };
1636 const numbers = bytesAsSlice(u32, bytes[0..]);
1637 comptime testing.expect(@TypeOf(numbers) == []align(@alignOf(@TypeOf(bytes))) u32);
1638}
1639
1640test "bytesAsSlice on a packed struct" {
1641 const F = packed struct {
1642 a: u8,
1643 };
1644
1645 var b = [1]u8{9};
1646 var f = bytesAsSlice(F, &b);
1647 testing.expect(f[0].a == 9);
1648}
1649
1650test "bytesAsSlice with specified alignment" {
1651 var bytes align(4) = [_]u8{
1652 0x33,
1653 0x33,
1654 0x33,
1655 0x33,
1656 };
1657 const slice: []u32 = std.mem.bytesAsSlice(u32, bytes[0..]);
1658 testing.expect(slice[0] == 0x33333333);
1659}
1660
1661//TODO copy also is_volatile, etc. I tried to use @typeInfo, modify child type, use @Type, but ran into issues.
1662fn SliceAsBytesReturnType(comptime sliceType: type) type {
1663 if (!trait.isSlice(sliceType) and !trait.isPtrTo(.Array)(sliceType)) {
1664 @compileError("expected []T or *[_]T, passed " ++ @typeName(sliceType));
1665 }
1666
1667 const alignment = meta.alignment(sliceType);
1668
1669 return if (trait.isConstPtr(sliceType)) []align(alignment) const u8 else []align(alignment) u8;
1670}
1671
1672pub fn sliceAsBytes(slice: var) SliceAsBytesReturnType(@TypeOf(slice)) {
1673 const actualSlice = if (comptime trait.isPtrTo(.Array)(@TypeOf(slice))) slice[0..] else slice;
1674
1675 // let's not give an undefined pointer to @ptrCast
1676 // it may be equal to zero and fail a null check
1677 if (actualSlice.len == 0) {
1678 return &[0]u8{};
1679 }
1680
1681 const sliceType = @TypeOf(actualSlice);
1682 const alignment = comptime meta.alignment(sliceType);
1683
1684 const castTarget = if (comptime trait.isConstPtr(sliceType)) [*]align(alignment) const u8 else [*]align(alignment) u8;
1685
1686 return @ptrCast(castTarget, actualSlice.ptr)[0 .. actualSlice.len * @sizeOf(comptime meta.Child(sliceType))];
1687}
1688
1689test "sliceAsBytes" {
1690 const bytes = [_]u16{ 0xDEAD, 0xBEEF };
1691 const slice = sliceAsBytes(bytes[0..]);
1692 testing.expect(slice.len == 4);
1693 testing.expect(eql(u8, slice, switch (builtin.endian) {
1694 .Big => "\xDE\xAD\xBE\xEF",
1695 .Little => "\xAD\xDE\xEF\xBE",
1696 }));
1697}
1698
1699test "sliceAsBytes packed struct at runtime and comptime" {
1700 const Foo = packed struct {
1701 a: u4,
1702 b: u4,
1703 };
1704 const S = struct {
1705 fn doTheTest() void {
1706 var foo: Foo = undefined;
1707 var slice = sliceAsBytes(@as(*[1]Foo, &foo)[0..1]);
1708 slice[0] = 0x13;
1709 switch (builtin.endian) {
1710 .Big => {
1711 testing.expect(foo.a == 0x1);
1712 testing.expect(foo.b == 0x3);
1713 },
1714 .Little => {
1715 testing.expect(foo.a == 0x3);
1716 testing.expect(foo.b == 0x1);
1717 },
1718 }
1719 }
1720 };
1721 S.doTheTest();
1722 comptime S.doTheTest();
1723}
1724
1725test "sliceAsBytes and bytesAsSlice back" {
1726 testing.expect(@sizeOf(i32) == 4);
1727
1728 var big_thing_array = [_]i32{ 1, 2, 3, 4 };
1729 const big_thing_slice: []i32 = big_thing_array[0..];
1730
1731 const bytes = sliceAsBytes(big_thing_slice);
1732 testing.expect(bytes.len == 4 * 4);
1733
1734 bytes[4] = 0;
1735 bytes[5] = 0;
1736 bytes[6] = 0;
1737 bytes[7] = 0;
1738 testing.expect(big_thing_slice[1] == 0);
1739
1740 const big_thing_again = bytesAsSlice(i32, bytes);
1741 testing.expect(big_thing_again[2] == 3);
1742
1743 big_thing_again[2] = -1;
1744 testing.expect(bytes[8] == math.maxInt(u8));
1745 testing.expect(bytes[9] == math.maxInt(u8));
1746 testing.expect(bytes[10] == math.maxInt(u8));
1747 testing.expect(bytes[11] == math.maxInt(u8));
1748}
1749
1481fn SubArrayPtrReturnType(comptime T: type, comptime length: usize) type {1750fn SubArrayPtrReturnType(comptime T: type, comptime length: usize) type {
1482 if (trait.isConstPtr(T))1751 if (trait.isConstPtr(T))
1483 return *const [length]meta.Child(meta.Child(T));1752 return *const [length]meta.Child(meta.Child(T));
lib/std/meta.zig+15-5
...@@ -437,7 +437,7 @@ pub fn eql(a: var, b: @TypeOf(a)) bool {...@@ -437,7 +437,7 @@ pub fn eql(a: var, b: @TypeOf(a)) bool {
437 },437 },
438 .Pointer => |info| {438 .Pointer => |info| {
439 return switch (info.size) {439 return switch (info.size) {
440 .One, .Many, .C, => a == b,440 .One, .Many, .C => a == b,
441 .Slice => a.ptr == b.ptr and a.len == b.len,441 .Slice => a.ptr == b.ptr and a.len == b.len,
442 };442 };
443 },443 },
...@@ -536,9 +536,8 @@ test "intToEnum with error return" {...@@ -536,9 +536,8 @@ test "intToEnum with error return" {
536pub const IntToEnumError = error{InvalidEnumTag};536pub const IntToEnumError = error{InvalidEnumTag};
537537
538pub fn intToEnum(comptime Tag: type, tag_int: var) IntToEnumError!Tag {538pub fn intToEnum(comptime Tag: type, tag_int: var) IntToEnumError!Tag {
539 comptime var i = 0;539 inline for (@typeInfo(Tag).Enum.fields) |f| {
540 inline while (i != @memberCount(Tag)) : (i += 1) {540 const this_tag_value = @field(Tag, f.name);
541 const this_tag_value = @field(Tag, @memberName(Tag, i));
542 if (tag_int == @enumToInt(this_tag_value)) {541 if (tag_int == @enumToInt(this_tag_value)) {
543 return this_tag_value;542 return this_tag_value;
544 }543 }
...@@ -559,7 +558,9 @@ pub fn fieldIndex(comptime T: type, comptime name: []const u8) ?comptime_int {...@@ -559,7 +558,9 @@ pub fn fieldIndex(comptime T: type, comptime name: []const u8) ?comptime_int {
559/// Given a type, reference all the declarations inside, so that the semantic analyzer sees them.558/// Given a type, reference all the declarations inside, so that the semantic analyzer sees them.
560pub fn refAllDecls(comptime T: type) void {559pub fn refAllDecls(comptime T: type) void {
561 if (!builtin.is_test) return;560 if (!builtin.is_test) return;
562 _ = declarations(T);561 inline for (declarations(T)) |decl| {
562 _ = decl;
563 }
563}564}
564565
565/// Returns a slice of pointers to public declarations of a namespace.566/// Returns a slice of pointers to public declarations of a namespace.
...@@ -579,3 +580,12 @@ pub fn declList(comptime Namespace: type, comptime Decl: type) []const *const De...@@ -579,3 +580,12 @@ pub fn declList(comptime Namespace: type, comptime Decl: type) []const *const De
579 return &array;580 return &array;
580 }581 }
581}582}
583
584pub fn IntType(comptime is_signed: bool, comptime bit_count: u16) type {
585 return @Type(TypeInfo{
586 .Int = .{
587 .is_signed = is_signed,
588 .bits = bit_count,
589 },
590 });
591}
lib/std/meta/trait.zig+22-6
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2const builtin = @import("builtin");2const builtin = std.builtin;
3const mem = std.mem;3const mem = std.mem;
4const debug = std.debug;4const debug = std.debug;
5const testing = std.testing;5const testing = std.testing;
...@@ -54,7 +54,7 @@ pub fn hasFn(comptime name: []const u8) TraitFn {...@@ -54,7 +54,7 @@ pub fn hasFn(comptime name: []const u8) TraitFn {
54 if (!comptime isContainer(T)) return false;54 if (!comptime isContainer(T)) return false;
55 if (!comptime @hasDecl(T, name)) return false;55 if (!comptime @hasDecl(T, name)) return false;
56 const DeclType = @TypeOf(@field(T, name));56 const DeclType = @TypeOf(@field(T, name));
57 return @typeId(DeclType) == .Fn;57 return @typeInfo(DeclType) == .Fn;
58 }58 }
59 };59 };
60 return Closure.trait;60 return Closure.trait;
...@@ -105,7 +105,7 @@ test "std.meta.trait.hasField" {...@@ -105,7 +105,7 @@ test "std.meta.trait.hasField" {
105pub fn is(comptime id: builtin.TypeId) TraitFn {105pub fn is(comptime id: builtin.TypeId) TraitFn {
106 const Closure = struct {106 const Closure = struct {
107 pub fn trait(comptime T: type) bool {107 pub fn trait(comptime T: type) bool {
108 return id == @typeId(T);108 return id == @typeInfo(T);
109 }109 }
110 };110 };
111 return Closure.trait;111 return Closure.trait;
...@@ -123,7 +123,7 @@ pub fn isPtrTo(comptime id: builtin.TypeId) TraitFn {...@@ -123,7 +123,7 @@ pub fn isPtrTo(comptime id: builtin.TypeId) TraitFn {
123 const Closure = struct {123 const Closure = struct {
124 pub fn trait(comptime T: type) bool {124 pub fn trait(comptime T: type) bool {
125 if (!comptime isSingleItemPtr(T)) return false;125 if (!comptime isSingleItemPtr(T)) return false;
126 return id == @typeId(meta.Child(T));126 return id == @typeInfo(meta.Child(T));
127 }127 }
128 };128 };
129 return Closure.trait;129 return Closure.trait;
...@@ -135,6 +135,22 @@ test "std.meta.trait.isPtrTo" {...@@ -135,6 +135,22 @@ test "std.meta.trait.isPtrTo" {
135 testing.expect(!isPtrTo(.Struct)(**struct {}));135 testing.expect(!isPtrTo(.Struct)(**struct {}));
136}136}
137137
138pub fn isSliceOf(comptime id: builtin.TypeId) TraitFn {
139 const Closure = struct {
140 pub fn trait(comptime T: type) bool {
141 if (!comptime isSlice(T)) return false;
142 return id == @typeInfo(meta.Child(T));
143 }
144 };
145 return Closure.trait;
146}
147
148test "std.meta.trait.isSliceOf" {
149 testing.expect(!isSliceOf(.Struct)(struct {}));
150 testing.expect(isSliceOf(.Struct)([]struct {}));
151 testing.expect(!isSliceOf(.Struct)([][]struct {}));
152}
153
138///////////Strait trait Fns154///////////Strait trait Fns
139155
140//@TODO:156//@TODO:
...@@ -269,7 +285,7 @@ test "std.meta.trait.isIndexable" {...@@ -269,7 +285,7 @@ test "std.meta.trait.isIndexable" {
269}285}
270286
271pub fn isNumber(comptime T: type) bool {287pub fn isNumber(comptime T: type) bool {
272 return switch (@typeId(T)) {288 return switch (@typeInfo(T)) {
273 .Int, .Float, .ComptimeInt, .ComptimeFloat => true,289 .Int, .Float, .ComptimeInt, .ComptimeFloat => true,
274 else => false,290 else => false,
275 };291 };
...@@ -304,7 +320,7 @@ test "std.meta.trait.isConstPtr" {...@@ -304,7 +320,7 @@ test "std.meta.trait.isConstPtr" {
304}320}
305321
306pub fn isContainer(comptime T: type) bool {322pub fn isContainer(comptime T: type) bool {
307 return switch (@typeId(T)) {323 return switch (@typeInfo(T)) {
308 .Struct, .Union, .Enum => true,324 .Struct, .Union, .Enum => true,
309 else => false,325 else => false,
310 };326 };
lib/std/net.zig+3-3
...@@ -18,7 +18,7 @@ pub const Address = extern union {...@@ -18,7 +18,7 @@ pub const Address = extern union {
18 in6: os.sockaddr_in6,18 in6: os.sockaddr_in6,
19 un: if (has_unix_sockets) os.sockaddr_un else void,19 un: if (has_unix_sockets) os.sockaddr_un else void,
2020
21 // TODO this crashed the compiler21 // TODO this crashed the compiler. https://github.com/ziglang/zig/issues/3512
22 //pub const localhost = initIp4(parseIp4("127.0.0.1") catch unreachable, 0);22 //pub const localhost = initIp4(parseIp4("127.0.0.1") catch unreachable, 0);
2323
24 pub fn parseIp(name: []const u8, port: u16) !Address {24 pub fn parseIp(name: []const u8, port: u16) !Address {
...@@ -120,7 +120,7 @@ pub const Address = extern union {...@@ -120,7 +120,7 @@ pub const Address = extern union {
120 ip_slice[10] = 0xff;120 ip_slice[10] = 0xff;
121 ip_slice[11] = 0xff;121 ip_slice[11] = 0xff;
122122
123 const ptr = @sliceToBytes(@as(*const [1]u32, &addr)[0..]);123 const ptr = mem.sliceAsBytes(@as(*const [1]u32, &addr)[0..]);
124124
125 ip_slice[12] = ptr[0];125 ip_slice[12] = ptr[0];
126 ip_slice[13] = ptr[1];126 ip_slice[13] = ptr[1];
...@@ -164,7 +164,7 @@ pub const Address = extern union {...@@ -164,7 +164,7 @@ pub const Address = extern union {
164 .addr = undefined,164 .addr = undefined,
165 },165 },
166 };166 };
167 const out_ptr = @sliceToBytes(@as(*[1]u32, &result.in.addr)[0..]);167 const out_ptr = mem.sliceAsBytes(@as(*[1]u32, &result.in.addr)[0..]);
168168
169 var x: u8 = 0;169 var x: u8 = 0;
170 var index: u8 = 0;170 var index: u8 = 0;
lib/std/os.zig+248-40
...@@ -70,6 +70,8 @@ else switch (builtin.os) {...@@ -70,6 +70,8 @@ else switch (builtin.os) {
70pub usingnamespace @import("os/bits.zig");70pub usingnamespace @import("os/bits.zig");
7171
72/// See also `getenv`. Populated by startup code before main().72/// See also `getenv`. Populated by startup code before main().
73/// TODO this is a footgun because the value will be undefined when using `zig build-lib`.
74/// https://github.com/ziglang/zig/issues/4524
73pub var environ: [][*:0]u8 = undefined;75pub var environ: [][*:0]u8 = undefined;
7476
75/// Populated by startup code before main().77/// Populated by startup code before main().
...@@ -916,10 +918,17 @@ pub const ExecveError = error{...@@ -916,10 +918,17 @@ pub const ExecveError = error{
916 NameTooLong,918 NameTooLong,
917} || UnexpectedError;919} || UnexpectedError;
918920
921/// Deprecated in favor of `execveZ`.
922pub const execveC = execveZ;
923
919/// Like `execve` except the parameters are null-terminated,924/// Like `execve` except the parameters are null-terminated,
920/// matching the syscall API on all targets. This removes the need for an allocator.925/// matching the syscall API on all targets. This removes the need for an allocator.
921/// This function ignores PATH environment variable. See `execvpeC` for that.926/// This function ignores PATH environment variable. See `execvpeZ` for that.
922pub fn execveC(path: [*:0]const u8, child_argv: [*:null]const ?[*:0]const u8, envp: [*:null]const ?[*:0]const u8) ExecveError {927pub fn execveZ(
928 path: [*:0]const u8,
929 child_argv: [*:null]const ?[*:0]const u8,
930 envp: [*:null]const ?[*:0]const u8,
931) ExecveError {
923 switch (errno(system.execve(path, child_argv, envp))) {932 switch (errno(system.execve(path, child_argv, envp))) {
924 0 => unreachable,933 0 => unreachable,
925 EFAULT => unreachable,934 EFAULT => unreachable,
...@@ -942,19 +951,42 @@ pub fn execveC(path: [*:0]const u8, child_argv: [*:null]const ?[*:0]const u8, en...@@ -942,19 +951,42 @@ pub fn execveC(path: [*:0]const u8, child_argv: [*:null]const ?[*:0]const u8, en
942 }951 }
943}952}
944953
945/// Like `execvpe` except the parameters are null-terminated,954/// Deprecated in favor of `execvpeZ`.
946/// matching the syscall API on all targets. This removes the need for an allocator.955pub const execvpeC = execvpeZ;
947/// This function also uses the PATH environment variable to get the full path to the executable.956
948/// If `file` is an absolute path, this is the same as `execveC`.957pub const Arg0Expand = enum {
949pub fn execvpeC(file: [*:0]const u8, child_argv: [*:null]const ?[*:0]const u8, envp: [*:null]const ?[*:0]const u8) ExecveError {958 expand,
959 no_expand,
960};
961
962/// Like `execvpeZ` except if `arg0_expand` is `.expand`, then `argv` is mutable,
963/// and `argv[0]` is expanded to be the same absolute path that is passed to the execve syscall.
964/// If this function returns with an error, `argv[0]` will be restored to the value it was when it was passed in.
965pub fn execvpeZ_expandArg0(
966 comptime arg0_expand: Arg0Expand,
967 file: [*:0]const u8,
968 child_argv: switch (arg0_expand) {
969 .expand => [*:null]?[*:0]const u8,
970 .no_expand => [*:null]const ?[*:0]const u8,
971 },
972 envp: [*:null]const ?[*:0]const u8,
973) ExecveError {
950 const file_slice = mem.toSliceConst(u8, file);974 const file_slice = mem.toSliceConst(u8, file);
951 if (mem.indexOfScalar(u8, file_slice, '/') != null) return execveC(file, child_argv, envp);975 if (mem.indexOfScalar(u8, file_slice, '/') != null) return execveZ(file, child_argv, envp);
952976
953 const PATH = getenv("PATH") orelse "/usr/local/bin:/bin/:/usr/bin";977 const PATH = getenvZ("PATH") orelse "/usr/local/bin:/bin/:/usr/bin";
954 var path_buf: [MAX_PATH_BYTES]u8 = undefined;978 var path_buf: [MAX_PATH_BYTES]u8 = undefined;
955 var it = mem.tokenize(PATH, ":");979 var it = mem.tokenize(PATH, ":");
956 var seen_eacces = false;980 var seen_eacces = false;
957 var err: ExecveError = undefined;981 var err: ExecveError = undefined;
982
983 // In case of expanding arg0 we must put it back if we return with an error.
984 const prev_arg0 = child_argv[0];
985 defer switch (arg0_expand) {
986 .expand => child_argv[0] = prev_arg0,
987 .no_expand => {},
988 };
989
958 while (it.next()) |search_path| {990 while (it.next()) |search_path| {
959 if (path_buf.len < search_path.len + file_slice.len + 1) return error.NameTooLong;991 if (path_buf.len < search_path.len + file_slice.len + 1) return error.NameTooLong;
960 mem.copy(u8, &path_buf, search_path);992 mem.copy(u8, &path_buf, search_path);
...@@ -962,7 +994,12 @@ pub fn execvpeC(file: [*:0]const u8, child_argv: [*:null]const ?[*:0]const u8, e...@@ -962,7 +994,12 @@ pub fn execvpeC(file: [*:0]const u8, child_argv: [*:null]const ?[*:0]const u8, e
962 mem.copy(u8, path_buf[search_path.len + 1 ..], file_slice);994 mem.copy(u8, path_buf[search_path.len + 1 ..], file_slice);
963 const path_len = search_path.len + file_slice.len + 1;995 const path_len = search_path.len + file_slice.len + 1;
964 path_buf[path_len] = 0;996 path_buf[path_len] = 0;
965 err = execveC(path_buf[0..path_len :0].ptr, child_argv, envp);997 const full_path = path_buf[0..path_len :0].ptr;
998 switch (arg0_expand) {
999 .expand => child_argv[0] = full_path,
1000 .no_expand => {},
1001 }
1002 err = execveZ(full_path, child_argv, envp);
966 switch (err) {1003 switch (err) {
967 error.AccessDenied => seen_eacces = true,1004 error.AccessDenied => seen_eacces = true,
968 error.FileNotFound, error.NotDir => {},1005 error.FileNotFound, error.NotDir => {},
...@@ -973,13 +1010,24 @@ pub fn execvpeC(file: [*:0]const u8, child_argv: [*:null]const ?[*:0]const u8, e...@@ -973,13 +1010,24 @@ pub fn execvpeC(file: [*:0]const u8, child_argv: [*:null]const ?[*:0]const u8, e
973 return err;1010 return err;
974}1011}
9751012
976/// This function must allocate memory to add a null terminating bytes on path and each arg.1013/// Like `execvpe` except the parameters are null-terminated,
977/// It must also convert to KEY=VALUE\0 format for environment variables, and include null1014/// matching the syscall API on all targets. This removes the need for an allocator.
978/// pointers after the args and after the environment variables.
979/// `argv_slice[0]` is the executable path.
980/// This function also uses the PATH environment variable to get the full path to the executable.1015/// This function also uses the PATH environment variable to get the full path to the executable.
981pub fn execvpe(1016/// If `file` is an absolute path, this is the same as `execveZ`.
1017pub fn execvpeZ(
1018 file: [*:0]const u8,
1019 argv: [*:null]const ?[*:0]const u8,
1020 envp: [*:null]const ?[*:0]const u8,
1021) ExecveError {
1022 return execvpeZ_expandArg0(.no_expand, file, argv, envp);
1023}
1024
1025/// This is the same as `execvpe` except if the `arg0_expand` parameter is set to `.expand`,
1026/// then argv[0] will be replaced with the expanded version of it, after resolving in accordance
1027/// with the PATH environment variable.
1028pub fn execvpe_expandArg0(
982 allocator: *mem.Allocator,1029 allocator: *mem.Allocator,
1030 arg0_expand: Arg0Expand,
983 argv_slice: []const []const u8,1031 argv_slice: []const []const u8,
984 env_map: *const std.BufMap,1032 env_map: *const std.BufMap,
985) (ExecveError || error{OutOfMemory}) {1033) (ExecveError || error{OutOfMemory}) {
...@@ -1004,7 +1052,23 @@ pub fn execvpe(...@@ -1004,7 +1052,23 @@ pub fn execvpe(
1004 const envp_buf = try createNullDelimitedEnvMap(allocator, env_map);1052 const envp_buf = try createNullDelimitedEnvMap(allocator, env_map);
1005 defer freeNullDelimitedEnvMap(allocator, envp_buf);1053 defer freeNullDelimitedEnvMap(allocator, envp_buf);
10061054
1007 return execvpeC(argv_buf.ptr[0].?, argv_ptr, envp_buf.ptr);1055 switch (arg0_expand) {
1056 .expand => return execvpeZ_expandArg0(.expand, argv_buf.ptr[0].?, argv_ptr, envp_buf.ptr),
1057 .no_expand => return execvpeZ_expandArg0(.no_expand, argv_buf.ptr[0].?, argv_ptr, envp_buf.ptr),
1058 }
1059}
1060
1061/// This function must allocate memory to add a null terminating bytes on path and each arg.
1062/// It must also convert to KEY=VALUE\0 format for environment variables, and include null
1063/// pointers after the args and after the environment variables.
1064/// `argv_slice[0]` is the executable path.
1065/// This function also uses the PATH environment variable to get the full path to the executable.
1066pub fn execvpe(
1067 allocator: *mem.Allocator,
1068 argv_slice: []const []const u8,
1069 env_map: *const std.BufMap,
1070) (ExecveError || error{OutOfMemory}) {
1071 return execvpe_expandArg0(allocator, .no_expand, argv_slice, env_map);
1008}1072}
10091073
1010pub fn createNullDelimitedEnvMap(allocator: *mem.Allocator, env_map: *const std.BufMap) ![:null]?[*:0]u8 {1074pub fn createNullDelimitedEnvMap(allocator: *mem.Allocator, env_map: *const std.BufMap) ![:null]?[*:0]u8 {
...@@ -1038,9 +1102,37 @@ pub fn freeNullDelimitedEnvMap(allocator: *mem.Allocator, envp_buf: []?[*:0]u8)...@@ -1038,9 +1102,37 @@ pub fn freeNullDelimitedEnvMap(allocator: *mem.Allocator, envp_buf: []?[*:0]u8)
1038}1102}
10391103
1040/// Get an environment variable.1104/// Get an environment variable.
1041/// See also `getenvC`.1105/// See also `getenvZ`.
1042/// TODO make this go through libc when we have it
1043pub fn getenv(key: []const u8) ?[]const u8 {1106pub fn getenv(key: []const u8) ?[]const u8 {
1107 if (builtin.link_libc) {
1108 var small_key_buf: [64]u8 = undefined;
1109 if (key.len < small_key_buf.len) {
1110 mem.copy(u8, &small_key_buf, key);
1111 small_key_buf[key.len] = 0;
1112 const key0 = small_key_buf[0..key.len :0];
1113 return getenvZ(key0);
1114 }
1115 // Search the entire `environ` because we don't have a null terminated pointer.
1116 var ptr = std.c.environ;
1117 while (ptr.*) |line| : (ptr += 1) {
1118 var line_i: usize = 0;
1119 while (line[line_i] != 0 and line[line_i] != '=') : (line_i += 1) {}
1120 const this_key = line[0..line_i];
1121
1122 if (!mem.eql(u8, this_key, key)) continue;
1123
1124 var end_i: usize = line_i;
1125 while (line[end_i] != 0) : (end_i += 1) {}
1126 const value = line[line_i + 1 .. end_i];
1127
1128 return value;
1129 }
1130 return null;
1131 }
1132 if (builtin.os == .windows) {
1133 @compileError("std.os.getenv is unavailable for Windows because environment string is in WTF-16 format. See std.process.getEnvVarOwned for cross-platform API or std.os.getenvW for Windows-specific API.");
1134 }
1135 // TODO see https://github.com/ziglang/zig/issues/4524
1044 for (environ) |ptr| {1136 for (environ) |ptr| {
1045 var line_i: usize = 0;1137 var line_i: usize = 0;
1046 while (ptr[line_i] != 0 and ptr[line_i] != '=') : (line_i += 1) {}1138 while (ptr[line_i] != 0 and ptr[line_i] != '=') : (line_i += 1) {}
...@@ -1056,16 +1148,50 @@ pub fn getenv(key: []const u8) ?[]const u8 {...@@ -1056,16 +1148,50 @@ pub fn getenv(key: []const u8) ?[]const u8 {
1056 return null;1148 return null;
1057}1149}
10581150
1151/// Deprecated in favor of `getenvZ`.
1152pub const getenvC = getenvZ;
1153
1059/// Get an environment variable with a null-terminated name.1154/// Get an environment variable with a null-terminated name.
1060/// See also `getenv`.1155/// See also `getenv`.
1061pub fn getenvC(key: [*:0]const u8) ?[]const u8 {1156pub fn getenvZ(key: [*:0]const u8) ?[]const u8 {
1062 if (builtin.link_libc) {1157 if (builtin.link_libc) {
1063 const value = system.getenv(key) orelse return null;1158 const value = system.getenv(key) orelse return null;
1064 return mem.toSliceConst(u8, value);1159 return mem.toSliceConst(u8, value);
1065 }1160 }
1161 if (builtin.os == .windows) {
1162 @compileError("std.os.getenvZ is unavailable for Windows because environment string is in WTF-16 format. See std.process.getEnvVarOwned for cross-platform API or std.os.getenvW for Windows-specific API.");
1163 }
1066 return getenv(mem.toSliceConst(u8, key));1164 return getenv(mem.toSliceConst(u8, key));
1067}1165}
10681166
1167/// Windows-only. Get an environment variable with a null-terminated, WTF-16 encoded name.
1168/// See also `getenv`.
1169pub fn getenvW(key: [*:0]const u16) ?[:0]const u16 {
1170 if (builtin.os != .windows) {
1171 @compileError("std.os.getenvW is a Windows-only API");
1172 }
1173 const key_slice = mem.toSliceConst(u16, key);
1174 const ptr = windows.peb().ProcessParameters.Environment;
1175 var i: usize = 0;
1176 while (ptr[i] != 0) {
1177 const key_start = i;
1178
1179 while (ptr[i] != 0 and ptr[i] != '=') : (i += 1) {}
1180 const this_key = ptr[key_start..i];
1181
1182 if (ptr[i] == '=') i += 1;
1183
1184 const value_start = i;
1185 while (ptr[i] != 0) : (i += 1) {}
1186 const this_value = ptr[value_start..i :0];
1187
1188 if (mem.eql(u16, key_slice, this_key)) return this_value;
1189
1190 i += 1; // skip over null byte
1191 }
1192 return null;
1193}
1194
1069pub const GetCwdError = error{1195pub const GetCwdError = error{
1070 NameTooLong,1196 NameTooLong,
1071 CurrentWorkingDirectoryUnlinked,1197 CurrentWorkingDirectoryUnlinked,
...@@ -1726,7 +1852,7 @@ pub fn isCygwinPty(handle: fd_t) bool {...@@ -1726,7 +1852,7 @@ pub fn isCygwinPty(handle: fd_t) bool {
17261852
1727 const name_info = @ptrCast(*const windows.FILE_NAME_INFO, &name_info_bytes[0]);1853 const name_info = @ptrCast(*const windows.FILE_NAME_INFO, &name_info_bytes[0]);
1728 const name_bytes = name_info_bytes[size .. size + @as(usize, name_info.FileNameLength)];1854 const name_bytes = name_info_bytes[size .. size + @as(usize, name_info.FileNameLength)];
1729 const name_wide = @bytesToSlice(u16, name_bytes);1855 const name_wide = mem.bytesAsSlice(u16, name_bytes);
1730 return mem.indexOf(u16, name_wide, &[_]u16{ 'm', 's', 'y', 's', '-' }) != null or1856 return mem.indexOf(u16, name_wide, &[_]u16{ 'm', 's', 'y', 's', '-' }) != null or
1731 mem.indexOf(u16, name_wide, &[_]u16{ '-', 'p', 't', 'y' }) != null;1857 mem.indexOf(u16, name_wide, &[_]u16{ '-', 'p', 't', 'y' }) != null;
1732}1858}
...@@ -2452,6 +2578,9 @@ pub const AccessError = error{...@@ -2452,6 +2578,9 @@ pub const AccessError = error{
2452 InputOutput,2578 InputOutput,
2453 SystemResources,2579 SystemResources,
2454 BadPathName,2580 BadPathName,
2581 FileBusy,
2582 SymLinkLoop,
2583 ReadOnlyFileSystem,
24552584
2456 /// On Windows, file paths must be valid Unicode.2585 /// On Windows, file paths must be valid Unicode.
2457 InvalidUtf8,2586 InvalidUtf8,
...@@ -2469,8 +2598,11 @@ pub fn access(path: []const u8, mode: u32) AccessError!void {...@@ -2469,8 +2598,11 @@ pub fn access(path: []const u8, mode: u32) AccessError!void {
2469 return accessC(&path_c, mode);2598 return accessC(&path_c, mode);
2470}2599}
24712600
2601/// Deprecated in favor of `accessZ`.
2602pub const accessC = accessZ;
2603
2472/// Same as `access` except `path` is null-terminated.2604/// Same as `access` except `path` is null-terminated.
2473pub fn accessC(path: [*:0]const u8, mode: u32) AccessError!void {2605pub fn accessZ(path: [*:0]const u8, mode: u32) AccessError!void {
2474 if (builtin.os == .windows) {2606 if (builtin.os == .windows) {
2475 const path_w = try windows.cStrToPrefixedFileW(path);2607 const path_w = try windows.cStrToPrefixedFileW(path);
2476 _ = try windows.GetFileAttributesW(&path_w);2608 _ = try windows.GetFileAttributesW(&path_w);
...@@ -2479,12 +2611,11 @@ pub fn accessC(path: [*:0]const u8, mode: u32) AccessError!void {...@@ -2479,12 +2611,11 @@ pub fn accessC(path: [*:0]const u8, mode: u32) AccessError!void {
2479 switch (errno(system.access(path, mode))) {2611 switch (errno(system.access(path, mode))) {
2480 0 => return,2612 0 => return,
2481 EACCES => return error.PermissionDenied,2613 EACCES => return error.PermissionDenied,
2482 EROFS => return error.PermissionDenied,2614 EROFS => return error.ReadOnlyFileSystem,
2483 ELOOP => return error.PermissionDenied,2615 ELOOP => return error.SymLinkLoop,
2484 ETXTBSY => return error.PermissionDenied,2616 ETXTBSY => return error.FileBusy,
2485 ENOTDIR => return error.FileNotFound,2617 ENOTDIR => return error.FileNotFound,
2486 ENOENT => return error.FileNotFound,2618 ENOENT => return error.FileNotFound,
2487
2488 ENAMETOOLONG => return error.NameTooLong,2619 ENAMETOOLONG => return error.NameTooLong,
2489 EINVAL => unreachable,2620 EINVAL => unreachable,
2490 EFAULT => unreachable,2621 EFAULT => unreachable,
...@@ -2510,6 +2641,79 @@ pub fn accessW(path: [*:0]const u16, mode: u32) windows.GetFileAttributesError!v...@@ -2510,6 +2641,79 @@ pub fn accessW(path: [*:0]const u16, mode: u32) windows.GetFileAttributesError!v
2510 }2641 }
2511}2642}
25122643
2644/// Check user's permissions for a file, based on an open directory handle.
2645/// TODO currently this ignores `mode` and `flags` on Windows.
2646pub fn faccessat(dirfd: fd_t, path: []const u8, mode: u32, flags: u32) AccessError!void {
2647 if (builtin.os == .windows) {
2648 const path_w = try windows.sliceToPrefixedFileW(path);
2649 return faccessatW(dirfd, &path_w, mode, flags);
2650 }
2651 const path_c = try toPosixPath(path);
2652 return faccessatZ(dirfd, &path_c, mode, flags);
2653}
2654
2655/// Same as `faccessat` except the path parameter is null-terminated.
2656pub fn faccessatZ(dirfd: fd_t, path: [*:0]const u8, mode: u32, flags: u32) AccessError!void {
2657 if (builtin.os == .windows) {
2658 const path_w = try windows.cStrToPrefixedFileW(path);
2659 return faccessatW(dirfd, &path_w, mode, flags);
2660 }
2661 switch (errno(system.faccessat(dirfd, path, mode, flags))) {
2662 0 => return,
2663 EACCES => return error.PermissionDenied,
2664 EROFS => return error.ReadOnlyFileSystem,
2665 ELOOP => return error.SymLinkLoop,
2666 ETXTBSY => return error.FileBusy,
2667 ENOTDIR => return error.FileNotFound,
2668 ENOENT => return error.FileNotFound,
2669 ENAMETOOLONG => return error.NameTooLong,
2670 EINVAL => unreachable,
2671 EFAULT => unreachable,
2672 EIO => return error.InputOutput,
2673 ENOMEM => return error.SystemResources,
2674 else => |err| return unexpectedErrno(err),
2675 }
2676}
2677
2678/// Same as `faccessat` except asserts the target is Windows and the path parameter
2679/// is NtDll-prefixed, null-terminated, WTF-16 encoded.
2680/// TODO currently this ignores `mode` and `flags`
2681pub fn faccessatW(dirfd: fd_t, sub_path_w: [*:0]const u16, mode: u32, flags: u32) AccessError!void {
2682 if (sub_path_w[0] == '.' and sub_path_w[1] == 0) {
2683 return;
2684 }
2685 if (sub_path_w[0] == '.' and sub_path_w[1] == '.' and sub_path_w[2] == 0) {
2686 return;
2687 }
2688
2689 const path_len_bytes = math.cast(u16, mem.toSliceConst(u16, sub_path_w).len * 2) catch |err| switch (err) {
2690 error.Overflow => return error.NameTooLong,
2691 };
2692 var nt_name = windows.UNICODE_STRING{
2693 .Length = path_len_bytes,
2694 .MaximumLength = path_len_bytes,
2695 .Buffer = @intToPtr([*]u16, @ptrToInt(sub_path_w)),
2696 };
2697 var attr = windows.OBJECT_ATTRIBUTES{
2698 .Length = @sizeOf(windows.OBJECT_ATTRIBUTES),
2699 .RootDirectory = if (std.fs.path.isAbsoluteWindowsW(sub_path_w)) null else dirfd,
2700 .Attributes = 0, // Note we do not use OBJ_CASE_INSENSITIVE here.
2701 .ObjectName = &nt_name,
2702 .SecurityDescriptor = null,
2703 .SecurityQualityOfService = null,
2704 };
2705 var basic_info: windows.FILE_BASIC_INFORMATION = undefined;
2706 switch (windows.ntdll.NtQueryAttributesFile(&attr, &basic_info)) {
2707 .SUCCESS => return,
2708 .OBJECT_NAME_NOT_FOUND => return error.FileNotFound,
2709 .OBJECT_PATH_NOT_FOUND => return error.FileNotFound,
2710 .INVALID_PARAMETER => unreachable,
2711 .ACCESS_DENIED => return error.PermissionDenied,
2712 .OBJECT_PATH_SYNTAX_BAD => unreachable,
2713 else => |rc| return windows.unexpectedStatus(rc),
2714 }
2715}
2716
2513pub const PipeError = error{2717pub const PipeError = error{
2514 SystemFdQuotaExceeded,2718 SystemFdQuotaExceeded,
2515 ProcessFdQuotaExceeded,2719 ProcessFdQuotaExceeded,
...@@ -2844,18 +3048,26 @@ pub fn nanosleep(seconds: u64, nanoseconds: u64) void {...@@ -2844,18 +3048,26 @@ pub fn nanosleep(seconds: u64, nanoseconds: u64) void {
2844}3048}
28453049
2846pub fn dl_iterate_phdr(3050pub fn dl_iterate_phdr(
2847 comptime T: type,3051 context: var,
2848 callback: extern fn (info: *dl_phdr_info, size: usize, data: ?*T) i32,3052 comptime Error: type,
2849 data: ?*T,3053 comptime callback: fn (info: *dl_phdr_info, size: usize, context: @TypeOf(context)) Error!void,
2850) isize {3054) Error!void {
3055 const Context = @TypeOf(context);
3056
2851 if (builtin.object_format != .elf)3057 if (builtin.object_format != .elf)
2852 @compileError("dl_iterate_phdr is not available for this target");3058 @compileError("dl_iterate_phdr is not available for this target");
28533059
2854 if (builtin.link_libc) {3060 if (builtin.link_libc) {
2855 return system.dl_iterate_phdr(3061 switch (system.dl_iterate_phdr(struct {
2856 @ptrCast(std.c.dl_iterate_phdr_callback, callback),3062 fn callbackC(info: *dl_phdr_info, size: usize, data: ?*c_void) callconv(.C) c_int {
2857 @ptrCast(?*c_void, data),3063 const context_ptr = @ptrCast(*const Context, @alignCast(@alignOf(*const Context), data));
2858 );3064 callback(info, size, context_ptr.*) catch |err| return @errorToInt(err);
3065 return 0;
3066 }
3067 }.callbackC, @intToPtr(?*c_void, @ptrToInt(&context)))) {
3068 0 => return,
3069 else => |err| return @errSetCast(Error, @intToError(@intCast(u16, err))), // TODO don't hardcode u16
3070 }
2859 }3071 }
28603072
2861 const elf_base = std.process.getBaseAddress();3073 const elf_base = std.process.getBaseAddress();
...@@ -2877,11 +3089,10 @@ pub fn dl_iterate_phdr(...@@ -2877,11 +3089,10 @@ pub fn dl_iterate_phdr(
2877 .dlpi_phnum = ehdr.e_phnum,3089 .dlpi_phnum = ehdr.e_phnum,
2878 };3090 };
28793091
2880 return callback(&info, @sizeOf(dl_phdr_info), data);3092 return callback(&info, @sizeOf(dl_phdr_info), context);
2881 }3093 }
28823094
2883 // Last return value from the callback function3095 // Last return value from the callback function
2884 var last_r: isize = 0;
2885 while (it.next()) |entry| {3096 while (it.next()) |entry| {
2886 var dlpi_phdr: [*]elf.Phdr = undefined;3097 var dlpi_phdr: [*]elf.Phdr = undefined;
2887 var dlpi_phnum: u16 = undefined;3098 var dlpi_phnum: u16 = undefined;
...@@ -2903,11 +3114,8 @@ pub fn dl_iterate_phdr(...@@ -2903,11 +3114,8 @@ pub fn dl_iterate_phdr(
2903 .dlpi_phnum = dlpi_phnum,3114 .dlpi_phnum = dlpi_phnum,
2904 };3115 };
29053116
2906 last_r = callback(&info, @sizeOf(dl_phdr_info), data);3117 try callback(&info, @sizeOf(dl_phdr_info), context);
2907 if (last_r != 0) break;
2908 }3118 }
2909
2910 return last_r;
2911}3119}
29123120
2913pub const ClockGetTimeError = error{UnsupportedClock} || UnexpectedError;3121pub const ClockGetTimeError = error{UnsupportedClock} || UnexpectedError;
...@@ -3141,7 +3349,7 @@ pub fn res_mkquery(...@@ -3141,7 +3349,7 @@ pub fn res_mkquery(
3141 // Make a reasonably unpredictable id3349 // Make a reasonably unpredictable id
3142 var ts: timespec = undefined;3350 var ts: timespec = undefined;
3143 clock_gettime(CLOCK_REALTIME, &ts) catch {};3351 clock_gettime(CLOCK_REALTIME, &ts) catch {};
3144 const UInt = @IntType(false, @TypeOf(ts.tv_nsec).bit_count);3352 const UInt = std.meta.IntType(false, @TypeOf(ts.tv_nsec).bit_count);
3145 const unsec = @bitCast(UInt, ts.tv_nsec);3353 const unsec = @bitCast(UInt, ts.tv_nsec);
3146 const id = @truncate(u32, unsec + unsec / 65536);3354 const id = @truncate(u32, unsec + unsec / 65536);
3147 q[0] = @truncate(u8, id / 256);3355 q[0] = @truncate(u8, id / 256);
lib/std/os/bits/linux.zig+1-1
...@@ -1004,7 +1004,7 @@ pub const dl_phdr_info = extern struct {...@@ -1004,7 +1004,7 @@ pub const dl_phdr_info = extern struct {
10041004
1005pub const CPU_SETSIZE = 128;1005pub const CPU_SETSIZE = 128;
1006pub const cpu_set_t = [CPU_SETSIZE / @sizeOf(usize)]usize;1006pub const cpu_set_t = [CPU_SETSIZE / @sizeOf(usize)]usize;
1007pub const cpu_count_t = @IntType(false, std.math.log2(CPU_SETSIZE * 8));1007pub const cpu_count_t = std.meta.IntType(false, std.math.log2(CPU_SETSIZE * 8));
10081008
1009pub fn CPU_COUNT(set: cpu_set_t) cpu_count_t {1009pub fn CPU_COUNT(set: cpu_set_t) cpu_count_t {
1010 var sum: cpu_count_t = 0;1010 var sum: cpu_count_t = 0;
lib/std/os/linux/tls.zig+1-1
...@@ -152,7 +152,7 @@ pub fn setThreadPointer(addr: usize) void {...@@ -152,7 +152,7 @@ pub fn setThreadPointer(addr: usize) void {
152 : [addr] "r" (addr)152 : [addr] "r" (addr)
153 );153 );
154 },154 },
155 .arm => |arm| {155 .arm => {
156 const rc = std.os.linux.syscall1(std.os.linux.SYS_set_tls, addr);156 const rc = std.os.linux.syscall1(std.os.linux.SYS_set_tls, addr);
157 assert(rc == 0);157 assert(rc == 0);
158 },158 },
lib/std/os/test.zig+21-12
...@@ -29,7 +29,7 @@ test "makePath, put some files in it, deleteTree" {...@@ -29,7 +29,7 @@ test "makePath, put some files in it, deleteTree" {
2929
30test "access file" {30test "access file" {
31 try fs.makePath(a, "os_test_tmp");31 try fs.makePath(a, "os_test_tmp");
32 if (File.access("os_test_tmp" ++ fs.path.sep_str ++ "file.txt")) |ok| {32 if (fs.cwd().access("os_test_tmp" ++ fs.path.sep_str ++ "file.txt", .{})) |ok| {
33 @panic("expected error");33 @panic("expected error");
34 } else |err| {34 } else |err| {
35 expect(err == error.FileNotFound);35 expect(err == error.FileNotFound);
...@@ -165,16 +165,19 @@ test "sigaltstack" {...@@ -165,16 +165,19 @@ test "sigaltstack" {
165// analyzed165// analyzed
166const dl_phdr_info = if (@hasDecl(os, "dl_phdr_info")) os.dl_phdr_info else c_void;166const dl_phdr_info = if (@hasDecl(os, "dl_phdr_info")) os.dl_phdr_info else c_void;
167167
168fn iter_fn(info: *dl_phdr_info, size: usize, data: ?*usize) callconv(.C) i32 {168const IterFnError = error{
169 if (builtin.os == .windows or builtin.os == .wasi or builtin.os == .macosx)169 MissingPtLoadSegment,
170 return 0;170 MissingLoad,
171 BadElfMagic,
172 FailedConsistencyCheck,
173};
171174
172 var counter = data.?;175fn iter_fn(info: *dl_phdr_info, size: usize, counter: *usize) IterFnError!void {
173 // Count how many libraries are loaded176 // Count how many libraries are loaded
174 counter.* += @as(usize, 1);177 counter.* += @as(usize, 1);
175178
176 // The image should contain at least a PT_LOAD segment179 // The image should contain at least a PT_LOAD segment
177 if (info.dlpi_phnum < 1) return -1;180 if (info.dlpi_phnum < 1) return error.MissingPtLoadSegment;
178181
179 // Quick & dirty validation of the phdr pointers, make sure we're not182 // Quick & dirty validation of the phdr pointers, make sure we're not
180 // pointing to some random gibberish183 // pointing to some random gibberish
...@@ -189,17 +192,15 @@ fn iter_fn(info: *dl_phdr_info, size: usize, data: ?*usize) callconv(.C) i32 {...@@ -189,17 +192,15 @@ fn iter_fn(info: *dl_phdr_info, size: usize, data: ?*usize) callconv(.C) i32 {
189 // Find the ELF header192 // Find the ELF header
190 const elf_header = @intToPtr(*elf.Ehdr, reloc_addr - phdr.p_offset);193 const elf_header = @intToPtr(*elf.Ehdr, reloc_addr - phdr.p_offset);
191 // Validate the magic194 // Validate the magic
192 if (!mem.eql(u8, elf_header.e_ident[0..4], "\x7fELF")) return -1;195 if (!mem.eql(u8, elf_header.e_ident[0..4], "\x7fELF")) return error.BadElfMagic;
193 // Consistency check196 // Consistency check
194 if (elf_header.e_phnum != info.dlpi_phnum) return -1;197 if (elf_header.e_phnum != info.dlpi_phnum) return error.FailedConsistencyCheck;
195198
196 found_load = true;199 found_load = true;
197 break;200 break;
198 }201 }
199202
200 if (!found_load) return -1;203 if (!found_load) return error.MissingLoad;
201
202 return 42;
203}204}
204205
205test "dl_iterate_phdr" {206test "dl_iterate_phdr" {
...@@ -207,7 +208,7 @@ test "dl_iterate_phdr" {...@@ -207,7 +208,7 @@ test "dl_iterate_phdr" {
207 return error.SkipZigTest;208 return error.SkipZigTest;
208209
209 var counter: usize = 0;210 var counter: usize = 0;
210 expect(os.dl_iterate_phdr(usize, iter_fn, &counter) != 0);211 try os.dl_iterate_phdr(&counter, IterFnError, iter_fn);
211 expect(counter != 0);212 expect(counter != 0);
212}213}
213214
...@@ -350,3 +351,11 @@ test "mmap" {...@@ -350,3 +351,11 @@ test "mmap" {
350351
351 try fs.cwd().deleteFile(test_out_file);352 try fs.cwd().deleteFile(test_out_file);
352}353}
354
355test "getenv" {
356 if (builtin.os == .windows) {
357 expect(os.getenvW(&[_:0]u16{ 'B', 'O', 'G', 'U', 'S', 0x11, 0x22, 0x33, 0x44, 0x55 }) == null);
358 } else {
359 expect(os.getenvZ("BOGUSDOESNOTEXISTENVVAR") == null);
360 }
361}
lib/std/os/windows/bits.zig+1-1
...@@ -1187,7 +1187,7 @@ pub const RTL_USER_PROCESS_PARAMETERS = extern struct {...@@ -1187,7 +1187,7 @@ pub const RTL_USER_PROCESS_PARAMETERS = extern struct {
1187 DllPath: UNICODE_STRING,1187 DllPath: UNICODE_STRING,
1188 ImagePathName: UNICODE_STRING,1188 ImagePathName: UNICODE_STRING,
1189 CommandLine: UNICODE_STRING,1189 CommandLine: UNICODE_STRING,
1190 Environment: [*]WCHAR,1190 Environment: [*:0]WCHAR,
1191 dwX: ULONG,1191 dwX: ULONG,
1192 dwY: ULONG,1192 dwY: ULONG,
1193 dwXSize: ULONG,1193 dwXSize: ULONG,
lib/std/os/windows/ntdll.zig+6
...@@ -8,6 +8,12 @@ pub extern "NtDll" fn NtQueryInformationFile(...@@ -8,6 +8,12 @@ pub extern "NtDll" fn NtQueryInformationFile(
8 Length: ULONG,8 Length: ULONG,
9 FileInformationClass: FILE_INFORMATION_CLASS,9 FileInformationClass: FILE_INFORMATION_CLASS,
10) callconv(.Stdcall) NTSTATUS;10) callconv(.Stdcall) NTSTATUS;
11
12pub extern "NtDll" fn NtQueryAttributesFile(
13 ObjectAttributes: *OBJECT_ATTRIBUTES,
14 FileAttributes: *FILE_BASIC_INFORMATION,
15) callconv(.Stdcall) NTSTATUS;
16
11pub extern "NtDll" fn NtCreateFile(17pub extern "NtDll" fn NtCreateFile(
12 FileHandle: *HANDLE,18 FileHandle: *HANDLE,
13 DesiredAccess: ACCESS_MASK,19 DesiredAccess: ACCESS_MASK,
lib/std/packed_int_array.zig+6-6
...@@ -34,13 +34,13 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type {...@@ -34,13 +34,13 @@ pub fn PackedIntIo(comptime Int: type, comptime endian: builtin.Endian) type {
3434
35 //we bitcast the desired Int type to an unsigned version of itself35 //we bitcast the desired Int type to an unsigned version of itself
36 // to avoid issues with shifting signed ints.36 // to avoid issues with shifting signed ints.
37 const UnInt = @IntType(false, int_bits);37 const UnInt = std.meta.IntType(false, int_bits);
3838
39 //The maximum container int type39 //The maximum container int type
40 const MinIo = @IntType(false, min_io_bits);40 const MinIo = std.meta.IntType(false, min_io_bits);
4141
42 //The minimum container int type42 //The minimum container int type
43 const MaxIo = @IntType(false, max_io_bits);43 const MaxIo = std.meta.IntType(false, max_io_bits);
4444
45 return struct {45 return struct {
46 pub fn get(bytes: []const u8, index: usize, bit_offset: u7) Int {46 pub fn get(bytes: []const u8, index: usize, bit_offset: u7) Int {
...@@ -322,7 +322,7 @@ test "PackedIntArray" {...@@ -322,7 +322,7 @@ test "PackedIntArray" {
322 inline while (bits <= 256) : (bits += 1) {322 inline while (bits <= 256) : (bits += 1) {
323 //alternate unsigned and signed323 //alternate unsigned and signed
324 const even = bits % 2 == 0;324 const even = bits % 2 == 0;
325 const I = @IntType(even, bits);325 const I = std.meta.IntType(even, bits);
326326
327 const PackedArray = PackedIntArray(I, int_count);327 const PackedArray = PackedIntArray(I, int_count);
328 const expected_bytes = ((bits * int_count) + 7) / 8;328 const expected_bytes = ((bits * int_count) + 7) / 8;
...@@ -369,7 +369,7 @@ test "PackedIntSlice" {...@@ -369,7 +369,7 @@ test "PackedIntSlice" {
369 inline while (bits <= 256) : (bits += 1) {369 inline while (bits <= 256) : (bits += 1) {
370 //alternate unsigned and signed370 //alternate unsigned and signed
371 const even = bits % 2 == 0;371 const even = bits % 2 == 0;
372 const I = @IntType(even, bits);372 const I = std.meta.IntType(even, bits);
373 const P = PackedIntSlice(I);373 const P = PackedIntSlice(I);
374374
375 var data = P.init(&buffer, int_count);375 var data = P.init(&buffer, int_count);
...@@ -399,7 +399,7 @@ test "PackedIntSlice of PackedInt(Array/Slice)" {...@@ -399,7 +399,7 @@ test "PackedIntSlice of PackedInt(Array/Slice)" {
399399
400 comptime var bits = 0;400 comptime var bits = 0;
401 inline while (bits <= max_bits) : (bits += 1) {401 inline while (bits <= max_bits) : (bits += 1) {
402 const Int = @IntType(false, bits);402 const Int = std.meta.IntType(false, bits);
403403
404 const PackedArray = PackedIntArray(Int, int_count);404 const PackedArray = PackedIntArray(Int, int_count);
405 var packed_array = @as(PackedArray, undefined);405 var packed_array = @as(PackedArray, undefined);
lib/std/process.zig+92-42
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1const builtin = @import("builtin");
2const std = @import("std.zig");1const std = @import("std.zig");
2const builtin = std.builtin;
3const os = std.os;3const os = std.os;
4const fs = std.fs;4const fs = std.fs;
5const BufMap = std.BufMap;5const BufMap = std.BufMap;
...@@ -31,20 +31,16 @@ test "getCwdAlloc" {...@@ -31,20 +31,16 @@ test "getCwdAlloc" {
31 testing.allocator.free(cwd);31 testing.allocator.free(cwd);
32}32}
3333
34/// Caller must free result when done.34/// Caller owns resulting `BufMap`.
35/// TODO make this go through libc when we have it
36pub fn getEnvMap(allocator: *Allocator) !BufMap {35pub fn getEnvMap(allocator: *Allocator) !BufMap {
37 var result = BufMap.init(allocator);36 var result = BufMap.init(allocator);
38 errdefer result.deinit();37 errdefer result.deinit();
3938
40 if (builtin.os == .windows) {39 if (builtin.os == .windows) {
41 const ptr = try os.windows.GetEnvironmentStringsW();40 const ptr = os.windows.peb().ProcessParameters.Environment;
42 defer os.windows.FreeEnvironmentStringsW(ptr);
4341
44 var i: usize = 0;42 var i: usize = 0;
45 while (true) {43 while (ptr[i] != 0) {
46 if (ptr[i] == 0) return result;
47
48 const key_start = i;44 const key_start = i;
4945
50 while (ptr[i] != 0 and ptr[i] != '=') : (i += 1) {}46 while (ptr[i] != 0 and ptr[i] != '=') : (i += 1) {}
...@@ -64,6 +60,7 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {...@@ -64,6 +60,7 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {
6460
65 try result.setMove(key, value);61 try result.setMove(key, value);
66 }62 }
63 return result;
67 } else if (builtin.os == .wasi) {64 } else if (builtin.os == .wasi) {
68 var environ_count: usize = undefined;65 var environ_count: usize = undefined;
69 var environ_buf_size: usize = undefined;66 var environ_buf_size: usize = undefined;
...@@ -95,15 +92,29 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {...@@ -95,15 +92,29 @@ pub fn getEnvMap(allocator: *Allocator) !BufMap {
95 }92 }
96 }93 }
97 return result;94 return result;
95 } else if (builtin.link_libc) {
96 var ptr = std.c.environ;
97 while (ptr.*) |line| : (ptr += 1) {
98 var line_i: usize = 0;
99 while (line[line_i] != 0 and line[line_i] != '=') : (line_i += 1) {}
100 const key = line[0..line_i];
101
102 var end_i: usize = line_i;
103 while (line[end_i] != 0) : (end_i += 1) {}
104 const value = line[line_i + 1 .. end_i];
105
106 try result.set(key, value);
107 }
108 return result;
98 } else {109 } else {
99 for (os.environ) |ptr| {110 for (os.environ) |line| {
100 var line_i: usize = 0;111 var line_i: usize = 0;
101 while (ptr[line_i] != 0 and ptr[line_i] != '=') : (line_i += 1) {}112 while (line[line_i] != 0 and line[line_i] != '=') : (line_i += 1) {}
102 const key = ptr[0..line_i];113 const key = line[0..line_i];
103114
104 var end_i: usize = line_i;115 var end_i: usize = line_i;
105 while (ptr[end_i] != 0) : (end_i += 1) {}116 while (line[end_i] != 0) : (end_i += 1) {}
106 const value = ptr[line_i + 1 .. end_i];117 const value = line[line_i + 1 .. end_i];
107118
108 try result.set(key, value);119 try result.set(key, value);
109 }120 }
...@@ -125,37 +136,20 @@ pub const GetEnvVarOwnedError = error{...@@ -125,37 +136,20 @@ pub const GetEnvVarOwnedError = error{
125};136};
126137
127/// Caller must free returned memory.138/// Caller must free returned memory.
128/// TODO make this go through libc when we have it
129pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwnedError![]u8 {139pub fn getEnvVarOwned(allocator: *mem.Allocator, key: []const u8) GetEnvVarOwnedError![]u8 {
130 if (builtin.os == .windows) {140 if (builtin.os == .windows) {
131 const key_with_null = try std.unicode.utf8ToUtf16LeWithNull(allocator, key);141 const result_w = blk: {
132 defer allocator.free(key_with_null);142 const key_w = try std.unicode.utf8ToUtf16LeWithNull(allocator, key);
133143 defer allocator.free(key_w);
134 var buf = try allocator.alloc(u16, 256);
135 defer allocator.free(buf);
136
137 while (true) {
138 const windows_buf_len = math.cast(os.windows.DWORD, buf.len) catch return error.OutOfMemory;
139 const result = os.windows.GetEnvironmentVariableW(
140 key_with_null.ptr,
141 buf.ptr,
142 windows_buf_len,
143 ) catch |err| switch (err) {
144 error.Unexpected => return error.EnvironmentVariableNotFound,
145 else => |e| return e,
146 };
147 if (result > buf.len) {
148 buf = try allocator.realloc(buf, result);
149 continue;
150 }
151144
152 return std.unicode.utf16leToUtf8Alloc(allocator, buf[0..result]) catch |err| switch (err) {145 break :blk std.os.getenvW(key_w) orelse return error.EnvironmentVariableNotFound;
153 error.DanglingSurrogateHalf => return error.InvalidUtf8,146 };
154 error.ExpectedSecondSurrogateHalf => return error.InvalidUtf8,147 return std.unicode.utf16leToUtf8Alloc(allocator, result_w) catch |err| switch (err) {
155 error.UnexpectedSecondSurrogateHalf => return error.InvalidUtf8,148 error.DanglingSurrogateHalf => return error.InvalidUtf8,
156 else => |e| return e,149 error.ExpectedSecondSurrogateHalf => return error.InvalidUtf8,
157 };150 error.UnexpectedSecondSurrogateHalf => return error.InvalidUtf8,
158 }151 else => |e| return e,
152 };
159 } else {153 } else {
160 const result = os.getenv(key) orelse return error.EnvironmentVariableNotFound;154 const result = os.getenv(key) orelse return error.EnvironmentVariableNotFound;
161 return mem.dupe(allocator, u8, result);155 return mem.dupe(allocator, u8, result);
...@@ -436,7 +430,7 @@ pub fn argsAlloc(allocator: *mem.Allocator) ![][]u8 {...@@ -436,7 +430,7 @@ pub fn argsAlloc(allocator: *mem.Allocator) ![][]u8 {
436 const buf = try allocator.alignedAlloc(u8, @alignOf([]u8), total_bytes);430 const buf = try allocator.alignedAlloc(u8, @alignOf([]u8), total_bytes);
437 errdefer allocator.free(buf);431 errdefer allocator.free(buf);
438432
439 const result_slice_list = @bytesToSlice([]u8, buf[0..slice_list_bytes]);433 const result_slice_list = mem.bytesAsSlice([]u8, buf[0..slice_list_bytes]);
440 const result_contents = buf[slice_list_bytes..];434 const result_contents = buf[slice_list_bytes..];
441 mem.copy(u8, result_contents, contents_slice);435 mem.copy(u8, result_contents, contents_slice);
442436
...@@ -613,3 +607,59 @@ pub fn getBaseAddress() usize {...@@ -613,3 +607,59 @@ pub fn getBaseAddress() usize {
613 else => @compileError("Unsupported OS"),607 else => @compileError("Unsupported OS"),
614 }608 }
615}609}
610
611/// Caller owns the result value and each inner slice.
612pub fn getSelfExeSharedLibPaths(allocator: *Allocator) error{OutOfMemory}![][:0]u8 {
613 switch (builtin.link_mode) {
614 .Static => return &[_][:0]u8{},
615 .Dynamic => {},
616 }
617 const List = std.ArrayList([:0]u8);
618 switch (builtin.os) {
619 .linux,
620 .freebsd,
621 .netbsd,
622 .dragonfly,
623 => {
624 var paths = List.init(allocator);
625 errdefer {
626 const slice = paths.toOwnedSlice();
627 for (slice) |item| {
628 allocator.free(item);
629 }
630 allocator.free(slice);
631 }
632 try os.dl_iterate_phdr(&paths, error{OutOfMemory}, struct {
633 fn callback(info: *os.dl_phdr_info, size: usize, list: *List) !void {
634 const name = info.dlpi_name orelse return;
635 if (name[0] == '/') {
636 const item = try mem.dupeZ(list.allocator, u8, mem.toSliceConst(u8, name));
637 errdefer list.allocator.free(item);
638 try list.append(item);
639 }
640 }
641 }.callback);
642 return paths.toOwnedSlice();
643 },
644 .macosx, .ios, .watchos, .tvos => {
645 var paths = List.init(allocator);
646 errdefer {
647 const slice = paths.toOwnedSlice();
648 for (slice) |item| {
649 allocator.free(item);
650 }
651 allocator.free(slice);
652 }
653 const img_count = std.c._dyld_image_count();
654 var i: u32 = 0;
655 while (i < img_count) : (i += 1) {
656 const name = std.c._dyld_get_image_name(i);
657 const item = try mem.dupeZ(allocator, u8, mem.toSliceConst(u8, name));
658 errdefer allocator.free(item);
659 try paths.append(item);
660 }
661 return paths.toOwnedSlice();
662 },
663 else => @compileError("getSelfExeSharedLibPaths unimplemented for this target"),
664 }
665}
lib/std/rand.zig+10-10
...@@ -45,8 +45,8 @@ pub const Random = struct {...@@ -45,8 +45,8 @@ pub const Random = struct {
45 /// Returns a random int `i` such that `0 <= i <= maxInt(T)`.45 /// Returns a random int `i` such that `0 <= i <= maxInt(T)`.
46 /// `i` is evenly distributed.46 /// `i` is evenly distributed.
47 pub fn int(r: *Random, comptime T: type) T {47 pub fn int(r: *Random, comptime T: type) T {
48 const UnsignedT = @IntType(false, T.bit_count);48 const UnsignedT = std.meta.IntType(false, T.bit_count);
49 const ByteAlignedT = @IntType(false, @divTrunc(T.bit_count + 7, 8) * 8);49 const ByteAlignedT = std.meta.IntType(false, @divTrunc(T.bit_count + 7, 8) * 8);
5050
51 var rand_bytes: [@sizeOf(ByteAlignedT)]u8 = undefined;51 var rand_bytes: [@sizeOf(ByteAlignedT)]u8 = undefined;
52 r.bytes(rand_bytes[0..]);52 r.bytes(rand_bytes[0..]);
...@@ -85,9 +85,9 @@ pub const Random = struct {...@@ -85,9 +85,9 @@ pub const Random = struct {
85 comptime assert(T.bit_count <= 64); // TODO: workaround: LLVM ERROR: Unsupported library call operation!85 comptime assert(T.bit_count <= 64); // TODO: workaround: LLVM ERROR: Unsupported library call operation!
86 assert(0 < less_than);86 assert(0 < less_than);
87 // Small is typically u3287 // Small is typically u32
88 const Small = @IntType(false, @divTrunc(T.bit_count + 31, 32) * 32);88 const Small = std.meta.IntType(false, @divTrunc(T.bit_count + 31, 32) * 32);
89 // Large is typically u6489 // Large is typically u64
90 const Large = @IntType(false, Small.bit_count * 2);90 const Large = std.meta.IntType(false, Small.bit_count * 2);
9191
92 // adapted from:92 // adapted from:
93 // http://www.pcg-random.org/posts/bounded-rands.html93 // http://www.pcg-random.org/posts/bounded-rands.html
...@@ -99,7 +99,7 @@ pub const Random = struct {...@@ -99,7 +99,7 @@ pub const Random = struct {
99 // TODO: workaround for https://github.com/ziglang/zig/issues/177099 // TODO: workaround for https://github.com/ziglang/zig/issues/1770
100 // should be:100 // should be:
101 // var t: Small = -%less_than;101 // var t: Small = -%less_than;
102 var t: Small = @bitCast(Small, -%@bitCast(@IntType(true, Small.bit_count), @as(Small, less_than)));102 var t: Small = @bitCast(Small, -%@bitCast(std.meta.IntType(true, Small.bit_count), @as(Small, less_than)));
103103
104 if (t >= less_than) {104 if (t >= less_than) {
105 t -= less_than;105 t -= less_than;
...@@ -145,7 +145,7 @@ pub const Random = struct {...@@ -145,7 +145,7 @@ pub const Random = struct {
145 assert(at_least < less_than);145 assert(at_least < less_than);
146 if (T.is_signed) {146 if (T.is_signed) {
147 // Two's complement makes this math pretty easy.147 // Two's complement makes this math pretty easy.
148 const UnsignedT = @IntType(false, T.bit_count);148 const UnsignedT = std.meta.IntType(false, T.bit_count);
149 const lo = @bitCast(UnsignedT, at_least);149 const lo = @bitCast(UnsignedT, at_least);
150 const hi = @bitCast(UnsignedT, less_than);150 const hi = @bitCast(UnsignedT, less_than);
151 const result = lo +% r.uintLessThanBiased(UnsignedT, hi -% lo);151 const result = lo +% r.uintLessThanBiased(UnsignedT, hi -% lo);
...@@ -163,7 +163,7 @@ pub const Random = struct {...@@ -163,7 +163,7 @@ pub const Random = struct {
163 assert(at_least < less_than);163 assert(at_least < less_than);
164 if (T.is_signed) {164 if (T.is_signed) {
165 // Two's complement makes this math pretty easy.165 // Two's complement makes this math pretty easy.
166 const UnsignedT = @IntType(false, T.bit_count);166 const UnsignedT = std.meta.IntType(false, T.bit_count);
167 const lo = @bitCast(UnsignedT, at_least);167 const lo = @bitCast(UnsignedT, at_least);
168 const hi = @bitCast(UnsignedT, less_than);168 const hi = @bitCast(UnsignedT, less_than);
169 const result = lo +% r.uintLessThan(UnsignedT, hi -% lo);169 const result = lo +% r.uintLessThan(UnsignedT, hi -% lo);
...@@ -180,7 +180,7 @@ pub const Random = struct {...@@ -180,7 +180,7 @@ pub const Random = struct {
180 assert(at_least <= at_most);180 assert(at_least <= at_most);
181 if (T.is_signed) {181 if (T.is_signed) {
182 // Two's complement makes this math pretty easy.182 // Two's complement makes this math pretty easy.
183 const UnsignedT = @IntType(false, T.bit_count);183 const UnsignedT = std.meta.IntType(false, T.bit_count);
184 const lo = @bitCast(UnsignedT, at_least);184 const lo = @bitCast(UnsignedT, at_least);
185 const hi = @bitCast(UnsignedT, at_most);185 const hi = @bitCast(UnsignedT, at_most);
186 const result = lo +% r.uintAtMostBiased(UnsignedT, hi -% lo);186 const result = lo +% r.uintAtMostBiased(UnsignedT, hi -% lo);
...@@ -198,7 +198,7 @@ pub const Random = struct {...@@ -198,7 +198,7 @@ pub const Random = struct {
198 assert(at_least <= at_most);198 assert(at_least <= at_most);
199 if (T.is_signed) {199 if (T.is_signed) {
200 // Two's complement makes this math pretty easy.200 // Two's complement makes this math pretty easy.
201 const UnsignedT = @IntType(false, T.bit_count);201 const UnsignedT = std.meta.IntType(false, T.bit_count);
202 const lo = @bitCast(UnsignedT, at_least);202 const lo = @bitCast(UnsignedT, at_least);
203 const hi = @bitCast(UnsignedT, at_most);203 const hi = @bitCast(UnsignedT, at_most);
204 const result = lo +% r.uintAtMost(UnsignedT, hi -% lo);204 const result = lo +% r.uintAtMost(UnsignedT, hi -% lo);
...@@ -281,7 +281,7 @@ pub const Random = struct {...@@ -281,7 +281,7 @@ pub const Random = struct {
281/// This function introduces a minor bias.281/// This function introduces a minor bias.
282pub fn limitRangeBiased(comptime T: type, random_int: T, less_than: T) T {282pub fn limitRangeBiased(comptime T: type, random_int: T, less_than: T) T {
283 comptime assert(T.is_signed == false);283 comptime assert(T.is_signed == false);
284 const T2 = @IntType(false, T.bit_count * 2);284 const T2 = std.meta.IntType(false, T.bit_count * 2);
285285
286 // adapted from:286 // adapted from:
287 // http://www.pcg-random.org/posts/bounded-rands.html287 // http://www.pcg-random.org/posts/bounded-rands.html
lib/std/special/build_runner.zig+14-11
...@@ -96,6 +96,8 @@ pub fn main() !void {...@@ -96,6 +96,8 @@ pub fn main() !void {
96 builder.verbose_cimport = true;96 builder.verbose_cimport = true;
97 } else if (mem.eql(u8, arg, "--verbose-cc")) {97 } else if (mem.eql(u8, arg, "--verbose-cc")) {
98 builder.verbose_cc = true;98 builder.verbose_cc = true;
99 } else if (mem.eql(u8, arg, "--verbose-llvm-cpu-features")) {
100 builder.verbose_llvm_cpu_features = true;
99 } else if (mem.eql(u8, arg, "--")) {101 } else if (mem.eql(u8, arg, "--")) {
100 builder.args = argsRest(args, arg_idx);102 builder.args = argsRest(args, arg_idx);
101 break;103 break;
...@@ -126,7 +128,7 @@ pub fn main() !void {...@@ -126,7 +128,7 @@ pub fn main() !void {
126}128}
127129
128fn runBuild(builder: *Builder) anyerror!void {130fn runBuild(builder: *Builder) anyerror!void {
129 switch (@typeId(@TypeOf(root.build).ReturnType)) {131 switch (@typeInfo(@TypeOf(root.build).ReturnType)) {
130 .Void => root.build(builder),132 .Void => root.build(builder),
131 .ErrorUnion => try root.build(builder),133 .ErrorUnion => try root.build(builder),
132 else => @compileError("expected return type of build to be 'void' or '!void'"),134 else => @compileError("expected return type of build to be 'void' or '!void'"),
...@@ -185,16 +187,17 @@ fn usage(builder: *Builder, already_ran_build: bool, out_stream: var) !void {...@@ -185,16 +187,17 @@ fn usage(builder: *Builder, already_ran_build: bool, out_stream: var) !void {
185 try out_stream.write(187 try out_stream.write(
186 \\188 \\
187 \\Advanced Options:189 \\Advanced Options:
188 \\ --build-file [file] Override path to build.zig190 \\ --build-file [file] Override path to build.zig
189 \\ --cache-dir [path] Override path to zig cache directory191 \\ --cache-dir [path] Override path to zig cache directory
190 \\ --override-lib-dir [arg] Override path to Zig lib directory192 \\ --override-lib-dir [arg] Override path to Zig lib directory
191 \\ --verbose-tokenize Enable compiler debug output for tokenization193 \\ --verbose-tokenize Enable compiler debug output for tokenization
192 \\ --verbose-ast Enable compiler debug output for parsing into an AST194 \\ --verbose-ast Enable compiler debug output for parsing into an AST
193 \\ --verbose-link Enable compiler debug output for linking195 \\ --verbose-link Enable compiler debug output for linking
194 \\ --verbose-ir Enable compiler debug output for Zig IR196 \\ --verbose-ir Enable compiler debug output for Zig IR
195 \\ --verbose-llvm-ir Enable compiler debug output for LLVM IR197 \\ --verbose-llvm-ir Enable compiler debug output for LLVM IR
196 \\ --verbose-cimport Enable compiler debug output for C imports198 \\ --verbose-cimport Enable compiler debug output for C imports
197 \\ --verbose-cc Enable compiler debug output for C compilation199 \\ --verbose-cc Enable compiler debug output for C compilation
200 \\ --verbose-llvm-cpu-features Enable compiler debug output for LLVM CPU features
198 \\201 \\
199 );202 );
200}203}
lib/std/special/c.zig+1-1
...@@ -511,7 +511,7 @@ export fn roundf(a: f32) f32 {...@@ -511,7 +511,7 @@ export fn roundf(a: f32) f32 {
511fn generic_fmod(comptime T: type, x: T, y: T) T {511fn generic_fmod(comptime T: type, x: T, y: T) T {
512 @setRuntimeSafety(false);512 @setRuntimeSafety(false);
513513
514 const uint = @IntType(false, T.bit_count);514 const uint = std.meta.IntType(false, T.bit_count);
515 const log2uint = math.Log2Int(uint);515 const log2uint = math.Log2Int(uint);
516 const digits = if (T == f32) 23 else 52;516 const digits = if (T == f32) 23 else 52;
517 const exp_bits = if (T == f32) 9 else 12;517 const exp_bits = if (T == f32) 9 else 12;
lib/std/special/compiler_rt/addXf3.zig+7-7
...@@ -54,21 +54,21 @@ pub fn __aeabi_dsub(a: f64, b: f64) callconv(.AAPCS) f64 {...@@ -54,21 +54,21 @@ pub fn __aeabi_dsub(a: f64, b: f64) callconv(.AAPCS) f64 {
54}54}
5555
56// TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/215456// TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154
57fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {57fn normalize(comptime T: type, significand: *std.meta.IntType(false, T.bit_count)) i32 {
58 const Z = @IntType(false, T.bit_count);58 const Z = std.meta.IntType(false, T.bit_count);
59 const S = @IntType(false, T.bit_count - @clz(Z, @as(Z, T.bit_count) - 1));59 const S = std.meta.IntType(false, T.bit_count - @clz(Z, @as(Z, T.bit_count) - 1));
60 const significandBits = std.math.floatMantissaBits(T);60 const significandBits = std.math.floatMantissaBits(T);
61 const implicitBit = @as(Z, 1) << significandBits;61 const implicitBit = @as(Z, 1) << significandBits;
6262
63 const shift = @clz(@IntType(false, T.bit_count), significand.*) - @clz(Z, implicitBit);63 const shift = @clz(std.meta.IntType(false, T.bit_count), significand.*) - @clz(Z, implicitBit);
64 significand.* <<= @intCast(S, shift);64 significand.* <<= @intCast(S, shift);
65 return 1 - shift;65 return 1 - shift;
66}66}
6767
68// TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/215468// TODO: restore inline keyword, see: https://github.com/ziglang/zig/issues/2154
69fn addXf3(comptime T: type, a: T, b: T) T {69fn addXf3(comptime T: type, a: T, b: T) T {
70 const Z = @IntType(false, T.bit_count);70 const Z = std.meta.IntType(false, T.bit_count);
71 const S = @IntType(false, T.bit_count - @clz(Z, @as(Z, T.bit_count) - 1));71 const S = std.meta.IntType(false, T.bit_count - @clz(Z, @as(Z, T.bit_count) - 1));
7272
73 const typeWidth = T.bit_count;73 const typeWidth = T.bit_count;
74 const significandBits = std.math.floatMantissaBits(T);74 const significandBits = std.math.floatMantissaBits(T);
...@@ -182,7 +182,7 @@ fn addXf3(comptime T: type, a: T, b: T) T {...@@ -182,7 +182,7 @@ fn addXf3(comptime T: type, a: T, b: T) T {
182 // If partial cancellation occured, we need to left-shift the result182 // If partial cancellation occured, we need to left-shift the result
183 // and adjust the exponent:183 // and adjust the exponent:
184 if (aSignificand < implicitBit << 3) {184 if (aSignificand < implicitBit << 3) {
185 const shift = @intCast(i32, @clz(Z, aSignificand)) - @intCast(i32, @clz(@IntType(false, T.bit_count), implicitBit << 3));185 const shift = @intCast(i32, @clz(Z, aSignificand)) - @intCast(i32, @clz(std.meta.IntType(false, T.bit_count), implicitBit << 3));
186 aSignificand <<= @intCast(S, shift);186 aSignificand <<= @intCast(S, shift);
187 aExponent -= shift;187 aExponent -= shift;
188 }188 }
lib/std/special/compiler_rt/compareXf2.zig+3-3
...@@ -22,8 +22,8 @@ const GE = extern enum(i32) {...@@ -22,8 +22,8 @@ const GE = extern enum(i32) {
22pub fn cmp(comptime T: type, comptime RT: type, a: T, b: T) RT {22pub fn cmp(comptime T: type, comptime RT: type, a: T, b: T) RT {
23 @setRuntimeSafety(builtin.is_test);23 @setRuntimeSafety(builtin.is_test);
2424
25 const srep_t = @IntType(true, T.bit_count);25 const srep_t = std.meta.IntType(true, T.bit_count);
26 const rep_t = @IntType(false, T.bit_count);26 const rep_t = std.meta.IntType(false, T.bit_count);
2727
28 const significandBits = std.math.floatMantissaBits(T);28 const significandBits = std.math.floatMantissaBits(T);
29 const exponentBits = std.math.floatExponentBits(T);29 const exponentBits = std.math.floatExponentBits(T);
...@@ -68,7 +68,7 @@ pub fn cmp(comptime T: type, comptime RT: type, a: T, b: T) RT {...@@ -68,7 +68,7 @@ pub fn cmp(comptime T: type, comptime RT: type, a: T, b: T) RT {
68pub fn unordcmp(comptime T: type, a: T, b: T) i32 {68pub fn unordcmp(comptime T: type, a: T, b: T) i32 {
69 @setRuntimeSafety(builtin.is_test);69 @setRuntimeSafety(builtin.is_test);
7070
71 const rep_t = @IntType(false, T.bit_count);71 const rep_t = std.meta.IntType(false, T.bit_count);
7272
73 const significandBits = std.math.floatMantissaBits(T);73 const significandBits = std.math.floatMantissaBits(T);
74 const exponentBits = std.math.floatExponentBits(T);74 const exponentBits = std.math.floatExponentBits(T);
lib/std/special/compiler_rt/divdf3.zig+4-4
...@@ -7,8 +7,8 @@ const builtin = @import("builtin");...@@ -7,8 +7,8 @@ const builtin = @import("builtin");
77
8pub fn __divdf3(a: f64, b: f64) callconv(.C) f64 {8pub fn __divdf3(a: f64, b: f64) callconv(.C) f64 {
9 @setRuntimeSafety(builtin.is_test);9 @setRuntimeSafety(builtin.is_test);
10 const Z = @IntType(false, f64.bit_count);10 const Z = std.meta.IntType(false, f64.bit_count);
11 const SignedZ = @IntType(true, f64.bit_count);11 const SignedZ = std.meta.IntType(true, f64.bit_count);
1212
13 const typeWidth = f64.bit_count;13 const typeWidth = f64.bit_count;
14 const significandBits = std.math.floatMantissaBits(f64);14 const significandBits = std.math.floatMantissaBits(f64);
...@@ -312,9 +312,9 @@ fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {...@@ -312,9 +312,9 @@ fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {
312 }312 }
313}313}
314314
315fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {315fn normalize(comptime T: type, significand: *std.meta.IntType(false, T.bit_count)) i32 {
316 @setRuntimeSafety(builtin.is_test);316 @setRuntimeSafety(builtin.is_test);
317 const Z = @IntType(false, T.bit_count);317 const Z = std.meta.IntType(false, T.bit_count);
318 const significandBits = std.math.floatMantissaBits(T);318 const significandBits = std.math.floatMantissaBits(T);
319 const implicitBit = @as(Z, 1) << significandBits;319 const implicitBit = @as(Z, 1) << significandBits;
320320
lib/std/special/compiler_rt/divsf3.zig+3-3
...@@ -7,7 +7,7 @@ const builtin = @import("builtin");...@@ -7,7 +7,7 @@ const builtin = @import("builtin");
77
8pub fn __divsf3(a: f32, b: f32) callconv(.C) f32 {8pub fn __divsf3(a: f32, b: f32) callconv(.C) f32 {
9 @setRuntimeSafety(builtin.is_test);9 @setRuntimeSafety(builtin.is_test);
10 const Z = @IntType(false, f32.bit_count);10 const Z = std.meta.IntType(false, f32.bit_count);
1111
12 const typeWidth = f32.bit_count;12 const typeWidth = f32.bit_count;
13 const significandBits = std.math.floatMantissaBits(f32);13 const significandBits = std.math.floatMantissaBits(f32);
...@@ -185,9 +185,9 @@ pub fn __divsf3(a: f32, b: f32) callconv(.C) f32 {...@@ -185,9 +185,9 @@ pub fn __divsf3(a: f32, b: f32) callconv(.C) f32 {
185 }185 }
186}186}
187187
188fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {188fn normalize(comptime T: type, significand: *std.meta.IntType(false, T.bit_count)) i32 {
189 @setRuntimeSafety(builtin.is_test);189 @setRuntimeSafety(builtin.is_test);
190 const Z = @IntType(false, T.bit_count);190 const Z = std.meta.IntType(false, T.bit_count);
191 const significandBits = std.math.floatMantissaBits(T);191 const significandBits = std.math.floatMantissaBits(T);
192 const implicitBit = @as(Z, 1) << significandBits;192 const implicitBit = @as(Z, 1) << significandBits;
193193
lib/std/special/compiler_rt/extendXfYf2.zig+3-3
...@@ -30,11 +30,11 @@ pub fn __aeabi_f2d(arg: f32) callconv(.AAPCS) f64 {...@@ -30,11 +30,11 @@ pub fn __aeabi_f2d(arg: f32) callconv(.AAPCS) f64 {
3030
31const CHAR_BIT = 8;31const CHAR_BIT = 8;
3232
33fn extendXfYf2(comptime dst_t: type, comptime src_t: type, a: @IntType(false, @typeInfo(src_t).Float.bits)) dst_t {33fn extendXfYf2(comptime dst_t: type, comptime src_t: type, a: std.meta.IntType(false, @typeInfo(src_t).Float.bits)) dst_t {
34 @setRuntimeSafety(builtin.is_test);34 @setRuntimeSafety(builtin.is_test);
3535
36 const src_rep_t = @IntType(false, @typeInfo(src_t).Float.bits);36 const src_rep_t = std.meta.IntType(false, @typeInfo(src_t).Float.bits);
37 const dst_rep_t = @IntType(false, @typeInfo(dst_t).Float.bits);37 const dst_rep_t = std.meta.IntType(false, @typeInfo(dst_t).Float.bits);
38 const srcSigBits = std.math.floatMantissaBits(src_t);38 const srcSigBits = std.math.floatMantissaBits(src_t);
39 const dstSigBits = std.math.floatMantissaBits(dst_t);39 const dstSigBits = std.math.floatMantissaBits(dst_t);
40 const SrcShift = std.math.Log2Int(src_rep_t);40 const SrcShift = std.math.Log2Int(src_rep_t);
lib/std/special/compiler_rt/fixint.zig+1-1
...@@ -45,7 +45,7 @@ pub fn fixint(comptime fp_t: type, comptime fixint_t: type, a: fp_t) fixint_t {...@@ -45,7 +45,7 @@ pub fn fixint(comptime fp_t: type, comptime fixint_t: type, a: fp_t) fixint_t {
45 if (exponent < 0) return 0;45 if (exponent < 0) return 0;
4646
47 // The unsigned result needs to be large enough to handle an fixint_t or rep_t47 // The unsigned result needs to be large enough to handle an fixint_t or rep_t
48 const fixuint_t = @IntType(false, fixint_t.bit_count);48 const fixuint_t = std.meta.IntType(false, fixint_t.bit_count);
49 const UintResultType = if (fixint_t.bit_count > rep_t.bit_count) fixuint_t else rep_t;49 const UintResultType = if (fixint_t.bit_count > rep_t.bit_count) fixuint_t else rep_t;
50 var uint_result: UintResultType = undefined;50 var uint_result: UintResultType = undefined;
5151
lib/std/special/compiler_rt/fixuint.zig+1-1
...@@ -10,7 +10,7 @@ pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) fixuint_t...@@ -10,7 +10,7 @@ pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) fixuint_t
10 f128 => u128,10 f128 => u128,
11 else => unreachable,11 else => unreachable,
12 };12 };
13 const srep_t = @IntType(true, rep_t.bit_count);13 const srep_t = @import("std").meta.IntType(true, rep_t.bit_count);
14 const significandBits = switch (fp_t) {14 const significandBits = switch (fp_t) {
15 f32 => 23,15 f32 => 23,
16 f64 => 52,16 f64 => 52,
lib/std/special/compiler_rt/floatsiXf.zig+2-2
...@@ -5,8 +5,8 @@ const maxInt = std.math.maxInt;...@@ -5,8 +5,8 @@ const maxInt = std.math.maxInt;
5fn floatsiXf(comptime T: type, a: i32) T {5fn floatsiXf(comptime T: type, a: i32) T {
6 @setRuntimeSafety(builtin.is_test);6 @setRuntimeSafety(builtin.is_test);
77
8 const Z = @IntType(false, T.bit_count);8 const Z = std.meta.IntType(false, T.bit_count);
9 const S = @IntType(false, T.bit_count - @clz(Z, @as(Z, T.bit_count) - 1));9 const S = std.meta.IntType(false, T.bit_count - @clz(Z, @as(Z, T.bit_count) - 1));
1010
11 if (a == 0) {11 if (a == 0) {
12 return @as(T, 0.0);12 return @as(T, 0.0);
lib/std/special/compiler_rt/mulXf3.zig+3-3
...@@ -28,7 +28,7 @@ pub fn __aeabi_dmul(a: f64, b: f64) callconv(.C) f64 {...@@ -28,7 +28,7 @@ pub fn __aeabi_dmul(a: f64, b: f64) callconv(.C) f64 {
2828
29fn mulXf3(comptime T: type, a: T, b: T) T {29fn mulXf3(comptime T: type, a: T, b: T) T {
30 @setRuntimeSafety(builtin.is_test);30 @setRuntimeSafety(builtin.is_test);
31 const Z = @IntType(false, T.bit_count);31 const Z = std.meta.IntType(false, T.bit_count);
3232
33 const typeWidth = T.bit_count;33 const typeWidth = T.bit_count;
34 const significandBits = std.math.floatMantissaBits(T);34 const significandBits = std.math.floatMantissaBits(T);
...@@ -264,9 +264,9 @@ fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {...@@ -264,9 +264,9 @@ fn wideMultiply(comptime Z: type, a: Z, b: Z, hi: *Z, lo: *Z) void {
264 }264 }
265}265}
266266
267fn normalize(comptime T: type, significand: *@IntType(false, T.bit_count)) i32 {267fn normalize(comptime T: type, significand: *std.meta.IntType(false, T.bit_count)) i32 {
268 @setRuntimeSafety(builtin.is_test);268 @setRuntimeSafety(builtin.is_test);
269 const Z = @IntType(false, T.bit_count);269 const Z = std.meta.IntType(false, T.bit_count);
270 const significandBits = std.math.floatMantissaBits(T);270 const significandBits = std.math.floatMantissaBits(T);
271 const implicitBit = @as(Z, 1) << significandBits;271 const implicitBit = @as(Z, 1) << significandBits;
272272
lib/std/special/compiler_rt/negXf2.zig+1-1
...@@ -19,7 +19,7 @@ pub fn __aeabi_dneg(arg: f64) callconv(.AAPCS) f64 {...@@ -19,7 +19,7 @@ pub fn __aeabi_dneg(arg: f64) callconv(.AAPCS) f64 {
19}19}
2020
21fn negXf2(comptime T: type, a: T) T {21fn negXf2(comptime T: type, a: T) T {
22 const Z = @IntType(false, T.bit_count);22 const Z = std.meta.IntType(false, T.bit_count);
2323
24 const typeWidth = T.bit_count;24 const typeWidth = T.bit_count;
25 const significandBits = std.math.floatMantissaBits(T);25 const significandBits = std.math.floatMantissaBits(T);
lib/std/special/compiler_rt/truncXfYf2.zig+2-2
...@@ -36,8 +36,8 @@ pub fn __aeabi_f2h(a: f32) callconv(.AAPCS) u16 {...@@ -36,8 +36,8 @@ pub fn __aeabi_f2h(a: f32) callconv(.AAPCS) u16 {
36}36}
3737
38inline fn truncXfYf2(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t {38inline fn truncXfYf2(comptime dst_t: type, comptime src_t: type, a: src_t) dst_t {
39 const src_rep_t = @IntType(false, @typeInfo(src_t).Float.bits);39 const src_rep_t = std.meta.IntType(false, @typeInfo(src_t).Float.bits);
40 const dst_rep_t = @IntType(false, @typeInfo(dst_t).Float.bits);40 const dst_rep_t = std.meta.IntType(false, @typeInfo(dst_t).Float.bits);
41 const srcSigBits = std.math.floatMantissaBits(src_t);41 const srcSigBits = std.math.floatMantissaBits(src_t);
42 const dstSigBits = std.math.floatMantissaBits(dst_t);42 const dstSigBits = std.math.floatMantissaBits(dst_t);
43 const SrcShift = std.math.Log2Int(src_rep_t);43 const SrcShift = std.math.Log2Int(src_rep_t);
lib/std/special/compiler_rt/udivmod.zig+2-2
...@@ -10,8 +10,8 @@ const high = 1 - low;...@@ -10,8 +10,8 @@ const high = 1 - low;
10pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: ?*DoubleInt) DoubleInt {10pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: ?*DoubleInt) DoubleInt {
11 @setRuntimeSafety(is_test);11 @setRuntimeSafety(is_test);
1212
13 const SingleInt = @IntType(false, @divExact(DoubleInt.bit_count, 2));13 const SingleInt = @import("std").meta.IntType(false, @divExact(DoubleInt.bit_count, 2));
14 const SignedDoubleInt = @IntType(true, DoubleInt.bit_count);14 const SignedDoubleInt = @import("std").meta.IntType(true, DoubleInt.bit_count);
15 const Log2SingleInt = @import("std").math.Log2Int(SingleInt);15 const Log2SingleInt = @import("std").math.Log2Int(SingleInt);
1616
17 const n = @ptrCast(*const [2]SingleInt, &a).*; // TODO issue #42117 const n = @ptrCast(*const [2]SingleInt, &a).*; // TODO issue #421
lib/std/start.zig+8-2
...@@ -21,7 +21,9 @@ comptime {...@@ -21,7 +21,9 @@ comptime {
21 @export(main, .{ .name = "main", .linkage = .Weak });21 @export(main, .{ .name = "main", .linkage = .Weak });
22 }22 }
23 } else if (builtin.os == .windows) {23 } else if (builtin.os == .windows) {
24 if (!@hasDecl(root, "WinMain") and !@hasDecl(root, "WinMainCRTStartup") and !@hasDecl(root, "wWinMain") and !@hasDecl(root, "wWinMainCRTStartup")) {24 if (!@hasDecl(root, "WinMain") and !@hasDecl(root, "WinMainCRTStartup") and
25 !@hasDecl(root, "wWinMain") and !@hasDecl(root, "wWinMainCRTStartup"))
26 {
25 @export(WinMainCRTStartup, .{ .name = "WinMainCRTStartup" });27 @export(WinMainCRTStartup, .{ .name = "WinMainCRTStartup" });
26 }28 }
27 } else if (builtin.os == .uefi) {29 } else if (builtin.os == .uefi) {
...@@ -34,7 +36,11 @@ comptime {...@@ -34,7 +36,11 @@ comptime {
34 }36 }
35}37}
3638
37fn _DllMainCRTStartup(hinstDLL: std.os.windows.HINSTANCE, fdwReason: std.os.windows.DWORD, lpReserved: std.os.windows.LPVOID) callconv(.Stdcall) std.os.windows.BOOL {39fn _DllMainCRTStartup(
40 hinstDLL: std.os.windows.HINSTANCE,
41 fdwReason: std.os.windows.DWORD,
42 lpReserved: std.os.windows.LPVOID,
43) callconv(.Stdcall) std.os.windows.BOOL {
38 if (@hasDecl(root, "DllMain")) {44 if (@hasDecl(root, "DllMain")) {
39 return root.DllMain(hinstDLL, fdwReason, lpReserved);45 return root.DllMain(hinstDLL, fdwReason, lpReserved);
40 }46 }
lib/std/target.zig+763-650
...@@ -47,6 +47,16 @@ pub const Target = union(enum) {...@@ -47,6 +47,16 @@ pub const Target = union(enum) {
47 emscripten,47 emscripten,
48 uefi,48 uefi,
49 other,49 other,
50
51 pub fn parse(text: []const u8) !Os {
52 const info = @typeInfo(Os);
53 inline for (info.Enum.fields) |field| {
54 if (mem.eql(u8, text, field.name)) {
55 return @field(Os, field.name);
56 }
57 }
58 return error.UnknownOperatingSystem;
59 }
50 };60 };
5161
52 pub const aarch64 = @import("target/aarch64.zig");62 pub const aarch64 = @import("target/aarch64.zig");
...@@ -65,463 +75,6 @@ pub const Target = union(enum) {...@@ -65,463 +75,6 @@ pub const Target = union(enum) {
65 pub const wasm = @import("target/wasm.zig");75 pub const wasm = @import("target/wasm.zig");
66 pub const x86 = @import("target/x86.zig");76 pub const x86 = @import("target/x86.zig");
6777
68 pub const Arch = union(enum) {
69 arm: Arm32,
70 armeb: Arm32,
71 aarch64: Arm64,
72 aarch64_be: Arm64,
73 aarch64_32: Arm64,
74 arc,
75 avr,
76 bpfel,
77 bpfeb,
78 hexagon,
79 mips,
80 mipsel,
81 mips64,
82 mips64el,
83 msp430,
84 powerpc,
85 powerpc64,
86 powerpc64le,
87 r600,
88 amdgcn,
89 riscv32,
90 riscv64,
91 sparc,
92 sparcv9,
93 sparcel,
94 s390x,
95 tce,
96 tcele,
97 thumb: Arm32,
98 thumbeb: Arm32,
99 i386,
100 x86_64,
101 xcore,
102 nvptx,
103 nvptx64,
104 le32,
105 le64,
106 amdil,
107 amdil64,
108 hsail,
109 hsail64,
110 spir,
111 spir64,
112 kalimba: Kalimba,
113 shave,
114 lanai,
115 wasm32,
116 wasm64,
117 renderscript32,
118 renderscript64,
119 ve,
120
121 pub const Arm32 = enum {
122 v8_5a,
123 v8_4a,
124 v8_3a,
125 v8_2a,
126 v8_1a,
127 v8a,
128 v8r,
129 v8m_baseline,
130 v8m_mainline,
131 v8_1m_mainline,
132 v7a,
133 v7em,
134 v7m,
135 v7s,
136 v7k,
137 v7ve,
138 v6,
139 v6m,
140 v6k,
141 v6t2,
142 v5,
143 v5te,
144 v4t,
145
146 pub fn version(version: Arm32) comptime_int {
147 return switch (version) {
148 .v8_5a, .v8_4a, .v8_3a, .v8_2a, .v8_1a, .v8a, .v8r, .v8m_baseline, .v8m_mainline, .v8_1m_mainline => 8,
149 .v7a, .v7em, .v7m, .v7s, .v7k, .v7ve => 7,
150 .v6, .v6m, .v6k, .v6t2 => 6,
151 .v5, .v5te => 5,
152 .v4t => 4,
153 };
154 }
155 };
156 pub const Arm64 = enum {
157 v8_5a,
158 v8_4a,
159 v8_3a,
160 v8_2a,
161 v8_1a,
162 v8a,
163 };
164 pub const Kalimba = enum {
165 v5,
166 v4,
167 v3,
168 };
169 pub const Mips = enum {
170 r6,
171 };
172 pub const PPC = enum {
173 spe,
174 };
175
176 pub fn subArchName(arch: Arch) ?[]const u8 {
177 return switch (arch) {
178 .arm, .armeb, .thumb, .thumbeb => |arm32| @tagName(arm32),
179 .aarch64, .aarch64_be, .aarch64_32 => |arm64| @tagName(arm64),
180 .kalimba => |kalimba| @tagName(kalimba),
181 else => return null,
182 };
183 }
184
185 pub fn subArchFeature(arch: Arch) ?Cpu.Feature.Set.Index {
186 return switch (arch) {
187 .arm, .armeb, .thumb, .thumbeb => |arm32| switch (arm32) {
188 .v8_5a => @enumToInt(arm.Feature.armv8_5_a),
189 .v8_4a => @enumToInt(arm.Feature.armv8_4_a),
190 .v8_3a => @enumToInt(arm.Feature.armv8_3_a),
191 .v8_2a => @enumToInt(arm.Feature.armv8_2_a),
192 .v8_1a => @enumToInt(arm.Feature.armv8_1_a),
193 .v8a => @enumToInt(arm.Feature.armv8_a),
194 .v8r => @enumToInt(arm.Feature.armv8_r),
195 .v8m_baseline => @enumToInt(arm.Feature.armv8_m_base),
196 .v8m_mainline => @enumToInt(arm.Feature.armv8_m_main),
197 .v8_1m_mainline => @enumToInt(arm.Feature.armv8_1_m_main),
198 .v7a => @enumToInt(arm.Feature.armv7_a),
199 .v7em => @enumToInt(arm.Feature.armv7e_m),
200 .v7m => @enumToInt(arm.Feature.armv7_m),
201 .v7s => @enumToInt(arm.Feature.armv7s),
202 .v7k => @enumToInt(arm.Feature.armv7k),
203 .v7ve => @enumToInt(arm.Feature.armv7ve),
204 .v6 => @enumToInt(arm.Feature.armv6),
205 .v6m => @enumToInt(arm.Feature.armv6_m),
206 .v6k => @enumToInt(arm.Feature.armv6k),
207 .v6t2 => @enumToInt(arm.Feature.armv6t2),
208 .v5 => @enumToInt(arm.Feature.armv5t),
209 .v5te => @enumToInt(arm.Feature.armv5te),
210 .v4t => @enumToInt(arm.Feature.armv4t),
211 },
212 .aarch64, .aarch64_be, .aarch64_32 => |arm64| switch (arm64) {
213 .v8_5a => @enumToInt(aarch64.Feature.v8_5a),
214 .v8_4a => @enumToInt(aarch64.Feature.v8_4a),
215 .v8_3a => @enumToInt(aarch64.Feature.v8_3a),
216 .v8_2a => @enumToInt(aarch64.Feature.v8_2a),
217 .v8_1a => @enumToInt(aarch64.Feature.v8_1a),
218 .v8a => @enumToInt(aarch64.Feature.v8a),
219 },
220 else => return null,
221 };
222 }
223
224 pub fn isARM(arch: Arch) bool {
225 return switch (arch) {
226 .arm, .armeb => true,
227 else => false,
228 };
229 }
230
231 pub fn isThumb(arch: Arch) bool {
232 return switch (arch) {
233 .thumb, .thumbeb => true,
234 else => false,
235 };
236 }
237
238 pub fn isWasm(arch: Arch) bool {
239 return switch (arch) {
240 .wasm32, .wasm64 => true,
241 else => false,
242 };
243 }
244
245 pub fn isRISCV(arch: Arch) bool {
246 return switch (arch) {
247 .riscv32, .riscv64 => true,
248 else => false,
249 };
250 }
251
252 pub fn isMIPS(arch: Arch) bool {
253 return switch (arch) {
254 .mips, .mipsel, .mips64, .mips64el => true,
255 else => false,
256 };
257 }
258
259 pub fn parseCpu(arch: Arch, cpu_name: []const u8) !*const Cpu {
260 for (arch.allCpus()) |cpu| {
261 if (mem.eql(u8, cpu_name, cpu.name)) {
262 return cpu;
263 }
264 }
265 return error.UnknownCpu;
266 }
267
268 /// Comma-separated list of features, with + or - in front of each feature. This
269 /// form represents a deviation from baseline CPU, which is provided as a parameter.
270 /// Extra commas are ignored.
271 pub fn parseCpuFeatureSet(arch: Arch, cpu: *const Cpu, features_text: []const u8) !Cpu.Feature.Set {
272 const all_features = arch.allFeaturesList();
273 var set = cpu.features;
274 var it = mem.tokenize(features_text, ",");
275 while (it.next()) |item_text| {
276 var feature_name: []const u8 = undefined;
277 var op: enum {
278 add,
279 sub,
280 } = undefined;
281 if (mem.startsWith(u8, item_text, "+")) {
282 op = .add;
283 feature_name = item_text[1..];
284 } else if (mem.startsWith(u8, item_text, "-")) {
285 op = .sub;
286 feature_name = item_text[1..];
287 } else {
288 return error.InvalidCpuFeatures;
289 }
290 for (all_features) |feature, index_usize| {
291 const index = @intCast(Cpu.Feature.Set.Index, index_usize);
292 if (mem.eql(u8, feature_name, feature.name)) {
293 switch (op) {
294 .add => set.addFeature(index),
295 .sub => set.removeFeature(index),
296 }
297 break;
298 }
299 } else {
300 return error.UnknownCpuFeature;
301 }
302 }
303 return set;
304 }
305
306 pub fn toElfMachine(arch: Arch) std.elf.EM {
307 return switch (arch) {
308 .avr => ._AVR,
309 .msp430 => ._MSP430,
310 .arc => ._ARC,
311 .arm => ._ARM,
312 .armeb => ._ARM,
313 .hexagon => ._HEXAGON,
314 .le32 => ._NONE,
315 .mips => ._MIPS,
316 .mipsel => ._MIPS_RS3_LE,
317 .powerpc => ._PPC,
318 .r600 => ._NONE,
319 .riscv32 => ._RISCV,
320 .sparc => ._SPARC,
321 .sparcel => ._SPARC,
322 .tce => ._NONE,
323 .tcele => ._NONE,
324 .thumb => ._ARM,
325 .thumbeb => ._ARM,
326 .i386 => ._386,
327 .xcore => ._XCORE,
328 .nvptx => ._NONE,
329 .amdil => ._NONE,
330 .hsail => ._NONE,
331 .spir => ._NONE,
332 .kalimba => ._CSR_KALIMBA,
333 .shave => ._NONE,
334 .lanai => ._LANAI,
335 .wasm32 => ._NONE,
336 .renderscript32 => ._NONE,
337 .aarch64_32 => ._AARCH64,
338 .aarch64 => ._AARCH64,
339 .aarch64_be => ._AARCH64,
340 .mips64 => ._MIPS,
341 .mips64el => ._MIPS_RS3_LE,
342 .powerpc64 => ._PPC64,
343 .powerpc64le => ._PPC64,
344 .riscv64 => ._RISCV,
345 .x86_64 => ._X86_64,
346 .nvptx64 => ._NONE,
347 .le64 => ._NONE,
348 .amdil64 => ._NONE,
349 .hsail64 => ._NONE,
350 .spir64 => ._NONE,
351 .wasm64 => ._NONE,
352 .renderscript64 => ._NONE,
353 .amdgcn => ._NONE,
354 .bpfel => ._BPF,
355 .bpfeb => ._BPF,
356 .sparcv9 => ._SPARCV9,
357 .s390x => ._S390,
358 .ve => ._NONE,
359 };
360 }
361
362 pub fn endian(arch: Arch) builtin.Endian {
363 return switch (arch) {
364 .avr,
365 .arm,
366 .aarch64_32,
367 .aarch64,
368 .amdgcn,
369 .amdil,
370 .amdil64,
371 .bpfel,
372 .hexagon,
373 .hsail,
374 .hsail64,
375 .kalimba,
376 .le32,
377 .le64,
378 .mipsel,
379 .mips64el,
380 .msp430,
381 .nvptx,
382 .nvptx64,
383 .sparcel,
384 .tcele,
385 .powerpc64le,
386 .r600,
387 .riscv32,
388 .riscv64,
389 .i386,
390 .x86_64,
391 .wasm32,
392 .wasm64,
393 .xcore,
394 .thumb,
395 .spir,
396 .spir64,
397 .renderscript32,
398 .renderscript64,
399 .shave,
400 .ve,
401 => .Little,
402
403 .arc,
404 .armeb,
405 .aarch64_be,
406 .bpfeb,
407 .mips,
408 .mips64,
409 .powerpc,
410 .powerpc64,
411 .thumbeb,
412 .sparc,
413 .sparcv9,
414 .tce,
415 .lanai,
416 .s390x,
417 => .Big,
418 };
419 }
420
421 /// Returns a name that matches the lib/std/target/* directory name.
422 pub fn genericName(arch: Arch) []const u8 {
423 return switch (arch) {
424 .arm, .armeb, .thumb, .thumbeb => "arm",
425 .aarch64, .aarch64_be, .aarch64_32 => "aarch64",
426 .avr => "avr",
427 .bpfel, .bpfeb => "bpf",
428 .hexagon => "hexagon",
429 .mips, .mipsel, .mips64, .mips64el => "mips",
430 .msp430 => "msp430",
431 .powerpc, .powerpc64, .powerpc64le => "powerpc",
432 .amdgcn => "amdgpu",
433 .riscv32, .riscv64 => "riscv",
434 .sparc, .sparcv9, .sparcel => "sparc",
435 .s390x => "systemz",
436 .i386, .x86_64 => "x86",
437 .nvptx, .nvptx64 => "nvptx",
438 .wasm32, .wasm64 => "wasm",
439 else => @tagName(arch),
440 };
441 }
442
443 /// All CPU features Zig is aware of, sorted lexicographically by name.
444 pub fn allFeaturesList(arch: Arch) []const Cpu.Feature {
445 return switch (arch) {
446 .arm, .armeb, .thumb, .thumbeb => &arm.all_features,
447 .aarch64, .aarch64_be, .aarch64_32 => &aarch64.all_features,
448 .avr => &avr.all_features,
449 .bpfel, .bpfeb => &bpf.all_features,
450 .hexagon => &hexagon.all_features,
451 .mips, .mipsel, .mips64, .mips64el => &mips.all_features,
452 .msp430 => &msp430.all_features,
453 .powerpc, .powerpc64, .powerpc64le => &powerpc.all_features,
454 .amdgcn => &amdgpu.all_features,
455 .riscv32, .riscv64 => &riscv.all_features,
456 .sparc, .sparcv9, .sparcel => &sparc.all_features,
457 .s390x => &systemz.all_features,
458 .i386, .x86_64 => &x86.all_features,
459 .nvptx, .nvptx64 => &nvptx.all_features,
460 .wasm32, .wasm64 => &wasm.all_features,
461
462 else => &[0]Cpu.Feature{},
463 };
464 }
465
466 /// The "default" set of CPU features for cross-compiling. A conservative set
467 /// of features that is expected to be supported on most available hardware.
468 pub fn getBaselineCpuFeatures(arch: Arch) CpuFeatures {
469 const S = struct {
470 const generic_cpu = Cpu{
471 .name = "generic",
472 .llvm_name = null,
473 .features = Cpu.Feature.Set.empty,
474 };
475 };
476 const cpu = switch (arch) {
477 .arm, .armeb, .thumb, .thumbeb => &arm.cpu.generic,
478 .aarch64, .aarch64_be, .aarch64_32 => &aarch64.cpu.generic,
479 .avr => &avr.cpu.avr1,
480 .bpfel, .bpfeb => &bpf.cpu.generic,
481 .hexagon => &hexagon.cpu.generic,
482 .mips, .mipsel => &mips.cpu.mips32,
483 .mips64, .mips64el => &mips.cpu.mips64,
484 .msp430 => &msp430.cpu.generic,
485 .powerpc, .powerpc64, .powerpc64le => &powerpc.cpu.generic,
486 .amdgcn => &amdgpu.cpu.generic,
487 .riscv32 => &riscv.cpu.baseline_rv32,
488 .riscv64 => &riscv.cpu.baseline_rv64,
489 .sparc, .sparcv9, .sparcel => &sparc.cpu.generic,
490 .s390x => &systemz.cpu.generic,
491 .i386 => &x86.cpu.pentium4,
492 .x86_64 => &x86.cpu.x86_64,
493 .nvptx, .nvptx64 => &nvptx.cpu.sm_20,
494 .wasm32, .wasm64 => &wasm.cpu.generic,
495
496 else => &S.generic_cpu,
497 };
498 return CpuFeatures.initFromCpu(arch, cpu);
499 }
500
501 /// All CPUs Zig is aware of, sorted lexicographically by name.
502 pub fn allCpus(arch: Arch) []const *const Cpu {
503 return switch (arch) {
504 .arm, .armeb, .thumb, .thumbeb => arm.all_cpus,
505 .aarch64, .aarch64_be, .aarch64_32 => aarch64.all_cpus,
506 .avr => avr.all_cpus,
507 .bpfel, .bpfeb => bpf.all_cpus,
508 .hexagon => hexagon.all_cpus,
509 .mips, .mipsel, .mips64, .mips64el => mips.all_cpus,
510 .msp430 => msp430.all_cpus,
511 .powerpc, .powerpc64, .powerpc64le => powerpc.all_cpus,
512 .amdgcn => amdgpu.all_cpus,
513 .riscv32, .riscv64 => riscv.all_cpus,
514 .sparc, .sparcv9, .sparcel => sparc.all_cpus,
515 .s390x => systemz.all_cpus,
516 .i386, .x86_64 => x86.all_cpus,
517 .nvptx, .nvptx64 => nvptx.all_cpus,
518 .wasm32, .wasm64 => wasm.all_cpus,
519
520 else => &[0]*const Cpu{},
521 };
522 }
523 };
524
525 pub const Abi = enum {78 pub const Abi = enum {
526 none,79 none,
527 gnu,80 gnu,
...@@ -543,11 +96,102 @@ pub const Target = union(enum) {...@@ -543,11 +96,102 @@ pub const Target = union(enum) {
543 coreclr,96 coreclr,
544 simulator,97 simulator,
545 macabi,98 macabi,
99
100 pub fn default(arch: Cpu.Arch, target_os: Os) Abi {
101 switch (arch) {
102 .wasm32, .wasm64 => return .musl,
103 else => {},
104 }
105 switch (target_os) {
106 .freestanding,
107 .ananas,
108 .cloudabi,
109 .dragonfly,
110 .lv2,
111 .solaris,
112 .haiku,
113 .minix,
114 .rtems,
115 .nacl,
116 .cnk,
117 .aix,
118 .cuda,
119 .nvcl,
120 .amdhsa,
121 .ps4,
122 .elfiamcu,
123 .mesa3d,
124 .contiki,
125 .amdpal,
126 .hermit,
127 .other,
128 => return .eabi,
129 .openbsd,
130 .macosx,
131 .freebsd,
132 .ios,
133 .tvos,
134 .watchos,
135 .fuchsia,
136 .kfreebsd,
137 .netbsd,
138 .hurd,
139 => return .gnu,
140 .windows,
141 .uefi,
142 => return .msvc,
143 .linux,
144 .wasi,
145 .emscripten,
146 => return .musl,
147 }
148 }
149
150 pub fn parse(text: []const u8) !Abi {
151 const info = @typeInfo(Abi);
152 inline for (info.Enum.fields) |field| {
153 if (mem.eql(u8, text, field.name)) {
154 return @field(Abi, field.name);
155 }
156 }
157 return error.UnknownApplicationBinaryInterface;
158 }
159 };
160
161 pub const ObjectFormat = enum {
162 unknown,
163 coff,
164 elf,
165 macho,
166 wasm,
167 };
168
169 pub const SubSystem = enum {
170 Console,
171 Windows,
172 Posix,
173 Native,
174 EfiApplication,
175 EfiBootServiceDriver,
176 EfiRom,
177 EfiRuntimeDriver,
178 };
179
180 pub const Cross = struct {
181 cpu: Cpu,
182 os: Os,
183 abi: Abi,
546 };184 };
547185
548 pub const Cpu = struct {186 pub const Cpu = struct {
549 name: []const u8,187 /// Architecture
550 llvm_name: ?[:0]const u8,188 arch: Arch,
189
190 /// The CPU model to target. It has a set of features
191 /// which are overridden with the `features` field.
192 model: *const Model,
193
194 /// An explicit list of the entire CPU feature set. It may differ from the specific CPU model's features.
551 features: Feature.Set,195 features: Feature.Set,
552196
553 pub const Feature = struct {197 pub const Feature = struct {
...@@ -573,10 +217,10 @@ pub const Target = union(enum) {...@@ -573,10 +217,10 @@ pub const Target = union(enum) {
573 pub const Set = struct {217 pub const Set = struct {
574 ints: [usize_count]usize,218 ints: [usize_count]usize,
575219
576 pub const needed_bit_count = 175;220 pub const needed_bit_count = 155;
577 pub const byte_count = (needed_bit_count + 7) / 8;221 pub const byte_count = (needed_bit_count + 7) / 8;
578 pub const usize_count = (byte_count + (@sizeOf(usize) - 1)) / @sizeOf(usize);222 pub const usize_count = (byte_count + (@sizeOf(usize) - 1)) / @sizeOf(usize);
579 pub const Index = std.math.Log2Int(@IntType(false, usize_count * @bitSizeOf(usize)));223 pub const Index = std.math.Log2Int(std.meta.IntType(false, usize_count * @bitSizeOf(usize)));
580 pub const ShiftInt = std.math.Log2Int(usize);224 pub const ShiftInt = std.math.Log2Int(usize);
581225
582 pub const empty = Set{ .ints = [1]usize{0} ** usize_count };226 pub const empty = Set{ .ints = [1]usize{0} ** usize_count };
...@@ -597,6 +241,12 @@ pub const Target = union(enum) {...@@ -597,6 +241,12 @@ pub const Target = union(enum) {
597 set.ints[usize_index] |= @as(usize, 1) << bit_index;241 set.ints[usize_index] |= @as(usize, 1) << bit_index;
598 }242 }
599243
244 /// Adds the specified feature set but not its dependencies.
245 pub fn addFeatureSet(set: *Set, other_set: Set) void {
246 set.ints = @as(@Vector(usize_count, usize), set.ints) |
247 @as(@Vector(usize_count, usize), other_set.ints);
248 }
249
600 /// Removes the specified feature but not its dependents.250 /// Removes the specified feature but not its dependents.
601 pub fn removeFeature(set: *Set, arch_feature_index: Index) void {251 pub fn removeFeature(set: *Set, arch_feature_index: Index) void {
602 const usize_index = arch_feature_index / @bitSizeOf(usize);252 const usize_index = arch_feature_index / @bitSizeOf(usize);
...@@ -612,8 +262,7 @@ pub const Target = union(enum) {...@@ -612,8 +262,7 @@ pub const Target = union(enum) {
612 for (all_features_list) |feature, index_usize| {262 for (all_features_list) |feature, index_usize| {
613 const index = @intCast(Index, index_usize);263 const index = @intCast(Index, index_usize);
614 if (set.isEnabled(index)) {264 if (set.isEnabled(index)) {
615 set.ints = @as(@Vector(usize_count, usize), set.ints) |265 set.addFeatureSet(feature.dependencies);
616 @as(@Vector(usize_count, usize), feature.dependencies.ints);
617 }266 }
618 }267 }
619 const nothing_changed = mem.eql(usize, &old, &set.ints);268 const nothing_changed = mem.eql(usize, &old, &set.ints);
...@@ -648,77 +297,361 @@ pub const Target = union(enum) {...@@ -648,77 +297,361 @@ pub const Target = union(enum) {
648 };297 };
649 }298 }
650 };299 };
651 };
652300
653 pub const ObjectFormat = enum {301 pub const Arch = enum {
654 unknown,302 arm,
655 coff,303 armeb,
656 elf,304 aarch64,
657 macho,305 aarch64_be,
658 wasm,306 aarch64_32,
659 };307 arc,
308 avr,
309 bpfel,
310 bpfeb,
311 hexagon,
312 mips,
313 mipsel,
314 mips64,
315 mips64el,
316 msp430,
317 powerpc,
318 powerpc64,
319 powerpc64le,
320 r600,
321 amdgcn,
322 riscv32,
323 riscv64,
324 sparc,
325 sparcv9,
326 sparcel,
327 s390x,
328 tce,
329 tcele,
330 thumb,
331 thumbeb,
332 i386,
333 x86_64,
334 xcore,
335 nvptx,
336 nvptx64,
337 le32,
338 le64,
339 amdil,
340 amdil64,
341 hsail,
342 hsail64,
343 spir,
344 spir64,
345 kalimba,
346 shave,
347 lanai,
348 wasm32,
349 wasm64,
350 renderscript32,
351 renderscript64,
352 ve,
353
354 pub fn isARM(arch: Arch) bool {
355 return switch (arch) {
356 .arm, .armeb => true,
357 else => false,
358 };
359 }
660360
661 pub const SubSystem = enum {361 pub fn isThumb(arch: Arch) bool {
662 Console,362 return switch (arch) {
663 Windows,363 .thumb, .thumbeb => true,
664 Posix,364 else => false,
665 Native,365 };
666 EfiApplication,366 }
667 EfiBootServiceDriver,
668 EfiRom,
669 EfiRuntimeDriver,
670 };
671367
672 pub const Cross = struct {368 pub fn isWasm(arch: Arch) bool {
673 arch: Arch,369 return switch (arch) {
674 os: Os,370 .wasm32, .wasm64 => true,
675 abi: Abi,371 else => false,
676 cpu_features: CpuFeatures,372 };
677 };373 }
678374
679 pub const CpuFeatures = struct {375 pub fn isRISCV(arch: Arch) bool {
680 /// The CPU to target. It has a set of features376 return switch (arch) {
681 /// which are overridden with the `features` field.377 .riscv32, .riscv64 => true,
682 cpu: *const Cpu,378 else => false,
379 };
380 }
683381
684 /// Explicitly provide the entire CPU feature set.382 pub fn isMIPS(arch: Arch) bool {
685 features: Cpu.Feature.Set,383 return switch (arch) {
384 .mips, .mipsel, .mips64, .mips64el => true,
385 else => false,
386 };
387 }
686388
687 pub fn initFromCpu(arch: Arch, cpu: *const Cpu) CpuFeatures {389 pub fn parseCpuModel(arch: Arch, cpu_name: []const u8) !*const Cpu.Model {
688 var features = cpu.features;390 for (arch.allCpuModels()) |cpu| {
689 if (arch.subArchFeature()) |sub_arch_index| {391 if (mem.eql(u8, cpu_name, cpu.name)) {
690 features.addFeature(sub_arch_index);392 return cpu;
393 }
394 }
395 return error.UnknownCpu;
396 }
397
398 pub fn toElfMachine(arch: Arch) std.elf.EM {
399 return switch (arch) {
400 .avr => ._AVR,
401 .msp430 => ._MSP430,
402 .arc => ._ARC,
403 .arm => ._ARM,
404 .armeb => ._ARM,
405 .hexagon => ._HEXAGON,
406 .le32 => ._NONE,
407 .mips => ._MIPS,
408 .mipsel => ._MIPS_RS3_LE,
409 .powerpc => ._PPC,
410 .r600 => ._NONE,
411 .riscv32 => ._RISCV,
412 .sparc => ._SPARC,
413 .sparcel => ._SPARC,
414 .tce => ._NONE,
415 .tcele => ._NONE,
416 .thumb => ._ARM,
417 .thumbeb => ._ARM,
418 .i386 => ._386,
419 .xcore => ._XCORE,
420 .nvptx => ._NONE,
421 .amdil => ._NONE,
422 .hsail => ._NONE,
423 .spir => ._NONE,
424 .kalimba => ._CSR_KALIMBA,
425 .shave => ._NONE,
426 .lanai => ._LANAI,
427 .wasm32 => ._NONE,
428 .renderscript32 => ._NONE,
429 .aarch64_32 => ._AARCH64,
430 .aarch64 => ._AARCH64,
431 .aarch64_be => ._AARCH64,
432 .mips64 => ._MIPS,
433 .mips64el => ._MIPS_RS3_LE,
434 .powerpc64 => ._PPC64,
435 .powerpc64le => ._PPC64,
436 .riscv64 => ._RISCV,
437 .x86_64 => ._X86_64,
438 .nvptx64 => ._NONE,
439 .le64 => ._NONE,
440 .amdil64 => ._NONE,
441 .hsail64 => ._NONE,
442 .spir64 => ._NONE,
443 .wasm64 => ._NONE,
444 .renderscript64 => ._NONE,
445 .amdgcn => ._NONE,
446 .bpfel => ._BPF,
447 .bpfeb => ._BPF,
448 .sparcv9 => ._SPARCV9,
449 .s390x => ._S390,
450 };
451 }
452
453 pub fn endian(arch: Arch) builtin.Endian {
454 return switch (arch) {
455 .avr,
456 .arm,
457 .aarch64_32,
458 .aarch64,
459 .amdgcn,
460 .amdil,
461 .amdil64,
462 .bpfel,
463 .hexagon,
464 .hsail,
465 .hsail64,
466 .kalimba,
467 .le32,
468 .le64,
469 .mipsel,
470 .mips64el,
471 .msp430,
472 .nvptx,
473 .nvptx64,
474 .sparcel,
475 .tcele,
476 .powerpc64le,
477 .r600,
478 .riscv32,
479 .riscv64,
480 .i386,
481 .x86_64,
482 .wasm32,
483 .wasm64,
484 .xcore,
485 .thumb,
486 .spir,
487 .spir64,
488 .renderscript32,
489 .renderscript64,
490 .shave,
491 => .Little,
492
493 .arc,
494 .armeb,
495 .aarch64_be,
496 .bpfeb,
497 .mips,
498 .mips64,
499 .powerpc,
500 .powerpc64,
501 .thumbeb,
502 .sparc,
503 .sparcv9,
504 .tce,
505 .lanai,
506 .s390x,
507 => .Big,
508 };
509 }
510
511 /// Returns a name that matches the lib/std/target/* directory name.
512 pub fn genericName(arch: Arch) []const u8 {
513 return switch (arch) {
514 .arm, .armeb, .thumb, .thumbeb => "arm",
515 .aarch64, .aarch64_be, .aarch64_32 => "aarch64",
516 .avr => "avr",
517 .bpfel, .bpfeb => "bpf",
518 .hexagon => "hexagon",
519 .mips, .mipsel, .mips64, .mips64el => "mips",
520 .msp430 => "msp430",
521 .powerpc, .powerpc64, .powerpc64le => "powerpc",
522 .amdgcn => "amdgpu",
523 .riscv32, .riscv64 => "riscv",
524 .sparc, .sparcv9, .sparcel => "sparc",
525 .s390x => "systemz",
526 .i386, .x86_64 => "x86",
527 .nvptx, .nvptx64 => "nvptx",
528 .wasm32, .wasm64 => "wasm",
529 else => @tagName(arch),
530 };
691 }531 }
692 features.populateDependencies(arch.allFeaturesList());532
693 return CpuFeatures{533 /// All CPU features Zig is aware of, sorted lexicographically by name.
694 .cpu = cpu,534 pub fn allFeaturesList(arch: Arch) []const Cpu.Feature {
695 .features = features,535 return switch (arch) {
536 .arm, .armeb, .thumb, .thumbeb => &arm.all_features,
537 .aarch64, .aarch64_be, .aarch64_32 => &aarch64.all_features,
538 .avr => &avr.all_features,
539 .bpfel, .bpfeb => &bpf.all_features,
540 .hexagon => &hexagon.all_features,
541 .mips, .mipsel, .mips64, .mips64el => &mips.all_features,
542 .msp430 => &msp430.all_features,
543 .powerpc, .powerpc64, .powerpc64le => &powerpc.all_features,
544 .amdgcn => &amdgpu.all_features,
545 .riscv32, .riscv64 => &riscv.all_features,
546 .sparc, .sparcv9, .sparcel => &sparc.all_features,
547 .s390x => &systemz.all_features,
548 .i386, .x86_64 => &x86.all_features,
549 .nvptx, .nvptx64 => &nvptx.all_features,
550 .wasm32, .wasm64 => &wasm.all_features,
551
552 else => &[0]Cpu.Feature{},
553 };
554 }
555
556 /// All processors Zig is aware of, sorted lexicographically by name.
557 pub fn allCpuModels(arch: Arch) []const *const Cpu.Model {
558 return switch (arch) {
559 .arm, .armeb, .thumb, .thumbeb => arm.all_cpus,
560 .aarch64, .aarch64_be, .aarch64_32 => aarch64.all_cpus,
561 .avr => avr.all_cpus,
562 .bpfel, .bpfeb => bpf.all_cpus,
563 .hexagon => hexagon.all_cpus,
564 .mips, .mipsel, .mips64, .mips64el => mips.all_cpus,
565 .msp430 => msp430.all_cpus,
566 .powerpc, .powerpc64, .powerpc64le => powerpc.all_cpus,
567 .amdgcn => amdgpu.all_cpus,
568 .riscv32, .riscv64 => riscv.all_cpus,
569 .sparc, .sparcv9, .sparcel => sparc.all_cpus,
570 .s390x => systemz.all_cpus,
571 .i386, .x86_64 => x86.all_cpus,
572 .nvptx, .nvptx64 => nvptx.all_cpus,
573 .wasm32, .wasm64 => wasm.all_cpus,
574
575 else => &[0]*const Model{},
576 };
577 }
578
579 pub fn parse(text: []const u8) !Arch {
580 const info = @typeInfo(Arch);
581 inline for (info.Enum.fields) |field| {
582 if (mem.eql(u8, text, field.name)) {
583 return @as(Arch, @field(Arch, field.name));
584 }
585 }
586 return error.UnknownArchitecture;
587 }
588 };
589
590 pub const Model = struct {
591 name: []const u8,
592 llvm_name: ?[:0]const u8,
593 features: Feature.Set,
594
595 pub fn toCpu(model: *const Model, arch: Arch) Cpu {
596 var features = model.features;
597 features.populateDependencies(arch.allFeaturesList());
598 return .{
599 .arch = arch,
600 .model = model,
601 .features = features,
602 };
603 }
604 };
605
606 /// The "default" set of CPU features for cross-compiling. A conservative set
607 /// of features that is expected to be supported on most available hardware.
608 pub fn baseline(arch: Arch) Cpu {
609 const S = struct {
610 const generic_model = Model{
611 .name = "generic",
612 .llvm_name = null,
613 .features = Cpu.Feature.Set.empty,
614 };
696 };615 };
616 const model = switch (arch) {
617 .arm, .armeb, .thumb, .thumbeb => &arm.cpu.baseline,
618 .aarch64, .aarch64_be, .aarch64_32 => &aarch64.cpu.generic,
619 .avr => &avr.cpu.avr1,
620 .bpfel, .bpfeb => &bpf.cpu.generic,
621 .hexagon => &hexagon.cpu.generic,
622 .mips, .mipsel => &mips.cpu.mips32,
623 .mips64, .mips64el => &mips.cpu.mips64,
624 .msp430 => &msp430.cpu.generic,
625 .powerpc, .powerpc64, .powerpc64le => &powerpc.cpu.generic,
626 .amdgcn => &amdgpu.cpu.generic,
627 .riscv32 => &riscv.cpu.baseline_rv32,
628 .riscv64 => &riscv.cpu.baseline_rv64,
629 .sparc, .sparcv9, .sparcel => &sparc.cpu.generic,
630 .s390x => &systemz.cpu.generic,
631 .i386 => &x86.cpu.pentium4,
632 .x86_64 => &x86.cpu.x86_64,
633 .nvptx, .nvptx64 => &nvptx.cpu.sm_20,
634 .wasm32, .wasm64 => &wasm.cpu.generic,
635
636 else => &S.generic_model,
637 };
638 return model.toCpu(arch);
697 }639 }
698 };640 };
699641
700 pub const current = Target{642 pub const current = Target{
701 .Cross = Cross{643 .Cross = Cross{
702 .arch = builtin.arch,644 .cpu = builtin.cpu,
703 .os = builtin.os,645 .os = builtin.os,
704 .abi = builtin.abi,646 .abi = builtin.abi,
705 .cpu_features = builtin.cpu_features,
706 },647 },
707 };648 };
708649
709 pub const stack_align = 16;650 pub const stack_align = 16;
710651
711 pub fn getCpuFeatures(self: Target) CpuFeatures {
712 return switch (self) {
713 .Native => builtin.cpu_features,
714 .Cross => |cross| cross.cpu_features,
715 };
716 }
717
718 pub fn zigTriple(self: Target, allocator: *mem.Allocator) ![]u8 {652 pub fn zigTriple(self: Target, allocator: *mem.Allocator) ![]u8 {
719 return std.fmt.allocPrint(allocator, "{}{}-{}-{}", .{653 return std.fmt.allocPrint(allocator, "{}-{}-{}", .{
720 @tagName(self.getArch()),654 @tagName(self.getArch()),
721 Target.archSubArchName(self.getArch()),
722 @tagName(self.getOs()),655 @tagName(self.getOs()),
723 @tagName(self.getAbi()),656 @tagName(self.getAbi()),
724 });657 });
...@@ -780,139 +713,115 @@ pub const Target = union(enum) {...@@ -780,139 +713,115 @@ pub const Target = union(enum) {
780 });713 });
781 }714 }
782715
783 /// TODO: Support CPU features here?716 pub const ParseOptions = struct {
784 /// https://github.com/ziglang/zig/issues/4261717 /// This is sometimes called a "triple". It looks roughly like this:
785 pub fn parse(text: []const u8) !Target {718 /// riscv64-linux-gnu
786 var it = mem.separate(text, "-");719 /// The fields are, respectively:
787 const arch_name = it.next() orelse return error.MissingArchitecture;720 /// * CPU Architecture
788 const os_name = it.next() orelse return error.MissingOperatingSystem;721 /// * Operating System
789 const abi_name = it.next();722 /// * C ABI (optional)
790 const arch = try parseArchSub(arch_name);723 arch_os_abi: []const u8,
791724
792 var cross = Cross{725 /// Looks like "name+a+b-c-d+e", where "name" is a CPU Model name, "a", "b", and "e"
793 .arch = arch,726 /// are examples of CPU features to add to the set, and "c" and "d" are examples of CPU features
794 .cpu_features = arch.getBaselineCpuFeatures(),727 /// to remove from the set.
795 .os = try parseOs(os_name),728 cpu_features: []const u8 = "baseline",
796 .abi = undefined,
797 };
798 cross.abi = if (abi_name) |n| try parseAbi(n) else defaultAbi(cross.arch, cross.os);
799 return Target{ .Cross = cross };
800 }
801729
802 pub fn defaultAbi(arch: Arch, target_os: Os) Abi {730 /// If this is provided, the function will populate some information about parsing failures,
803 switch (arch) {731 /// so that user-friendly error messages can be delivered.
804 .wasm32, .wasm64 => return .musl,732 diagnostics: ?*Diagnostics = null,
805 else => {},
806 }
807 switch (target_os) {
808 .freestanding,
809 .ananas,
810 .cloudabi,
811 .dragonfly,
812 .lv2,
813 .solaris,
814 .haiku,
815 .minix,
816 .rtems,
817 .nacl,
818 .cnk,
819 .aix,
820 .cuda,
821 .nvcl,
822 .amdhsa,
823 .ps4,
824 .elfiamcu,
825 .mesa3d,
826 .contiki,
827 .amdpal,
828 .hermit,
829 .other,
830 => return .eabi,
831 .openbsd,
832 .macosx,
833 .freebsd,
834 .ios,
835 .tvos,
836 .watchos,
837 .fuchsia,
838 .kfreebsd,
839 .netbsd,
840 .hurd,
841 => return .gnu,
842 .windows,
843 .uefi,
844 => return .msvc,
845 .linux,
846 .wasi,
847 .emscripten,
848 => return .musl,
849 }
850 }
851733
852 pub const ParseArchSubError = error{734 pub const Diagnostics = struct {
853 UnknownArchitecture,735 /// If the architecture was determined, this will be populated.
854 UnknownSubArchitecture,736 arch: ?Cpu.Arch = null,
855 };
856737
857 pub fn parseArchSub(text: []const u8) ParseArchSubError!Arch {738 /// If the OS was determined, this will be populated.
858 const info = @typeInfo(Arch);739 os: ?Os = null,
859 inline for (info.Union.fields) |field| {
860 if (mem.startsWith(u8, text, field.name)) {
861 if (field.field_type == void) {
862 return @as(Arch, @field(Arch, field.name));
863 } else {
864 const sub_info = @typeInfo(field.field_type);
865 inline for (sub_info.Enum.fields) |sub_field| {
866 const combined = field.name ++ sub_field.name;
867 if (mem.eql(u8, text, combined)) {
868 return @unionInit(Arch, field.name, @field(field.field_type, sub_field.name));
869 }
870 }
871 return error.UnknownSubArchitecture;
872 }
873 }
874 }
875 return error.UnknownArchitecture;
876 }
877740
878 pub fn parseOs(text: []const u8) !Os {741 /// If the ABI was determined, this will be populated.
879 const info = @typeInfo(Os);742 abi: ?Abi = null,
880 inline for (info.Enum.fields) |field| {
881 if (mem.eql(u8, text, field.name)) {
882 return @field(Os, field.name);
883 }
884 }
885 return error.UnknownOperatingSystem;
886 }
887743
888 pub fn parseAbi(text: []const u8) !Abi {744 /// If the CPU name was determined, this will be populated.
889 const info = @typeInfo(Abi);745 cpu_name: ?[]const u8 = null,
890 inline for (info.Enum.fields) |field| {
891 if (mem.eql(u8, text, field.name)) {
892 return @field(Abi, field.name);
893 }
894 }
895 return error.UnknownApplicationBinaryInterface;
896 }
897746
898 fn archSubArchName(arch: Arch) []const u8 {747 /// If error.UnknownCpuFeature is returned, this will be populated.
899 return switch (arch) {748 unknown_feature_name: ?[]const u8 = null,
900 .arm => |sub| @tagName(sub),
901 .armeb => |sub| @tagName(sub),
902 .thumb => |sub| @tagName(sub),
903 .thumbeb => |sub| @tagName(sub),
904 .aarch64 => |sub| @tagName(sub),
905 .aarch64_be => |sub| @tagName(sub),
906 .kalimba => |sub| @tagName(sub),
907 else => "",
908 };749 };
909 }750 };
910751
911 pub fn subArchName(self: Target) []const u8 {752 pub fn parse(args: ParseOptions) !Target {
912 switch (self) {753 var dummy_diags: ParseOptions.Diagnostics = undefined;
913 .Native => return archSubArchName(builtin.arch),754 var diags = args.diagnostics orelse &dummy_diags;
914 .Cross => |cross| return archSubArchName(cross.arch),755
756 var it = mem.separate(args.arch_os_abi, "-");
757 const arch_name = it.next() orelse return error.MissingArchitecture;
758 const arch = try Cpu.Arch.parse(arch_name);
759 diags.arch = arch;
760
761 const os_name = it.next() orelse return error.MissingOperatingSystem;
762 const os = try Os.parse(os_name);
763 diags.os = os;
764
765 const abi_name = it.next();
766 const abi = if (abi_name) |n| try Abi.parse(n) else Abi.default(arch, os);
767 diags.abi = abi;
768
769 if (it.next() != null) return error.UnexpectedExtraField;
770
771 const all_features = arch.allFeaturesList();
772 var index: usize = 0;
773 while (index < args.cpu_features.len and
774 args.cpu_features[index] != '+' and
775 args.cpu_features[index] != '-')
776 {
777 index += 1;
915 }778 }
779 const cpu_name = args.cpu_features[0..index];
780 diags.cpu_name = cpu_name;
781
782 const cpu: Cpu = if (mem.eql(u8, cpu_name, "baseline")) Cpu.baseline(arch) else blk: {
783 const cpu_model = try arch.parseCpuModel(cpu_name);
784
785 var set = cpu_model.features;
786 while (index < args.cpu_features.len) {
787 const op = args.cpu_features[index];
788 index += 1;
789 const start = index;
790 while (index < args.cpu_features.len and
791 args.cpu_features[index] != '+' and
792 args.cpu_features[index] != '-')
793 {
794 index += 1;
795 }
796 const feature_name = args.cpu_features[start..index];
797 for (all_features) |feature, feat_index_usize| {
798 const feat_index = @intCast(Cpu.Feature.Set.Index, feat_index_usize);
799 if (mem.eql(u8, feature_name, feature.name)) {
800 switch (op) {
801 '+' => set.addFeature(feat_index),
802 '-' => set.removeFeature(feat_index),
803 else => unreachable,
804 }
805 break;
806 }
807 } else {
808 diags.unknown_feature_name = feature_name;
809 return error.UnknownCpuFeature;
810 }
811 }
812 set.populateDependencies(all_features);
813 break :blk .{
814 .arch = arch,
815 .model = cpu_model,
816 .features = set,
817 };
818 };
819 var cross = Cross{
820 .cpu = cpu,
821 .os = os,
822 .abi = abi,
823 };
824 return Target{ .Cross = cross };
916 }825 }
917826
918 pub fn oFileExt(self: Target) []const u8 {827 pub fn oFileExt(self: Target) []const u8 {
...@@ -971,11 +880,15 @@ pub const Target = union(enum) {...@@ -971,11 +880,15 @@ pub const Target = union(enum) {
971 };880 };
972 }881 }
973882
974 pub fn getArch(self: Target) Arch {883 pub fn getCpu(self: Target) Cpu {
975 switch (self) {884 return switch (self) {
976 .Native => return builtin.arch,885 .Native => builtin.cpu,
977 .Cross => |t| return t.arch,886 .Cross => |cross| cross.cpu,
978 }887 };
888 }
889
890 pub fn getArch(self: Target) Cpu.Arch {
891 return self.getCpu().arch;
979 }892 }
980893
981 pub fn getAbi(self: Target) Abi {894 pub fn getAbi(self: Target) Abi {
...@@ -1041,6 +954,20 @@ pub const Target = union(enum) {...@@ -1041,6 +954,20 @@ pub const Target = union(enum) {
1041 };954 };
1042 }955 }
1043956
957 pub fn isAndroid(self: Target) bool {
958 return switch (self.getAbi()) {
959 .android => true,
960 else => false,
961 };
962 }
963
964 pub fn isDragonFlyBSD(self: Target) bool {
965 return switch (self.getOs()) {
966 .dragonfly => true,
967 else => false,
968 };
969 }
970
1044 pub fn isUefi(self: Target) bool {971 pub fn isUefi(self: Target) bool {
1045 return switch (self.getOs()) {972 return switch (self.getOs()) {
1046 .uefi => true,973 .uefi => true,
...@@ -1194,16 +1121,202 @@ pub const Target = union(enum) {...@@ -1194,16 +1121,202 @@ pub const Target = union(enum) {
11941121
1195 return .unavailable;1122 return .unavailable;
1196 }1123 }
1124
1125 pub const FloatAbi = enum {
1126 hard,
1127 soft,
1128 soft_fp,
1129 };
1130
1131 pub fn getFloatAbi(self: Target) FloatAbi {
1132 return switch (self.getAbi()) {
1133 .gnueabihf,
1134 .eabihf,
1135 .musleabihf,
1136 => .hard,
1137 else => .soft,
1138 };
1139 }
1140
1141 pub fn hasDynamicLinker(self: Target) bool {
1142 switch (self.getArch()) {
1143 .wasm32,
1144 .wasm64,
1145 => return false,
1146 else => {},
1147 }
1148 switch (self.getOs()) {
1149 .freestanding,
1150 .ios,
1151 .tvos,
1152 .watchos,
1153 .macosx,
1154 .uefi,
1155 .windows,
1156 .emscripten,
1157 .other,
1158 => return false,
1159 else => return true,
1160 }
1161 }
1162
1163 /// Caller owns returned memory.
1164 pub fn getStandardDynamicLinkerPath(
1165 self: Target,
1166 allocator: *mem.Allocator,
1167 ) error{
1168 OutOfMemory,
1169 UnknownDynamicLinkerPath,
1170 TargetHasNoDynamicLinker,
1171 }![:0]u8 {
1172 const a = allocator;
1173 if (self.isAndroid()) {
1174 return mem.dupeZ(a, u8, if (self.getArchPtrBitWidth() == 64)
1175 "/system/bin/linker64"
1176 else
1177 "/system/bin/linker");
1178 }
1179
1180 if (self.isMusl()) {
1181 var result = try std.Buffer.init(allocator, "/lib/ld-musl-");
1182 defer result.deinit();
1183
1184 var is_arm = false;
1185 switch (self.getArch()) {
1186 .arm, .thumb => {
1187 try result.append("arm");
1188 is_arm = true;
1189 },
1190 .armeb, .thumbeb => {
1191 try result.append("armeb");
1192 is_arm = true;
1193 },
1194 else => |arch| try result.append(@tagName(arch)),
1195 }
1196 if (is_arm and self.getFloatAbi() == .hard) {
1197 try result.append("hf");
1198 }
1199 try result.append(".so.1");
1200 return result.toOwnedSlice();
1201 }
1202
1203 switch (self.getOs()) {
1204 .freebsd => return mem.dupeZ(a, u8, "/libexec/ld-elf.so.1"),
1205 .netbsd => return mem.dupeZ(a, u8, "/libexec/ld.elf_so"),
1206 .dragonfly => return mem.dupeZ(a, u8, "/libexec/ld-elf.so.2"),
1207 .linux => switch (self.getArch()) {
1208 .i386,
1209 .sparc,
1210 .sparcel,
1211 => return mem.dupeZ(a, u8, "/lib/ld-linux.so.2"),
1212
1213 .aarch64 => return mem.dupeZ(a, u8, "/lib/ld-linux-aarch64.so.1"),
1214 .aarch64_be => return mem.dupeZ(a, u8, "/lib/ld-linux-aarch64_be.so.1"),
1215 .aarch64_32 => return mem.dupeZ(a, u8, "/lib/ld-linux-aarch64_32.so.1"),
1216
1217 .arm,
1218 .armeb,
1219 .thumb,
1220 .thumbeb,
1221 => return mem.dupeZ(a, u8, switch (self.getFloatAbi()) {
1222 .hard => "/lib/ld-linux-armhf.so.3",
1223 else => "/lib/ld-linux.so.3",
1224 }),
1225
1226 .mips,
1227 .mipsel,
1228 .mips64,
1229 .mips64el,
1230 => return error.UnknownDynamicLinkerPath,
1231
1232 .powerpc => return mem.dupeZ(a, u8, "/lib/ld.so.1"),
1233 .powerpc64, .powerpc64le => return mem.dupeZ(a, u8, "/lib64/ld64.so.2"),
1234 .s390x => return mem.dupeZ(a, u8, "/lib64/ld64.so.1"),
1235 .sparcv9 => return mem.dupeZ(a, u8, "/lib64/ld-linux.so.2"),
1236 .x86_64 => return mem.dupeZ(a, u8, switch (self.getAbi()) {
1237 .gnux32 => "/libx32/ld-linux-x32.so.2",
1238 else => "/lib64/ld-linux-x86-64.so.2",
1239 }),
1240
1241 .riscv32 => return mem.dupeZ(a, u8, "/lib/ld-linux-riscv32-ilp32.so.1"),
1242 .riscv64 => return mem.dupeZ(a, u8, "/lib/ld-linux-riscv64-lp64.so.1"),
1243
1244 .wasm32,
1245 .wasm64,
1246 => return error.TargetHasNoDynamicLinker,
1247
1248 .arc,
1249 .avr,
1250 .bpfel,
1251 .bpfeb,
1252 .hexagon,
1253 .msp430,
1254 .r600,
1255 .amdgcn,
1256 .tce,
1257 .tcele,
1258 .xcore,
1259 .nvptx,
1260 .nvptx64,
1261 .le32,
1262 .le64,
1263 .amdil,
1264 .amdil64,
1265 .hsail,
1266 .hsail64,
1267 .spir,
1268 .spir64,
1269 .kalimba,
1270 .shave,
1271 .lanai,
1272 .renderscript32,
1273 .renderscript64,
1274 .ve,
1275 => return error.UnknownDynamicLinkerPath,
1276 },
1277
1278 .freestanding,
1279 .ios,
1280 .tvos,
1281 .watchos,
1282 .macosx,
1283 .uefi,
1284 .windows,
1285 .emscripten,
1286 .other,
1287 => return error.TargetHasNoDynamicLinker,
1288
1289 else => return error.UnknownDynamicLinkerPath,
1290 }
1291 }
1197};1292};
11981293
1199test "parseCpuFeatureSet" {1294test "Target.parse" {
1200 const arch: Target.Arch = .x86_64;1295 {
1201 const baseline = arch.getBaselineCpuFeatures();1296 const target = (try Target.parse(.{
1202 const set = try arch.parseCpuFeatureSet(baseline.cpu, "-sse,-avx,-cx8");1297 .arch_os_abi = "x86_64-linux-gnu",
1203 std.testing.expect(!Target.x86.featureSetHas(set, .sse));1298 .cpu_features = "x86_64-sse-sse2-avx-cx8",
1204 std.testing.expect(!Target.x86.featureSetHas(set, .avx));1299 })).Cross;
1205 std.testing.expect(!Target.x86.featureSetHas(set, .cx8));1300
1206 // These are expected because they are part of the baseline1301 std.testing.expect(target.os == .linux);
1207 std.testing.expect(Target.x86.featureSetHas(set, .cmov));1302 std.testing.expect(target.abi == .gnu);
1208 std.testing.expect(Target.x86.featureSetHas(set, .fxsr));1303 std.testing.expect(target.cpu.arch == .x86_64);
1304 std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .sse));
1305 std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .avx));
1306 std.testing.expect(!Target.x86.featureSetHas(target.cpu.features, .cx8));
1307 std.testing.expect(Target.x86.featureSetHas(target.cpu.features, .cmov));
1308 std.testing.expect(Target.x86.featureSetHas(target.cpu.features, .fxsr));
1309 }
1310 {
1311 const target = (try Target.parse(.{
1312 .arch_os_abi = "arm-linux-musleabihf",
1313 .cpu_features = "generic+v8a",
1314 })).Cross;
1315
1316 std.testing.expect(target.os == .linux);
1317 std.testing.expect(target.abi == .musleabihf);
1318 std.testing.expect(target.cpu.arch == .arm);
1319 std.testing.expect(target.cpu.model == &Target.arm.cpu.generic);
1320 std.testing.expect(Target.arm.featureSetHas(target.cpu.features, .v8a));
1321 }
1209}1322}
lib/std/target/aarch64.zig+201-373
...@@ -1,15 +1,9 @@...@@ -1,15 +1,9 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2const Cpu = std.Target.Cpu;2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
34
4pub const Feature = enum {5pub const Feature = enum {
5 a35,
6 a53,
7 a55,
8 a57,
9 a65,6 a65,
10 a72,
11 a73,
12 a75,
13 a76,7 a76,
14 aes,8 aes,
15 aggressive_fma,9 aggressive_fma,
...@@ -46,11 +40,7 @@ pub const Feature = enum {...@@ -46,11 +40,7 @@ pub const Feature = enum {
46 dotprod,40 dotprod,
47 ete,41 ete,
48 exynos_cheap_as_move,42 exynos_cheap_as_move,
49 exynosm1,
50 exynosm2,
51 exynosm3,
52 exynosm4,43 exynosm4,
53 falkor,
54 fmi,44 fmi,
55 force_32bit_jump_tables,45 force_32bit_jump_tables,
56 fp_armv8,46 fp_armv8,
...@@ -64,7 +54,6 @@ pub const Feature = enum {...@@ -64,7 +54,6 @@ pub const Feature = enum {
64 fuse_csel,54 fuse_csel,
65 fuse_literals,55 fuse_literals,
66 jsconv,56 jsconv,
67 kryo,
68 lor,57 lor,
69 lse,58 lse,
70 lsl_fast,59 lsl_fast,
...@@ -112,7 +101,6 @@ pub const Feature = enum {...@@ -112,7 +101,6 @@ pub const Feature = enum {
112 reserve_x6,101 reserve_x6,
113 reserve_x7,102 reserve_x7,
114 reserve_x9,103 reserve_x9,
115 saphira,
116 sb,104 sb,
117 sel2,105 sel2,
118 sha2,106 sha2,
...@@ -132,11 +120,6 @@ pub const Feature = enum {...@@ -132,11 +120,6 @@ pub const Feature = enum {
132 sve2_sha3,120 sve2_sha3,
133 sve2_sm4,121 sve2_sm4,
134 tagged_globals,122 tagged_globals,
135 thunderx,
136 thunderx2t99,
137 thunderxt81,
138 thunderxt83,
139 thunderxt88,
140 tlb_rmi,123 tlb_rmi,
141 tme,124 tme,
142 tpidr_el1,125 tpidr_el1,
...@@ -144,7 +127,6 @@ pub const Feature = enum {...@@ -144,7 +127,6 @@ pub const Feature = enum {
144 tpidr_el3,127 tpidr_el3,
145 tracev8_4,128 tracev8_4,
146 trbe,129 trbe,
147 tsv110,
148 uaops,130 uaops,
149 use_aa,131 use_aa,
150 use_postra_scheduler,132 use_postra_scheduler,
...@@ -163,72 +145,13 @@ pub const Feature = enum {...@@ -163,72 +145,13 @@ pub const Feature = enum {
163 zcz_gp,145 zcz_gp,
164};146};
165147
166pub usingnamespace Cpu.Feature.feature_set_fns(Feature);148pub usingnamespace CpuFeature.feature_set_fns(Feature);
167149
168pub const all_features = blk: {150pub const all_features = blk: {
169 @setEvalBranchQuota(2000);151 @setEvalBranchQuota(2000);
170 const len = @typeInfo(Feature).Enum.fields.len;152 const len = @typeInfo(Feature).Enum.fields.len;
171 std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);153 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
172 var result: [len]Cpu.Feature = undefined;154 var result: [len]CpuFeature = undefined;
173 result[@enumToInt(Feature.a35)] = .{
174 .llvm_name = "a35",
175 .description = "Cortex-A35 ARM processors",
176 .dependencies = featureSet(&[_]Feature{
177 .crc,
178 .crypto,
179 .fp_armv8,
180 .neon,
181 .perfmon,
182 }),
183 };
184 result[@enumToInt(Feature.a53)] = .{
185 .llvm_name = "a53",
186 .description = "Cortex-A53 ARM processors",
187 .dependencies = featureSet(&[_]Feature{
188 .balance_fp_ops,
189 .crc,
190 .crypto,
191 .custom_cheap_as_move,
192 .fp_armv8,
193 .fuse_aes,
194 .neon,
195 .perfmon,
196 .use_aa,
197 .use_postra_scheduler,
198 }),
199 };
200 result[@enumToInt(Feature.a55)] = .{
201 .llvm_name = "a55",
202 .description = "Cortex-A55 ARM processors",
203 .dependencies = featureSet(&[_]Feature{
204 .crypto,
205 .dotprod,
206 .fp_armv8,
207 .fullfp16,
208 .fuse_aes,
209 .neon,
210 .perfmon,
211 .rcpc,
212 .v8_2a,
213 }),
214 };
215 result[@enumToInt(Feature.a57)] = .{
216 .llvm_name = "a57",
217 .description = "Cortex-A57 ARM processors",
218 .dependencies = featureSet(&[_]Feature{
219 .balance_fp_ops,
220 .crc,
221 .crypto,
222 .custom_cheap_as_move,
223 .fp_armv8,
224 .fuse_aes,
225 .fuse_literals,
226 .neon,
227 .perfmon,
228 .predictable_select_expensive,
229 .use_postra_scheduler,
230 }),
231 };
232 result[@enumToInt(Feature.a65)] = .{155 result[@enumToInt(Feature.a65)] = .{
233 .llvm_name = "a65",156 .llvm_name = "a65",
234 .description = "Cortex-A65 ARM processors",157 .description = "Cortex-A65 ARM processors",
...@@ -244,54 +167,13 @@ pub const all_features = blk: {...@@ -244,54 +167,13 @@ pub const all_features = blk: {
244 .v8_2a,167 .v8_2a,
245 }),168 }),
246 };169 };
247 result[@enumToInt(Feature.a72)] = .{
248 .llvm_name = "a72",
249 .description = "Cortex-A72 ARM processors",
250 .dependencies = featureSet(&[_]Feature{
251 .crc,
252 .crypto,
253 .fp_armv8,
254 .fuse_aes,
255 .neon,
256 .perfmon,
257 }),
258 };
259 result[@enumToInt(Feature.a73)] = .{
260 .llvm_name = "a73",
261 .description = "Cortex-A73 ARM processors",
262 .dependencies = featureSet(&[_]Feature{
263 .crc,
264 .crypto,
265 .fp_armv8,
266 .fuse_aes,
267 .neon,
268 .perfmon,
269 }),
270 };
271 result[@enumToInt(Feature.a75)] = .{
272 .llvm_name = "a75",
273 .description = "Cortex-A75 ARM processors",
274 .dependencies = featureSet(&[_]Feature{
275 .crypto,
276 .dotprod,
277 .fp_armv8,
278 .fullfp16,
279 .fuse_aes,
280 .neon,
281 .perfmon,
282 .rcpc,
283 .v8_2a,
284 }),
285 };
286 result[@enumToInt(Feature.a76)] = .{170 result[@enumToInt(Feature.a76)] = .{
287 .llvm_name = "a76",171 .llvm_name = "a76",
288 .description = "Cortex-A76 ARM processors",172 .description = "Cortex-A76 ARM processors",
289 .dependencies = featureSet(&[_]Feature{173 .dependencies = featureSet(&[_]Feature{
290 .crypto,174 .crypto,
291 .dotprod,175 .dotprod,
292 .fp_armv8,
293 .fullfp16,176 .fullfp16,
294 .neon,
295 .rcpc,177 .rcpc,
296 .ssbs,178 .ssbs,
297 .v8_2a,179 .v8_2a,
...@@ -563,58 +445,6 @@ pub const all_features = blk: {...@@ -563,58 +445,6 @@ pub const all_features = blk: {
563 .custom_cheap_as_move,445 .custom_cheap_as_move,
564 }),446 }),
565 };447 };
566 result[@enumToInt(Feature.exynosm1)] = .{
567 .llvm_name = null,
568 .description = "Samsung Exynos-M1 processors",
569 .dependencies = featureSet(&[_]Feature{
570 .crc,
571 .crypto,
572 .exynos_cheap_as_move,
573 .force_32bit_jump_tables,
574 .fuse_aes,
575 .perfmon,
576 .slow_misaligned_128store,
577 .slow_paired_128,
578 .use_postra_scheduler,
579 .use_reciprocal_square_root,
580 .zcz_fp,
581 }),
582 };
583 result[@enumToInt(Feature.exynosm2)] = .{
584 .llvm_name = null,
585 .description = "Samsung Exynos-M2 processors",
586 .dependencies = featureSet(&[_]Feature{
587 .crc,
588 .crypto,
589 .exynos_cheap_as_move,
590 .force_32bit_jump_tables,
591 .fuse_aes,
592 .perfmon,
593 .slow_misaligned_128store,
594 .slow_paired_128,
595 .use_postra_scheduler,
596 .zcz_fp,
597 }),
598 };
599 result[@enumToInt(Feature.exynosm3)] = .{
600 .llvm_name = "exynosm3",
601 .description = "Samsung Exynos-M3 processors",
602 .dependencies = featureSet(&[_]Feature{
603 .crc,
604 .crypto,
605 .exynos_cheap_as_move,
606 .force_32bit_jump_tables,
607 .fuse_address,
608 .fuse_aes,
609 .fuse_csel,
610 .fuse_literals,
611 .lsl_fast,
612 .perfmon,
613 .predictable_select_expensive,
614 .use_postra_scheduler,
615 .zcz_fp,
616 }),
617 };
618 result[@enumToInt(Feature.exynosm4)] = .{448 result[@enumToInt(Feature.exynosm4)] = .{
619 .llvm_name = "exynosm4",449 .llvm_name = "exynosm4",
620 .description = "Samsung Exynos-M4 processors",450 .description = "Samsung Exynos-M4 processors",
...@@ -638,24 +468,6 @@ pub const all_features = blk: {...@@ -638,24 +468,6 @@ pub const all_features = blk: {
638 .zcz,468 .zcz,
639 }),469 }),
640 };470 };
641 result[@enumToInt(Feature.falkor)] = .{
642 .llvm_name = "falkor",
643 .description = "Qualcomm Falkor processors",
644 .dependencies = featureSet(&[_]Feature{
645 .crc,
646 .crypto,
647 .custom_cheap_as_move,
648 .fp_armv8,
649 .lsl_fast,
650 .neon,
651 .perfmon,
652 .predictable_select_expensive,
653 .rdm,
654 .slow_strqro_store,
655 .use_postra_scheduler,
656 .zcz,
657 }),
658 };
659 result[@enumToInt(Feature.fmi)] = .{471 result[@enumToInt(Feature.fmi)] = .{
660 .llvm_name = "fmi",472 .llvm_name = "fmi",
661 .description = "Enable v8.4-A Flag Manipulation Instructions",473 .description = "Enable v8.4-A Flag Manipulation Instructions",
...@@ -727,22 +539,6 @@ pub const all_features = blk: {...@@ -727,22 +539,6 @@ pub const all_features = blk: {
727 .fp_armv8,539 .fp_armv8,
728 }),540 }),
729 };541 };
730 result[@enumToInt(Feature.kryo)] = .{
731 .llvm_name = "kryo",
732 .description = "Qualcomm Kryo processors",
733 .dependencies = featureSet(&[_]Feature{
734 .crc,
735 .crypto,
736 .custom_cheap_as_move,
737 .fp_armv8,
738 .lsl_fast,
739 .neon,
740 .perfmon,
741 .predictable_select_expensive,
742 .use_postra_scheduler,
743 .zcz,
744 }),
745 };
746 result[@enumToInt(Feature.lor)] = .{542 result[@enumToInt(Feature.lor)] = .{
747 .llvm_name = "lor",543 .llvm_name = "lor",
748 .description = "Enables ARM v8.1 Limited Ordering Regions extension",544 .description = "Enables ARM v8.1 Limited Ordering Regions extension",
...@@ -1005,23 +801,6 @@ pub const all_features = blk: {...@@ -1005,23 +801,6 @@ pub const all_features = blk: {
1005 .description = "Reserve X9, making it unavailable as a GPR",801 .description = "Reserve X9, making it unavailable as a GPR",
1006 .dependencies = featureSet(&[_]Feature{}),802 .dependencies = featureSet(&[_]Feature{}),
1007 };803 };
1008 result[@enumToInt(Feature.saphira)] = .{
1009 .llvm_name = "saphira",
1010 .description = "Qualcomm Saphira processors",
1011 .dependencies = featureSet(&[_]Feature{
1012 .crypto,
1013 .custom_cheap_as_move,
1014 .fp_armv8,
1015 .lsl_fast,
1016 .neon,
1017 .perfmon,
1018 .predictable_select_expensive,
1019 .spe,
1020 .use_postra_scheduler,
1021 .v8_4a,
1022 .zcz,
1023 }),
1024 };
1025 result[@enumToInt(Feature.sb)] = .{804 result[@enumToInt(Feature.sb)] = .{
1026 .llvm_name = "sb",805 .llvm_name = "sb",
1027 .description = "Enable v8.5 Speculation Barrier",806 .description = "Enable v8.5 Speculation Barrier",
...@@ -1137,74 +916,6 @@ pub const all_features = blk: {...@@ -1137,74 +916,6 @@ pub const all_features = blk: {
1137 .description = "Use an instruction sequence for taking the address of a global that allows a memory tag in the upper address bits",916 .description = "Use an instruction sequence for taking the address of a global that allows a memory tag in the upper address bits",
1138 .dependencies = featureSet(&[_]Feature{}),917 .dependencies = featureSet(&[_]Feature{}),
1139 };918 };
1140 result[@enumToInt(Feature.thunderx)] = .{
1141 .llvm_name = "thunderx",
1142 .description = "Cavium ThunderX processors",
1143 .dependencies = featureSet(&[_]Feature{
1144 .crc,
1145 .crypto,
1146 .fp_armv8,
1147 .neon,
1148 .perfmon,
1149 .predictable_select_expensive,
1150 .use_postra_scheduler,
1151 }),
1152 };
1153 result[@enumToInt(Feature.thunderx2t99)] = .{
1154 .llvm_name = "thunderx2t99",
1155 .description = "Cavium ThunderX2 processors",
1156 .dependencies = featureSet(&[_]Feature{
1157 .aggressive_fma,
1158 .arith_bcc_fusion,
1159 .crc,
1160 .crypto,
1161 .fp_armv8,
1162 .lse,
1163 .neon,
1164 .predictable_select_expensive,
1165 .use_postra_scheduler,
1166 .v8_1a,
1167 }),
1168 };
1169 result[@enumToInt(Feature.thunderxt81)] = .{
1170 .llvm_name = "thunderxt81",
1171 .description = "Cavium ThunderX processors",
1172 .dependencies = featureSet(&[_]Feature{
1173 .crc,
1174 .crypto,
1175 .fp_armv8,
1176 .neon,
1177 .perfmon,
1178 .predictable_select_expensive,
1179 .use_postra_scheduler,
1180 }),
1181 };
1182 result[@enumToInt(Feature.thunderxt83)] = .{
1183 .llvm_name = "thunderxt83",
1184 .description = "Cavium ThunderX processors",
1185 .dependencies = featureSet(&[_]Feature{
1186 .crc,
1187 .crypto,
1188 .fp_armv8,
1189 .neon,
1190 .perfmon,
1191 .predictable_select_expensive,
1192 .use_postra_scheduler,
1193 }),
1194 };
1195 result[@enumToInt(Feature.thunderxt88)] = .{
1196 .llvm_name = "thunderxt88",
1197 .description = "Cavium ThunderX processors",
1198 .dependencies = featureSet(&[_]Feature{
1199 .crc,
1200 .crypto,
1201 .fp_armv8,
1202 .neon,
1203 .perfmon,
1204 .predictable_select_expensive,
1205 .use_postra_scheduler,
1206 }),
1207 };
1208 result[@enumToInt(Feature.tlb_rmi)] = .{919 result[@enumToInt(Feature.tlb_rmi)] = .{
1209 .llvm_name = "tlb-rmi",920 .llvm_name = "tlb-rmi",
1210 .description = "Enable v8.4-A TLB Range and Maintenance Instructions",921 .description = "Enable v8.4-A TLB Range and Maintenance Instructions",
...@@ -1240,24 +951,6 @@ pub const all_features = blk: {...@@ -1240,24 +951,6 @@ pub const all_features = blk: {
1240 .description = "Enable Trace Buffer Extension",951 .description = "Enable Trace Buffer Extension",
1241 .dependencies = featureSet(&[_]Feature{}),952 .dependencies = featureSet(&[_]Feature{}),
1242 };953 };
1243 result[@enumToInt(Feature.tsv110)] = .{
1244 .llvm_name = "tsv110",
1245 .description = "HiSilicon TS-V110 processors",
1246 .dependencies = featureSet(&[_]Feature{
1247 .crypto,
1248 .custom_cheap_as_move,
1249 .dotprod,
1250 .fp_armv8,
1251 .fp16fml,
1252 .fullfp16,
1253 .fuse_aes,
1254 .neon,
1255 .perfmon,
1256 .spe,
1257 .use_postra_scheduler,
1258 .v8_2a,
1259 }),
1260 };
1261 result[@enumToInt(Feature.uaops)] = .{954 result[@enumToInt(Feature.uaops)] = .{
1262 .llvm_name = "uaops",955 .llvm_name = "uaops",
1263 .description = "Enable v8.2 UAO PState",956 .description = "Enable v8.2 UAO PState",
...@@ -1398,282 +1091,417 @@ pub const all_features = blk: {...@@ -1398,282 +1091,417 @@ pub const all_features = blk: {
1398};1091};
13991092
1400pub const cpu = struct {1093pub const cpu = struct {
1401 pub const apple_a10 = Cpu{1094 pub const apple_a10 = CpuModel{
1402 .name = "apple_a10",1095 .name = "apple_a10",
1403 .llvm_name = "apple-a10",1096 .llvm_name = "apple-a10",
1404 .features = featureSet(&[_]Feature{1097 .features = featureSet(&[_]Feature{
1405 .apple_a10,1098 .apple_a10,
1406 }),1099 }),
1407 };1100 };
1408 pub const apple_a11 = Cpu{1101 pub const apple_a11 = CpuModel{
1409 .name = "apple_a11",1102 .name = "apple_a11",
1410 .llvm_name = "apple-a11",1103 .llvm_name = "apple-a11",
1411 .features = featureSet(&[_]Feature{1104 .features = featureSet(&[_]Feature{
1412 .apple_a11,1105 .apple_a11,
1413 }),1106 }),
1414 };1107 };
1415 pub const apple_a12 = Cpu{1108 pub const apple_a12 = CpuModel{
1416 .name = "apple_a12",1109 .name = "apple_a12",
1417 .llvm_name = "apple-a12",1110 .llvm_name = "apple-a12",
1418 .features = featureSet(&[_]Feature{1111 .features = featureSet(&[_]Feature{
1419 .apple_a12,1112 .apple_a12,
1420 }),1113 }),
1421 };1114 };
1422 pub const apple_a13 = Cpu{1115 pub const apple_a13 = CpuModel{
1423 .name = "apple_a13",1116 .name = "apple_a13",
1424 .llvm_name = "apple-a13",1117 .llvm_name = "apple-a13",
1425 .features = featureSet(&[_]Feature{1118 .features = featureSet(&[_]Feature{
1426 .apple_a13,1119 .apple_a13,
1427 }),1120 }),
1428 };1121 };
1429 pub const apple_a7 = Cpu{1122 pub const apple_a7 = CpuModel{
1430 .name = "apple_a7",1123 .name = "apple_a7",
1431 .llvm_name = "apple-a7",1124 .llvm_name = "apple-a7",
1432 .features = featureSet(&[_]Feature{1125 .features = featureSet(&[_]Feature{
1433 .apple_a7,1126 .apple_a7,
1434 }),1127 }),
1435 };1128 };
1436 pub const apple_a8 = Cpu{1129 pub const apple_a8 = CpuModel{
1437 .name = "apple_a8",1130 .name = "apple_a8",
1438 .llvm_name = "apple-a8",1131 .llvm_name = "apple-a8",
1439 .features = featureSet(&[_]Feature{1132 .features = featureSet(&[_]Feature{
1440 .apple_a7,1133 .apple_a7,
1441 }),1134 }),
1442 };1135 };
1443 pub const apple_a9 = Cpu{1136 pub const apple_a9 = CpuModel{
1444 .name = "apple_a9",1137 .name = "apple_a9",
1445 .llvm_name = "apple-a9",1138 .llvm_name = "apple-a9",
1446 .features = featureSet(&[_]Feature{1139 .features = featureSet(&[_]Feature{
1447 .apple_a7,1140 .apple_a7,
1448 }),1141 }),
1449 };1142 };
1450 pub const apple_latest = Cpu{1143 pub const apple_latest = CpuModel{
1451 .name = "apple_latest",1144 .name = "apple_latest",
1452 .llvm_name = "apple-latest",1145 .llvm_name = "apple-latest",
1453 .features = featureSet(&[_]Feature{1146 .features = featureSet(&[_]Feature{
1454 .apple_a13,1147 .apple_a13,
1455 }),1148 }),
1456 };1149 };
1457 pub const apple_s4 = Cpu{1150 pub const apple_s4 = CpuModel{
1458 .name = "apple_s4",1151 .name = "apple_s4",
1459 .llvm_name = "apple-s4",1152 .llvm_name = "apple-s4",
1460 .features = featureSet(&[_]Feature{1153 .features = featureSet(&[_]Feature{
1461 .apple_a12,1154 .apple_a12,
1462 }),1155 }),
1463 };1156 };
1464 pub const apple_s5 = Cpu{1157 pub const apple_s5 = CpuModel{
1465 .name = "apple_s5",1158 .name = "apple_s5",
1466 .llvm_name = "apple-s5",1159 .llvm_name = "apple-s5",
1467 .features = featureSet(&[_]Feature{1160 .features = featureSet(&[_]Feature{
1468 .apple_a12,1161 .apple_a12,
1469 }),1162 }),
1470 };1163 };
1471 pub const cortex_a35 = Cpu{1164 pub const cortex_a35 = CpuModel{
1472 .name = "cortex_a35",1165 .name = "cortex_a35",
1473 .llvm_name = "cortex-a35",1166 .llvm_name = "cortex-a35",
1474 .features = featureSet(&[_]Feature{1167 .features = featureSet(&[_]Feature{
1475 .a35,1168 .crc,
1169 .crypto,
1170 .perfmon,
1171 .v8a,
1476 }),1172 }),
1477 };1173 };
1478 pub const cortex_a53 = Cpu{1174 pub const cortex_a53 = CpuModel{
1479 .name = "cortex_a53",1175 .name = "cortex_a53",
1480 .llvm_name = "cortex-a53",1176 .llvm_name = "cortex-a53",
1481 .features = featureSet(&[_]Feature{1177 .features = featureSet(&[_]Feature{
1482 .a53,1178 .balance_fp_ops,
1179 .crc,
1180 .crypto,
1181 .custom_cheap_as_move,
1182 .fuse_aes,
1183 .perfmon,
1184 .use_aa,
1185 .use_postra_scheduler,
1186 .v8a,
1483 }),1187 }),
1484 };1188 };
1485 pub const cortex_a55 = Cpu{1189 pub const cortex_a55 = CpuModel{
1486 .name = "cortex_a55",1190 .name = "cortex_a55",
1487 .llvm_name = "cortex-a55",1191 .llvm_name = "cortex-a55",
1488 .features = featureSet(&[_]Feature{1192 .features = featureSet(&[_]Feature{
1489 .a55,1193 .crypto,
1194 .dotprod,
1195 .fullfp16,
1196 .fuse_aes,
1197 .perfmon,
1198 .rcpc,
1199 .v8_2a,
1490 }),1200 }),
1491 };1201 };
1492 pub const cortex_a57 = Cpu{1202 pub const cortex_a57 = CpuModel{
1493 .name = "cortex_a57",1203 .name = "cortex_a57",
1494 .llvm_name = "cortex-a57",1204 .llvm_name = "cortex-a57",
1495 .features = featureSet(&[_]Feature{1205 .features = featureSet(&[_]Feature{
1496 .a57,1206 .balance_fp_ops,
1207 .crc,
1208 .crypto,
1209 .custom_cheap_as_move,
1210 .fuse_aes,
1211 .fuse_literals,
1212 .perfmon,
1213 .predictable_select_expensive,
1214 .use_postra_scheduler,
1215 .v8a,
1497 }),1216 }),
1498 };1217 };
1499 pub const cortex_a65 = Cpu{1218 pub const cortex_a65 = CpuModel{
1500 .name = "cortex_a65",1219 .name = "cortex_a65",
1501 .llvm_name = "cortex-a65",1220 .llvm_name = "cortex-a65",
1502 .features = featureSet(&[_]Feature{1221 .features = featureSet(&[_]Feature{
1503 .a65,1222 .a65,
1504 }),1223 }),
1505 };1224 };
1506 pub const cortex_a65ae = Cpu{1225 pub const cortex_a65ae = CpuModel{
1507 .name = "cortex_a65ae",1226 .name = "cortex_a65ae",
1508 .llvm_name = "cortex-a65ae",1227 .llvm_name = "cortex-a65ae",
1509 .features = featureSet(&[_]Feature{1228 .features = featureSet(&[_]Feature{
1510 .a65,1229 .a65,
1511 }),1230 }),
1512 };1231 };
1513 pub const cortex_a72 = Cpu{1232 pub const cortex_a72 = CpuModel{
1514 .name = "cortex_a72",1233 .name = "cortex_a72",
1515 .llvm_name = "cortex-a72",1234 .llvm_name = "cortex-a72",
1516 .features = featureSet(&[_]Feature{1235 .features = featureSet(&[_]Feature{
1517 .a72,1236 .crc,
1237 .crypto,
1238 .fuse_aes,
1239 .perfmon,
1240 .v8a,
1518 }),1241 }),
1519 };1242 };
1520 pub const cortex_a73 = Cpu{1243 pub const cortex_a73 = CpuModel{
1521 .name = "cortex_a73",1244 .name = "cortex_a73",
1522 .llvm_name = "cortex-a73",1245 .llvm_name = "cortex-a73",
1523 .features = featureSet(&[_]Feature{1246 .features = featureSet(&[_]Feature{
1524 .a73,1247 .crc,
1248 .crypto,
1249 .fuse_aes,
1250 .perfmon,
1251 .v8a,
1525 }),1252 }),
1526 };1253 };
1527 pub const cortex_a75 = Cpu{1254 pub const cortex_a75 = CpuModel{
1528 .name = "cortex_a75",1255 .name = "cortex_a75",
1529 .llvm_name = "cortex-a75",1256 .llvm_name = "cortex-a75",
1530 .features = featureSet(&[_]Feature{1257 .features = featureSet(&[_]Feature{
1531 .a75,1258 .crypto,
1259 .dotprod,
1260 .fullfp16,
1261 .fuse_aes,
1262 .perfmon,
1263 .rcpc,
1264 .v8_2a,
1532 }),1265 }),
1533 };1266 };
1534 pub const cortex_a76 = Cpu{1267 pub const cortex_a76 = CpuModel{
1535 .name = "cortex_a76",1268 .name = "cortex_a76",
1536 .llvm_name = "cortex-a76",1269 .llvm_name = "cortex-a76",
1537 .features = featureSet(&[_]Feature{1270 .features = featureSet(&[_]Feature{
1538 .a76,1271 .a76,
1539 }),1272 }),
1540 };1273 };
1541 pub const cortex_a76ae = Cpu{1274 pub const cortex_a76ae = CpuModel{
1542 .name = "cortex_a76ae",1275 .name = "cortex_a76ae",
1543 .llvm_name = "cortex-a76ae",1276 .llvm_name = "cortex-a76ae",
1544 .features = featureSet(&[_]Feature{1277 .features = featureSet(&[_]Feature{
1545 .a76,1278 .a76,
1546 }),1279 }),
1547 };1280 };
1548 pub const cyclone = Cpu{1281 pub const cyclone = CpuModel{
1549 .name = "cyclone",1282 .name = "cyclone",
1550 .llvm_name = "cyclone",1283 .llvm_name = "cyclone",
1551 .features = featureSet(&[_]Feature{1284 .features = featureSet(&[_]Feature{
1552 .apple_a7,1285 .apple_a7,
1553 }),1286 }),
1554 };1287 };
1555 pub const exynos_m1 = Cpu{1288 pub const exynos_m1 = CpuModel{
1556 .name = "exynos_m1",1289 .name = "exynos_m1",
1557 .llvm_name = null,1290 .llvm_name = null,
1558 .features = featureSet(&[_]Feature{1291 .features = featureSet(&[_]Feature{
1559 .exynosm1,1292 .crc,
1293 .crypto,
1294 .exynos_cheap_as_move,
1295 .force_32bit_jump_tables,
1296 .fuse_aes,
1297 .perfmon,
1298 .slow_misaligned_128store,
1299 .slow_paired_128,
1300 .use_postra_scheduler,
1301 .use_reciprocal_square_root,
1302 .v8a,
1303 .zcz_fp,
1560 }),1304 }),
1561 };1305 };
1562 pub const exynos_m2 = Cpu{1306 pub const exynos_m2 = CpuModel{
1563 .name = "exynos_m2",1307 .name = "exynos_m2",
1564 .llvm_name = null,1308 .llvm_name = null,
1565 .features = featureSet(&[_]Feature{1309 .features = featureSet(&[_]Feature{
1566 .exynosm2,1310 .crc,
1311 .crypto,
1312 .exynos_cheap_as_move,
1313 .force_32bit_jump_tables,
1314 .fuse_aes,
1315 .perfmon,
1316 .slow_misaligned_128store,
1317 .slow_paired_128,
1318 .use_postra_scheduler,
1319 .v8a,
1320 .zcz_fp,
1567 }),1321 }),
1568 };1322 };
1569 pub const exynos_m3 = Cpu{1323 pub const exynos_m3 = CpuModel{
1570 .name = "exynos_m3",1324 .name = "exynos_m3",
1571 .llvm_name = "exynos-m3",1325 .llvm_name = "exynos-m3",
1572 .features = featureSet(&[_]Feature{1326 .features = featureSet(&[_]Feature{
1573 .exynosm3,1327 .crc,
1328 .crypto,
1329 .exynos_cheap_as_move,
1330 .force_32bit_jump_tables,
1331 .fuse_address,
1332 .fuse_aes,
1333 .fuse_csel,
1334 .fuse_literals,
1335 .lsl_fast,
1336 .perfmon,
1337 .predictable_select_expensive,
1338 .use_postra_scheduler,
1339 .v8a,
1340 .zcz_fp,
1574 }),1341 }),
1575 };1342 };
1576 pub const exynos_m4 = Cpu{1343 pub const exynos_m4 = CpuModel{
1577 .name = "exynos_m4",1344 .name = "exynos_m4",
1578 .llvm_name = "exynos-m4",1345 .llvm_name = "exynos-m4",
1579 .features = featureSet(&[_]Feature{1346 .features = featureSet(&[_]Feature{
1580 .exynosm4,1347 .exynosm4,
1581 }),1348 }),
1582 };1349 };
1583 pub const exynos_m5 = Cpu{1350 pub const exynos_m5 = CpuModel{
1584 .name = "exynos_m5",1351 .name = "exynos_m5",
1585 .llvm_name = "exynos-m5",1352 .llvm_name = "exynos-m5",
1586 .features = featureSet(&[_]Feature{1353 .features = featureSet(&[_]Feature{
1587 .exynosm4,1354 .exynosm4,
1588 }),1355 }),
1589 };1356 };
1590 pub const falkor = Cpu{1357 pub const falkor = CpuModel{
1591 .name = "falkor",1358 .name = "falkor",
1592 .llvm_name = "falkor",1359 .llvm_name = "falkor",
1593 .features = featureSet(&[_]Feature{1360 .features = featureSet(&[_]Feature{
1594 .falkor,1361 .crc,
1362 .crypto,
1363 .custom_cheap_as_move,
1364 .lsl_fast,
1365 .perfmon,
1366 .predictable_select_expensive,
1367 .rdm,
1368 .slow_strqro_store,
1369 .use_postra_scheduler,
1370 .v8a,
1371 .zcz,
1595 }),1372 }),
1596 };1373 };
1597 pub const generic = Cpu{1374 pub const generic = CpuModel{
1598 .name = "generic",1375 .name = "generic",
1599 .llvm_name = "generic",1376 .llvm_name = "generic",
1600 .features = featureSet(&[_]Feature{1377 .features = featureSet(&[_]Feature{
1601 .ete,1378 .ete,
1602 .fp_armv8,
1603 .fuse_aes,1379 .fuse_aes,
1604 .neon,
1605 .perfmon,1380 .perfmon,
1606 .use_postra_scheduler,1381 .use_postra_scheduler,
1382 .v8a,
1607 }),1383 }),
1608 };1384 };
1609 pub const kryo = Cpu{1385 pub const kryo = CpuModel{
1610 .name = "kryo",1386 .name = "kryo",
1611 .llvm_name = "kryo",1387 .llvm_name = "kryo",
1612 .features = featureSet(&[_]Feature{1388 .features = featureSet(&[_]Feature{
1613 .kryo,1389 .crc,
1390 .crypto,
1391 .custom_cheap_as_move,
1392 .lsl_fast,
1393 .perfmon,
1394 .predictable_select_expensive,
1395 .use_postra_scheduler,
1396 .zcz,
1397 .v8a,
1614 }),1398 }),
1615 };1399 };
1616 pub const neoverse_e1 = Cpu{1400 pub const neoverse_e1 = CpuModel{
1617 .name = "neoverse_e1",1401 .name = "neoverse_e1",
1618 .llvm_name = "neoverse-e1",1402 .llvm_name = "neoverse-e1",
1619 .features = featureSet(&[_]Feature{1403 .features = featureSet(&[_]Feature{
1620 .neoversee1,1404 .neoversee1,
1621 }),1405 }),
1622 };1406 };
1623 pub const neoverse_n1 = Cpu{1407 pub const neoverse_n1 = CpuModel{
1624 .name = "neoverse_n1",1408 .name = "neoverse_n1",
1625 .llvm_name = "neoverse-n1",1409 .llvm_name = "neoverse-n1",
1626 .features = featureSet(&[_]Feature{1410 .features = featureSet(&[_]Feature{
1627 .neoversen1,1411 .neoversen1,
1628 }),1412 }),
1629 };1413 };
1630 pub const saphira = Cpu{1414 pub const saphira = CpuModel{
1631 .name = "saphira",1415 .name = "saphira",
1632 .llvm_name = "saphira",1416 .llvm_name = "saphira",
1633 .features = featureSet(&[_]Feature{1417 .features = featureSet(&[_]Feature{
1634 .saphira,1418 .crypto,
1419 .custom_cheap_as_move,
1420 .lsl_fast,
1421 .perfmon,
1422 .predictable_select_expensive,
1423 .spe,
1424 .use_postra_scheduler,
1425 .v8_4a,
1426 .zcz,
1635 }),1427 }),
1636 };1428 };
1637 pub const thunderx = Cpu{1429 pub const thunderx = CpuModel{
1638 .name = "thunderx",1430 .name = "thunderx",
1639 .llvm_name = "thunderx",1431 .llvm_name = "thunderx",
1640 .features = featureSet(&[_]Feature{1432 .features = featureSet(&[_]Feature{
1641 .thunderx,1433 .crc,
1434 .crypto,
1435 .perfmon,
1436 .predictable_select_expensive,
1437 .use_postra_scheduler,
1438 .v8a,
1642 }),1439 }),
1643 };1440 };
1644 pub const thunderx2t99 = Cpu{1441 pub const thunderx2t99 = CpuModel{
1645 .name = "thunderx2t99",1442 .name = "thunderx2t99",
1646 .llvm_name = "thunderx2t99",1443 .llvm_name = "thunderx2t99",
1647 .features = featureSet(&[_]Feature{1444 .features = featureSet(&[_]Feature{
1648 .thunderx2t99,1445 .aggressive_fma,
1446 .arith_bcc_fusion,
1447 .crc,
1448 .crypto,
1449 .lse,
1450 .predictable_select_expensive,
1451 .use_postra_scheduler,
1452 .v8_1a,
1649 }),1453 }),
1650 };1454 };
1651 pub const thunderxt81 = Cpu{1455 pub const thunderxt81 = CpuModel{
1652 .name = "thunderxt81",1456 .name = "thunderxt81",
1653 .llvm_name = "thunderxt81",1457 .llvm_name = "thunderxt81",
1654 .features = featureSet(&[_]Feature{1458 .features = featureSet(&[_]Feature{
1655 .thunderxt81,1459 .crc,
1460 .crypto,
1461 .perfmon,
1462 .predictable_select_expensive,
1463 .use_postra_scheduler,
1464 .v8a,
1656 }),1465 }),
1657 };1466 };
1658 pub const thunderxt83 = Cpu{1467 pub const thunderxt83 = CpuModel{
1659 .name = "thunderxt83",1468 .name = "thunderxt83",
1660 .llvm_name = "thunderxt83",1469 .llvm_name = "thunderxt83",
1661 .features = featureSet(&[_]Feature{1470 .features = featureSet(&[_]Feature{
1662 .thunderxt83,1471 .crc,
1472 .crypto,
1473 .perfmon,
1474 .predictable_select_expensive,
1475 .use_postra_scheduler,
1476 .v8a,
1663 }),1477 }),
1664 };1478 };
1665 pub const thunderxt88 = Cpu{1479 pub const thunderxt88 = CpuModel{
1666 .name = "thunderxt88",1480 .name = "thunderxt88",
1667 .llvm_name = "thunderxt88",1481 .llvm_name = "thunderxt88",
1668 .features = featureSet(&[_]Feature{1482 .features = featureSet(&[_]Feature{
1669 .thunderxt88,1483 .crc,
1484 .crypto,
1485 .perfmon,
1486 .predictable_select_expensive,
1487 .use_postra_scheduler,
1488 .v8a,
1670 }),1489 }),
1671 };1490 };
1672 pub const tsv110 = Cpu{1491 pub const tsv110 = CpuModel{
1673 .name = "tsv110",1492 .name = "tsv110",
1674 .llvm_name = "tsv110",1493 .llvm_name = "tsv110",
1675 .features = featureSet(&[_]Feature{1494 .features = featureSet(&[_]Feature{
1676 .tsv110,1495 .crypto,
1496 .custom_cheap_as_move,
1497 .dotprod,
1498 .fp16fml,
1499 .fullfp16,
1500 .fuse_aes,
1501 .perfmon,
1502 .spe,
1503 .use_postra_scheduler,
1504 .v8_2a,
1677 }),1505 }),
1678 };1506 };
1679};1507};
...@@ -1681,7 +1509,7 @@ pub const cpu = struct {...@@ -1681,7 +1509,7 @@ pub const cpu = struct {
1681/// All aarch64 CPUs, sorted alphabetically by name.1509/// All aarch64 CPUs, sorted alphabetically by name.
1682/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage11510/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
1683/// compiler has inefficient memory and CPU usage, affecting build times.1511/// compiler has inefficient memory and CPU usage, affecting build times.
1684pub const all_cpus = &[_]*const Cpu{1512pub const all_cpus = &[_]*const CpuModel{
1685 &cpu.apple_a10,1513 &cpu.apple_a10,
1686 &cpu.apple_a11,1514 &cpu.apple_a11,
1687 &cpu.apple_a12,1515 &cpu.apple_a12,
lib/std/target/amdgpu.zig+45-44
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2const Cpu = std.Target.Cpu;2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
34
4pub const Feature = enum {5pub const Feature = enum {
5 @"16_bit_insts",6 @"16_bit_insts",
...@@ -112,12 +113,12 @@ pub const Feature = enum {...@@ -112,12 +113,12 @@ pub const Feature = enum {
112 xnack,113 xnack,
113};114};
114115
115pub usingnamespace Cpu.Feature.feature_set_fns(Feature);116pub usingnamespace CpuFeature.feature_set_fns(Feature);
116117
117pub const all_features = blk: {118pub const all_features = blk: {
118 const len = @typeInfo(Feature).Enum.fields.len;119 const len = @typeInfo(Feature).Enum.fields.len;
119 std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);120 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
120 var result: [len]Cpu.Feature = undefined;121 var result: [len]CpuFeature = undefined;
121 result[@enumToInt(Feature.@"16_bit_insts")] = .{122 result[@enumToInt(Feature.@"16_bit_insts")] = .{
122 .llvm_name = "16-bit-insts",123 .llvm_name = "16-bit-insts",
123 .description = "Has i16/f16 instructions",124 .description = "Has i16/f16 instructions",
...@@ -784,7 +785,7 @@ pub const all_features = blk: {...@@ -784,7 +785,7 @@ pub const all_features = blk: {
784};785};
785786
786pub const cpu = struct {787pub const cpu = struct {
787 pub const bonaire = Cpu{788 pub const bonaire = CpuModel{
788 .name = "bonaire",789 .name = "bonaire",
789 .llvm_name = "bonaire",790 .llvm_name = "bonaire",
790 .features = featureSet(&[_]Feature{791 .features = featureSet(&[_]Feature{
...@@ -794,7 +795,7 @@ pub const cpu = struct {...@@ -794,7 +795,7 @@ pub const cpu = struct {
794 .sea_islands,795 .sea_islands,
795 }),796 }),
796 };797 };
797 pub const carrizo = Cpu{798 pub const carrizo = CpuModel{
798 .name = "carrizo",799 .name = "carrizo",
799 .llvm_name = "carrizo",800 .llvm_name = "carrizo",
800 .features = featureSet(&[_]Feature{801 .features = featureSet(&[_]Feature{
...@@ -807,7 +808,7 @@ pub const cpu = struct {...@@ -807,7 +808,7 @@ pub const cpu = struct {
807 .xnack,808 .xnack,
808 }),809 }),
809 };810 };
810 pub const fiji = Cpu{811 pub const fiji = CpuModel{
811 .name = "fiji",812 .name = "fiji",
812 .llvm_name = "fiji",813 .llvm_name = "fiji",
813 .features = featureSet(&[_]Feature{814 .features = featureSet(&[_]Feature{
...@@ -818,14 +819,14 @@ pub const cpu = struct {...@@ -818,14 +819,14 @@ pub const cpu = struct {
818 .volcanic_islands,819 .volcanic_islands,
819 }),820 }),
820 };821 };
821 pub const generic = Cpu{822 pub const generic = CpuModel{
822 .name = "generic",823 .name = "generic",
823 .llvm_name = "generic",824 .llvm_name = "generic",
824 .features = featureSet(&[_]Feature{825 .features = featureSet(&[_]Feature{
825 .wavefrontsize64,826 .wavefrontsize64,
826 }),827 }),
827 };828 };
828 pub const generic_hsa = Cpu{829 pub const generic_hsa = CpuModel{
829 .name = "generic_hsa",830 .name = "generic_hsa",
830 .llvm_name = "generic-hsa",831 .llvm_name = "generic-hsa",
831 .features = featureSet(&[_]Feature{832 .features = featureSet(&[_]Feature{
...@@ -833,7 +834,7 @@ pub const cpu = struct {...@@ -833,7 +834,7 @@ pub const cpu = struct {
833 .wavefrontsize64,834 .wavefrontsize64,
834 }),835 }),
835 };836 };
836 pub const gfx1010 = Cpu{837 pub const gfx1010 = CpuModel{
837 .name = "gfx1010",838 .name = "gfx1010",
838 .llvm_name = "gfx1010",839 .llvm_name = "gfx1010",
839 .features = featureSet(&[_]Feature{840 .features = featureSet(&[_]Feature{
...@@ -859,7 +860,7 @@ pub const cpu = struct {...@@ -859,7 +860,7 @@ pub const cpu = struct {
859 .wavefrontsize32,860 .wavefrontsize32,
860 }),861 }),
861 };862 };
862 pub const gfx1011 = Cpu{863 pub const gfx1011 = CpuModel{
863 .name = "gfx1011",864 .name = "gfx1011",
864 .llvm_name = "gfx1011",865 .llvm_name = "gfx1011",
865 .features = featureSet(&[_]Feature{866 .features = featureSet(&[_]Feature{
...@@ -888,7 +889,7 @@ pub const cpu = struct {...@@ -888,7 +889,7 @@ pub const cpu = struct {
888 .wavefrontsize32,889 .wavefrontsize32,
889 }),890 }),
890 };891 };
891 pub const gfx1012 = Cpu{892 pub const gfx1012 = CpuModel{
892 .name = "gfx1012",893 .name = "gfx1012",
893 .llvm_name = "gfx1012",894 .llvm_name = "gfx1012",
894 .features = featureSet(&[_]Feature{895 .features = featureSet(&[_]Feature{
...@@ -918,7 +919,7 @@ pub const cpu = struct {...@@ -918,7 +919,7 @@ pub const cpu = struct {
918 .wavefrontsize32,919 .wavefrontsize32,
919 }),920 }),
920 };921 };
921 pub const gfx600 = Cpu{922 pub const gfx600 = CpuModel{
922 .name = "gfx600",923 .name = "gfx600",
923 .llvm_name = "gfx600",924 .llvm_name = "gfx600",
924 .features = featureSet(&[_]Feature{925 .features = featureSet(&[_]Feature{
...@@ -930,7 +931,7 @@ pub const cpu = struct {...@@ -930,7 +931,7 @@ pub const cpu = struct {
930 .southern_islands,931 .southern_islands,
931 }),932 }),
932 };933 };
933 pub const gfx601 = Cpu{934 pub const gfx601 = CpuModel{
934 .name = "gfx601",935 .name = "gfx601",
935 .llvm_name = "gfx601",936 .llvm_name = "gfx601",
936 .features = featureSet(&[_]Feature{937 .features = featureSet(&[_]Feature{
...@@ -940,7 +941,7 @@ pub const cpu = struct {...@@ -940,7 +941,7 @@ pub const cpu = struct {
940 .southern_islands,941 .southern_islands,
941 }),942 }),
942 };943 };
943 pub const gfx700 = Cpu{944 pub const gfx700 = CpuModel{
944 .name = "gfx700",945 .name = "gfx700",
945 .llvm_name = "gfx700",946 .llvm_name = "gfx700",
946 .features = featureSet(&[_]Feature{947 .features = featureSet(&[_]Feature{
...@@ -950,7 +951,7 @@ pub const cpu = struct {...@@ -950,7 +951,7 @@ pub const cpu = struct {
950 .sea_islands,951 .sea_islands,
951 }),952 }),
952 };953 };
953 pub const gfx701 = Cpu{954 pub const gfx701 = CpuModel{
954 .name = "gfx701",955 .name = "gfx701",
955 .llvm_name = "gfx701",956 .llvm_name = "gfx701",
956 .features = featureSet(&[_]Feature{957 .features = featureSet(&[_]Feature{
...@@ -962,7 +963,7 @@ pub const cpu = struct {...@@ -962,7 +963,7 @@ pub const cpu = struct {
962 .sea_islands,963 .sea_islands,
963 }),964 }),
964 };965 };
965 pub const gfx702 = Cpu{966 pub const gfx702 = CpuModel{
966 .name = "gfx702",967 .name = "gfx702",
967 .llvm_name = "gfx702",968 .llvm_name = "gfx702",
968 .features = featureSet(&[_]Feature{969 .features = featureSet(&[_]Feature{
...@@ -973,7 +974,7 @@ pub const cpu = struct {...@@ -973,7 +974,7 @@ pub const cpu = struct {
973 .sea_islands,974 .sea_islands,
974 }),975 }),
975 };976 };
976 pub const gfx703 = Cpu{977 pub const gfx703 = CpuModel{
977 .name = "gfx703",978 .name = "gfx703",
978 .llvm_name = "gfx703",979 .llvm_name = "gfx703",
979 .features = featureSet(&[_]Feature{980 .features = featureSet(&[_]Feature{
...@@ -983,7 +984,7 @@ pub const cpu = struct {...@@ -983,7 +984,7 @@ pub const cpu = struct {
983 .sea_islands,984 .sea_islands,
984 }),985 }),
985 };986 };
986 pub const gfx704 = Cpu{987 pub const gfx704 = CpuModel{
987 .name = "gfx704",988 .name = "gfx704",
988 .llvm_name = "gfx704",989 .llvm_name = "gfx704",
989 .features = featureSet(&[_]Feature{990 .features = featureSet(&[_]Feature{
...@@ -993,7 +994,7 @@ pub const cpu = struct {...@@ -993,7 +994,7 @@ pub const cpu = struct {
993 .sea_islands,994 .sea_islands,
994 }),995 }),
995 };996 };
996 pub const gfx801 = Cpu{997 pub const gfx801 = CpuModel{
997 .name = "gfx801",998 .name = "gfx801",
998 .llvm_name = "gfx801",999 .llvm_name = "gfx801",
999 .features = featureSet(&[_]Feature{1000 .features = featureSet(&[_]Feature{
...@@ -1006,7 +1007,7 @@ pub const cpu = struct {...@@ -1006,7 +1007,7 @@ pub const cpu = struct {
1006 .xnack,1007 .xnack,
1007 }),1008 }),
1008 };1009 };
1009 pub const gfx802 = Cpu{1010 pub const gfx802 = CpuModel{
1010 .name = "gfx802",1011 .name = "gfx802",
1011 .llvm_name = "gfx802",1012 .llvm_name = "gfx802",
1012 .features = featureSet(&[_]Feature{1013 .features = featureSet(&[_]Feature{
...@@ -1018,7 +1019,7 @@ pub const cpu = struct {...@@ -1018,7 +1019,7 @@ pub const cpu = struct {
1018 .volcanic_islands,1019 .volcanic_islands,
1019 }),1020 }),
1020 };1021 };
1021 pub const gfx803 = Cpu{1022 pub const gfx803 = CpuModel{
1022 .name = "gfx803",1023 .name = "gfx803",
1023 .llvm_name = "gfx803",1024 .llvm_name = "gfx803",
1024 .features = featureSet(&[_]Feature{1025 .features = featureSet(&[_]Feature{
...@@ -1029,7 +1030,7 @@ pub const cpu = struct {...@@ -1029,7 +1030,7 @@ pub const cpu = struct {
1029 .volcanic_islands,1030 .volcanic_islands,
1030 }),1031 }),
1031 };1032 };
1032 pub const gfx810 = Cpu{1033 pub const gfx810 = CpuModel{
1033 .name = "gfx810",1034 .name = "gfx810",
1034 .llvm_name = "gfx810",1035 .llvm_name = "gfx810",
1035 .features = featureSet(&[_]Feature{1036 .features = featureSet(&[_]Feature{
...@@ -1039,7 +1040,7 @@ pub const cpu = struct {...@@ -1039,7 +1040,7 @@ pub const cpu = struct {
1039 .xnack,1040 .xnack,
1040 }),1041 }),
1041 };1042 };
1042 pub const gfx900 = Cpu{1043 pub const gfx900 = CpuModel{
1043 .name = "gfx900",1044 .name = "gfx900",
1044 .llvm_name = "gfx900",1045 .llvm_name = "gfx900",
1045 .features = featureSet(&[_]Feature{1046 .features = featureSet(&[_]Feature{
...@@ -1051,7 +1052,7 @@ pub const cpu = struct {...@@ -1051,7 +1052,7 @@ pub const cpu = struct {
1051 .no_xnack_support,1052 .no_xnack_support,
1052 }),1053 }),
1053 };1054 };
1054 pub const gfx902 = Cpu{1055 pub const gfx902 = CpuModel{
1055 .name = "gfx902",1056 .name = "gfx902",
1056 .llvm_name = "gfx902",1057 .llvm_name = "gfx902",
1057 .features = featureSet(&[_]Feature{1058 .features = featureSet(&[_]Feature{
...@@ -1063,7 +1064,7 @@ pub const cpu = struct {...@@ -1063,7 +1064,7 @@ pub const cpu = struct {
1063 .xnack,1064 .xnack,
1064 }),1065 }),
1065 };1066 };
1066 pub const gfx904 = Cpu{1067 pub const gfx904 = CpuModel{
1067 .name = "gfx904",1068 .name = "gfx904",
1068 .llvm_name = "gfx904",1069 .llvm_name = "gfx904",
1069 .features = featureSet(&[_]Feature{1070 .features = featureSet(&[_]Feature{
...@@ -1075,7 +1076,7 @@ pub const cpu = struct {...@@ -1075,7 +1076,7 @@ pub const cpu = struct {
1075 .no_xnack_support,1076 .no_xnack_support,
1076 }),1077 }),
1077 };1078 };
1078 pub const gfx906 = Cpu{1079 pub const gfx906 = CpuModel{
1079 .name = "gfx906",1080 .name = "gfx906",
1080 .llvm_name = "gfx906",1081 .llvm_name = "gfx906",
1081 .features = featureSet(&[_]Feature{1082 .features = featureSet(&[_]Feature{
...@@ -1090,7 +1091,7 @@ pub const cpu = struct {...@@ -1090,7 +1091,7 @@ pub const cpu = struct {
1090 .no_xnack_support,1091 .no_xnack_support,
1091 }),1092 }),
1092 };1093 };
1093 pub const gfx908 = Cpu{1094 pub const gfx908 = CpuModel{
1094 .name = "gfx908",1095 .name = "gfx908",
1095 .llvm_name = "gfx908",1096 .llvm_name = "gfx908",
1096 .features = featureSet(&[_]Feature{1097 .features = featureSet(&[_]Feature{
...@@ -1113,7 +1114,7 @@ pub const cpu = struct {...@@ -1113,7 +1114,7 @@ pub const cpu = struct {
1113 .sram_ecc,1114 .sram_ecc,
1114 }),1115 }),
1115 };1116 };
1116 pub const gfx909 = Cpu{1117 pub const gfx909 = CpuModel{
1117 .name = "gfx909",1118 .name = "gfx909",
1118 .llvm_name = "gfx909",1119 .llvm_name = "gfx909",
1119 .features = featureSet(&[_]Feature{1120 .features = featureSet(&[_]Feature{
...@@ -1124,7 +1125,7 @@ pub const cpu = struct {...@@ -1124,7 +1125,7 @@ pub const cpu = struct {
1124 .xnack,1125 .xnack,
1125 }),1126 }),
1126 };1127 };
1127 pub const hainan = Cpu{1128 pub const hainan = CpuModel{
1128 .name = "hainan",1129 .name = "hainan",
1129 .llvm_name = "hainan",1130 .llvm_name = "hainan",
1130 .features = featureSet(&[_]Feature{1131 .features = featureSet(&[_]Feature{
...@@ -1134,7 +1135,7 @@ pub const cpu = struct {...@@ -1134,7 +1135,7 @@ pub const cpu = struct {
1134 .southern_islands,1135 .southern_islands,
1135 }),1136 }),
1136 };1137 };
1137 pub const hawaii = Cpu{1138 pub const hawaii = CpuModel{
1138 .name = "hawaii",1139 .name = "hawaii",
1139 .llvm_name = "hawaii",1140 .llvm_name = "hawaii",
1140 .features = featureSet(&[_]Feature{1141 .features = featureSet(&[_]Feature{
...@@ -1146,7 +1147,7 @@ pub const cpu = struct {...@@ -1146,7 +1147,7 @@ pub const cpu = struct {
1146 .sea_islands,1147 .sea_islands,
1147 }),1148 }),
1148 };1149 };
1149 pub const iceland = Cpu{1150 pub const iceland = CpuModel{
1150 .name = "iceland",1151 .name = "iceland",
1151 .llvm_name = "iceland",1152 .llvm_name = "iceland",
1152 .features = featureSet(&[_]Feature{1153 .features = featureSet(&[_]Feature{
...@@ -1158,7 +1159,7 @@ pub const cpu = struct {...@@ -1158,7 +1159,7 @@ pub const cpu = struct {
1158 .volcanic_islands,1159 .volcanic_islands,
1159 }),1160 }),
1160 };1161 };
1161 pub const kabini = Cpu{1162 pub const kabini = CpuModel{
1162 .name = "kabini",1163 .name = "kabini",
1163 .llvm_name = "kabini",1164 .llvm_name = "kabini",
1164 .features = featureSet(&[_]Feature{1165 .features = featureSet(&[_]Feature{
...@@ -1168,7 +1169,7 @@ pub const cpu = struct {...@@ -1168,7 +1169,7 @@ pub const cpu = struct {
1168 .sea_islands,1169 .sea_islands,
1169 }),1170 }),
1170 };1171 };
1171 pub const kaveri = Cpu{1172 pub const kaveri = CpuModel{
1172 .name = "kaveri",1173 .name = "kaveri",
1173 .llvm_name = "kaveri",1174 .llvm_name = "kaveri",
1174 .features = featureSet(&[_]Feature{1175 .features = featureSet(&[_]Feature{
...@@ -1178,7 +1179,7 @@ pub const cpu = struct {...@@ -1178,7 +1179,7 @@ pub const cpu = struct {
1178 .sea_islands,1179 .sea_islands,
1179 }),1180 }),
1180 };1181 };
1181 pub const mullins = Cpu{1182 pub const mullins = CpuModel{
1182 .name = "mullins",1183 .name = "mullins",
1183 .llvm_name = "mullins",1184 .llvm_name = "mullins",
1184 .features = featureSet(&[_]Feature{1185 .features = featureSet(&[_]Feature{
...@@ -1188,7 +1189,7 @@ pub const cpu = struct {...@@ -1188,7 +1189,7 @@ pub const cpu = struct {
1188 .sea_islands,1189 .sea_islands,
1189 }),1190 }),
1190 };1191 };
1191 pub const oland = Cpu{1192 pub const oland = CpuModel{
1192 .name = "oland",1193 .name = "oland",
1193 .llvm_name = "oland",1194 .llvm_name = "oland",
1194 .features = featureSet(&[_]Feature{1195 .features = featureSet(&[_]Feature{
...@@ -1198,7 +1199,7 @@ pub const cpu = struct {...@@ -1198,7 +1199,7 @@ pub const cpu = struct {
1198 .southern_islands,1199 .southern_islands,
1199 }),1200 }),
1200 };1201 };
1201 pub const pitcairn = Cpu{1202 pub const pitcairn = CpuModel{
1202 .name = "pitcairn",1203 .name = "pitcairn",
1203 .llvm_name = "pitcairn",1204 .llvm_name = "pitcairn",
1204 .features = featureSet(&[_]Feature{1205 .features = featureSet(&[_]Feature{
...@@ -1208,7 +1209,7 @@ pub const cpu = struct {...@@ -1208,7 +1209,7 @@ pub const cpu = struct {
1208 .southern_islands,1209 .southern_islands,
1209 }),1210 }),
1210 };1211 };
1211 pub const polaris10 = Cpu{1212 pub const polaris10 = CpuModel{
1212 .name = "polaris10",1213 .name = "polaris10",
1213 .llvm_name = "polaris10",1214 .llvm_name = "polaris10",
1214 .features = featureSet(&[_]Feature{1215 .features = featureSet(&[_]Feature{
...@@ -1219,7 +1220,7 @@ pub const cpu = struct {...@@ -1219,7 +1220,7 @@ pub const cpu = struct {
1219 .volcanic_islands,1220 .volcanic_islands,
1220 }),1221 }),
1221 };1222 };
1222 pub const polaris11 = Cpu{1223 pub const polaris11 = CpuModel{
1223 .name = "polaris11",1224 .name = "polaris11",
1224 .llvm_name = "polaris11",1225 .llvm_name = "polaris11",
1225 .features = featureSet(&[_]Feature{1226 .features = featureSet(&[_]Feature{
...@@ -1230,7 +1231,7 @@ pub const cpu = struct {...@@ -1230,7 +1231,7 @@ pub const cpu = struct {
1230 .volcanic_islands,1231 .volcanic_islands,
1231 }),1232 }),
1232 };1233 };
1233 pub const stoney = Cpu{1234 pub const stoney = CpuModel{
1234 .name = "stoney",1235 .name = "stoney",
1235 .llvm_name = "stoney",1236 .llvm_name = "stoney",
1236 .features = featureSet(&[_]Feature{1237 .features = featureSet(&[_]Feature{
...@@ -1240,7 +1241,7 @@ pub const cpu = struct {...@@ -1240,7 +1241,7 @@ pub const cpu = struct {
1240 .xnack,1241 .xnack,
1241 }),1242 }),
1242 };1243 };
1243 pub const tahiti = Cpu{1244 pub const tahiti = CpuModel{
1244 .name = "tahiti",1245 .name = "tahiti",
1245 .llvm_name = "tahiti",1246 .llvm_name = "tahiti",
1246 .features = featureSet(&[_]Feature{1247 .features = featureSet(&[_]Feature{
...@@ -1252,7 +1253,7 @@ pub const cpu = struct {...@@ -1252,7 +1253,7 @@ pub const cpu = struct {
1252 .southern_islands,1253 .southern_islands,
1253 }),1254 }),
1254 };1255 };
1255 pub const tonga = Cpu{1256 pub const tonga = CpuModel{
1256 .name = "tonga",1257 .name = "tonga",
1257 .llvm_name = "tonga",1258 .llvm_name = "tonga",
1258 .features = featureSet(&[_]Feature{1259 .features = featureSet(&[_]Feature{
...@@ -1264,7 +1265,7 @@ pub const cpu = struct {...@@ -1264,7 +1265,7 @@ pub const cpu = struct {
1264 .volcanic_islands,1265 .volcanic_islands,
1265 }),1266 }),
1266 };1267 };
1267 pub const verde = Cpu{1268 pub const verde = CpuModel{
1268 .name = "verde",1269 .name = "verde",
1269 .llvm_name = "verde",1270 .llvm_name = "verde",
1270 .features = featureSet(&[_]Feature{1271 .features = featureSet(&[_]Feature{
...@@ -1279,7 +1280,7 @@ pub const cpu = struct {...@@ -1279,7 +1280,7 @@ pub const cpu = struct {
1279/// All amdgpu CPUs, sorted alphabetically by name.1280/// All amdgpu CPUs, sorted alphabetically by name.
1280/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage11281/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
1281/// compiler has inefficient memory and CPU usage, affecting build times.1282/// compiler has inefficient memory and CPU usage, affecting build times.
1282pub const all_cpus = &[_]*const Cpu{1283pub const all_cpus = &[_]*const CpuModel{
1283 &cpu.bonaire,1284 &cpu.bonaire,
1284 &cpu.carrizo,1285 &cpu.carrizo,
1285 &cpu.fiji,1286 &cpu.fiji,
lib/std/target/arm.zig+698-829
...@@ -1,61 +1,14 @@...@@ -1,61 +1,14 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2const Cpu = std.Target.Cpu;2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
34
4pub const Feature = enum {5pub const Feature = enum {
5 @"32bit",6 @"32bit",
6 @"8msecext",7 @"8msecext",
7 a12,
8 a15,
9 a17,
10 a32,
11 a35,
12 a5,
13 a53,
14 a55,
15 a57,
16 a7,
17 a72,
18 a73,
19 a75,
20 a76,8 a76,
21 a8,
22 a9,
23 aclass,9 aclass,
24 acquire_release,10 acquire_release,
25 aes,11 aes,
26 armv2,
27 armv2a,
28 armv3,
29 armv3m,
30 armv4,
31 armv4t,
32 armv5t,
33 armv5te,
34 armv5tej,
35 armv6,
36 armv6_m,
37 armv6j,
38 armv6k,
39 armv6kz,
40 armv6s_m,
41 armv6t2,
42 armv7_a,
43 armv7_m,
44 armv7_r,
45 armv7e_m,
46 armv7k,
47 armv7s,
48 armv7ve,
49 armv8_a,
50 armv8_m_base,
51 armv8_m_main,
52 armv8_r,
53 armv8_1_a,
54 armv8_1_m_main,
55 armv8_2_a,
56 armv8_3_a,
57 armv8_4_a,
58 armv8_5_a,
59 avoid_movs_shop,12 avoid_movs_shop,
60 avoid_partial_cpsr,13 avoid_partial_cpsr,
61 cheap_predicable_cpsr,14 cheap_predicable_cpsr,
...@@ -71,13 +24,13 @@ pub const Feature = enum {...@@ -71,13 +24,13 @@ pub const Feature = enum {
71 execute_only,24 execute_only,
72 expand_fp_mlx,25 expand_fp_mlx,
73 exynos,26 exynos,
27 fp16,
28 fp16fml,
29 fp64,
74 fp_armv8,30 fp_armv8,
75 fp_armv8d16,31 fp_armv8d16,
76 fp_armv8d16sp,32 fp_armv8d16sp,
77 fp_armv8sp,33 fp_armv8sp,
78 fp16,
79 fp16fml,
80 fp64,
81 fpao,34 fpao,
82 fpregs,35 fpregs,
83 fpregs16,36 fpregs16,
...@@ -85,12 +38,28 @@ pub const Feature = enum {...@@ -85,12 +38,28 @@ pub const Feature = enum {
85 fullfp16,38 fullfp16,
86 fuse_aes,39 fuse_aes,
87 fuse_literals,40 fuse_literals,
41 has_v4t,
42 has_v5t,
43 has_v5te,
44 has_v6,
45 has_v6k,
46 has_v6m,
47 has_v6t2,
48 has_v7,
49 has_v7clrex,
50 has_v8_1a,
51 has_v8_1m_main,
52 has_v8_2a,
53 has_v8_3a,
54 has_v8_4a,
55 has_v8_5a,
56 has_v8,
57 has_v8m,
58 has_v8m_main,
88 hwdiv,59 hwdiv,
89 hwdiv_arm,60 hwdiv_arm,
90 iwmmxt,61 iwmmxt,
91 iwmmxt2,62 iwmmxt2,
92 krait,
93 kryo,
94 lob,63 lob,
95 long_calls,64 long_calls,
96 loop_align,65 loop_align,
...@@ -117,9 +86,6 @@ pub const Feature = enum {...@@ -117,9 +86,6 @@ pub const Feature = enum {
117 prefer_vmovsr,86 prefer_vmovsr,
118 prof_unpr,87 prof_unpr,
119 r4,88 r4,
120 r5,
121 r52,
122 r7,
123 ras,89 ras,
124 rclass,90 rclass,
125 read_tp_hard,91 read_tp_hard,
...@@ -138,28 +104,43 @@ pub const Feature = enum {...@@ -138,28 +104,43 @@ pub const Feature = enum {
138 splat_vfp_neon,104 splat_vfp_neon,
139 strict_align,105 strict_align,
140 swift,106 swift,
141 thumb_mode,
142 thumb2,107 thumb2,
108 thumb_mode,
143 trustzone,109 trustzone,
144 use_misched,110 use_misched,
111 v2,
112 v2a,
113 v3,
114 v3m,
115 v4,
145 v4t,116 v4t,
146 v5t,117 v5t,
147 v5te,118 v5te,
119 v5tej,
148 v6,120 v6,
121 v6j,
149 v6k,122 v6k,
123 v6kz,
150 v6m,124 v6m,
125 v6sm,
151 v6t2,126 v6t2,
152 v7,127 v7a,
153 v7clrex,128 v7em,
154 v8,129 v7k,
130 v7m,
131 v7r,
132 v7s,
133 v7ve,
134 v8a,
135 v8m,
136 v8m_main,
137 v8r,
155 v8_1a,138 v8_1a,
156 v8_1m_main,139 v8_1m_main,
157 v8_2a,140 v8_2a,
158 v8_3a,141 v8_3a,
159 v8_4a,142 v8_4a,
160 v8_5a,143 v8_5a,
161 v8m,
162 v8m_main,
163 vfp2,144 vfp2,
164 vfp2sp,145 vfp2sp,
165 vfp3,146 vfp3,
...@@ -179,13 +160,13 @@ pub const Feature = enum {...@@ -179,13 +160,13 @@ pub const Feature = enum {
179 zcz,160 zcz,
180};161};
181162
182pub usingnamespace Cpu.Feature.feature_set_fns(Feature);163pub usingnamespace CpuFeature.feature_set_fns(Feature);
183164
184pub const all_features = blk: {165pub const all_features = blk: {
185 @setEvalBranchQuota(10000);166 @setEvalBranchQuota(10000);
186 const len = @typeInfo(Feature).Enum.fields.len;167 const len = @typeInfo(Feature).Enum.fields.len;
187 std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);168 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
188 var result: [len]Cpu.Feature = undefined;169 var result: [len]CpuFeature = undefined;
189 result[@enumToInt(Feature.@"32bit")] = .{170 result[@enumToInt(Feature.@"32bit")] = .{
190 .llvm_name = "32bit",171 .llvm_name = "32bit",
191 .description = "Prefer 32-bit Thumb instrs",172 .description = "Prefer 32-bit Thumb instrs",
...@@ -196,86 +177,11 @@ pub const all_features = blk: {...@@ -196,86 +177,11 @@ pub const all_features = blk: {
196 .description = "Enable support for ARMv8-M Security Extensions",177 .description = "Enable support for ARMv8-M Security Extensions",
197 .dependencies = featureSet(&[_]Feature{}),178 .dependencies = featureSet(&[_]Feature{}),
198 };179 };
199 result[@enumToInt(Feature.a12)] = .{
200 .llvm_name = "a12",
201 .description = "Cortex-A12 ARM processors",
202 .dependencies = featureSet(&[_]Feature{}),
203 };
204 result[@enumToInt(Feature.a15)] = .{
205 .llvm_name = "a15",
206 .description = "Cortex-A15 ARM processors",
207 .dependencies = featureSet(&[_]Feature{}),
208 };
209 result[@enumToInt(Feature.a17)] = .{
210 .llvm_name = "a17",
211 .description = "Cortex-A17 ARM processors",
212 .dependencies = featureSet(&[_]Feature{}),
213 };
214 result[@enumToInt(Feature.a32)] = .{
215 .llvm_name = "a32",
216 .description = "Cortex-A32 ARM processors",
217 .dependencies = featureSet(&[_]Feature{}),
218 };
219 result[@enumToInt(Feature.a35)] = .{
220 .llvm_name = "a35",
221 .description = "Cortex-A35 ARM processors",
222 .dependencies = featureSet(&[_]Feature{}),
223 };
224 result[@enumToInt(Feature.a5)] = .{
225 .llvm_name = "a5",
226 .description = "Cortex-A5 ARM processors",
227 .dependencies = featureSet(&[_]Feature{}),
228 };
229 result[@enumToInt(Feature.a53)] = .{
230 .llvm_name = "a53",
231 .description = "Cortex-A53 ARM processors",
232 .dependencies = featureSet(&[_]Feature{}),
233 };
234 result[@enumToInt(Feature.a55)] = .{
235 .llvm_name = "a55",
236 .description = "Cortex-A55 ARM processors",
237 .dependencies = featureSet(&[_]Feature{}),
238 };
239 result[@enumToInt(Feature.a57)] = .{
240 .llvm_name = "a57",
241 .description = "Cortex-A57 ARM processors",
242 .dependencies = featureSet(&[_]Feature{}),
243 };
244 result[@enumToInt(Feature.a7)] = .{
245 .llvm_name = "a7",
246 .description = "Cortex-A7 ARM processors",
247 .dependencies = featureSet(&[_]Feature{}),
248 };
249 result[@enumToInt(Feature.a72)] = .{
250 .llvm_name = "a72",
251 .description = "Cortex-A72 ARM processors",
252 .dependencies = featureSet(&[_]Feature{}),
253 };
254 result[@enumToInt(Feature.a73)] = .{
255 .llvm_name = "a73",
256 .description = "Cortex-A73 ARM processors",
257 .dependencies = featureSet(&[_]Feature{}),
258 };
259 result[@enumToInt(Feature.a75)] = .{
260 .llvm_name = "a75",
261 .description = "Cortex-A75 ARM processors",
262 .dependencies = featureSet(&[_]Feature{}),
263 };
264 result[@enumToInt(Feature.a76)] = .{180 result[@enumToInt(Feature.a76)] = .{
265 .llvm_name = "a76",181 .llvm_name = "a76",
266 .description = "Cortex-A76 ARM processors",182 .description = "Cortex-A76 ARM processors",
267 .dependencies = featureSet(&[_]Feature{}),183 .dependencies = featureSet(&[_]Feature{}),
268 };184 };
269 result[@enumToInt(Feature.a8)] = .{
270 .llvm_name = "a8",
271 .description = "Cortex-A8 ARM processors",
272 .dependencies = featureSet(&[_]Feature{}),
273 };
274 result[@enumToInt(Feature.a9)] = .{
275 .llvm_name = "a9",
276 .description = "Cortex-A9 ARM processors",
277 .dependencies = featureSet(&[_]Feature{}),
278 };
279 result[@enumToInt(Feature.aclass)] = .{185 result[@enumToInt(Feature.aclass)] = .{
280 .llvm_name = "aclass",186 .llvm_name = "aclass",
281 .description = "Is application profile ('A' series)",187 .description = "Is application profile ('A' series)",
...@@ -293,368 +199,6 @@ pub const all_features = blk: {...@@ -293,368 +199,6 @@ pub const all_features = blk: {
293 .neon,199 .neon,
294 }),200 }),
295 };201 };
296 result[@enumToInt(Feature.armv2)] = .{
297 .llvm_name = "armv2",
298 .description = "ARMv2 architecture",
299 .dependencies = featureSet(&[_]Feature{}),
300 };
301 result[@enumToInt(Feature.armv2a)] = .{
302 .llvm_name = "armv2a",
303 .description = "ARMv2a architecture",
304 .dependencies = featureSet(&[_]Feature{}),
305 };
306 result[@enumToInt(Feature.armv3)] = .{
307 .llvm_name = "armv3",
308 .description = "ARMv3 architecture",
309 .dependencies = featureSet(&[_]Feature{}),
310 };
311 result[@enumToInt(Feature.armv3m)] = .{
312 .llvm_name = "armv3m",
313 .description = "ARMv3m architecture",
314 .dependencies = featureSet(&[_]Feature{}),
315 };
316 result[@enumToInt(Feature.armv4)] = .{
317 .llvm_name = "armv4",
318 .description = "ARMv4 architecture",
319 .dependencies = featureSet(&[_]Feature{}),
320 };
321 result[@enumToInt(Feature.armv4t)] = .{
322 .llvm_name = "armv4t",
323 .description = "ARMv4t architecture",
324 .dependencies = featureSet(&[_]Feature{
325 .v4t,
326 }),
327 };
328 result[@enumToInt(Feature.armv5t)] = .{
329 .llvm_name = "armv5t",
330 .description = "ARMv5t architecture",
331 .dependencies = featureSet(&[_]Feature{
332 .v5t,
333 }),
334 };
335 result[@enumToInt(Feature.armv5te)] = .{
336 .llvm_name = "armv5te",
337 .description = "ARMv5te architecture",
338 .dependencies = featureSet(&[_]Feature{
339 .v5te,
340 }),
341 };
342 result[@enumToInt(Feature.armv5tej)] = .{
343 .llvm_name = "armv5tej",
344 .description = "ARMv5tej architecture",
345 .dependencies = featureSet(&[_]Feature{
346 .v5te,
347 }),
348 };
349 result[@enumToInt(Feature.armv6)] = .{
350 .llvm_name = "armv6",
351 .description = "ARMv6 architecture",
352 .dependencies = featureSet(&[_]Feature{
353 .dsp,
354 .v6,
355 }),
356 };
357 result[@enumToInt(Feature.armv6_m)] = .{
358 .llvm_name = "armv6-m",
359 .description = "ARMv6m architecture",
360 .dependencies = featureSet(&[_]Feature{
361 .db,
362 .mclass,
363 .noarm,
364 .strict_align,
365 .thumb_mode,
366 .v6m,
367 }),
368 };
369 result[@enumToInt(Feature.armv6j)] = .{
370 .llvm_name = "armv6j",
371 .description = "ARMv7a architecture",
372 .dependencies = featureSet(&[_]Feature{
373 .armv6,
374 }),
375 };
376 result[@enumToInt(Feature.armv6k)] = .{
377 .llvm_name = "armv6k",
378 .description = "ARMv6k architecture",
379 .dependencies = featureSet(&[_]Feature{
380 .v6k,
381 }),
382 };
383 result[@enumToInt(Feature.armv6kz)] = .{
384 .llvm_name = "armv6kz",
385 .description = "ARMv6kz architecture",
386 .dependencies = featureSet(&[_]Feature{
387 .trustzone,
388 .v6k,
389 }),
390 };
391 result[@enumToInt(Feature.armv6s_m)] = .{
392 .llvm_name = "armv6s-m",
393 .description = "ARMv6sm architecture",
394 .dependencies = featureSet(&[_]Feature{
395 .db,
396 .mclass,
397 .noarm,
398 .strict_align,
399 .thumb_mode,
400 .v6m,
401 }),
402 };
403 result[@enumToInt(Feature.armv6t2)] = .{
404 .llvm_name = "armv6t2",
405 .description = "ARMv6t2 architecture",
406 .dependencies = featureSet(&[_]Feature{
407 .dsp,
408 .v6t2,
409 }),
410 };
411 result[@enumToInt(Feature.armv7_a)] = .{
412 .llvm_name = "armv7-a",
413 .description = "ARMv7a architecture",
414 .dependencies = featureSet(&[_]Feature{
415 .aclass,
416 .db,
417 .dsp,
418 .neon,
419 .v7,
420 }),
421 };
422 result[@enumToInt(Feature.armv7_m)] = .{
423 .llvm_name = "armv7-m",
424 .description = "ARMv7m architecture",
425 .dependencies = featureSet(&[_]Feature{
426 .db,
427 .hwdiv,
428 .mclass,
429 .noarm,
430 .thumb_mode,
431 .thumb2,
432 .v7,
433 }),
434 };
435 result[@enumToInt(Feature.armv7_r)] = .{
436 .llvm_name = "armv7-r",
437 .description = "ARMv7r architecture",
438 .dependencies = featureSet(&[_]Feature{
439 .db,
440 .dsp,
441 .hwdiv,
442 .rclass,
443 .v7,
444 }),
445 };
446 result[@enumToInt(Feature.armv7e_m)] = .{
447 .llvm_name = "armv7e-m",
448 .description = "ARMv7em architecture",
449 .dependencies = featureSet(&[_]Feature{
450 .db,
451 .dsp,
452 .hwdiv,
453 .mclass,
454 .noarm,
455 .thumb_mode,
456 .thumb2,
457 .v7,
458 }),
459 };
460 result[@enumToInt(Feature.armv7k)] = .{
461 .llvm_name = "armv7k",
462 .description = "ARMv7a architecture",
463 .dependencies = featureSet(&[_]Feature{
464 .armv7_a,
465 }),
466 };
467 result[@enumToInt(Feature.armv7s)] = .{
468 .llvm_name = "armv7s",
469 .description = "ARMv7a architecture",
470 .dependencies = featureSet(&[_]Feature{
471 .armv7_a,
472 }),
473 };
474 result[@enumToInt(Feature.armv7ve)] = .{
475 .llvm_name = "armv7ve",
476 .description = "ARMv7ve architecture",
477 .dependencies = featureSet(&[_]Feature{
478 .aclass,
479 .db,
480 .dsp,
481 .mp,
482 .neon,
483 .trustzone,
484 .v7,
485 .virtualization,
486 }),
487 };
488 result[@enumToInt(Feature.armv8_a)] = .{
489 .llvm_name = "armv8-a",
490 .description = "ARMv8a architecture",
491 .dependencies = featureSet(&[_]Feature{
492 .aclass,
493 .crc,
494 .crypto,
495 .db,
496 .dsp,
497 .fp_armv8,
498 .mp,
499 .neon,
500 .trustzone,
501 .v8,
502 .virtualization,
503 }),
504 };
505 result[@enumToInt(Feature.armv8_m_base)] = .{
506 .llvm_name = "armv8-m.base",
507 .description = "ARMv8mBaseline architecture",
508 .dependencies = featureSet(&[_]Feature{
509 .@"8msecext",
510 .acquire_release,
511 .db,
512 .hwdiv,
513 .mclass,
514 .noarm,
515 .strict_align,
516 .thumb_mode,
517 .v7clrex,
518 .v8m,
519 }),
520 };
521 result[@enumToInt(Feature.armv8_m_main)] = .{
522 .llvm_name = "armv8-m.main",
523 .description = "ARMv8mMainline architecture",
524 .dependencies = featureSet(&[_]Feature{
525 .@"8msecext",
526 .acquire_release,
527 .db,
528 .hwdiv,
529 .mclass,
530 .noarm,
531 .thumb_mode,
532 .v8m_main,
533 }),
534 };
535 result[@enumToInt(Feature.armv8_r)] = .{
536 .llvm_name = "armv8-r",
537 .description = "ARMv8r architecture",
538 .dependencies = featureSet(&[_]Feature{
539 .crc,
540 .db,
541 .dfb,
542 .dsp,
543 .fp_armv8,
544 .mp,
545 .neon,
546 .rclass,
547 .v8,
548 .virtualization,
549 }),
550 };
551 result[@enumToInt(Feature.armv8_1_a)] = .{
552 .llvm_name = "armv8.1-a",
553 .description = "ARMv81a architecture",
554 .dependencies = featureSet(&[_]Feature{
555 .aclass,
556 .crc,
557 .crypto,
558 .db,
559 .dsp,
560 .fp_armv8,
561 .mp,
562 .neon,
563 .trustzone,
564 .v8_1a,
565 .virtualization,
566 }),
567 };
568 result[@enumToInt(Feature.armv8_1_m_main)] = .{
569 .llvm_name = "armv8.1-m.main",
570 .description = "ARMv81mMainline architecture",
571 .dependencies = featureSet(&[_]Feature{
572 .@"8msecext",
573 .acquire_release,
574 .db,
575 .hwdiv,
576 .lob,
577 .mclass,
578 .noarm,
579 .ras,
580 .thumb_mode,
581 .v8_1m_main,
582 }),
583 };
584 result[@enumToInt(Feature.armv8_2_a)] = .{
585 .llvm_name = "armv8.2-a",
586 .description = "ARMv82a architecture",
587 .dependencies = featureSet(&[_]Feature{
588 .aclass,
589 .crc,
590 .crypto,
591 .db,
592 .dsp,
593 .fp_armv8,
594 .mp,
595 .neon,
596 .ras,
597 .trustzone,
598 .v8_2a,
599 .virtualization,
600 }),
601 };
602 result[@enumToInt(Feature.armv8_3_a)] = .{
603 .llvm_name = "armv8.3-a",
604 .description = "ARMv83a architecture",
605 .dependencies = featureSet(&[_]Feature{
606 .aclass,
607 .crc,
608 .crypto,
609 .db,
610 .dsp,
611 .fp_armv8,
612 .mp,
613 .neon,
614 .ras,
615 .trustzone,
616 .v8_3a,
617 .virtualization,
618 }),
619 };
620 result[@enumToInt(Feature.armv8_4_a)] = .{
621 .llvm_name = "armv8.4-a",
622 .description = "ARMv84a architecture",
623 .dependencies = featureSet(&[_]Feature{
624 .aclass,
625 .crc,
626 .crypto,
627 .db,
628 .dotprod,
629 .dsp,
630 .fp_armv8,
631 .mp,
632 .neon,
633 .ras,
634 .trustzone,
635 .v8_4a,
636 .virtualization,
637 }),
638 };
639 result[@enumToInt(Feature.armv8_5_a)] = .{
640 .llvm_name = "armv8.5-a",
641 .description = "ARMv85a architecture",
642 .dependencies = featureSet(&[_]Feature{
643 .aclass,
644 .crc,
645 .crypto,
646 .db,
647 .dotprod,
648 .dsp,
649 .fp_armv8,
650 .mp,
651 .neon,
652 .ras,
653 .trustzone,
654 .v8_5a,
655 .virtualization,
656 }),
657 };
658 result[@enumToInt(Feature.avoid_movs_shop)] = .{202 result[@enumToInt(Feature.avoid_movs_shop)] = .{
659 .llvm_name = "avoid-movs-shop",203 .llvm_name = "avoid-movs-shop",
660 .description = "Avoid movs instructions with shifter operand",204 .description = "Avoid movs instructions with shifter operand",
...@@ -754,6 +298,25 @@ pub const all_features = blk: {...@@ -754,6 +298,25 @@ pub const all_features = blk: {
754 .zcz,298 .zcz,
755 }),299 }),
756 };300 };
301 result[@enumToInt(Feature.fp16)] = .{
302 .llvm_name = "fp16",
303 .description = "Enable half-precision floating point",
304 .dependencies = featureSet(&[_]Feature{}),
305 };
306 result[@enumToInt(Feature.fp16fml)] = .{
307 .llvm_name = "fp16fml",
308 .description = "Enable full half-precision floating point fml instructions",
309 .dependencies = featureSet(&[_]Feature{
310 .fullfp16,
311 }),
312 };
313 result[@enumToInt(Feature.fp64)] = .{
314 .llvm_name = "fp64",
315 .description = "Floating point unit supports double precision",
316 .dependencies = featureSet(&[_]Feature{
317 .fpregs64,
318 }),
319 };
757 result[@enumToInt(Feature.fp_armv8)] = .{320 result[@enumToInt(Feature.fp_armv8)] = .{
758 .llvm_name = "fp-armv8",321 .llvm_name = "fp-armv8",
759 .description = "Enable ARMv8 FP",322 .description = "Enable ARMv8 FP",
...@@ -772,39 +335,20 @@ pub const all_features = blk: {...@@ -772,39 +335,20 @@ pub const all_features = blk: {
772 .vfp4d16,335 .vfp4d16,
773 }),336 }),
774 };337 };
775 result[@enumToInt(Feature.fp_armv8d16sp)] = .{338 result[@enumToInt(Feature.fp_armv8d16sp)] = .{
776 .llvm_name = "fp-armv8d16sp",339 .llvm_name = "fp-armv8d16sp",
777 .description = "Enable ARMv8 FP with only 16 d-registers and no double precision",340 .description = "Enable ARMv8 FP with only 16 d-registers and no double precision",
778 .dependencies = featureSet(&[_]Feature{
779 .vfp4d16sp,
780 }),
781 };
782 result[@enumToInt(Feature.fp_armv8sp)] = .{
783 .llvm_name = "fp-armv8sp",
784 .description = "Enable ARMv8 FP with no double precision",
785 .dependencies = featureSet(&[_]Feature{
786 .d32,
787 .fp_armv8d16sp,
788 .vfp4sp,
789 }),
790 };
791 result[@enumToInt(Feature.fp16)] = .{
792 .llvm_name = "fp16",
793 .description = "Enable half-precision floating point",
794 .dependencies = featureSet(&[_]Feature{}),
795 };
796 result[@enumToInt(Feature.fp16fml)] = .{
797 .llvm_name = "fp16fml",
798 .description = "Enable full half-precision floating point fml instructions",
799 .dependencies = featureSet(&[_]Feature{341 .dependencies = featureSet(&[_]Feature{
800 .fullfp16,342 .vfp4d16sp,
801 }),343 }),
802 };344 };
803 result[@enumToInt(Feature.fp64)] = .{345 result[@enumToInt(Feature.fp_armv8sp)] = .{
804 .llvm_name = "fp64",346 .llvm_name = "fp-armv8sp",
805 .description = "Floating point unit supports double precision",347 .description = "Enable ARMv8 FP with no double precision",
806 .dependencies = featureSet(&[_]Feature{348 .dependencies = featureSet(&[_]Feature{
807 .fpregs64,349 .d32,
350 .fp_armv8d16sp,
351 .vfp4sp,
808 }),352 }),
809 };353 };
810 result[@enumToInt(Feature.fpao)] = .{354 result[@enumToInt(Feature.fpao)] = .{
...@@ -849,6 +393,135 @@ pub const all_features = blk: {...@@ -849,6 +393,135 @@ pub const all_features = blk: {
849 .description = "CPU fuses literal generation operations",393 .description = "CPU fuses literal generation operations",
850 .dependencies = featureSet(&[_]Feature{}),394 .dependencies = featureSet(&[_]Feature{}),
851 };395 };
396 result[@enumToInt(Feature.has_v4t)] = .{
397 .llvm_name = "v4t",
398 .description = "Support ARM v4T instructions",
399 .dependencies = featureSet(&[_]Feature{}),
400 };
401 result[@enumToInt(Feature.has_v5t)] = .{
402 .llvm_name = "v5t",
403 .description = "Support ARM v5T instructions",
404 .dependencies = featureSet(&[_]Feature{
405 .has_v4t,
406 }),
407 };
408 result[@enumToInt(Feature.has_v5te)] = .{
409 .llvm_name = "v5te",
410 .description = "Support ARM v5TE, v5TEj, and v5TExp instructions",
411 .dependencies = featureSet(&[_]Feature{
412 .has_v5t,
413 }),
414 };
415 result[@enumToInt(Feature.has_v6)] = .{
416 .llvm_name = "v6",
417 .description = "Support ARM v6 instructions",
418 .dependencies = featureSet(&[_]Feature{
419 .has_v5te,
420 }),
421 };
422 result[@enumToInt(Feature.has_v6k)] = .{
423 .llvm_name = "v6k",
424 .description = "Support ARM v6k instructions",
425 .dependencies = featureSet(&[_]Feature{
426 .has_v6,
427 }),
428 };
429 result[@enumToInt(Feature.has_v6m)] = .{
430 .llvm_name = "v6m",
431 .description = "Support ARM v6M instructions",
432 .dependencies = featureSet(&[_]Feature{
433 .has_v6,
434 }),
435 };
436 result[@enumToInt(Feature.has_v6t2)] = .{
437 .llvm_name = "v6t2",
438 .description = "Support ARM v6t2 instructions",
439 .dependencies = featureSet(&[_]Feature{
440 .thumb2,
441 .has_v6k,
442 .has_v8m,
443 }),
444 };
445 result[@enumToInt(Feature.has_v7)] = .{
446 .llvm_name = "v7",
447 .description = "Support ARM v7 instructions",
448 .dependencies = featureSet(&[_]Feature{
449 .perfmon,
450 .has_v6t2,
451 .has_v7clrex,
452 }),
453 };
454 result[@enumToInt(Feature.has_v7clrex)] = .{
455 .llvm_name = "v7clrex",
456 .description = "Has v7 clrex instruction",
457 .dependencies = featureSet(&[_]Feature{}),
458 };
459 result[@enumToInt(Feature.has_v8)] = .{
460 .llvm_name = "v8",
461 .description = "Support ARM v8 instructions",
462 .dependencies = featureSet(&[_]Feature{
463 .acquire_release,
464 .has_v7,
465 }),
466 };
467 result[@enumToInt(Feature.has_v8_1a)] = .{
468 .llvm_name = "v8.1a",
469 .description = "Support ARM v8.1a instructions",
470 .dependencies = featureSet(&[_]Feature{
471 .has_v8,
472 }),
473 };
474 result[@enumToInt(Feature.has_v8_1m_main)] = .{
475 .llvm_name = "v8.1m.main",
476 .description = "Support ARM v8-1M Mainline instructions",
477 .dependencies = featureSet(&[_]Feature{
478 .has_v8m_main,
479 }),
480 };
481 result[@enumToInt(Feature.has_v8_2a)] = .{
482 .llvm_name = "v8.2a",
483 .description = "Support ARM v8.2a instructions",
484 .dependencies = featureSet(&[_]Feature{
485 .has_v8_1a,
486 }),
487 };
488 result[@enumToInt(Feature.has_v8_3a)] = .{
489 .llvm_name = "v8.3a",
490 .description = "Support ARM v8.3a instructions",
491 .dependencies = featureSet(&[_]Feature{
492 .has_v8_2a,
493 }),
494 };
495 result[@enumToInt(Feature.has_v8_4a)] = .{
496 .llvm_name = "v8.4a",
497 .description = "Support ARM v8.4a instructions",
498 .dependencies = featureSet(&[_]Feature{
499 .dotprod,
500 .has_v8_3a,
501 }),
502 };
503 result[@enumToInt(Feature.has_v8_5a)] = .{
504 .llvm_name = "v8.5a",
505 .description = "Support ARM v8.5a instructions",
506 .dependencies = featureSet(&[_]Feature{
507 .sb,
508 .has_v8_4a,
509 }),
510 };
511 result[@enumToInt(Feature.has_v8m)] = .{
512 .llvm_name = "v8m",
513 .description = "Support ARM v8M Baseline instructions",
514 .dependencies = featureSet(&[_]Feature{
515 .has_v6m,
516 }),
517 };
518 result[@enumToInt(Feature.has_v8m_main)] = .{
519 .llvm_name = "v8m.main",
520 .description = "Support ARM v8M Mainline instructions",
521 .dependencies = featureSet(&[_]Feature{
522 .has_v7,
523 }),
524 };
852 result[@enumToInt(Feature.hwdiv)] = .{525 result[@enumToInt(Feature.hwdiv)] = .{
853 .llvm_name = "hwdiv",526 .llvm_name = "hwdiv",
854 .description = "Enable divide instructions in Thumb",527 .description = "Enable divide instructions in Thumb",
...@@ -863,26 +536,16 @@ pub const all_features = blk: {...@@ -863,26 +536,16 @@ pub const all_features = blk: {
863 .llvm_name = "iwmmxt",536 .llvm_name = "iwmmxt",
864 .description = "ARMv5te architecture",537 .description = "ARMv5te architecture",
865 .dependencies = featureSet(&[_]Feature{538 .dependencies = featureSet(&[_]Feature{
866 .armv5te,539 .has_v5te,
867 }),540 }),
868 };541 };
869 result[@enumToInt(Feature.iwmmxt2)] = .{542 result[@enumToInt(Feature.iwmmxt2)] = .{
870 .llvm_name = "iwmmxt2",543 .llvm_name = "iwmmxt2",
871 .description = "ARMv5te architecture",544 .description = "ARMv5te architecture",
872 .dependencies = featureSet(&[_]Feature{545 .dependencies = featureSet(&[_]Feature{
873 .armv5te,546 .has_v5te,
874 }),547 }),
875 };548 };
876 result[@enumToInt(Feature.krait)] = .{
877 .llvm_name = "krait",
878 .description = "Qualcomm Krait processors",
879 .dependencies = featureSet(&[_]Feature{}),
880 };
881 result[@enumToInt(Feature.kryo)] = .{
882 .llvm_name = "kryo",
883 .description = "Qualcomm Kryo processors",
884 .dependencies = featureSet(&[_]Feature{}),
885 };
886 result[@enumToInt(Feature.lob)] = .{549 result[@enumToInt(Feature.lob)] = .{
887 .llvm_name = "lob",550 .llvm_name = "lob",
888 .description = "Enable Low Overhead Branch extensions",551 .description = "Enable Low Overhead Branch extensions",
...@@ -925,7 +588,7 @@ pub const all_features = blk: {...@@ -925,7 +588,7 @@ pub const all_features = blk: {
925 .dsp,588 .dsp,
926 .fpregs16,589 .fpregs16,
927 .fpregs64,590 .fpregs64,
928 .v8_1m_main,591 .has_v8_1m_main,
929 }),592 }),
930 };593 };
931 result[@enumToInt(Feature.mve_fp)] = .{594 result[@enumToInt(Feature.mve_fp)] = .{
...@@ -1024,21 +687,6 @@ pub const all_features = blk: {...@@ -1024,21 +687,6 @@ pub const all_features = blk: {
1024 .description = "Cortex-R4 ARM processors",687 .description = "Cortex-R4 ARM processors",
1025 .dependencies = featureSet(&[_]Feature{}),688 .dependencies = featureSet(&[_]Feature{}),
1026 };689 };
1027 result[@enumToInt(Feature.r5)] = .{
1028 .llvm_name = "r5",
1029 .description = "Cortex-R5 ARM processors",
1030 .dependencies = featureSet(&[_]Feature{}),
1031 };
1032 result[@enumToInt(Feature.r52)] = .{
1033 .llvm_name = "r52",
1034 .description = "Cortex-R52 ARM processors",
1035 .dependencies = featureSet(&[_]Feature{}),
1036 };
1037 result[@enumToInt(Feature.r7)] = .{
1038 .llvm_name = "r7",
1039 .description = "Cortex-R7 ARM processors",
1040 .dependencies = featureSet(&[_]Feature{}),
1041 };
1042 result[@enumToInt(Feature.ras)] = .{690 result[@enumToInt(Feature.ras)] = .{
1043 .llvm_name = "ras",691 .llvm_name = "ras",
1044 .description = "Enable Reliability, Availability and Serviceability extensions",692 .description = "Enable Reliability, Availability and Serviceability extensions",
...@@ -1133,16 +781,16 @@ pub const all_features = blk: {...@@ -1133,16 +781,16 @@ pub const all_features = blk: {
1133 .description = "Swift ARM processors",781 .description = "Swift ARM processors",
1134 .dependencies = featureSet(&[_]Feature{}),782 .dependencies = featureSet(&[_]Feature{}),
1135 };783 };
1136 result[@enumToInt(Feature.thumb_mode)] = .{
1137 .llvm_name = "thumb-mode",
1138 .description = "Thumb mode",
1139 .dependencies = featureSet(&[_]Feature{}),
1140 };
1141 result[@enumToInt(Feature.thumb2)] = .{784 result[@enumToInt(Feature.thumb2)] = .{
1142 .llvm_name = "thumb2",785 .llvm_name = "thumb2",
1143 .description = "Enable Thumb2 instructions",786 .description = "Enable Thumb2 instructions",
1144 .dependencies = featureSet(&[_]Feature{}),787 .dependencies = featureSet(&[_]Feature{}),
1145 };788 };
789 result[@enumToInt(Feature.thumb_mode)] = .{
790 .llvm_name = "thumb-mode",
791 .description = "Thumb mode",
792 .dependencies = featureSet(&[_]Feature{}),
793 };
1146 result[@enumToInt(Feature.trustzone)] = .{794 result[@enumToInt(Feature.trustzone)] = .{
1147 .llvm_name = "trustzone",795 .llvm_name = "trustzone",
1148 .description = "Enable support for TrustZone security extensions",796 .description = "Enable support for TrustZone security extensions",
...@@ -1153,133 +801,366 @@ pub const all_features = blk: {...@@ -1153,133 +801,366 @@ pub const all_features = blk: {
1153 .description = "Use the MachineScheduler",801 .description = "Use the MachineScheduler",
1154 .dependencies = featureSet(&[_]Feature{}),802 .dependencies = featureSet(&[_]Feature{}),
1155 };803 };
1156 result[@enumToInt(Feature.v4t)] = .{804 result[@enumToInt(Feature.v2)] = .{
1157 .llvm_name = "v4t",805 .llvm_name = "armv2",
1158 .description = "Support ARM v4T instructions",806 .description = "ARMv2 architecture",
807 .dependencies = featureSet(&[_]Feature{}),
808 };
809 result[@enumToInt(Feature.v2a)] = .{
810 .llvm_name = "armv2a",
811 .description = "ARMv2a architecture",
812 .dependencies = featureSet(&[_]Feature{}),
813 };
814 result[@enumToInt(Feature.v3)] = .{
815 .llvm_name = "armv3",
816 .description = "ARMv3 architecture",
817 .dependencies = featureSet(&[_]Feature{}),
818 };
819 result[@enumToInt(Feature.v3m)] = .{
820 .llvm_name = "armv3m",
821 .description = "ARMv3m architecture",
822 .dependencies = featureSet(&[_]Feature{}),
823 };
824 result[@enumToInt(Feature.v4)] = .{
825 .llvm_name = "armv4",
826 .description = "ARMv4 architecture",
1159 .dependencies = featureSet(&[_]Feature{}),827 .dependencies = featureSet(&[_]Feature{}),
1160 };828 };
1161 result[@enumToInt(Feature.v5t)] = .{829 result[@enumToInt(Feature.v4t)] = .{
1162 .llvm_name = "v5t",830 .llvm_name = "armv4t",
1163 .description = "Support ARM v5T instructions",831 .description = "ARMv4t architecture",
832 .dependencies = featureSet(&[_]Feature{
833 .has_v4t,
834 }),
835 };
836 result[@enumToInt(Feature.v5t)] = .{
837 .llvm_name = "armv5t",
838 .description = "ARMv5t architecture",
839 .dependencies = featureSet(&[_]Feature{
840 .has_v5t,
841 }),
842 };
843 result[@enumToInt(Feature.v5te)] = .{
844 .llvm_name = "armv5te",
845 .description = "ARMv5te architecture",
846 .dependencies = featureSet(&[_]Feature{
847 .has_v5te,
848 }),
849 };
850 result[@enumToInt(Feature.v5tej)] = .{
851 .llvm_name = "armv5tej",
852 .description = "ARMv5tej architecture",
853 .dependencies = featureSet(&[_]Feature{
854 .has_v5te,
855 }),
856 };
857 result[@enumToInt(Feature.v6)] = .{
858 .llvm_name = "armv6",
859 .description = "ARMv6 architecture",
860 .dependencies = featureSet(&[_]Feature{
861 .dsp,
862 .has_v6,
863 }),
864 };
865 result[@enumToInt(Feature.v6m)] = .{
866 .llvm_name = "armv6-m",
867 .description = "ARMv6m architecture",
868 .dependencies = featureSet(&[_]Feature{
869 .db,
870 .mclass,
871 .noarm,
872 .strict_align,
873 .thumb_mode,
874 .has_v6m,
875 }),
876 };
877 result[@enumToInt(Feature.v6j)] = .{
878 .llvm_name = "armv6j",
879 .description = "ARMv7a architecture",
880 .dependencies = featureSet(&[_]Feature{
881 .v6,
882 }),
883 };
884 result[@enumToInt(Feature.v6k)] = .{
885 .llvm_name = "armv6k",
886 .description = "ARMv6k architecture",
887 .dependencies = featureSet(&[_]Feature{
888 .has_v6k,
889 }),
890 };
891 result[@enumToInt(Feature.v6kz)] = .{
892 .llvm_name = "armv6kz",
893 .description = "ARMv6kz architecture",
894 .dependencies = featureSet(&[_]Feature{
895 .trustzone,
896 .has_v6k,
897 }),
898 };
899 result[@enumToInt(Feature.v6sm)] = .{
900 .llvm_name = "armv6s-m",
901 .description = "ARMv6sm architecture",
902 .dependencies = featureSet(&[_]Feature{
903 .db,
904 .mclass,
905 .noarm,
906 .strict_align,
907 .thumb_mode,
908 .has_v6m,
909 }),
910 };
911 result[@enumToInt(Feature.v6t2)] = .{
912 .llvm_name = "armv6t2",
913 .description = "ARMv6t2 architecture",
914 .dependencies = featureSet(&[_]Feature{
915 .dsp,
916 .has_v6t2,
917 }),
918 };
919 result[@enumToInt(Feature.v7a)] = .{
920 .llvm_name = "armv7-a",
921 .description = "ARMv7a architecture",
922 .dependencies = featureSet(&[_]Feature{
923 .aclass,
924 .db,
925 .dsp,
926 .neon,
927 .has_v7,
928 }),
929 };
930 result[@enumToInt(Feature.v7m)] = .{
931 .llvm_name = "armv7-m",
932 .description = "ARMv7m architecture",
933 .dependencies = featureSet(&[_]Feature{
934 .db,
935 .hwdiv,
936 .mclass,
937 .noarm,
938 .thumb_mode,
939 .thumb2,
940 .has_v7,
941 }),
942 };
943 result[@enumToInt(Feature.v7r)] = .{
944 .llvm_name = "armv7-r",
945 .description = "ARMv7r architecture",
946 .dependencies = featureSet(&[_]Feature{
947 .db,
948 .dsp,
949 .hwdiv,
950 .rclass,
951 .has_v7,
952 }),
953 };
954 result[@enumToInt(Feature.v7em)] = .{
955 .llvm_name = "armv7e-m",
956 .description = "ARMv7em architecture",
1164 .dependencies = featureSet(&[_]Feature{957 .dependencies = featureSet(&[_]Feature{
1165 .v4t,958 .db,
959 .dsp,
960 .hwdiv,
961 .mclass,
962 .noarm,
963 .thumb_mode,
964 .thumb2,
965 .has_v7,
1166 }),966 }),
1167 };967 };
1168 result[@enumToInt(Feature.v5te)] = .{968 result[@enumToInt(Feature.v7k)] = .{
1169 .llvm_name = "v5te",969 .llvm_name = "armv7k",
1170 .description = "Support ARM v5TE, v5TEj, and v5TExp instructions",970 .description = "ARMv7a architecture",
1171 .dependencies = featureSet(&[_]Feature{971 .dependencies = featureSet(&[_]Feature{
1172 .v5t,972 .v7a,
1173 }),973 }),
1174 };974 };
1175 result[@enumToInt(Feature.v6)] = .{975 result[@enumToInt(Feature.v7s)] = .{
1176 .llvm_name = "v6",976 .llvm_name = "armv7s",
1177 .description = "Support ARM v6 instructions",977 .description = "ARMv7a architecture",
1178 .dependencies = featureSet(&[_]Feature{978 .dependencies = featureSet(&[_]Feature{
1179 .v5te,979 .v7a,
1180 }),980 }),
1181 };981 };
1182 result[@enumToInt(Feature.v6k)] = .{982 result[@enumToInt(Feature.v7ve)] = .{
1183 .llvm_name = "v6k",983 .llvm_name = "armv7ve",
1184 .description = "Support ARM v6k instructions",984 .description = "ARMv7ve architecture",
1185 .dependencies = featureSet(&[_]Feature{985 .dependencies = featureSet(&[_]Feature{
1186 .v6,986 .aclass,
987 .db,
988 .dsp,
989 .mp,
990 .neon,
991 .trustzone,
992 .has_v7,
993 .virtualization,
1187 }),994 }),
1188 };995 };
1189 result[@enumToInt(Feature.v6m)] = .{996 result[@enumToInt(Feature.v8a)] = .{
1190 .llvm_name = "v6m",997 .llvm_name = "armv8-a",
1191 .description = "Support ARM v6M instructions",998 .description = "ARMv8a architecture",
1192 .dependencies = featureSet(&[_]Feature{999 .dependencies = featureSet(&[_]Feature{
1193 .v6,1000 .aclass,
1001 .crc,
1002 .crypto,
1003 .db,
1004 .dsp,
1005 .fp_armv8,
1006 .mp,
1007 .neon,
1008 .trustzone,
1009 .has_v8,
1010 .virtualization,
1194 }),1011 }),
1195 };1012 };
1196 result[@enumToInt(Feature.v6t2)] = .{1013 result[@enumToInt(Feature.v8m)] = .{
1197 .llvm_name = "v6t2",1014 .llvm_name = "armv8-m.base",
1198 .description = "Support ARM v6t2 instructions",1015 .description = "ARMv8mBaseline architecture",
1199 .dependencies = featureSet(&[_]Feature{1016 .dependencies = featureSet(&[_]Feature{
1200 .thumb2,1017 .@"8msecext",
1201 .v6k,1018 .acquire_release,
1202 .v8m,1019 .db,
1020 .hwdiv,
1021 .mclass,
1022 .noarm,
1023 .strict_align,
1024 .thumb_mode,
1025 .has_v7clrex,
1026 .has_v8m,
1203 }),1027 }),
1204 };1028 };
1205 result[@enumToInt(Feature.v7)] = .{1029 result[@enumToInt(Feature.v8m_main)] = .{
1206 .llvm_name = "v7",1030 .llvm_name = "armv8-m.main",
1207 .description = "Support ARM v7 instructions",1031 .description = "ARMv8mMainline architecture",
1208 .dependencies = featureSet(&[_]Feature{1032 .dependencies = featureSet(&[_]Feature{
1209 .perfmon,1033 .@"8msecext",
1210 .v6t2,1034 .acquire_release,
1211 .v7clrex,1035 .db,
1036 .hwdiv,
1037 .mclass,
1038 .noarm,
1039 .thumb_mode,
1040 .has_v8m_main,
1212 }),1041 }),
1213 };1042 };
1214 result[@enumToInt(Feature.v7clrex)] = .{1043 result[@enumToInt(Feature.v8r)] = .{
1215 .llvm_name = "v7clrex",1044 .llvm_name = "armv8-r",
1216 .description = "Has v7 clrex instruction",1045 .description = "ARMv8r architecture",
1217 .dependencies = featureSet(&[_]Feature{}),
1218 };
1219 result[@enumToInt(Feature.v8)] = .{
1220 .llvm_name = "v8",
1221 .description = "Support ARM v8 instructions",
1222 .dependencies = featureSet(&[_]Feature{1046 .dependencies = featureSet(&[_]Feature{
1223 .acquire_release,1047 .crc,
1224 .v7,1048 .db,
1049 .dfb,
1050 .dsp,
1051 .fp_armv8,
1052 .mp,
1053 .neon,
1054 .rclass,
1055 .has_v8,
1056 .virtualization,
1225 }),1057 }),
1226 };1058 };
1227 result[@enumToInt(Feature.v8_1a)] = .{1059 result[@enumToInt(Feature.v8_1a)] = .{
1228 .llvm_name = "v8.1a",1060 .llvm_name = "armv8.1-a",
1229 .description = "Support ARM v8.1a instructions",1061 .description = "ARMv81a architecture",
1230 .dependencies = featureSet(&[_]Feature{1062 .dependencies = featureSet(&[_]Feature{
1231 .v8,1063 .aclass,
1064 .crc,
1065 .crypto,
1066 .db,
1067 .dsp,
1068 .fp_armv8,
1069 .mp,
1070 .neon,
1071 .trustzone,
1072 .has_v8_1a,
1073 .virtualization,
1232 }),1074 }),
1233 };1075 };
1234 result[@enumToInt(Feature.v8_1m_main)] = .{1076 result[@enumToInt(Feature.v8_1m_main)] = .{
1235 .llvm_name = "v8.1m.main",1077 .llvm_name = "armv8.1-m.main",
1236 .description = "Support ARM v8-1M Mainline instructions",1078 .description = "ARMv81mMainline architecture",
1237 .dependencies = featureSet(&[_]Feature{1079 .dependencies = featureSet(&[_]Feature{
1238 .v8m_main,1080 .@"8msecext",
1081 .acquire_release,
1082 .db,
1083 .hwdiv,
1084 .lob,
1085 .mclass,
1086 .noarm,
1087 .ras,
1088 .thumb_mode,
1089 .has_v8_1m_main,
1239 }),1090 }),
1240 };1091 };
1241 result[@enumToInt(Feature.v8_2a)] = .{1092 result[@enumToInt(Feature.v8_2a)] = .{
1242 .llvm_name = "v8.2a",1093 .llvm_name = "armv8.2-a",
1243 .description = "Support ARM v8.2a instructions",1094 .description = "ARMv82a architecture",
1244 .dependencies = featureSet(&[_]Feature{1095 .dependencies = featureSet(&[_]Feature{
1245 .v8_1a,1096 .aclass,
1097 .crc,
1098 .crypto,
1099 .db,
1100 .dsp,
1101 .fp_armv8,
1102 .mp,
1103 .neon,
1104 .ras,
1105 .trustzone,
1106 .has_v8_2a,
1107 .virtualization,
1246 }),1108 }),
1247 };1109 };
1248 result[@enumToInt(Feature.v8_3a)] = .{1110 result[@enumToInt(Feature.v8_3a)] = .{
1249 .llvm_name = "v8.3a",1111 .llvm_name = "armv8.3-a",
1250 .description = "Support ARM v8.3a instructions",1112 .description = "ARMv83a architecture",
1251 .dependencies = featureSet(&[_]Feature{1113 .dependencies = featureSet(&[_]Feature{
1252 .v8_2a,1114 .aclass,
1115 .crc,
1116 .crypto,
1117 .db,
1118 .dsp,
1119 .fp_armv8,
1120 .mp,
1121 .neon,
1122 .ras,
1123 .trustzone,
1124 .has_v8_3a,
1125 .virtualization,
1253 }),1126 }),
1254 };1127 };
1255 result[@enumToInt(Feature.v8_4a)] = .{1128 result[@enumToInt(Feature.v8_4a)] = .{
1256 .llvm_name = "v8.4a",1129 .llvm_name = "armv8.4-a",
1257 .description = "Support ARM v8.4a instructions",1130 .description = "ARMv84a architecture",
1258 .dependencies = featureSet(&[_]Feature{1131 .dependencies = featureSet(&[_]Feature{
1132 .aclass,
1133 .crc,
1134 .crypto,
1135 .db,
1259 .dotprod,1136 .dotprod,
1260 .v8_3a,1137 .dsp,
1138 .fp_armv8,
1139 .mp,
1140 .neon,
1141 .ras,
1142 .trustzone,
1143 .has_v8_4a,
1144 .virtualization,
1261 }),1145 }),
1262 };1146 };
1263 result[@enumToInt(Feature.v8_5a)] = .{1147 result[@enumToInt(Feature.v8_5a)] = .{
1264 .llvm_name = "v8.5a",1148 .llvm_name = "armv8.5-a",
1265 .description = "Support ARM v8.5a instructions",1149 .description = "ARMv85a architecture",
1266 .dependencies = featureSet(&[_]Feature{
1267 .sb,
1268 .v8_4a,
1269 }),
1270 };
1271 result[@enumToInt(Feature.v8m)] = .{
1272 .llvm_name = "v8m",
1273 .description = "Support ARM v8M Baseline instructions",
1274 .dependencies = featureSet(&[_]Feature{
1275 .v6m,
1276 }),
1277 };
1278 result[@enumToInt(Feature.v8m_main)] = .{
1279 .llvm_name = "v8m.main",
1280 .description = "Support ARM v8M Mainline instructions",
1281 .dependencies = featureSet(&[_]Feature{1150 .dependencies = featureSet(&[_]Feature{
1282 .v7,1151 .aclass,
1152 .crc,
1153 .crypto,
1154 .db,
1155 .dotprod,
1156 .dsp,
1157 .fp_armv8,
1158 .mp,
1159 .neon,
1160 .ras,
1161 .trustzone,
1162 .has_v8_5a,
1163 .virtualization,
1283 }),1164 }),
1284 };1165 };
1285 result[@enumToInt(Feature.vfp2)] = .{1166 result[@enumToInt(Feature.vfp2)] = .{
...@@ -1399,7 +1280,7 @@ pub const all_features = blk: {...@@ -1399,7 +1280,7 @@ pub const all_features = blk: {
1399 .llvm_name = "xscale",1280 .llvm_name = "xscale",
1400 .description = "ARMv5te architecture",1281 .description = "ARMv5te architecture",
1401 .dependencies = featureSet(&[_]Feature{1282 .dependencies = featureSet(&[_]Feature{
1402 .armv5te,1283 .has_v5te,
1403 }),1284 }),
1404 };1285 };
1405 result[@enumToInt(Feature.zcz)] = .{1286 result[@enumToInt(Feature.zcz)] = .{
...@@ -1416,221 +1297,227 @@ pub const all_features = blk: {...@@ -1416,221 +1297,227 @@ pub const all_features = blk: {
1416};1297};
14171298
1418pub const cpu = struct {1299pub const cpu = struct {
1419 pub const arm1020e = Cpu{1300 pub const arm1020e = CpuModel{
1420 .name = "arm1020e",1301 .name = "arm1020e",
1421 .llvm_name = "arm1020e",1302 .llvm_name = "arm1020e",
1422 .features = featureSet(&[_]Feature{1303 .features = featureSet(&[_]Feature{
1423 .armv5te,1304 .v5te,
1424 }),1305 }),
1425 };1306 };
1426 pub const arm1020t = Cpu{1307 pub const arm1020t = CpuModel{
1427 .name = "arm1020t",1308 .name = "arm1020t",
1428 .llvm_name = "arm1020t",1309 .llvm_name = "arm1020t",
1429 .features = featureSet(&[_]Feature{1310 .features = featureSet(&[_]Feature{
1430 .armv5t,1311 .v5t,
1431 }),1312 }),
1432 };1313 };
1433 pub const arm1022e = Cpu{1314 pub const arm1022e = CpuModel{
1434 .name = "arm1022e",1315 .name = "arm1022e",
1435 .llvm_name = "arm1022e",1316 .llvm_name = "arm1022e",
1436 .features = featureSet(&[_]Feature{1317 .features = featureSet(&[_]Feature{
1437 .armv5te,1318 .v5te,
1438 }),1319 }),
1439 };1320 };
1440 pub const arm10e = Cpu{1321 pub const arm10e = CpuModel{
1441 .name = "arm10e",1322 .name = "arm10e",
1442 .llvm_name = "arm10e",1323 .llvm_name = "arm10e",
1443 .features = featureSet(&[_]Feature{1324 .features = featureSet(&[_]Feature{
1444 .armv5te,1325 .v5te,
1445 }),1326 }),
1446 };1327 };
1447 pub const arm10tdmi = Cpu{1328 pub const arm10tdmi = CpuModel{
1448 .name = "arm10tdmi",1329 .name = "arm10tdmi",
1449 .llvm_name = "arm10tdmi",1330 .llvm_name = "arm10tdmi",
1450 .features = featureSet(&[_]Feature{1331 .features = featureSet(&[_]Feature{
1451 .armv5t,1332 .v5t,
1452 }),1333 }),
1453 };1334 };
1454 pub const arm1136j_s = Cpu{1335 pub const arm1136j_s = CpuModel{
1455 .name = "arm1136j_s",1336 .name = "arm1136j_s",
1456 .llvm_name = "arm1136j-s",1337 .llvm_name = "arm1136j-s",
1457 .features = featureSet(&[_]Feature{1338 .features = featureSet(&[_]Feature{
1458 .armv6,1339 .v6,
1459 }),1340 }),
1460 };1341 };
1461 pub const arm1136jf_s = Cpu{1342 pub const arm1136jf_s = CpuModel{
1462 .name = "arm1136jf_s",1343 .name = "arm1136jf_s",
1463 .llvm_name = "arm1136jf-s",1344 .llvm_name = "arm1136jf-s",
1464 .features = featureSet(&[_]Feature{1345 .features = featureSet(&[_]Feature{
1465 .armv6,1346 .v6,
1466 .slowfpvmlx,1347 .slowfpvmlx,
1467 .vfp2,1348 .vfp2,
1468 }),1349 }),
1469 };1350 };
1470 pub const arm1156t2_s = Cpu{1351 pub const arm1156t2_s = CpuModel{
1471 .name = "arm1156t2_s",1352 .name = "arm1156t2_s",
1472 .llvm_name = "arm1156t2-s",1353 .llvm_name = "arm1156t2-s",
1473 .features = featureSet(&[_]Feature{1354 .features = featureSet(&[_]Feature{
1474 .armv6t2,1355 .v6t2,
1475 }),1356 }),
1476 };1357 };
1477 pub const arm1156t2f_s = Cpu{1358 pub const arm1156t2f_s = CpuModel{
1478 .name = "arm1156t2f_s",1359 .name = "arm1156t2f_s",
1479 .llvm_name = "arm1156t2f-s",1360 .llvm_name = "arm1156t2f-s",
1480 .features = featureSet(&[_]Feature{1361 .features = featureSet(&[_]Feature{
1481 .armv6t2,1362 .v6t2,
1482 .slowfpvmlx,1363 .slowfpvmlx,
1483 .vfp2,1364 .vfp2,
1484 }),1365 }),
1485 };1366 };
1486 pub const arm1176j_s = Cpu{1367 pub const arm1176j_s = CpuModel{
1487 .name = "arm1176j_s",1368 .name = "arm1176j_s",
1488 .llvm_name = "arm1176j-s",1369 .llvm_name = "arm1176j-s",
1489 .features = featureSet(&[_]Feature{1370 .features = featureSet(&[_]Feature{
1490 .armv6kz,1371 .v6kz,
1491 }),1372 }),
1492 };1373 };
1493 pub const arm1176jz_s = Cpu{1374 pub const arm1176jz_s = CpuModel{
1494 .name = "arm1176jz_s",1375 .name = "arm1176jz_s",
1495 .llvm_name = "arm1176jz-s",1376 .llvm_name = "arm1176jz-s",
1496 .features = featureSet(&[_]Feature{1377 .features = featureSet(&[_]Feature{
1497 .armv6kz,1378 .v6kz,
1498 }),1379 }),
1499 };1380 };
1500 pub const arm1176jzf_s = Cpu{1381 pub const arm1176jzf_s = CpuModel{
1501 .name = "arm1176jzf_s",1382 .name = "arm1176jzf_s",
1502 .llvm_name = "arm1176jzf-s",1383 .llvm_name = "arm1176jzf-s",
1503 .features = featureSet(&[_]Feature{1384 .features = featureSet(&[_]Feature{
1504 .armv6kz,1385 .v6kz,
1505 .slowfpvmlx,1386 .slowfpvmlx,
1506 .vfp2,1387 .vfp2,
1507 }),1388 }),
1508 };1389 };
1509 pub const arm710t = Cpu{1390 pub const arm710t = CpuModel{
1510 .name = "arm710t",1391 .name = "arm710t",
1511 .llvm_name = "arm710t",1392 .llvm_name = "arm710t",
1512 .features = featureSet(&[_]Feature{1393 .features = featureSet(&[_]Feature{
1513 .armv4t,1394 .v4t,
1514 }),1395 }),
1515 };1396 };
1516 pub const arm720t = Cpu{1397 pub const arm720t = CpuModel{
1517 .name = "arm720t",1398 .name = "arm720t",
1518 .llvm_name = "arm720t",1399 .llvm_name = "arm720t",
1519 .features = featureSet(&[_]Feature{1400 .features = featureSet(&[_]Feature{
1520 .armv4t,1401 .v4t,
1521 }),1402 }),
1522 };1403 };
1523 pub const arm7tdmi = Cpu{1404 pub const arm7tdmi = CpuModel{
1524 .name = "arm7tdmi",1405 .name = "arm7tdmi",
1525 .llvm_name = "arm7tdmi",1406 .llvm_name = "arm7tdmi",
1526 .features = featureSet(&[_]Feature{1407 .features = featureSet(&[_]Feature{
1527 .armv4t,1408 .v4t,
1528 }),1409 }),
1529 };1410 };
1530 pub const arm7tdmi_s = Cpu{1411 pub const arm7tdmi_s = CpuModel{
1531 .name = "arm7tdmi_s",1412 .name = "arm7tdmi_s",
1532 .llvm_name = "arm7tdmi-s",1413 .llvm_name = "arm7tdmi-s",
1533 .features = featureSet(&[_]Feature{1414 .features = featureSet(&[_]Feature{
1534 .armv4t,1415 .v4t,
1535 }),1416 }),
1536 };1417 };
1537 pub const arm8 = Cpu{1418 pub const arm8 = CpuModel{
1538 .name = "arm8",1419 .name = "arm8",
1539 .llvm_name = "arm8",1420 .llvm_name = "arm8",
1540 .features = featureSet(&[_]Feature{1421 .features = featureSet(&[_]Feature{
1541 .armv4,1422 .v4,
1542 }),1423 }),
1543 };1424 };
1544 pub const arm810 = Cpu{1425 pub const arm810 = CpuModel{
1545 .name = "arm810",1426 .name = "arm810",
1546 .llvm_name = "arm810",1427 .llvm_name = "arm810",
1547 .features = featureSet(&[_]Feature{1428 .features = featureSet(&[_]Feature{
1548 .armv4,1429 .v4,
1549 }),1430 }),
1550 };1431 };
1551 pub const arm9 = Cpu{1432 pub const arm9 = CpuModel{
1552 .name = "arm9",1433 .name = "arm9",
1553 .llvm_name = "arm9",1434 .llvm_name = "arm9",
1554 .features = featureSet(&[_]Feature{1435 .features = featureSet(&[_]Feature{
1555 .armv4t,1436 .v4t,
1556 }),1437 }),
1557 };1438 };
1558 pub const arm920 = Cpu{1439 pub const arm920 = CpuModel{
1559 .name = "arm920",1440 .name = "arm920",
1560 .llvm_name = "arm920",1441 .llvm_name = "arm920",
1561 .features = featureSet(&[_]Feature{1442 .features = featureSet(&[_]Feature{
1562 .armv4t,1443 .v4t,
1563 }),1444 }),
1564 };1445 };
1565 pub const arm920t = Cpu{1446 pub const arm920t = CpuModel{
1566 .name = "arm920t",1447 .name = "arm920t",
1567 .llvm_name = "arm920t",1448 .llvm_name = "arm920t",
1568 .features = featureSet(&[_]Feature{1449 .features = featureSet(&[_]Feature{
1569 .armv4t,1450 .v4t,
1570 }),1451 }),
1571 };1452 };
1572 pub const arm922t = Cpu{1453 pub const arm922t = CpuModel{
1573 .name = "arm922t",1454 .name = "arm922t",
1574 .llvm_name = "arm922t",1455 .llvm_name = "arm922t",
1575 .features = featureSet(&[_]Feature{1456 .features = featureSet(&[_]Feature{
1576 .armv4t,1457 .v4t,
1577 }),1458 }),
1578 };1459 };
1579 pub const arm926ej_s = Cpu{1460 pub const arm926ej_s = CpuModel{
1580 .name = "arm926ej_s",1461 .name = "arm926ej_s",
1581 .llvm_name = "arm926ej-s",1462 .llvm_name = "arm926ej-s",
1582 .features = featureSet(&[_]Feature{1463 .features = featureSet(&[_]Feature{
1583 .armv5te,1464 .v5te,
1584 }),1465 }),
1585 };1466 };
1586 pub const arm940t = Cpu{1467 pub const arm940t = CpuModel{
1587 .name = "arm940t",1468 .name = "arm940t",
1588 .llvm_name = "arm940t",1469 .llvm_name = "arm940t",
1589 .features = featureSet(&[_]Feature{1470 .features = featureSet(&[_]Feature{
1590 .armv4t,1471 .v4t,
1591 }),1472 }),
1592 };1473 };
1593 pub const arm946e_s = Cpu{1474 pub const arm946e_s = CpuModel{
1594 .name = "arm946e_s",1475 .name = "arm946e_s",
1595 .llvm_name = "arm946e-s",1476 .llvm_name = "arm946e-s",
1596 .features = featureSet(&[_]Feature{1477 .features = featureSet(&[_]Feature{
1597 .armv5te,1478 .v5te,
1598 }),1479 }),
1599 };1480 };
1600 pub const arm966e_s = Cpu{1481 pub const arm966e_s = CpuModel{
1601 .name = "arm966e_s",1482 .name = "arm966e_s",
1602 .llvm_name = "arm966e-s",1483 .llvm_name = "arm966e-s",
1603 .features = featureSet(&[_]Feature{1484 .features = featureSet(&[_]Feature{
1604 .armv5te,1485 .v5te,
1605 }),1486 }),
1606 };1487 };
1607 pub const arm968e_s = Cpu{1488 pub const arm968e_s = CpuModel{
1608 .name = "arm968e_s",1489 .name = "arm968e_s",
1609 .llvm_name = "arm968e-s",1490 .llvm_name = "arm968e-s",
1610 .features = featureSet(&[_]Feature{1491 .features = featureSet(&[_]Feature{
1611 .armv5te,1492 .v5te,
1612 }),1493 }),
1613 };1494 };
1614 pub const arm9e = Cpu{1495 pub const arm9e = CpuModel{
1615 .name = "arm9e",1496 .name = "arm9e",
1616 .llvm_name = "arm9e",1497 .llvm_name = "arm9e",
1617 .features = featureSet(&[_]Feature{1498 .features = featureSet(&[_]Feature{
1618 .armv5te,1499 .v5te,
1619 }),1500 }),
1620 };1501 };
1621 pub const arm9tdmi = Cpu{1502 pub const arm9tdmi = CpuModel{
1622 .name = "arm9tdmi",1503 .name = "arm9tdmi",
1623 .llvm_name = "arm9tdmi",1504 .llvm_name = "arm9tdmi",
1624 .features = featureSet(&[_]Feature{1505 .features = featureSet(&[_]Feature{
1625 .armv4t,1506 .v4t,
1507 }),
1508 };
1509 pub const baseline = CpuModel{
1510 .name = "baseline",
1511 .llvm_name = "generic",
1512 .features = featureSet(&[_]Feature{
1513 .v6m,
1626 }),1514 }),
1627 };1515 };
1628 pub const cortex_a12 = Cpu{1516 pub const cortex_a12 = CpuModel{
1629 .name = "cortex_a12",1517 .name = "cortex_a12",
1630 .llvm_name = "cortex-a12",1518 .llvm_name = "cortex-a12",
1631 .features = featureSet(&[_]Feature{1519 .features = featureSet(&[_]Feature{
1632 .a12,1520 .v7a,
1633 .armv7_a,
1634 .avoid_partial_cpsr,1521 .avoid_partial_cpsr,
1635 .mp,1522 .mp,
1636 .ret_addr_stack,1523 .ret_addr_stack,
...@@ -1640,12 +1527,11 @@ pub const cpu = struct {...@@ -1640,12 +1527,11 @@ pub const cpu = struct {
1640 .vmlx_forwarding,1527 .vmlx_forwarding,
1641 }),1528 }),
1642 };1529 };
1643 pub const cortex_a15 = Cpu{1530 pub const cortex_a15 = CpuModel{
1644 .name = "cortex_a15",1531 .name = "cortex_a15",
1645 .llvm_name = "cortex-a15",1532 .llvm_name = "cortex-a15",
1646 .features = featureSet(&[_]Feature{1533 .features = featureSet(&[_]Feature{
1647 .a15,1534 .v7a,
1648 .armv7_a,
1649 .avoid_partial_cpsr,1535 .avoid_partial_cpsr,
1650 .dont_widen_vmovs,1536 .dont_widen_vmovs,
1651 .mp,1537 .mp,
...@@ -1658,12 +1544,11 @@ pub const cpu = struct {...@@ -1658,12 +1544,11 @@ pub const cpu = struct {
1658 .vldn_align,1544 .vldn_align,
1659 }),1545 }),
1660 };1546 };
1661 pub const cortex_a17 = Cpu{1547 pub const cortex_a17 = CpuModel{
1662 .name = "cortex_a17",1548 .name = "cortex_a17",
1663 .llvm_name = "cortex-a17",1549 .llvm_name = "cortex-a17",
1664 .features = featureSet(&[_]Feature{1550 .features = featureSet(&[_]Feature{
1665 .a17,1551 .v7a,
1666 .armv7_a,
1667 .avoid_partial_cpsr,1552 .avoid_partial_cpsr,
1668 .mp,1553 .mp,
1669 .ret_addr_stack,1554 .ret_addr_stack,
...@@ -1673,35 +1558,33 @@ pub const cpu = struct {...@@ -1673,35 +1558,33 @@ pub const cpu = struct {
1673 .vmlx_forwarding,1558 .vmlx_forwarding,
1674 }),1559 }),
1675 };1560 };
1676 pub const cortex_a32 = Cpu{1561 pub const cortex_a32 = CpuModel{
1677 .name = "cortex_a32",1562 .name = "cortex_a32",
1678 .llvm_name = "cortex-a32",1563 .llvm_name = "cortex-a32",
1679 .features = featureSet(&[_]Feature{1564 .features = featureSet(&[_]Feature{
1680 .armv8_a,
1681 .crc,1565 .crc,
1682 .crypto,1566 .crypto,
1683 .hwdiv,1567 .hwdiv,
1684 .hwdiv_arm,1568 .hwdiv_arm,
1569 .v8a,
1685 }),1570 }),
1686 };1571 };
1687 pub const cortex_a35 = Cpu{1572 pub const cortex_a35 = CpuModel{
1688 .name = "cortex_a35",1573 .name = "cortex_a35",
1689 .llvm_name = "cortex-a35",1574 .llvm_name = "cortex-a35",
1690 .features = featureSet(&[_]Feature{1575 .features = featureSet(&[_]Feature{
1691 .a35,
1692 .armv8_a,
1693 .crc,1576 .crc,
1694 .crypto,1577 .crypto,
1695 .hwdiv,1578 .hwdiv,
1696 .hwdiv_arm,1579 .hwdiv_arm,
1580 .v8a,
1697 }),1581 }),
1698 };1582 };
1699 pub const cortex_a5 = Cpu{1583 pub const cortex_a5 = CpuModel{
1700 .name = "cortex_a5",1584 .name = "cortex_a5",
1701 .llvm_name = "cortex-a5",1585 .llvm_name = "cortex-a5",
1702 .features = featureSet(&[_]Feature{1586 .features = featureSet(&[_]Feature{
1703 .a5,1587 .v7a,
1704 .armv7_a,
1705 .mp,1588 .mp,
1706 .ret_addr_stack,1589 .ret_addr_stack,
1707 .slow_fp_brcc,1590 .slow_fp_brcc,
...@@ -1712,12 +1595,11 @@ pub const cpu = struct {...@@ -1712,12 +1595,11 @@ pub const cpu = struct {
1712 .vmlx_forwarding,1595 .vmlx_forwarding,
1713 }),1596 }),
1714 };1597 };
1715 pub const cortex_a53 = Cpu{1598 pub const cortex_a53 = CpuModel{
1716 .name = "cortex_a53",1599 .name = "cortex_a53",
1717 .llvm_name = "cortex-a53",1600 .llvm_name = "cortex-a53",
1718 .features = featureSet(&[_]Feature{1601 .features = featureSet(&[_]Feature{
1719 .a53,1602 .v8a,
1720 .armv8_a,
1721 .crc,1603 .crc,
1722 .crypto,1604 .crypto,
1723 .fpao,1605 .fpao,
...@@ -1725,23 +1607,21 @@ pub const cpu = struct {...@@ -1725,23 +1607,21 @@ pub const cpu = struct {
1725 .hwdiv_arm,1607 .hwdiv_arm,
1726 }),1608 }),
1727 };1609 };
1728 pub const cortex_a55 = Cpu{1610 pub const cortex_a55 = CpuModel{
1729 .name = "cortex_a55",1611 .name = "cortex_a55",
1730 .llvm_name = "cortex-a55",1612 .llvm_name = "cortex-a55",
1731 .features = featureSet(&[_]Feature{1613 .features = featureSet(&[_]Feature{
1732 .a55,1614 .v8_2a,
1733 .armv8_2_a,
1734 .dotprod,1615 .dotprod,
1735 .hwdiv,1616 .hwdiv,
1736 .hwdiv_arm,1617 .hwdiv_arm,
1737 }),1618 }),
1738 };1619 };
1739 pub const cortex_a57 = Cpu{1620 pub const cortex_a57 = CpuModel{
1740 .name = "cortex_a57",1621 .name = "cortex_a57",
1741 .llvm_name = "cortex-a57",1622 .llvm_name = "cortex-a57",
1742 .features = featureSet(&[_]Feature{1623 .features = featureSet(&[_]Feature{
1743 .a57,1624 .v8a,
1744 .armv8_a,
1745 .avoid_partial_cpsr,1625 .avoid_partial_cpsr,
1746 .cheap_predicable_cpsr,1626 .cheap_predicable_cpsr,
1747 .crc,1627 .crc,
...@@ -1751,12 +1631,11 @@ pub const cpu = struct {...@@ -1751,12 +1631,11 @@ pub const cpu = struct {
1751 .hwdiv_arm,1631 .hwdiv_arm,
1752 }),1632 }),
1753 };1633 };
1754 pub const cortex_a7 = Cpu{1634 pub const cortex_a7 = CpuModel{
1755 .name = "cortex_a7",1635 .name = "cortex_a7",
1756 .llvm_name = "cortex-a7",1636 .llvm_name = "cortex-a7",
1757 .features = featureSet(&[_]Feature{1637 .features = featureSet(&[_]Feature{
1758 .a7,1638 .v7a,
1759 .armv7_a,
1760 .mp,1639 .mp,
1761 .ret_addr_stack,1640 .ret_addr_stack,
1762 .slow_fp_brcc,1641 .slow_fp_brcc,
...@@ -1769,47 +1648,44 @@ pub const cpu = struct {...@@ -1769,47 +1648,44 @@ pub const cpu = struct {
1769 .vmlx_hazards,1648 .vmlx_hazards,
1770 }),1649 }),
1771 };1650 };
1772 pub const cortex_a72 = Cpu{1651 pub const cortex_a72 = CpuModel{
1773 .name = "cortex_a72",1652 .name = "cortex_a72",
1774 .llvm_name = "cortex-a72",1653 .llvm_name = "cortex-a72",
1775 .features = featureSet(&[_]Feature{1654 .features = featureSet(&[_]Feature{
1776 .a72,1655 .v8a,
1777 .armv8_a,
1778 .crc,1656 .crc,
1779 .crypto,1657 .crypto,
1780 .hwdiv,1658 .hwdiv,
1781 .hwdiv_arm,1659 .hwdiv_arm,
1782 }),1660 }),
1783 };1661 };
1784 pub const cortex_a73 = Cpu{1662 pub const cortex_a73 = CpuModel{
1785 .name = "cortex_a73",1663 .name = "cortex_a73",
1786 .llvm_name = "cortex-a73",1664 .llvm_name = "cortex-a73",
1787 .features = featureSet(&[_]Feature{1665 .features = featureSet(&[_]Feature{
1788 .a73,1666 .v8a,
1789 .armv8_a,
1790 .crc,1667 .crc,
1791 .crypto,1668 .crypto,
1792 .hwdiv,1669 .hwdiv,
1793 .hwdiv_arm,1670 .hwdiv_arm,
1794 }),1671 }),
1795 };1672 };
1796 pub const cortex_a75 = Cpu{1673 pub const cortex_a75 = CpuModel{
1797 .name = "cortex_a75",1674 .name = "cortex_a75",
1798 .llvm_name = "cortex-a75",1675 .llvm_name = "cortex-a75",
1799 .features = featureSet(&[_]Feature{1676 .features = featureSet(&[_]Feature{
1800 .a75,1677 .v8_2a,
1801 .armv8_2_a,
1802 .dotprod,1678 .dotprod,
1803 .hwdiv,1679 .hwdiv,
1804 .hwdiv_arm,1680 .hwdiv_arm,
1805 }),1681 }),
1806 };1682 };
1807 pub const cortex_a76 = Cpu{1683 pub const cortex_a76 = CpuModel{
1808 .name = "cortex_a76",1684 .name = "cortex_a76",
1809 .llvm_name = "cortex-a76",1685 .llvm_name = "cortex-a76",
1810 .features = featureSet(&[_]Feature{1686 .features = featureSet(&[_]Feature{
1811 .a76,1687 .a76,
1812 .armv8_2_a,1688 .v8_2a,
1813 .crc,1689 .crc,
1814 .crypto,1690 .crypto,
1815 .dotprod,1691 .dotprod,
...@@ -1818,12 +1694,12 @@ pub const cpu = struct {...@@ -1818,12 +1694,12 @@ pub const cpu = struct {
1818 .hwdiv_arm,1694 .hwdiv_arm,
1819 }),1695 }),
1820 };1696 };
1821 pub const cortex_a76ae = Cpu{1697 pub const cortex_a76ae = CpuModel{
1822 .name = "cortex_a76ae",1698 .name = "cortex_a76ae",
1823 .llvm_name = "cortex-a76ae",1699 .llvm_name = "cortex-a76ae",
1824 .features = featureSet(&[_]Feature{1700 .features = featureSet(&[_]Feature{
1825 .a76,1701 .a76,
1826 .armv8_2_a,1702 .v8_2a,
1827 .crc,1703 .crc,
1828 .crypto,1704 .crypto,
1829 .dotprod,1705 .dotprod,
...@@ -1832,12 +1708,11 @@ pub const cpu = struct {...@@ -1832,12 +1708,11 @@ pub const cpu = struct {
1832 .hwdiv_arm,1708 .hwdiv_arm,
1833 }),1709 }),
1834 };1710 };
1835 pub const cortex_a8 = Cpu{1711 pub const cortex_a8 = CpuModel{
1836 .name = "cortex_a8",1712 .name = "cortex_a8",
1837 .llvm_name = "cortex-a8",1713 .llvm_name = "cortex-a8",
1838 .features = featureSet(&[_]Feature{1714 .features = featureSet(&[_]Feature{
1839 .a8,1715 .v7a,
1840 .armv7_a,
1841 .nonpipelined_vfp,1716 .nonpipelined_vfp,
1842 .ret_addr_stack,1717 .ret_addr_stack,
1843 .slow_fp_brcc,1718 .slow_fp_brcc,
...@@ -1848,12 +1723,11 @@ pub const cpu = struct {...@@ -1848,12 +1723,11 @@ pub const cpu = struct {
1848 .vmlx_hazards,1723 .vmlx_hazards,
1849 }),1724 }),
1850 };1725 };
1851 pub const cortex_a9 = Cpu{1726 pub const cortex_a9 = CpuModel{
1852 .name = "cortex_a9",1727 .name = "cortex_a9",
1853 .llvm_name = "cortex-a9",1728 .llvm_name = "cortex-a9",
1854 .features = featureSet(&[_]Feature{1729 .features = featureSet(&[_]Feature{
1855 .a9,1730 .v7a,
1856 .armv7_a,
1857 .avoid_partial_cpsr,1731 .avoid_partial_cpsr,
1858 .expand_fp_mlx,1732 .expand_fp_mlx,
1859 .fp16,1733 .fp16,
...@@ -1868,51 +1742,51 @@ pub const cpu = struct {...@@ -1868,51 +1742,51 @@ pub const cpu = struct {
1868 .vmlx_hazards,1742 .vmlx_hazards,
1869 }),1743 }),
1870 };1744 };
1871 pub const cortex_m0 = Cpu{1745 pub const cortex_m0 = CpuModel{
1872 .name = "cortex_m0",1746 .name = "cortex_m0",
1873 .llvm_name = "cortex-m0",1747 .llvm_name = "cortex-m0",
1874 .features = featureSet(&[_]Feature{1748 .features = featureSet(&[_]Feature{
1875 .armv6_m,1749 .v6m,
1876 }),1750 }),
1877 };1751 };
1878 pub const cortex_m0plus = Cpu{1752 pub const cortex_m0plus = CpuModel{
1879 .name = "cortex_m0plus",1753 .name = "cortex_m0plus",
1880 .llvm_name = "cortex-m0plus",1754 .llvm_name = "cortex-m0plus",
1881 .features = featureSet(&[_]Feature{1755 .features = featureSet(&[_]Feature{
1882 .armv6_m,1756 .v6m,
1883 }),1757 }),
1884 };1758 };
1885 pub const cortex_m1 = Cpu{1759 pub const cortex_m1 = CpuModel{
1886 .name = "cortex_m1",1760 .name = "cortex_m1",
1887 .llvm_name = "cortex-m1",1761 .llvm_name = "cortex-m1",
1888 .features = featureSet(&[_]Feature{1762 .features = featureSet(&[_]Feature{
1889 .armv6_m,1763 .v6m,
1890 }),1764 }),
1891 };1765 };
1892 pub const cortex_m23 = Cpu{1766 pub const cortex_m23 = CpuModel{
1893 .name = "cortex_m23",1767 .name = "cortex_m23",
1894 .llvm_name = "cortex-m23",1768 .llvm_name = "cortex-m23",
1895 .features = featureSet(&[_]Feature{1769 .features = featureSet(&[_]Feature{
1896 .armv8_m_base,1770 .v8m,
1897 .no_movt,1771 .no_movt,
1898 }),1772 }),
1899 };1773 };
1900 pub const cortex_m3 = Cpu{1774 pub const cortex_m3 = CpuModel{
1901 .name = "cortex_m3",1775 .name = "cortex_m3",
1902 .llvm_name = "cortex-m3",1776 .llvm_name = "cortex-m3",
1903 .features = featureSet(&[_]Feature{1777 .features = featureSet(&[_]Feature{
1904 .armv7_m,1778 .v7m,
1905 .loop_align,1779 .loop_align,
1906 .m3,1780 .m3,
1907 .no_branch_predictor,1781 .no_branch_predictor,
1908 .use_misched,1782 .use_misched,
1909 }),1783 }),
1910 };1784 };
1911 pub const cortex_m33 = Cpu{1785 pub const cortex_m33 = CpuModel{
1912 .name = "cortex_m33",1786 .name = "cortex_m33",
1913 .llvm_name = "cortex-m33",1787 .llvm_name = "cortex-m33",
1914 .features = featureSet(&[_]Feature{1788 .features = featureSet(&[_]Feature{
1915 .armv8_m_main,1789 .v8m_main,
1916 .dsp,1790 .dsp,
1917 .fp_armv8d16sp,1791 .fp_armv8d16sp,
1918 .loop_align,1792 .loop_align,
...@@ -1922,11 +1796,11 @@ pub const cpu = struct {...@@ -1922,11 +1796,11 @@ pub const cpu = struct {
1922 .use_misched,1796 .use_misched,
1923 }),1797 }),
1924 };1798 };
1925 pub const cortex_m35p = Cpu{1799 pub const cortex_m35p = CpuModel{
1926 .name = "cortex_m35p",1800 .name = "cortex_m35p",
1927 .llvm_name = "cortex-m35p",1801 .llvm_name = "cortex-m35p",
1928 .features = featureSet(&[_]Feature{1802 .features = featureSet(&[_]Feature{
1929 .armv8_m_main,1803 .v8m_main,
1930 .dsp,1804 .dsp,
1931 .fp_armv8d16sp,1805 .fp_armv8d16sp,
1932 .loop_align,1806 .loop_align,
...@@ -1936,11 +1810,11 @@ pub const cpu = struct {...@@ -1936,11 +1810,11 @@ pub const cpu = struct {
1936 .use_misched,1810 .use_misched,
1937 }),1811 }),
1938 };1812 };
1939 pub const cortex_m4 = Cpu{1813 pub const cortex_m4 = CpuModel{
1940 .name = "cortex_m4",1814 .name = "cortex_m4",
1941 .llvm_name = "cortex-m4",1815 .llvm_name = "cortex-m4",
1942 .features = featureSet(&[_]Feature{1816 .features = featureSet(&[_]Feature{
1943 .armv7e_m,1817 .v7em,
1944 .loop_align,1818 .loop_align,
1945 .no_branch_predictor,1819 .no_branch_predictor,
1946 .slowfpvfmx,1820 .slowfpvfmx,
...@@ -1949,29 +1823,29 @@ pub const cpu = struct {...@@ -1949,29 +1823,29 @@ pub const cpu = struct {
1949 .vfp4d16sp,1823 .vfp4d16sp,
1950 }),1824 }),
1951 };1825 };
1952 pub const cortex_m7 = Cpu{1826 pub const cortex_m7 = CpuModel{
1953 .name = "cortex_m7",1827 .name = "cortex_m7",
1954 .llvm_name = "cortex-m7",1828 .llvm_name = "cortex-m7",
1955 .features = featureSet(&[_]Feature{1829 .features = featureSet(&[_]Feature{
1956 .armv7e_m,1830 .v7em,
1957 .fp_armv8d16,1831 .fp_armv8d16,
1958 }),1832 }),
1959 };1833 };
1960 pub const cortex_r4 = Cpu{1834 pub const cortex_r4 = CpuModel{
1961 .name = "cortex_r4",1835 .name = "cortex_r4",
1962 .llvm_name = "cortex-r4",1836 .llvm_name = "cortex-r4",
1963 .features = featureSet(&[_]Feature{1837 .features = featureSet(&[_]Feature{
1964 .armv7_r,1838 .v7r,
1965 .avoid_partial_cpsr,1839 .avoid_partial_cpsr,
1966 .r4,1840 .r4,
1967 .ret_addr_stack,1841 .ret_addr_stack,
1968 }),1842 }),
1969 };1843 };
1970 pub const cortex_r4f = Cpu{1844 pub const cortex_r4f = CpuModel{
1971 .name = "cortex_r4f",1845 .name = "cortex_r4f",
1972 .llvm_name = "cortex-r4f",1846 .llvm_name = "cortex-r4f",
1973 .features = featureSet(&[_]Feature{1847 .features = featureSet(&[_]Feature{
1974 .armv7_r,1848 .v7r,
1975 .avoid_partial_cpsr,1849 .avoid_partial_cpsr,
1976 .r4,1850 .r4,
1977 .ret_addr_stack,1851 .ret_addr_stack,
...@@ -1981,14 +1855,13 @@ pub const cpu = struct {...@@ -1981,14 +1855,13 @@ pub const cpu = struct {
1981 .vfp3d16,1855 .vfp3d16,
1982 }),1856 }),
1983 };1857 };
1984 pub const cortex_r5 = Cpu{1858 pub const cortex_r5 = CpuModel{
1985 .name = "cortex_r5",1859 .name = "cortex_r5",
1986 .llvm_name = "cortex-r5",1860 .llvm_name = "cortex-r5",
1987 .features = featureSet(&[_]Feature{1861 .features = featureSet(&[_]Feature{
1988 .armv7_r,1862 .v7r,
1989 .avoid_partial_cpsr,1863 .avoid_partial_cpsr,
1990 .hwdiv_arm,1864 .hwdiv_arm,
1991 .r5,
1992 .ret_addr_stack,1865 .ret_addr_stack,
1993 .slow_fp_brcc,1866 .slow_fp_brcc,
1994 .slowfpvfmx,1867 .slowfpvfmx,
...@@ -1996,26 +1869,24 @@ pub const cpu = struct {...@@ -1996,26 +1869,24 @@ pub const cpu = struct {
1996 .vfp3d16,1869 .vfp3d16,
1997 }),1870 }),
1998 };1871 };
1999 pub const cortex_r52 = Cpu{1872 pub const cortex_r52 = CpuModel{
2000 .name = "cortex_r52",1873 .name = "cortex_r52",
2001 .llvm_name = "cortex-r52",1874 .llvm_name = "cortex-r52",
2002 .features = featureSet(&[_]Feature{1875 .features = featureSet(&[_]Feature{
2003 .armv8_r,1876 .v8r,
2004 .fpao,1877 .fpao,
2005 .r52,
2006 .use_misched,1878 .use_misched,
2007 }),1879 }),
2008 };1880 };
2009 pub const cortex_r7 = Cpu{1881 pub const cortex_r7 = CpuModel{
2010 .name = "cortex_r7",1882 .name = "cortex_r7",
2011 .llvm_name = "cortex-r7",1883 .llvm_name = "cortex-r7",
2012 .features = featureSet(&[_]Feature{1884 .features = featureSet(&[_]Feature{
2013 .armv7_r,1885 .v7r,
2014 .avoid_partial_cpsr,1886 .avoid_partial_cpsr,
2015 .fp16,1887 .fp16,
2016 .hwdiv_arm,1888 .hwdiv_arm,
2017 .mp,1889 .mp,
2018 .r7,
2019 .ret_addr_stack,1890 .ret_addr_stack,
2020 .slow_fp_brcc,1891 .slow_fp_brcc,
2021 .slowfpvfmx,1892 .slowfpvfmx,
...@@ -2023,11 +1894,11 @@ pub const cpu = struct {...@@ -2023,11 +1894,11 @@ pub const cpu = struct {
2023 .vfp3d16,1894 .vfp3d16,
2024 }),1895 }),
2025 };1896 };
2026 pub const cortex_r8 = Cpu{1897 pub const cortex_r8 = CpuModel{
2027 .name = "cortex_r8",1898 .name = "cortex_r8",
2028 .llvm_name = "cortex-r8",1899 .llvm_name = "cortex-r8",
2029 .features = featureSet(&[_]Feature{1900 .features = featureSet(&[_]Feature{
2030 .armv7_r,1901 .v7r,
2031 .avoid_partial_cpsr,1902 .avoid_partial_cpsr,
2032 .fp16,1903 .fp16,
2033 .hwdiv_arm,1904 .hwdiv_arm,
...@@ -2039,11 +1910,11 @@ pub const cpu = struct {...@@ -2039,11 +1910,11 @@ pub const cpu = struct {
2039 .vfp3d16,1910 .vfp3d16,
2040 }),1911 }),
2041 };1912 };
2042 pub const cyclone = Cpu{1913 pub const cyclone = CpuModel{
2043 .name = "cyclone",1914 .name = "cyclone",
2044 .llvm_name = "cyclone",1915 .llvm_name = "cyclone",
2045 .features = featureSet(&[_]Feature{1916 .features = featureSet(&[_]Feature{
2046 .armv8_a,1917 .v8a,
2047 .avoid_movs_shop,1918 .avoid_movs_shop,
2048 .avoid_partial_cpsr,1919 .avoid_partial_cpsr,
2049 .crypto,1920 .crypto,
...@@ -2061,119 +1932,117 @@ pub const cpu = struct {...@@ -2061,119 +1932,117 @@ pub const cpu = struct {
2061 .zcz,1932 .zcz,
2062 }),1933 }),
2063 };1934 };
2064 pub const ep9312 = Cpu{1935 pub const ep9312 = CpuModel{
2065 .name = "ep9312",1936 .name = "ep9312",
2066 .llvm_name = "ep9312",1937 .llvm_name = "ep9312",
2067 .features = featureSet(&[_]Feature{1938 .features = featureSet(&[_]Feature{
2068 .armv4t,1939 .v4t,
2069 }),1940 }),
2070 };1941 };
2071 pub const exynos_m1 = Cpu{1942 pub const exynos_m1 = CpuModel{
2072 .name = "exynos_m1",1943 .name = "exynos_m1",
2073 .llvm_name = null,1944 .llvm_name = null,
2074 .features = featureSet(&[_]Feature{1945 .features = featureSet(&[_]Feature{
2075 .armv8_a,1946 .v8a,
2076 .exynos,1947 .exynos,
2077 }),1948 }),
2078 };1949 };
2079 pub const exynos_m2 = Cpu{1950 pub const exynos_m2 = CpuModel{
2080 .name = "exynos_m2",1951 .name = "exynos_m2",
2081 .llvm_name = null,1952 .llvm_name = null,
2082 .features = featureSet(&[_]Feature{1953 .features = featureSet(&[_]Feature{
2083 .armv8_a,1954 .v8a,
2084 .exynos,1955 .exynos,
2085 }),1956 }),
2086 };1957 };
2087 pub const exynos_m3 = Cpu{1958 pub const exynos_m3 = CpuModel{
2088 .name = "exynos_m3",1959 .name = "exynos_m3",
2089 .llvm_name = "exynos-m3",1960 .llvm_name = "exynos-m3",
2090 .features = featureSet(&[_]Feature{1961 .features = featureSet(&[_]Feature{
2091 .armv8_a,1962 .v8_2a,
2092 .exynos,1963 .exynos,
2093 }),1964 }),
2094 };1965 };
2095 pub const exynos_m4 = Cpu{1966 pub const exynos_m4 = CpuModel{
2096 .name = "exynos_m4",1967 .name = "exynos_m4",
2097 .llvm_name = "exynos-m4",1968 .llvm_name = "exynos-m4",
2098 .features = featureSet(&[_]Feature{1969 .features = featureSet(&[_]Feature{
2099 .armv8_2_a,1970 .v8_2a,
2100 .dotprod,1971 .dotprod,
2101 .exynos,1972 .exynos,
2102 .fullfp16,1973 .fullfp16,
2103 }),1974 }),
2104 };1975 };
2105 pub const exynos_m5 = Cpu{1976 pub const exynos_m5 = CpuModel{
2106 .name = "exynos_m5",1977 .name = "exynos_m5",
2107 .llvm_name = "exynos-m5",1978 .llvm_name = "exynos-m5",
2108 .features = featureSet(&[_]Feature{1979 .features = featureSet(&[_]Feature{
2109 .armv8_2_a,
2110 .dotprod,1980 .dotprod,
2111 .exynos,1981 .exynos,
2112 .fullfp16,1982 .fullfp16,
1983 .v8_2a,
2113 }),1984 }),
2114 };1985 };
2115 pub const generic = Cpu{1986 pub const generic = CpuModel{
2116 .name = "generic",1987 .name = "generic",
2117 .llvm_name = "generic",1988 .llvm_name = "generic",
2118 .features = featureSet(&[_]Feature{}),1989 .features = featureSet(&[_]Feature{}),
2119 };1990 };
2120 pub const iwmmxt = Cpu{1991 pub const iwmmxt = CpuModel{
2121 .name = "iwmmxt",1992 .name = "iwmmxt",
2122 .llvm_name = "iwmmxt",1993 .llvm_name = "iwmmxt",
2123 .features = featureSet(&[_]Feature{1994 .features = featureSet(&[_]Feature{
2124 .armv5te,1995 .v5te,
2125 }),1996 }),
2126 };1997 };
2127 pub const krait = Cpu{1998 pub const krait = CpuModel{
2128 .name = "krait",1999 .name = "krait",
2129 .llvm_name = "krait",2000 .llvm_name = "krait",
2130 .features = featureSet(&[_]Feature{2001 .features = featureSet(&[_]Feature{
2131 .armv7_a,
2132 .avoid_partial_cpsr,2002 .avoid_partial_cpsr,
2133 .fp16,2003 .fp16,
2134 .hwdiv,2004 .hwdiv,
2135 .hwdiv_arm,2005 .hwdiv_arm,
2136 .krait,
2137 .muxed_units,2006 .muxed_units,
2138 .ret_addr_stack,2007 .ret_addr_stack,
2008 .v7a,
2139 .vfp4,2009 .vfp4,
2140 .vldn_align,2010 .vldn_align,
2141 .vmlx_forwarding,2011 .vmlx_forwarding,
2142 }),2012 }),
2143 };2013 };
2144 pub const kryo = Cpu{2014 pub const kryo = CpuModel{
2145 .name = "kryo",2015 .name = "kryo",
2146 .llvm_name = "kryo",2016 .llvm_name = "kryo",
2147 .features = featureSet(&[_]Feature{2017 .features = featureSet(&[_]Feature{
2148 .armv8_a,
2149 .crc,2018 .crc,
2150 .crypto,2019 .crypto,
2151 .hwdiv,2020 .hwdiv,
2152 .hwdiv_arm,2021 .hwdiv_arm,
2153 .kryo,2022 .v8a,
2154 }),2023 }),
2155 };2024 };
2156 pub const mpcore = Cpu{2025 pub const mpcore = CpuModel{
2157 .name = "mpcore",2026 .name = "mpcore",
2158 .llvm_name = "mpcore",2027 .llvm_name = "mpcore",
2159 .features = featureSet(&[_]Feature{2028 .features = featureSet(&[_]Feature{
2160 .armv6k,2029 .v6k,
2161 .slowfpvmlx,2030 .slowfpvmlx,
2162 .vfp2,2031 .vfp2,
2163 }),2032 }),
2164 };2033 };
2165 pub const mpcorenovfp = Cpu{2034 pub const mpcorenovfp = CpuModel{
2166 .name = "mpcorenovfp",2035 .name = "mpcorenovfp",
2167 .llvm_name = "mpcorenovfp",2036 .llvm_name = "mpcorenovfp",
2168 .features = featureSet(&[_]Feature{2037 .features = featureSet(&[_]Feature{
2169 .armv6k,2038 .v6k,
2170 }),2039 }),
2171 };2040 };
2172 pub const neoverse_n1 = Cpu{2041 pub const neoverse_n1 = CpuModel{
2173 .name = "neoverse_n1",2042 .name = "neoverse_n1",
2174 .llvm_name = "neoverse-n1",2043 .llvm_name = "neoverse-n1",
2175 .features = featureSet(&[_]Feature{2044 .features = featureSet(&[_]Feature{
2176 .armv8_2_a,2045 .v8_2a,
2177 .crc,2046 .crc,
2178 .crypto,2047 .crypto,
2179 .dotprod,2048 .dotprod,
...@@ -2181,56 +2050,56 @@ pub const cpu = struct {...@@ -2181,56 +2050,56 @@ pub const cpu = struct {
2181 .hwdiv_arm,2050 .hwdiv_arm,
2182 }),2051 }),
2183 };2052 };
2184 pub const sc000 = Cpu{2053 pub const sc000 = CpuModel{
2185 .name = "sc000",2054 .name = "sc000",
2186 .llvm_name = "sc000",2055 .llvm_name = "sc000",
2187 .features = featureSet(&[_]Feature{2056 .features = featureSet(&[_]Feature{
2188 .armv6_m,2057 .v6m,
2189 }),2058 }),
2190 };2059 };
2191 pub const sc300 = Cpu{2060 pub const sc300 = CpuModel{
2192 .name = "sc300",2061 .name = "sc300",
2193 .llvm_name = "sc300",2062 .llvm_name = "sc300",
2194 .features = featureSet(&[_]Feature{2063 .features = featureSet(&[_]Feature{
2195 .armv7_m,2064 .v7m,
2196 .m3,2065 .m3,
2197 .no_branch_predictor,2066 .no_branch_predictor,
2198 .use_misched,2067 .use_misched,
2199 }),2068 }),
2200 };2069 };
2201 pub const strongarm = Cpu{2070 pub const strongarm = CpuModel{
2202 .name = "strongarm",2071 .name = "strongarm",
2203 .llvm_name = "strongarm",2072 .llvm_name = "strongarm",
2204 .features = featureSet(&[_]Feature{2073 .features = featureSet(&[_]Feature{
2205 .armv4,2074 .v4,
2206 }),2075 }),
2207 };2076 };
2208 pub const strongarm110 = Cpu{2077 pub const strongarm110 = CpuModel{
2209 .name = "strongarm110",2078 .name = "strongarm110",
2210 .llvm_name = "strongarm110",2079 .llvm_name = "strongarm110",
2211 .features = featureSet(&[_]Feature{2080 .features = featureSet(&[_]Feature{
2212 .armv4,2081 .v4,
2213 }),2082 }),
2214 };2083 };
2215 pub const strongarm1100 = Cpu{2084 pub const strongarm1100 = CpuModel{
2216 .name = "strongarm1100",2085 .name = "strongarm1100",
2217 .llvm_name = "strongarm1100",2086 .llvm_name = "strongarm1100",
2218 .features = featureSet(&[_]Feature{2087 .features = featureSet(&[_]Feature{
2219 .armv4,2088 .v4,
2220 }),2089 }),
2221 };2090 };
2222 pub const strongarm1110 = Cpu{2091 pub const strongarm1110 = CpuModel{
2223 .name = "strongarm1110",2092 .name = "strongarm1110",
2224 .llvm_name = "strongarm1110",2093 .llvm_name = "strongarm1110",
2225 .features = featureSet(&[_]Feature{2094 .features = featureSet(&[_]Feature{
2226 .armv4,2095 .v4,
2227 }),2096 }),
2228 };2097 };
2229 pub const swift = Cpu{2098 pub const swift = CpuModel{
2230 .name = "swift",2099 .name = "swift",
2231 .llvm_name = "swift",2100 .llvm_name = "swift",
2232 .features = featureSet(&[_]Feature{2101 .features = featureSet(&[_]Feature{
2233 .armv7_a,2102 .v7a,
2234 .avoid_movs_shop,2103 .avoid_movs_shop,
2235 .avoid_partial_cpsr,2104 .avoid_partial_cpsr,
2236 .disable_postra_scheduler,2105 .disable_postra_scheduler,
...@@ -2254,11 +2123,11 @@ pub const cpu = struct {...@@ -2254,11 +2123,11 @@ pub const cpu = struct {
2254 .wide_stride_vfp,2123 .wide_stride_vfp,
2255 }),2124 }),
2256 };2125 };
2257 pub const xscale = Cpu{2126 pub const xscale = CpuModel{
2258 .name = "xscale",2127 .name = "xscale",
2259 .llvm_name = "xscale",2128 .llvm_name = "xscale",
2260 .features = featureSet(&[_]Feature{2129 .features = featureSet(&[_]Feature{
2261 .armv5te,2130 .v5te,
2262 }),2131 }),
2263 };2132 };
2264};2133};
...@@ -2266,7 +2135,7 @@ pub const cpu = struct {...@@ -2266,7 +2135,7 @@ pub const cpu = struct {
2266/// All arm CPUs, sorted alphabetically by name.2135/// All arm CPUs, sorted alphabetically by name.
2267/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage12136/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
2268/// compiler has inefficient memory and CPU usage, affecting build times.2137/// compiler has inefficient memory and CPU usage, affecting build times.
2269pub const all_cpus = &[_]*const Cpu{2138pub const all_cpus = &[_]*const CpuModel{
2270 &cpu.arm1020e,2139 &cpu.arm1020e,
2271 &cpu.arm1020t,2140 &cpu.arm1020t,
2272 &cpu.arm1022e,2141 &cpu.arm1022e,
lib/std/target/avr.zig+263-262
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2const Cpu = std.Target.Cpu;2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
34
4pub const Feature = enum {5pub const Feature = enum {
5 addsubiw,6 addsubiw,
...@@ -37,12 +38,12 @@ pub const Feature = enum {...@@ -37,12 +38,12 @@ pub const Feature = enum {
37 xmegau,38 xmegau,
38};39};
3940
40pub usingnamespace Cpu.Feature.feature_set_fns(Feature);41pub usingnamespace CpuFeature.feature_set_fns(Feature);
4142
42pub const all_features = blk: {43pub const all_features = blk: {
43 const len = @typeInfo(Feature).Enum.fields.len;44 const len = @typeInfo(Feature).Enum.fields.len;
44 std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);45 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
45 var result: [len]Cpu.Feature = undefined;46 var result: [len]CpuFeature = undefined;
46 result[@enumToInt(Feature.addsubiw)] = .{47 result[@enumToInt(Feature.addsubiw)] = .{
47 .llvm_name = "addsubiw",48 .llvm_name = "addsubiw",
48 .description = "Enable 16-bit register-immediate addition and subtraction instructions",49 .description = "Enable 16-bit register-immediate addition and subtraction instructions",
...@@ -293,28 +294,28 @@ pub const all_features = blk: {...@@ -293,28 +294,28 @@ pub const all_features = blk: {
293};294};
294295
295pub const cpu = struct {296pub const cpu = struct {
296 pub const at43usb320 = Cpu{297 pub const at43usb320 = CpuModel{
297 .name = "at43usb320",298 .name = "at43usb320",
298 .llvm_name = "at43usb320",299 .llvm_name = "at43usb320",
299 .features = featureSet(&[_]Feature{300 .features = featureSet(&[_]Feature{
300 .avr31,301 .avr31,
301 }),302 }),
302 };303 };
303 pub const at43usb355 = Cpu{304 pub const at43usb355 = CpuModel{
304 .name = "at43usb355",305 .name = "at43usb355",
305 .llvm_name = "at43usb355",306 .llvm_name = "at43usb355",
306 .features = featureSet(&[_]Feature{307 .features = featureSet(&[_]Feature{
307 .avr3,308 .avr3,
308 }),309 }),
309 };310 };
310 pub const at76c711 = Cpu{311 pub const at76c711 = CpuModel{
311 .name = "at76c711",312 .name = "at76c711",
312 .llvm_name = "at76c711",313 .llvm_name = "at76c711",
313 .features = featureSet(&[_]Feature{314 .features = featureSet(&[_]Feature{
314 .avr3,315 .avr3,
315 }),316 }),
316 };317 };
317 pub const at86rf401 = Cpu{318 pub const at86rf401 = CpuModel{
318 .name = "at86rf401",319 .name = "at86rf401",
319 .llvm_name = "at86rf401",320 .llvm_name = "at86rf401",
320 .features = featureSet(&[_]Feature{321 .features = featureSet(&[_]Feature{
...@@ -323,217 +324,217 @@ pub const cpu = struct {...@@ -323,217 +324,217 @@ pub const cpu = struct {
323 .movw,324 .movw,
324 }),325 }),
325 };326 };
326 pub const at90c8534 = Cpu{327 pub const at90c8534 = CpuModel{
327 .name = "at90c8534",328 .name = "at90c8534",
328 .llvm_name = "at90c8534",329 .llvm_name = "at90c8534",
329 .features = featureSet(&[_]Feature{330 .features = featureSet(&[_]Feature{
330 .avr2,331 .avr2,
331 }),332 }),
332 };333 };
333 pub const at90can128 = Cpu{334 pub const at90can128 = CpuModel{
334 .name = "at90can128",335 .name = "at90can128",
335 .llvm_name = "at90can128",336 .llvm_name = "at90can128",
336 .features = featureSet(&[_]Feature{337 .features = featureSet(&[_]Feature{
337 .avr51,338 .avr51,
338 }),339 }),
339 };340 };
340 pub const at90can32 = Cpu{341 pub const at90can32 = CpuModel{
341 .name = "at90can32",342 .name = "at90can32",
342 .llvm_name = "at90can32",343 .llvm_name = "at90can32",
343 .features = featureSet(&[_]Feature{344 .features = featureSet(&[_]Feature{
344 .avr5,345 .avr5,
345 }),346 }),
346 };347 };
347 pub const at90can64 = Cpu{348 pub const at90can64 = CpuModel{
348 .name = "at90can64",349 .name = "at90can64",
349 .llvm_name = "at90can64",350 .llvm_name = "at90can64",
350 .features = featureSet(&[_]Feature{351 .features = featureSet(&[_]Feature{
351 .avr5,352 .avr5,
352 }),353 }),
353 };354 };
354 pub const at90pwm1 = Cpu{355 pub const at90pwm1 = CpuModel{
355 .name = "at90pwm1",356 .name = "at90pwm1",
356 .llvm_name = "at90pwm1",357 .llvm_name = "at90pwm1",
357 .features = featureSet(&[_]Feature{358 .features = featureSet(&[_]Feature{
358 .avr4,359 .avr4,
359 }),360 }),
360 };361 };
361 pub const at90pwm161 = Cpu{362 pub const at90pwm161 = CpuModel{
362 .name = "at90pwm161",363 .name = "at90pwm161",
363 .llvm_name = "at90pwm161",364 .llvm_name = "at90pwm161",
364 .features = featureSet(&[_]Feature{365 .features = featureSet(&[_]Feature{
365 .avr5,366 .avr5,
366 }),367 }),
367 };368 };
368 pub const at90pwm2 = Cpu{369 pub const at90pwm2 = CpuModel{
369 .name = "at90pwm2",370 .name = "at90pwm2",
370 .llvm_name = "at90pwm2",371 .llvm_name = "at90pwm2",
371 .features = featureSet(&[_]Feature{372 .features = featureSet(&[_]Feature{
372 .avr4,373 .avr4,
373 }),374 }),
374 };375 };
375 pub const at90pwm216 = Cpu{376 pub const at90pwm216 = CpuModel{
376 .name = "at90pwm216",377 .name = "at90pwm216",
377 .llvm_name = "at90pwm216",378 .llvm_name = "at90pwm216",
378 .features = featureSet(&[_]Feature{379 .features = featureSet(&[_]Feature{
379 .avr5,380 .avr5,
380 }),381 }),
381 };382 };
382 pub const at90pwm2b = Cpu{383 pub const at90pwm2b = CpuModel{
383 .name = "at90pwm2b",384 .name = "at90pwm2b",
384 .llvm_name = "at90pwm2b",385 .llvm_name = "at90pwm2b",
385 .features = featureSet(&[_]Feature{386 .features = featureSet(&[_]Feature{
386 .avr4,387 .avr4,
387 }),388 }),
388 };389 };
389 pub const at90pwm3 = Cpu{390 pub const at90pwm3 = CpuModel{
390 .name = "at90pwm3",391 .name = "at90pwm3",
391 .llvm_name = "at90pwm3",392 .llvm_name = "at90pwm3",
392 .features = featureSet(&[_]Feature{393 .features = featureSet(&[_]Feature{
393 .avr4,394 .avr4,
394 }),395 }),
395 };396 };
396 pub const at90pwm316 = Cpu{397 pub const at90pwm316 = CpuModel{
397 .name = "at90pwm316",398 .name = "at90pwm316",
398 .llvm_name = "at90pwm316",399 .llvm_name = "at90pwm316",
399 .features = featureSet(&[_]Feature{400 .features = featureSet(&[_]Feature{
400 .avr5,401 .avr5,
401 }),402 }),
402 };403 };
403 pub const at90pwm3b = Cpu{404 pub const at90pwm3b = CpuModel{
404 .name = "at90pwm3b",405 .name = "at90pwm3b",
405 .llvm_name = "at90pwm3b",406 .llvm_name = "at90pwm3b",
406 .features = featureSet(&[_]Feature{407 .features = featureSet(&[_]Feature{
407 .avr4,408 .avr4,
408 }),409 }),
409 };410 };
410 pub const at90pwm81 = Cpu{411 pub const at90pwm81 = CpuModel{
411 .name = "at90pwm81",412 .name = "at90pwm81",
412 .llvm_name = "at90pwm81",413 .llvm_name = "at90pwm81",
413 .features = featureSet(&[_]Feature{414 .features = featureSet(&[_]Feature{
414 .avr4,415 .avr4,
415 }),416 }),
416 };417 };
417 pub const at90s1200 = Cpu{418 pub const at90s1200 = CpuModel{
418 .name = "at90s1200",419 .name = "at90s1200",
419 .llvm_name = "at90s1200",420 .llvm_name = "at90s1200",
420 .features = featureSet(&[_]Feature{421 .features = featureSet(&[_]Feature{
421 .avr0,422 .avr0,
422 }),423 }),
423 };424 };
424 pub const at90s2313 = Cpu{425 pub const at90s2313 = CpuModel{
425 .name = "at90s2313",426 .name = "at90s2313",
426 .llvm_name = "at90s2313",427 .llvm_name = "at90s2313",
427 .features = featureSet(&[_]Feature{428 .features = featureSet(&[_]Feature{
428 .avr2,429 .avr2,
429 }),430 }),
430 };431 };
431 pub const at90s2323 = Cpu{432 pub const at90s2323 = CpuModel{
432 .name = "at90s2323",433 .name = "at90s2323",
433 .llvm_name = "at90s2323",434 .llvm_name = "at90s2323",
434 .features = featureSet(&[_]Feature{435 .features = featureSet(&[_]Feature{
435 .avr2,436 .avr2,
436 }),437 }),
437 };438 };
438 pub const at90s2333 = Cpu{439 pub const at90s2333 = CpuModel{
439 .name = "at90s2333",440 .name = "at90s2333",
440 .llvm_name = "at90s2333",441 .llvm_name = "at90s2333",
441 .features = featureSet(&[_]Feature{442 .features = featureSet(&[_]Feature{
442 .avr2,443 .avr2,
443 }),444 }),
444 };445 };
445 pub const at90s2343 = Cpu{446 pub const at90s2343 = CpuModel{
446 .name = "at90s2343",447 .name = "at90s2343",
447 .llvm_name = "at90s2343",448 .llvm_name = "at90s2343",
448 .features = featureSet(&[_]Feature{449 .features = featureSet(&[_]Feature{
449 .avr2,450 .avr2,
450 }),451 }),
451 };452 };
452 pub const at90s4414 = Cpu{453 pub const at90s4414 = CpuModel{
453 .name = "at90s4414",454 .name = "at90s4414",
454 .llvm_name = "at90s4414",455 .llvm_name = "at90s4414",
455 .features = featureSet(&[_]Feature{456 .features = featureSet(&[_]Feature{
456 .avr2,457 .avr2,
457 }),458 }),
458 };459 };
459 pub const at90s4433 = Cpu{460 pub const at90s4433 = CpuModel{
460 .name = "at90s4433",461 .name = "at90s4433",
461 .llvm_name = "at90s4433",462 .llvm_name = "at90s4433",
462 .features = featureSet(&[_]Feature{463 .features = featureSet(&[_]Feature{
463 .avr2,464 .avr2,
464 }),465 }),
465 };466 };
466 pub const at90s4434 = Cpu{467 pub const at90s4434 = CpuModel{
467 .name = "at90s4434",468 .name = "at90s4434",
468 .llvm_name = "at90s4434",469 .llvm_name = "at90s4434",
469 .features = featureSet(&[_]Feature{470 .features = featureSet(&[_]Feature{
470 .avr2,471 .avr2,
471 }),472 }),
472 };473 };
473 pub const at90s8515 = Cpu{474 pub const at90s8515 = CpuModel{
474 .name = "at90s8515",475 .name = "at90s8515",
475 .llvm_name = "at90s8515",476 .llvm_name = "at90s8515",
476 .features = featureSet(&[_]Feature{477 .features = featureSet(&[_]Feature{
477 .avr2,478 .avr2,
478 }),479 }),
479 };480 };
480 pub const at90s8535 = Cpu{481 pub const at90s8535 = CpuModel{
481 .name = "at90s8535",482 .name = "at90s8535",
482 .llvm_name = "at90s8535",483 .llvm_name = "at90s8535",
483 .features = featureSet(&[_]Feature{484 .features = featureSet(&[_]Feature{
484 .avr2,485 .avr2,
485 }),486 }),
486 };487 };
487 pub const at90scr100 = Cpu{488 pub const at90scr100 = CpuModel{
488 .name = "at90scr100",489 .name = "at90scr100",
489 .llvm_name = "at90scr100",490 .llvm_name = "at90scr100",
490 .features = featureSet(&[_]Feature{491 .features = featureSet(&[_]Feature{
491 .avr5,492 .avr5,
492 }),493 }),
493 };494 };
494 pub const at90usb1286 = Cpu{495 pub const at90usb1286 = CpuModel{
495 .name = "at90usb1286",496 .name = "at90usb1286",
496 .llvm_name = "at90usb1286",497 .llvm_name = "at90usb1286",
497 .features = featureSet(&[_]Feature{498 .features = featureSet(&[_]Feature{
498 .avr51,499 .avr51,
499 }),500 }),
500 };501 };
501 pub const at90usb1287 = Cpu{502 pub const at90usb1287 = CpuModel{
502 .name = "at90usb1287",503 .name = "at90usb1287",
503 .llvm_name = "at90usb1287",504 .llvm_name = "at90usb1287",
504 .features = featureSet(&[_]Feature{505 .features = featureSet(&[_]Feature{
505 .avr51,506 .avr51,
506 }),507 }),
507 };508 };
508 pub const at90usb162 = Cpu{509 pub const at90usb162 = CpuModel{
509 .name = "at90usb162",510 .name = "at90usb162",
510 .llvm_name = "at90usb162",511 .llvm_name = "at90usb162",
511 .features = featureSet(&[_]Feature{512 .features = featureSet(&[_]Feature{
512 .avr35,513 .avr35,
513 }),514 }),
514 };515 };
515 pub const at90usb646 = Cpu{516 pub const at90usb646 = CpuModel{
516 .name = "at90usb646",517 .name = "at90usb646",
517 .llvm_name = "at90usb646",518 .llvm_name = "at90usb646",
518 .features = featureSet(&[_]Feature{519 .features = featureSet(&[_]Feature{
519 .avr5,520 .avr5,
520 }),521 }),
521 };522 };
522 pub const at90usb647 = Cpu{523 pub const at90usb647 = CpuModel{
523 .name = "at90usb647",524 .name = "at90usb647",
524 .llvm_name = "at90usb647",525 .llvm_name = "at90usb647",
525 .features = featureSet(&[_]Feature{526 .features = featureSet(&[_]Feature{
526 .avr5,527 .avr5,
527 }),528 }),
528 };529 };
529 pub const at90usb82 = Cpu{530 pub const at90usb82 = CpuModel{
530 .name = "at90usb82",531 .name = "at90usb82",
531 .llvm_name = "at90usb82",532 .llvm_name = "at90usb82",
532 .features = featureSet(&[_]Feature{533 .features = featureSet(&[_]Feature{
533 .avr35,534 .avr35,
534 }),535 }),
535 };536 };
536 pub const at94k = Cpu{537 pub const at94k = CpuModel{
537 .name = "at94k",538 .name = "at94k",
538 .llvm_name = "at94k",539 .llvm_name = "at94k",
539 .features = featureSet(&[_]Feature{540 .features = featureSet(&[_]Feature{
...@@ -543,133 +544,133 @@ pub const cpu = struct {...@@ -543,133 +544,133 @@ pub const cpu = struct {
543 .mul,544 .mul,
544 }),545 }),
545 };546 };
546 pub const ata5272 = Cpu{547 pub const ata5272 = CpuModel{
547 .name = "ata5272",548 .name = "ata5272",
548 .llvm_name = "ata5272",549 .llvm_name = "ata5272",
549 .features = featureSet(&[_]Feature{550 .features = featureSet(&[_]Feature{
550 .avr25,551 .avr25,
551 }),552 }),
552 };553 };
553 pub const ata5505 = Cpu{554 pub const ata5505 = CpuModel{
554 .name = "ata5505",555 .name = "ata5505",
555 .llvm_name = "ata5505",556 .llvm_name = "ata5505",
556 .features = featureSet(&[_]Feature{557 .features = featureSet(&[_]Feature{
557 .avr35,558 .avr35,
558 }),559 }),
559 };560 };
560 pub const ata5790 = Cpu{561 pub const ata5790 = CpuModel{
561 .name = "ata5790",562 .name = "ata5790",
562 .llvm_name = "ata5790",563 .llvm_name = "ata5790",
563 .features = featureSet(&[_]Feature{564 .features = featureSet(&[_]Feature{
564 .avr5,565 .avr5,
565 }),566 }),
566 };567 };
567 pub const ata5795 = Cpu{568 pub const ata5795 = CpuModel{
568 .name = "ata5795",569 .name = "ata5795",
569 .llvm_name = "ata5795",570 .llvm_name = "ata5795",
570 .features = featureSet(&[_]Feature{571 .features = featureSet(&[_]Feature{
571 .avr5,572 .avr5,
572 }),573 }),
573 };574 };
574 pub const ata6285 = Cpu{575 pub const ata6285 = CpuModel{
575 .name = "ata6285",576 .name = "ata6285",
576 .llvm_name = "ata6285",577 .llvm_name = "ata6285",
577 .features = featureSet(&[_]Feature{578 .features = featureSet(&[_]Feature{
578 .avr4,579 .avr4,
579 }),580 }),
580 };581 };
581 pub const ata6286 = Cpu{582 pub const ata6286 = CpuModel{
582 .name = "ata6286",583 .name = "ata6286",
583 .llvm_name = "ata6286",584 .llvm_name = "ata6286",
584 .features = featureSet(&[_]Feature{585 .features = featureSet(&[_]Feature{
585 .avr4,586 .avr4,
586 }),587 }),
587 };588 };
588 pub const ata6289 = Cpu{589 pub const ata6289 = CpuModel{
589 .name = "ata6289",590 .name = "ata6289",
590 .llvm_name = "ata6289",591 .llvm_name = "ata6289",
591 .features = featureSet(&[_]Feature{592 .features = featureSet(&[_]Feature{
592 .avr4,593 .avr4,
593 }),594 }),
594 };595 };
595 pub const atmega103 = Cpu{596 pub const atmega103 = CpuModel{
596 .name = "atmega103",597 .name = "atmega103",
597 .llvm_name = "atmega103",598 .llvm_name = "atmega103",
598 .features = featureSet(&[_]Feature{599 .features = featureSet(&[_]Feature{
599 .avr31,600 .avr31,
600 }),601 }),
601 };602 };
602 pub const atmega128 = Cpu{603 pub const atmega128 = CpuModel{
603 .name = "atmega128",604 .name = "atmega128",
604 .llvm_name = "atmega128",605 .llvm_name = "atmega128",
605 .features = featureSet(&[_]Feature{606 .features = featureSet(&[_]Feature{
606 .avr51,607 .avr51,
607 }),608 }),
608 };609 };
609 pub const atmega1280 = Cpu{610 pub const atmega1280 = CpuModel{
610 .name = "atmega1280",611 .name = "atmega1280",
611 .llvm_name = "atmega1280",612 .llvm_name = "atmega1280",
612 .features = featureSet(&[_]Feature{613 .features = featureSet(&[_]Feature{
613 .avr51,614 .avr51,
614 }),615 }),
615 };616 };
616 pub const atmega1281 = Cpu{617 pub const atmega1281 = CpuModel{
617 .name = "atmega1281",618 .name = "atmega1281",
618 .llvm_name = "atmega1281",619 .llvm_name = "atmega1281",
619 .features = featureSet(&[_]Feature{620 .features = featureSet(&[_]Feature{
620 .avr51,621 .avr51,
621 }),622 }),
622 };623 };
623 pub const atmega1284 = Cpu{624 pub const atmega1284 = CpuModel{
624 .name = "atmega1284",625 .name = "atmega1284",
625 .llvm_name = "atmega1284",626 .llvm_name = "atmega1284",
626 .features = featureSet(&[_]Feature{627 .features = featureSet(&[_]Feature{
627 .avr51,628 .avr51,
628 }),629 }),
629 };630 };
630 pub const atmega1284p = Cpu{631 pub const atmega1284p = CpuModel{
631 .name = "atmega1284p",632 .name = "atmega1284p",
632 .llvm_name = "atmega1284p",633 .llvm_name = "atmega1284p",
633 .features = featureSet(&[_]Feature{634 .features = featureSet(&[_]Feature{
634 .avr51,635 .avr51,
635 }),636 }),
636 };637 };
637 pub const atmega1284rfr2 = Cpu{638 pub const atmega1284rfr2 = CpuModel{
638 .name = "atmega1284rfr2",639 .name = "atmega1284rfr2",
639 .llvm_name = "atmega1284rfr2",640 .llvm_name = "atmega1284rfr2",
640 .features = featureSet(&[_]Feature{641 .features = featureSet(&[_]Feature{
641 .avr51,642 .avr51,
642 }),643 }),
643 };644 };
644 pub const atmega128a = Cpu{645 pub const atmega128a = CpuModel{
645 .name = "atmega128a",646 .name = "atmega128a",
646 .llvm_name = "atmega128a",647 .llvm_name = "atmega128a",
647 .features = featureSet(&[_]Feature{648 .features = featureSet(&[_]Feature{
648 .avr51,649 .avr51,
649 }),650 }),
650 };651 };
651 pub const atmega128rfa1 = Cpu{652 pub const atmega128rfa1 = CpuModel{
652 .name = "atmega128rfa1",653 .name = "atmega128rfa1",
653 .llvm_name = "atmega128rfa1",654 .llvm_name = "atmega128rfa1",
654 .features = featureSet(&[_]Feature{655 .features = featureSet(&[_]Feature{
655 .avr51,656 .avr51,
656 }),657 }),
657 };658 };
658 pub const atmega128rfr2 = Cpu{659 pub const atmega128rfr2 = CpuModel{
659 .name = "atmega128rfr2",660 .name = "atmega128rfr2",
660 .llvm_name = "atmega128rfr2",661 .llvm_name = "atmega128rfr2",
661 .features = featureSet(&[_]Feature{662 .features = featureSet(&[_]Feature{
662 .avr51,663 .avr51,
663 }),664 }),
664 };665 };
665 pub const atmega16 = Cpu{666 pub const atmega16 = CpuModel{
666 .name = "atmega16",667 .name = "atmega16",
667 .llvm_name = "atmega16",668 .llvm_name = "atmega16",
668 .features = featureSet(&[_]Feature{669 .features = featureSet(&[_]Feature{
669 .avr5,670 .avr5,
670 }),671 }),
671 };672 };
672 pub const atmega161 = Cpu{673 pub const atmega161 = CpuModel{
673 .name = "atmega161",674 .name = "atmega161",
674 .llvm_name = "atmega161",675 .llvm_name = "atmega161",
675 .features = featureSet(&[_]Feature{676 .features = featureSet(&[_]Feature{
...@@ -680,14 +681,14 @@ pub const cpu = struct {...@@ -680,14 +681,14 @@ pub const cpu = struct {
680 .spm,681 .spm,
681 }),682 }),
682 };683 };
683 pub const atmega162 = Cpu{684 pub const atmega162 = CpuModel{
684 .name = "atmega162",685 .name = "atmega162",
685 .llvm_name = "atmega162",686 .llvm_name = "atmega162",
686 .features = featureSet(&[_]Feature{687 .features = featureSet(&[_]Feature{
687 .avr5,688 .avr5,
688 }),689 }),
689 };690 };
690 pub const atmega163 = Cpu{691 pub const atmega163 = CpuModel{
691 .name = "atmega163",692 .name = "atmega163",
692 .llvm_name = "atmega163",693 .llvm_name = "atmega163",
693 .features = featureSet(&[_]Feature{694 .features = featureSet(&[_]Feature{
...@@ -698,623 +699,623 @@ pub const cpu = struct {...@@ -698,623 +699,623 @@ pub const cpu = struct {
698 .spm,699 .spm,
699 }),700 }),
700 };701 };
701 pub const atmega164a = Cpu{702 pub const atmega164a = CpuModel{
702 .name = "atmega164a",703 .name = "atmega164a",
703 .llvm_name = "atmega164a",704 .llvm_name = "atmega164a",
704 .features = featureSet(&[_]Feature{705 .features = featureSet(&[_]Feature{
705 .avr5,706 .avr5,
706 }),707 }),
707 };708 };
708 pub const atmega164p = Cpu{709 pub const atmega164p = CpuModel{
709 .name = "atmega164p",710 .name = "atmega164p",
710 .llvm_name = "atmega164p",711 .llvm_name = "atmega164p",
711 .features = featureSet(&[_]Feature{712 .features = featureSet(&[_]Feature{
712 .avr5,713 .avr5,
713 }),714 }),
714 };715 };
715 pub const atmega164pa = Cpu{716 pub const atmega164pa = CpuModel{
716 .name = "atmega164pa",717 .name = "atmega164pa",
717 .llvm_name = "atmega164pa",718 .llvm_name = "atmega164pa",
718 .features = featureSet(&[_]Feature{719 .features = featureSet(&[_]Feature{
719 .avr5,720 .avr5,
720 }),721 }),
721 };722 };
722 pub const atmega165 = Cpu{723 pub const atmega165 = CpuModel{
723 .name = "atmega165",724 .name = "atmega165",
724 .llvm_name = "atmega165",725 .llvm_name = "atmega165",
725 .features = featureSet(&[_]Feature{726 .features = featureSet(&[_]Feature{
726 .avr5,727 .avr5,
727 }),728 }),
728 };729 };
729 pub const atmega165a = Cpu{730 pub const atmega165a = CpuModel{
730 .name = "atmega165a",731 .name = "atmega165a",
731 .llvm_name = "atmega165a",732 .llvm_name = "atmega165a",
732 .features = featureSet(&[_]Feature{733 .features = featureSet(&[_]Feature{
733 .avr5,734 .avr5,
734 }),735 }),
735 };736 };
736 pub const atmega165p = Cpu{737 pub const atmega165p = CpuModel{
737 .name = "atmega165p",738 .name = "atmega165p",
738 .llvm_name = "atmega165p",739 .llvm_name = "atmega165p",
739 .features = featureSet(&[_]Feature{740 .features = featureSet(&[_]Feature{
740 .avr5,741 .avr5,
741 }),742 }),
742 };743 };
743 pub const atmega165pa = Cpu{744 pub const atmega165pa = CpuModel{
744 .name = "atmega165pa",745 .name = "atmega165pa",
745 .llvm_name = "atmega165pa",746 .llvm_name = "atmega165pa",
746 .features = featureSet(&[_]Feature{747 .features = featureSet(&[_]Feature{
747 .avr5,748 .avr5,
748 }),749 }),
749 };750 };
750 pub const atmega168 = Cpu{751 pub const atmega168 = CpuModel{
751 .name = "atmega168",752 .name = "atmega168",
752 .llvm_name = "atmega168",753 .llvm_name = "atmega168",
753 .features = featureSet(&[_]Feature{754 .features = featureSet(&[_]Feature{
754 .avr5,755 .avr5,
755 }),756 }),
756 };757 };
757 pub const atmega168a = Cpu{758 pub const atmega168a = CpuModel{
758 .name = "atmega168a",759 .name = "atmega168a",
759 .llvm_name = "atmega168a",760 .llvm_name = "atmega168a",
760 .features = featureSet(&[_]Feature{761 .features = featureSet(&[_]Feature{
761 .avr5,762 .avr5,
762 }),763 }),
763 };764 };
764 pub const atmega168p = Cpu{765 pub const atmega168p = CpuModel{
765 .name = "atmega168p",766 .name = "atmega168p",
766 .llvm_name = "atmega168p",767 .llvm_name = "atmega168p",
767 .features = featureSet(&[_]Feature{768 .features = featureSet(&[_]Feature{
768 .avr5,769 .avr5,
769 }),770 }),
770 };771 };
771 pub const atmega168pa = Cpu{772 pub const atmega168pa = CpuModel{
772 .name = "atmega168pa",773 .name = "atmega168pa",
773 .llvm_name = "atmega168pa",774 .llvm_name = "atmega168pa",
774 .features = featureSet(&[_]Feature{775 .features = featureSet(&[_]Feature{
775 .avr5,776 .avr5,
776 }),777 }),
777 };778 };
778 pub const atmega169 = Cpu{779 pub const atmega169 = CpuModel{
779 .name = "atmega169",780 .name = "atmega169",
780 .llvm_name = "atmega169",781 .llvm_name = "atmega169",
781 .features = featureSet(&[_]Feature{782 .features = featureSet(&[_]Feature{
782 .avr5,783 .avr5,
783 }),784 }),
784 };785 };
785 pub const atmega169a = Cpu{786 pub const atmega169a = CpuModel{
786 .name = "atmega169a",787 .name = "atmega169a",
787 .llvm_name = "atmega169a",788 .llvm_name = "atmega169a",
788 .features = featureSet(&[_]Feature{789 .features = featureSet(&[_]Feature{
789 .avr5,790 .avr5,
790 }),791 }),
791 };792 };
792 pub const atmega169p = Cpu{793 pub const atmega169p = CpuModel{
793 .name = "atmega169p",794 .name = "atmega169p",
794 .llvm_name = "atmega169p",795 .llvm_name = "atmega169p",
795 .features = featureSet(&[_]Feature{796 .features = featureSet(&[_]Feature{
796 .avr5,797 .avr5,
797 }),798 }),
798 };799 };
799 pub const atmega169pa = Cpu{800 pub const atmega169pa = CpuModel{
800 .name = "atmega169pa",801 .name = "atmega169pa",
801 .llvm_name = "atmega169pa",802 .llvm_name = "atmega169pa",
802 .features = featureSet(&[_]Feature{803 .features = featureSet(&[_]Feature{
803 .avr5,804 .avr5,
804 }),805 }),
805 };806 };
806 pub const atmega16a = Cpu{807 pub const atmega16a = CpuModel{
807 .name = "atmega16a",808 .name = "atmega16a",
808 .llvm_name = "atmega16a",809 .llvm_name = "atmega16a",
809 .features = featureSet(&[_]Feature{810 .features = featureSet(&[_]Feature{
810 .avr5,811 .avr5,
811 }),812 }),
812 };813 };
813 pub const atmega16hva = Cpu{814 pub const atmega16hva = CpuModel{
814 .name = "atmega16hva",815 .name = "atmega16hva",
815 .llvm_name = "atmega16hva",816 .llvm_name = "atmega16hva",
816 .features = featureSet(&[_]Feature{817 .features = featureSet(&[_]Feature{
817 .avr5,818 .avr5,
818 }),819 }),
819 };820 };
820 pub const atmega16hva2 = Cpu{821 pub const atmega16hva2 = CpuModel{
821 .name = "atmega16hva2",822 .name = "atmega16hva2",
822 .llvm_name = "atmega16hva2",823 .llvm_name = "atmega16hva2",
823 .features = featureSet(&[_]Feature{824 .features = featureSet(&[_]Feature{
824 .avr5,825 .avr5,
825 }),826 }),
826 };827 };
827 pub const atmega16hvb = Cpu{828 pub const atmega16hvb = CpuModel{
828 .name = "atmega16hvb",829 .name = "atmega16hvb",
829 .llvm_name = "atmega16hvb",830 .llvm_name = "atmega16hvb",
830 .features = featureSet(&[_]Feature{831 .features = featureSet(&[_]Feature{
831 .avr5,832 .avr5,
832 }),833 }),
833 };834 };
834 pub const atmega16hvbrevb = Cpu{835 pub const atmega16hvbrevb = CpuModel{
835 .name = "atmega16hvbrevb",836 .name = "atmega16hvbrevb",
836 .llvm_name = "atmega16hvbrevb",837 .llvm_name = "atmega16hvbrevb",
837 .features = featureSet(&[_]Feature{838 .features = featureSet(&[_]Feature{
838 .avr5,839 .avr5,
839 }),840 }),
840 };841 };
841 pub const atmega16m1 = Cpu{842 pub const atmega16m1 = CpuModel{
842 .name = "atmega16m1",843 .name = "atmega16m1",
843 .llvm_name = "atmega16m1",844 .llvm_name = "atmega16m1",
844 .features = featureSet(&[_]Feature{845 .features = featureSet(&[_]Feature{
845 .avr5,846 .avr5,
846 }),847 }),
847 };848 };
848 pub const atmega16u2 = Cpu{849 pub const atmega16u2 = CpuModel{
849 .name = "atmega16u2",850 .name = "atmega16u2",
850 .llvm_name = "atmega16u2",851 .llvm_name = "atmega16u2",
851 .features = featureSet(&[_]Feature{852 .features = featureSet(&[_]Feature{
852 .avr35,853 .avr35,
853 }),854 }),
854 };855 };
855 pub const atmega16u4 = Cpu{856 pub const atmega16u4 = CpuModel{
856 .name = "atmega16u4",857 .name = "atmega16u4",
857 .llvm_name = "atmega16u4",858 .llvm_name = "atmega16u4",
858 .features = featureSet(&[_]Feature{859 .features = featureSet(&[_]Feature{
859 .avr5,860 .avr5,
860 }),861 }),
861 };862 };
862 pub const atmega2560 = Cpu{863 pub const atmega2560 = CpuModel{
863 .name = "atmega2560",864 .name = "atmega2560",
864 .llvm_name = "atmega2560",865 .llvm_name = "atmega2560",
865 .features = featureSet(&[_]Feature{866 .features = featureSet(&[_]Feature{
866 .avr6,867 .avr6,
867 }),868 }),
868 };869 };
869 pub const atmega2561 = Cpu{870 pub const atmega2561 = CpuModel{
870 .name = "atmega2561",871 .name = "atmega2561",
871 .llvm_name = "atmega2561",872 .llvm_name = "atmega2561",
872 .features = featureSet(&[_]Feature{873 .features = featureSet(&[_]Feature{
873 .avr6,874 .avr6,
874 }),875 }),
875 };876 };
876 pub const atmega2564rfr2 = Cpu{877 pub const atmega2564rfr2 = CpuModel{
877 .name = "atmega2564rfr2",878 .name = "atmega2564rfr2",
878 .llvm_name = "atmega2564rfr2",879 .llvm_name = "atmega2564rfr2",
879 .features = featureSet(&[_]Feature{880 .features = featureSet(&[_]Feature{
880 .avr6,881 .avr6,
881 }),882 }),
882 };883 };
883 pub const atmega256rfr2 = Cpu{884 pub const atmega256rfr2 = CpuModel{
884 .name = "atmega256rfr2",885 .name = "atmega256rfr2",
885 .llvm_name = "atmega256rfr2",886 .llvm_name = "atmega256rfr2",
886 .features = featureSet(&[_]Feature{887 .features = featureSet(&[_]Feature{
887 .avr6,888 .avr6,
888 }),889 }),
889 };890 };
890 pub const atmega32 = Cpu{891 pub const atmega32 = CpuModel{
891 .name = "atmega32",892 .name = "atmega32",
892 .llvm_name = "atmega32",893 .llvm_name = "atmega32",
893 .features = featureSet(&[_]Feature{894 .features = featureSet(&[_]Feature{
894 .avr5,895 .avr5,
895 }),896 }),
896 };897 };
897 pub const atmega323 = Cpu{898 pub const atmega323 = CpuModel{
898 .name = "atmega323",899 .name = "atmega323",
899 .llvm_name = "atmega323",900 .llvm_name = "atmega323",
900 .features = featureSet(&[_]Feature{901 .features = featureSet(&[_]Feature{
901 .avr5,902 .avr5,
902 }),903 }),
903 };904 };
904 pub const atmega324a = Cpu{905 pub const atmega324a = CpuModel{
905 .name = "atmega324a",906 .name = "atmega324a",
906 .llvm_name = "atmega324a",907 .llvm_name = "atmega324a",
907 .features = featureSet(&[_]Feature{908 .features = featureSet(&[_]Feature{
908 .avr5,909 .avr5,
909 }),910 }),
910 };911 };
911 pub const atmega324p = Cpu{912 pub const atmega324p = CpuModel{
912 .name = "atmega324p",913 .name = "atmega324p",
913 .llvm_name = "atmega324p",914 .llvm_name = "atmega324p",
914 .features = featureSet(&[_]Feature{915 .features = featureSet(&[_]Feature{
915 .avr5,916 .avr5,
916 }),917 }),
917 };918 };
918 pub const atmega324pa = Cpu{919 pub const atmega324pa = CpuModel{
919 .name = "atmega324pa",920 .name = "atmega324pa",
920 .llvm_name = "atmega324pa",921 .llvm_name = "atmega324pa",
921 .features = featureSet(&[_]Feature{922 .features = featureSet(&[_]Feature{
922 .avr5,923 .avr5,
923 }),924 }),
924 };925 };
925 pub const atmega325 = Cpu{926 pub const atmega325 = CpuModel{
926 .name = "atmega325",927 .name = "atmega325",
927 .llvm_name = "atmega325",928 .llvm_name = "atmega325",
928 .features = featureSet(&[_]Feature{929 .features = featureSet(&[_]Feature{
929 .avr5,930 .avr5,
930 }),931 }),
931 };932 };
932 pub const atmega3250 = Cpu{933 pub const atmega3250 = CpuModel{
933 .name = "atmega3250",934 .name = "atmega3250",
934 .llvm_name = "atmega3250",935 .llvm_name = "atmega3250",
935 .features = featureSet(&[_]Feature{936 .features = featureSet(&[_]Feature{
936 .avr5,937 .avr5,
937 }),938 }),
938 };939 };
939 pub const atmega3250a = Cpu{940 pub const atmega3250a = CpuModel{
940 .name = "atmega3250a",941 .name = "atmega3250a",
941 .llvm_name = "atmega3250a",942 .llvm_name = "atmega3250a",
942 .features = featureSet(&[_]Feature{943 .features = featureSet(&[_]Feature{
943 .avr5,944 .avr5,
944 }),945 }),
945 };946 };
946 pub const atmega3250p = Cpu{947 pub const atmega3250p = CpuModel{
947 .name = "atmega3250p",948 .name = "atmega3250p",
948 .llvm_name = "atmega3250p",949 .llvm_name = "atmega3250p",
949 .features = featureSet(&[_]Feature{950 .features = featureSet(&[_]Feature{
950 .avr5,951 .avr5,
951 }),952 }),
952 };953 };
953 pub const atmega3250pa = Cpu{954 pub const atmega3250pa = CpuModel{
954 .name = "atmega3250pa",955 .name = "atmega3250pa",
955 .llvm_name = "atmega3250pa",956 .llvm_name = "atmega3250pa",
956 .features = featureSet(&[_]Feature{957 .features = featureSet(&[_]Feature{
957 .avr5,958 .avr5,
958 }),959 }),
959 };960 };
960 pub const atmega325a = Cpu{961 pub const atmega325a = CpuModel{
961 .name = "atmega325a",962 .name = "atmega325a",
962 .llvm_name = "atmega325a",963 .llvm_name = "atmega325a",
963 .features = featureSet(&[_]Feature{964 .features = featureSet(&[_]Feature{
964 .avr5,965 .avr5,
965 }),966 }),
966 };967 };
967 pub const atmega325p = Cpu{968 pub const atmega325p = CpuModel{
968 .name = "atmega325p",969 .name = "atmega325p",
969 .llvm_name = "atmega325p",970 .llvm_name = "atmega325p",
970 .features = featureSet(&[_]Feature{971 .features = featureSet(&[_]Feature{
971 .avr5,972 .avr5,
972 }),973 }),
973 };974 };
974 pub const atmega325pa = Cpu{975 pub const atmega325pa = CpuModel{
975 .name = "atmega325pa",976 .name = "atmega325pa",
976 .llvm_name = "atmega325pa",977 .llvm_name = "atmega325pa",
977 .features = featureSet(&[_]Feature{978 .features = featureSet(&[_]Feature{
978 .avr5,979 .avr5,
979 }),980 }),
980 };981 };
981 pub const atmega328 = Cpu{982 pub const atmega328 = CpuModel{
982 .name = "atmega328",983 .name = "atmega328",
983 .llvm_name = "atmega328",984 .llvm_name = "atmega328",
984 .features = featureSet(&[_]Feature{985 .features = featureSet(&[_]Feature{
985 .avr5,986 .avr5,
986 }),987 }),
987 };988 };
988 pub const atmega328p = Cpu{989 pub const atmega328p = CpuModel{
989 .name = "atmega328p",990 .name = "atmega328p",
990 .llvm_name = "atmega328p",991 .llvm_name = "atmega328p",
991 .features = featureSet(&[_]Feature{992 .features = featureSet(&[_]Feature{
992 .avr5,993 .avr5,
993 }),994 }),
994 };995 };
995 pub const atmega329 = Cpu{996 pub const atmega329 = CpuModel{
996 .name = "atmega329",997 .name = "atmega329",
997 .llvm_name = "atmega329",998 .llvm_name = "atmega329",
998 .features = featureSet(&[_]Feature{999 .features = featureSet(&[_]Feature{
999 .avr5,1000 .avr5,
1000 }),1001 }),
1001 };1002 };
1002 pub const atmega3290 = Cpu{1003 pub const atmega3290 = CpuModel{
1003 .name = "atmega3290",1004 .name = "atmega3290",
1004 .llvm_name = "atmega3290",1005 .llvm_name = "atmega3290",
1005 .features = featureSet(&[_]Feature{1006 .features = featureSet(&[_]Feature{
1006 .avr5,1007 .avr5,
1007 }),1008 }),
1008 };1009 };
1009 pub const atmega3290a = Cpu{1010 pub const atmega3290a = CpuModel{
1010 .name = "atmega3290a",1011 .name = "atmega3290a",
1011 .llvm_name = "atmega3290a",1012 .llvm_name = "atmega3290a",
1012 .features = featureSet(&[_]Feature{1013 .features = featureSet(&[_]Feature{
1013 .avr5,1014 .avr5,
1014 }),1015 }),
1015 };1016 };
1016 pub const atmega3290p = Cpu{1017 pub const atmega3290p = CpuModel{
1017 .name = "atmega3290p",1018 .name = "atmega3290p",
1018 .llvm_name = "atmega3290p",1019 .llvm_name = "atmega3290p",
1019 .features = featureSet(&[_]Feature{1020 .features = featureSet(&[_]Feature{
1020 .avr5,1021 .avr5,
1021 }),1022 }),
1022 };1023 };
1023 pub const atmega3290pa = Cpu{1024 pub const atmega3290pa = CpuModel{
1024 .name = "atmega3290pa",1025 .name = "atmega3290pa",
1025 .llvm_name = "atmega3290pa",1026 .llvm_name = "atmega3290pa",
1026 .features = featureSet(&[_]Feature{1027 .features = featureSet(&[_]Feature{
1027 .avr5,1028 .avr5,
1028 }),1029 }),
1029 };1030 };
1030 pub const atmega329a = Cpu{1031 pub const atmega329a = CpuModel{
1031 .name = "atmega329a",1032 .name = "atmega329a",
1032 .llvm_name = "atmega329a",1033 .llvm_name = "atmega329a",
1033 .features = featureSet(&[_]Feature{1034 .features = featureSet(&[_]Feature{
1034 .avr5,1035 .avr5,
1035 }),1036 }),
1036 };1037 };
1037 pub const atmega329p = Cpu{1038 pub const atmega329p = CpuModel{
1038 .name = "atmega329p",1039 .name = "atmega329p",
1039 .llvm_name = "atmega329p",1040 .llvm_name = "atmega329p",
1040 .features = featureSet(&[_]Feature{1041 .features = featureSet(&[_]Feature{
1041 .avr5,1042 .avr5,
1042 }),1043 }),
1043 };1044 };
1044 pub const atmega329pa = Cpu{1045 pub const atmega329pa = CpuModel{
1045 .name = "atmega329pa",1046 .name = "atmega329pa",
1046 .llvm_name = "atmega329pa",1047 .llvm_name = "atmega329pa",
1047 .features = featureSet(&[_]Feature{1048 .features = featureSet(&[_]Feature{
1048 .avr5,1049 .avr5,
1049 }),1050 }),
1050 };1051 };
1051 pub const atmega32a = Cpu{1052 pub const atmega32a = CpuModel{
1052 .name = "atmega32a",1053 .name = "atmega32a",
1053 .llvm_name = "atmega32a",1054 .llvm_name = "atmega32a",
1054 .features = featureSet(&[_]Feature{1055 .features = featureSet(&[_]Feature{
1055 .avr5,1056 .avr5,
1056 }),1057 }),
1057 };1058 };
1058 pub const atmega32c1 = Cpu{1059 pub const atmega32c1 = CpuModel{
1059 .name = "atmega32c1",1060 .name = "atmega32c1",
1060 .llvm_name = "atmega32c1",1061 .llvm_name = "atmega32c1",
1061 .features = featureSet(&[_]Feature{1062 .features = featureSet(&[_]Feature{
1062 .avr5,1063 .avr5,
1063 }),1064 }),
1064 };1065 };
1065 pub const atmega32hvb = Cpu{1066 pub const atmega32hvb = CpuModel{
1066 .name = "atmega32hvb",1067 .name = "atmega32hvb",
1067 .llvm_name = "atmega32hvb",1068 .llvm_name = "atmega32hvb",
1068 .features = featureSet(&[_]Feature{1069 .features = featureSet(&[_]Feature{
1069 .avr5,1070 .avr5,
1070 }),1071 }),
1071 };1072 };
1072 pub const atmega32hvbrevb = Cpu{1073 pub const atmega32hvbrevb = CpuModel{
1073 .name = "atmega32hvbrevb",1074 .name = "atmega32hvbrevb",
1074 .llvm_name = "atmega32hvbrevb",1075 .llvm_name = "atmega32hvbrevb",
1075 .features = featureSet(&[_]Feature{1076 .features = featureSet(&[_]Feature{
1076 .avr5,1077 .avr5,
1077 }),1078 }),
1078 };1079 };
1079 pub const atmega32m1 = Cpu{1080 pub const atmega32m1 = CpuModel{
1080 .name = "atmega32m1",1081 .name = "atmega32m1",
1081 .llvm_name = "atmega32m1",1082 .llvm_name = "atmega32m1",
1082 .features = featureSet(&[_]Feature{1083 .features = featureSet(&[_]Feature{
1083 .avr5,1084 .avr5,
1084 }),1085 }),
1085 };1086 };
1086 pub const atmega32u2 = Cpu{1087 pub const atmega32u2 = CpuModel{
1087 .name = "atmega32u2",1088 .name = "atmega32u2",
1088 .llvm_name = "atmega32u2",1089 .llvm_name = "atmega32u2",
1089 .features = featureSet(&[_]Feature{1090 .features = featureSet(&[_]Feature{
1090 .avr35,1091 .avr35,
1091 }),1092 }),
1092 };1093 };
1093 pub const atmega32u4 = Cpu{1094 pub const atmega32u4 = CpuModel{
1094 .name = "atmega32u4",1095 .name = "atmega32u4",
1095 .llvm_name = "atmega32u4",1096 .llvm_name = "atmega32u4",
1096 .features = featureSet(&[_]Feature{1097 .features = featureSet(&[_]Feature{
1097 .avr5,1098 .avr5,
1098 }),1099 }),
1099 };1100 };
1100 pub const atmega32u6 = Cpu{1101 pub const atmega32u6 = CpuModel{
1101 .name = "atmega32u6",1102 .name = "atmega32u6",
1102 .llvm_name = "atmega32u6",1103 .llvm_name = "atmega32u6",
1103 .features = featureSet(&[_]Feature{1104 .features = featureSet(&[_]Feature{
1104 .avr5,1105 .avr5,
1105 }),1106 }),
1106 };1107 };
1107 pub const atmega406 = Cpu{1108 pub const atmega406 = CpuModel{
1108 .name = "atmega406",1109 .name = "atmega406",
1109 .llvm_name = "atmega406",1110 .llvm_name = "atmega406",
1110 .features = featureSet(&[_]Feature{1111 .features = featureSet(&[_]Feature{
1111 .avr5,1112 .avr5,
1112 }),1113 }),
1113 };1114 };
1114 pub const atmega48 = Cpu{1115 pub const atmega48 = CpuModel{
1115 .name = "atmega48",1116 .name = "atmega48",
1116 .llvm_name = "atmega48",1117 .llvm_name = "atmega48",
1117 .features = featureSet(&[_]Feature{1118 .features = featureSet(&[_]Feature{
1118 .avr4,1119 .avr4,
1119 }),1120 }),
1120 };1121 };
1121 pub const atmega48a = Cpu{1122 pub const atmega48a = CpuModel{
1122 .name = "atmega48a",1123 .name = "atmega48a",
1123 .llvm_name = "atmega48a",1124 .llvm_name = "atmega48a",
1124 .features = featureSet(&[_]Feature{1125 .features = featureSet(&[_]Feature{
1125 .avr4,1126 .avr4,
1126 }),1127 }),
1127 };1128 };
1128 pub const atmega48p = Cpu{1129 pub const atmega48p = CpuModel{
1129 .name = "atmega48p",1130 .name = "atmega48p",
1130 .llvm_name = "atmega48p",1131 .llvm_name = "atmega48p",
1131 .features = featureSet(&[_]Feature{1132 .features = featureSet(&[_]Feature{
1132 .avr4,1133 .avr4,
1133 }),1134 }),
1134 };1135 };
1135 pub const atmega48pa = Cpu{1136 pub const atmega48pa = CpuModel{
1136 .name = "atmega48pa",1137 .name = "atmega48pa",
1137 .llvm_name = "atmega48pa",1138 .llvm_name = "atmega48pa",
1138 .features = featureSet(&[_]Feature{1139 .features = featureSet(&[_]Feature{
1139 .avr4,1140 .avr4,
1140 }),1141 }),
1141 };1142 };
1142 pub const atmega64 = Cpu{1143 pub const atmega64 = CpuModel{
1143 .name = "atmega64",1144 .name = "atmega64",
1144 .llvm_name = "atmega64",1145 .llvm_name = "atmega64",
1145 .features = featureSet(&[_]Feature{1146 .features = featureSet(&[_]Feature{
1146 .avr5,1147 .avr5,
1147 }),1148 }),
1148 };1149 };
1149 pub const atmega640 = Cpu{1150 pub const atmega640 = CpuModel{
1150 .name = "atmega640",1151 .name = "atmega640",
1151 .llvm_name = "atmega640",1152 .llvm_name = "atmega640",
1152 .features = featureSet(&[_]Feature{1153 .features = featureSet(&[_]Feature{
1153 .avr5,1154 .avr5,
1154 }),1155 }),
1155 };1156 };
1156 pub const atmega644 = Cpu{1157 pub const atmega644 = CpuModel{
1157 .name = "atmega644",1158 .name = "atmega644",
1158 .llvm_name = "atmega644",1159 .llvm_name = "atmega644",
1159 .features = featureSet(&[_]Feature{1160 .features = featureSet(&[_]Feature{
1160 .avr5,1161 .avr5,
1161 }),1162 }),
1162 };1163 };
1163 pub const atmega644a = Cpu{1164 pub const atmega644a = CpuModel{
1164 .name = "atmega644a",1165 .name = "atmega644a",
1165 .llvm_name = "atmega644a",1166 .llvm_name = "atmega644a",
1166 .features = featureSet(&[_]Feature{1167 .features = featureSet(&[_]Feature{
1167 .avr5,1168 .avr5,
1168 }),1169 }),
1169 };1170 };
1170 pub const atmega644p = Cpu{1171 pub const atmega644p = CpuModel{
1171 .name = "atmega644p",1172 .name = "atmega644p",
1172 .llvm_name = "atmega644p",1173 .llvm_name = "atmega644p",
1173 .features = featureSet(&[_]Feature{1174 .features = featureSet(&[_]Feature{
1174 .avr5,1175 .avr5,
1175 }),1176 }),
1176 };1177 };
1177 pub const atmega644pa = Cpu{1178 pub const atmega644pa = CpuModel{
1178 .name = "atmega644pa",1179 .name = "atmega644pa",
1179 .llvm_name = "atmega644pa",1180 .llvm_name = "atmega644pa",
1180 .features = featureSet(&[_]Feature{1181 .features = featureSet(&[_]Feature{
1181 .avr5,1182 .avr5,
1182 }),1183 }),
1183 };1184 };
1184 pub const atmega644rfr2 = Cpu{1185 pub const atmega644rfr2 = CpuModel{
1185 .name = "atmega644rfr2",1186 .name = "atmega644rfr2",
1186 .llvm_name = "atmega644rfr2",1187 .llvm_name = "atmega644rfr2",
1187 .features = featureSet(&[_]Feature{1188 .features = featureSet(&[_]Feature{
1188 .avr5,1189 .avr5,
1189 }),1190 }),
1190 };1191 };
1191 pub const atmega645 = Cpu{1192 pub const atmega645 = CpuModel{
1192 .name = "atmega645",1193 .name = "atmega645",
1193 .llvm_name = "atmega645",1194 .llvm_name = "atmega645",
1194 .features = featureSet(&[_]Feature{1195 .features = featureSet(&[_]Feature{
1195 .avr5,1196 .avr5,
1196 }),1197 }),
1197 };1198 };
1198 pub const atmega6450 = Cpu{1199 pub const atmega6450 = CpuModel{
1199 .name = "atmega6450",1200 .name = "atmega6450",
1200 .llvm_name = "atmega6450",1201 .llvm_name = "atmega6450",
1201 .features = featureSet(&[_]Feature{1202 .features = featureSet(&[_]Feature{
1202 .avr5,1203 .avr5,
1203 }),1204 }),
1204 };1205 };
1205 pub const atmega6450a = Cpu{1206 pub const atmega6450a = CpuModel{
1206 .name = "atmega6450a",1207 .name = "atmega6450a",
1207 .llvm_name = "atmega6450a",1208 .llvm_name = "atmega6450a",
1208 .features = featureSet(&[_]Feature{1209 .features = featureSet(&[_]Feature{
1209 .avr5,1210 .avr5,
1210 }),1211 }),
1211 };1212 };
1212 pub const atmega6450p = Cpu{1213 pub const atmega6450p = CpuModel{
1213 .name = "atmega6450p",1214 .name = "atmega6450p",
1214 .llvm_name = "atmega6450p",1215 .llvm_name = "atmega6450p",
1215 .features = featureSet(&[_]Feature{1216 .features = featureSet(&[_]Feature{
1216 .avr5,1217 .avr5,
1217 }),1218 }),
1218 };1219 };
1219 pub const atmega645a = Cpu{1220 pub const atmega645a = CpuModel{
1220 .name = "atmega645a",1221 .name = "atmega645a",
1221 .llvm_name = "atmega645a",1222 .llvm_name = "atmega645a",
1222 .features = featureSet(&[_]Feature{1223 .features = featureSet(&[_]Feature{
1223 .avr5,1224 .avr5,
1224 }),1225 }),
1225 };1226 };
1226 pub const atmega645p = Cpu{1227 pub const atmega645p = CpuModel{
1227 .name = "atmega645p",1228 .name = "atmega645p",
1228 .llvm_name = "atmega645p",1229 .llvm_name = "atmega645p",
1229 .features = featureSet(&[_]Feature{1230 .features = featureSet(&[_]Feature{
1230 .avr5,1231 .avr5,
1231 }),1232 }),
1232 };1233 };
1233 pub const atmega649 = Cpu{1234 pub const atmega649 = CpuModel{
1234 .name = "atmega649",1235 .name = "atmega649",
1235 .llvm_name = "atmega649",1236 .llvm_name = "atmega649",
1236 .features = featureSet(&[_]Feature{1237 .features = featureSet(&[_]Feature{
1237 .avr5,1238 .avr5,
1238 }),1239 }),
1239 };1240 };
1240 pub const atmega6490 = Cpu{1241 pub const atmega6490 = CpuModel{
1241 .name = "atmega6490",1242 .name = "atmega6490",
1242 .llvm_name = "atmega6490",1243 .llvm_name = "atmega6490",
1243 .features = featureSet(&[_]Feature{1244 .features = featureSet(&[_]Feature{
1244 .avr5,1245 .avr5,
1245 }),1246 }),
1246 };1247 };
1247 pub const atmega6490a = Cpu{1248 pub const atmega6490a = CpuModel{
1248 .name = "atmega6490a",1249 .name = "atmega6490a",
1249 .llvm_name = "atmega6490a",1250 .llvm_name = "atmega6490a",
1250 .features = featureSet(&[_]Feature{1251 .features = featureSet(&[_]Feature{
1251 .avr5,1252 .avr5,
1252 }),1253 }),
1253 };1254 };
1254 pub const atmega6490p = Cpu{1255 pub const atmega6490p = CpuModel{
1255 .name = "atmega6490p",1256 .name = "atmega6490p",
1256 .llvm_name = "atmega6490p",1257 .llvm_name = "atmega6490p",
1257 .features = featureSet(&[_]Feature{1258 .features = featureSet(&[_]Feature{
1258 .avr5,1259 .avr5,
1259 }),1260 }),
1260 };1261 };
1261 pub const atmega649a = Cpu{1262 pub const atmega649a = CpuModel{
1262 .name = "atmega649a",1263 .name = "atmega649a",
1263 .llvm_name = "atmega649a",1264 .llvm_name = "atmega649a",
1264 .features = featureSet(&[_]Feature{1265 .features = featureSet(&[_]Feature{
1265 .avr5,1266 .avr5,
1266 }),1267 }),
1267 };1268 };
1268 pub const atmega649p = Cpu{1269 pub const atmega649p = CpuModel{
1269 .name = "atmega649p",1270 .name = "atmega649p",
1270 .llvm_name = "atmega649p",1271 .llvm_name = "atmega649p",
1271 .features = featureSet(&[_]Feature{1272 .features = featureSet(&[_]Feature{
1272 .avr5,1273 .avr5,
1273 }),1274 }),
1274 };1275 };
1275 pub const atmega64a = Cpu{1276 pub const atmega64a = CpuModel{
1276 .name = "atmega64a",1277 .name = "atmega64a",
1277 .llvm_name = "atmega64a",1278 .llvm_name = "atmega64a",
1278 .features = featureSet(&[_]Feature{1279 .features = featureSet(&[_]Feature{
1279 .avr5,1280 .avr5,
1280 }),1281 }),
1281 };1282 };
1282 pub const atmega64c1 = Cpu{1283 pub const atmega64c1 = CpuModel{
1283 .name = "atmega64c1",1284 .name = "atmega64c1",
1284 .llvm_name = "atmega64c1",1285 .llvm_name = "atmega64c1",
1285 .features = featureSet(&[_]Feature{1286 .features = featureSet(&[_]Feature{
1286 .avr5,1287 .avr5,
1287 }),1288 }),
1288 };1289 };
1289 pub const atmega64hve = Cpu{1290 pub const atmega64hve = CpuModel{
1290 .name = "atmega64hve",1291 .name = "atmega64hve",
1291 .llvm_name = "atmega64hve",1292 .llvm_name = "atmega64hve",
1292 .features = featureSet(&[_]Feature{1293 .features = featureSet(&[_]Feature{
1293 .avr5,1294 .avr5,
1294 }),1295 }),
1295 };1296 };
1296 pub const atmega64m1 = Cpu{1297 pub const atmega64m1 = CpuModel{
1297 .name = "atmega64m1",1298 .name = "atmega64m1",
1298 .llvm_name = "atmega64m1",1299 .llvm_name = "atmega64m1",
1299 .features = featureSet(&[_]Feature{1300 .features = featureSet(&[_]Feature{
1300 .avr5,1301 .avr5,
1301 }),1302 }),
1302 };1303 };
1303 pub const atmega64rfr2 = Cpu{1304 pub const atmega64rfr2 = CpuModel{
1304 .name = "atmega64rfr2",1305 .name = "atmega64rfr2",
1305 .llvm_name = "atmega64rfr2",1306 .llvm_name = "atmega64rfr2",
1306 .features = featureSet(&[_]Feature{1307 .features = featureSet(&[_]Feature{
1307 .avr5,1308 .avr5,
1308 }),1309 }),
1309 };1310 };
1310 pub const atmega8 = Cpu{1311 pub const atmega8 = CpuModel{
1311 .name = "atmega8",1312 .name = "atmega8",
1312 .llvm_name = "atmega8",1313 .llvm_name = "atmega8",
1313 .features = featureSet(&[_]Feature{1314 .features = featureSet(&[_]Feature{
1314 .avr4,1315 .avr4,
1315 }),1316 }),
1316 };1317 };
1317 pub const atmega8515 = Cpu{1318 pub const atmega8515 = CpuModel{
1318 .name = "atmega8515",1319 .name = "atmega8515",
1319 .llvm_name = "atmega8515",1320 .llvm_name = "atmega8515",
1320 .features = featureSet(&[_]Feature{1321 .features = featureSet(&[_]Feature{
...@@ -1325,7 +1326,7 @@ pub const cpu = struct {...@@ -1325,7 +1326,7 @@ pub const cpu = struct {
1325 .spm,1326 .spm,
1326 }),1327 }),
1327 };1328 };
1328 pub const atmega8535 = Cpu{1329 pub const atmega8535 = CpuModel{
1329 .name = "atmega8535",1330 .name = "atmega8535",
1330 .llvm_name = "atmega8535",1331 .llvm_name = "atmega8535",
1331 .features = featureSet(&[_]Feature{1332 .features = featureSet(&[_]Feature{
...@@ -1336,175 +1337,175 @@ pub const cpu = struct {...@@ -1336,175 +1337,175 @@ pub const cpu = struct {
1336 .spm,1337 .spm,
1337 }),1338 }),
1338 };1339 };
1339 pub const atmega88 = Cpu{1340 pub const atmega88 = CpuModel{
1340 .name = "atmega88",1341 .name = "atmega88",
1341 .llvm_name = "atmega88",1342 .llvm_name = "atmega88",
1342 .features = featureSet(&[_]Feature{1343 .features = featureSet(&[_]Feature{
1343 .avr4,1344 .avr4,
1344 }),1345 }),
1345 };1346 };
1346 pub const atmega88a = Cpu{1347 pub const atmega88a = CpuModel{
1347 .name = "atmega88a",1348 .name = "atmega88a",
1348 .llvm_name = "atmega88a",1349 .llvm_name = "atmega88a",
1349 .features = featureSet(&[_]Feature{1350 .features = featureSet(&[_]Feature{
1350 .avr4,1351 .avr4,
1351 }),1352 }),
1352 };1353 };
1353 pub const atmega88p = Cpu{1354 pub const atmega88p = CpuModel{
1354 .name = "atmega88p",1355 .name = "atmega88p",
1355 .llvm_name = "atmega88p",1356 .llvm_name = "atmega88p",
1356 .features = featureSet(&[_]Feature{1357 .features = featureSet(&[_]Feature{
1357 .avr4,1358 .avr4,
1358 }),1359 }),
1359 };1360 };
1360 pub const atmega88pa = Cpu{1361 pub const atmega88pa = CpuModel{
1361 .name = "atmega88pa",1362 .name = "atmega88pa",
1362 .llvm_name = "atmega88pa",1363 .llvm_name = "atmega88pa",
1363 .features = featureSet(&[_]Feature{1364 .features = featureSet(&[_]Feature{
1364 .avr4,1365 .avr4,
1365 }),1366 }),
1366 };1367 };
1367 pub const atmega8a = Cpu{1368 pub const atmega8a = CpuModel{
1368 .name = "atmega8a",1369 .name = "atmega8a",
1369 .llvm_name = "atmega8a",1370 .llvm_name = "atmega8a",
1370 .features = featureSet(&[_]Feature{1371 .features = featureSet(&[_]Feature{
1371 .avr4,1372 .avr4,
1372 }),1373 }),
1373 };1374 };
1374 pub const atmega8hva = Cpu{1375 pub const atmega8hva = CpuModel{
1375 .name = "atmega8hva",1376 .name = "atmega8hva",
1376 .llvm_name = "atmega8hva",1377 .llvm_name = "atmega8hva",
1377 .features = featureSet(&[_]Feature{1378 .features = featureSet(&[_]Feature{
1378 .avr4,1379 .avr4,
1379 }),1380 }),
1380 };1381 };
1381 pub const atmega8u2 = Cpu{1382 pub const atmega8u2 = CpuModel{
1382 .name = "atmega8u2",1383 .name = "atmega8u2",
1383 .llvm_name = "atmega8u2",1384 .llvm_name = "atmega8u2",
1384 .features = featureSet(&[_]Feature{1385 .features = featureSet(&[_]Feature{
1385 .avr35,1386 .avr35,
1386 }),1387 }),
1387 };1388 };
1388 pub const attiny10 = Cpu{1389 pub const attiny10 = CpuModel{
1389 .name = "attiny10",1390 .name = "attiny10",
1390 .llvm_name = "attiny10",1391 .llvm_name = "attiny10",
1391 .features = featureSet(&[_]Feature{1392 .features = featureSet(&[_]Feature{
1392 .avrtiny,1393 .avrtiny,
1393 }),1394 }),
1394 };1395 };
1395 pub const attiny102 = Cpu{1396 pub const attiny102 = CpuModel{
1396 .name = "attiny102",1397 .name = "attiny102",
1397 .llvm_name = "attiny102",1398 .llvm_name = "attiny102",
1398 .features = featureSet(&[_]Feature{1399 .features = featureSet(&[_]Feature{
1399 .avrtiny,1400 .avrtiny,
1400 }),1401 }),
1401 };1402 };
1402 pub const attiny104 = Cpu{1403 pub const attiny104 = CpuModel{
1403 .name = "attiny104",1404 .name = "attiny104",
1404 .llvm_name = "attiny104",1405 .llvm_name = "attiny104",
1405 .features = featureSet(&[_]Feature{1406 .features = featureSet(&[_]Feature{
1406 .avrtiny,1407 .avrtiny,
1407 }),1408 }),
1408 };1409 };
1409 pub const attiny11 = Cpu{1410 pub const attiny11 = CpuModel{
1410 .name = "attiny11",1411 .name = "attiny11",
1411 .llvm_name = "attiny11",1412 .llvm_name = "attiny11",
1412 .features = featureSet(&[_]Feature{1413 .features = featureSet(&[_]Feature{
1413 .avr1,1414 .avr1,
1414 }),1415 }),
1415 };1416 };
1416 pub const attiny12 = Cpu{1417 pub const attiny12 = CpuModel{
1417 .name = "attiny12",1418 .name = "attiny12",
1418 .llvm_name = "attiny12",1419 .llvm_name = "attiny12",
1419 .features = featureSet(&[_]Feature{1420 .features = featureSet(&[_]Feature{
1420 .avr1,1421 .avr1,
1421 }),1422 }),
1422 };1423 };
1423 pub const attiny13 = Cpu{1424 pub const attiny13 = CpuModel{
1424 .name = "attiny13",1425 .name = "attiny13",
1425 .llvm_name = "attiny13",1426 .llvm_name = "attiny13",
1426 .features = featureSet(&[_]Feature{1427 .features = featureSet(&[_]Feature{
1427 .avr25,1428 .avr25,
1428 }),1429 }),
1429 };1430 };
1430 pub const attiny13a = Cpu{1431 pub const attiny13a = CpuModel{
1431 .name = "attiny13a",1432 .name = "attiny13a",
1432 .llvm_name = "attiny13a",1433 .llvm_name = "attiny13a",
1433 .features = featureSet(&[_]Feature{1434 .features = featureSet(&[_]Feature{
1434 .avr25,1435 .avr25,
1435 }),1436 }),
1436 };1437 };
1437 pub const attiny15 = Cpu{1438 pub const attiny15 = CpuModel{
1438 .name = "attiny15",1439 .name = "attiny15",
1439 .llvm_name = "attiny15",1440 .llvm_name = "attiny15",
1440 .features = featureSet(&[_]Feature{1441 .features = featureSet(&[_]Feature{
1441 .avr1,1442 .avr1,
1442 }),1443 }),
1443 };1444 };
1444 pub const attiny1634 = Cpu{1445 pub const attiny1634 = CpuModel{
1445 .name = "attiny1634",1446 .name = "attiny1634",
1446 .llvm_name = "attiny1634",1447 .llvm_name = "attiny1634",
1447 .features = featureSet(&[_]Feature{1448 .features = featureSet(&[_]Feature{
1448 .avr35,1449 .avr35,
1449 }),1450 }),
1450 };1451 };
1451 pub const attiny167 = Cpu{1452 pub const attiny167 = CpuModel{
1452 .name = "attiny167",1453 .name = "attiny167",
1453 .llvm_name = "attiny167",1454 .llvm_name = "attiny167",
1454 .features = featureSet(&[_]Feature{1455 .features = featureSet(&[_]Feature{
1455 .avr35,1456 .avr35,
1456 }),1457 }),
1457 };1458 };
1458 pub const attiny20 = Cpu{1459 pub const attiny20 = CpuModel{
1459 .name = "attiny20",1460 .name = "attiny20",
1460 .llvm_name = "attiny20",1461 .llvm_name = "attiny20",
1461 .features = featureSet(&[_]Feature{1462 .features = featureSet(&[_]Feature{
1462 .avrtiny,1463 .avrtiny,
1463 }),1464 }),
1464 };1465 };
1465 pub const attiny22 = Cpu{1466 pub const attiny22 = CpuModel{
1466 .name = "attiny22",1467 .name = "attiny22",
1467 .llvm_name = "attiny22",1468 .llvm_name = "attiny22",
1468 .features = featureSet(&[_]Feature{1469 .features = featureSet(&[_]Feature{
1469 .avr2,1470 .avr2,
1470 }),1471 }),
1471 };1472 };
1472 pub const attiny2313 = Cpu{1473 pub const attiny2313 = CpuModel{
1473 .name = "attiny2313",1474 .name = "attiny2313",
1474 .llvm_name = "attiny2313",1475 .llvm_name = "attiny2313",
1475 .features = featureSet(&[_]Feature{1476 .features = featureSet(&[_]Feature{
1476 .avr25,1477 .avr25,
1477 }),1478 }),
1478 };1479 };
1479 pub const attiny2313a = Cpu{1480 pub const attiny2313a = CpuModel{
1480 .name = "attiny2313a",1481 .name = "attiny2313a",
1481 .llvm_name = "attiny2313a",1482 .llvm_name = "attiny2313a",
1482 .features = featureSet(&[_]Feature{1483 .features = featureSet(&[_]Feature{
1483 .avr25,1484 .avr25,
1484 }),1485 }),
1485 };1486 };
1486 pub const attiny24 = Cpu{1487 pub const attiny24 = CpuModel{
1487 .name = "attiny24",1488 .name = "attiny24",
1488 .llvm_name = "attiny24",1489 .llvm_name = "attiny24",
1489 .features = featureSet(&[_]Feature{1490 .features = featureSet(&[_]Feature{
1490 .avr25,1491 .avr25,
1491 }),1492 }),
1492 };1493 };
1493 pub const attiny24a = Cpu{1494 pub const attiny24a = CpuModel{
1494 .name = "attiny24a",1495 .name = "attiny24a",
1495 .llvm_name = "attiny24a",1496 .llvm_name = "attiny24a",
1496 .features = featureSet(&[_]Feature{1497 .features = featureSet(&[_]Feature{
1497 .avr25,1498 .avr25,
1498 }),1499 }),
1499 };1500 };
1500 pub const attiny25 = Cpu{1501 pub const attiny25 = CpuModel{
1501 .name = "attiny25",1502 .name = "attiny25",
1502 .llvm_name = "attiny25",1503 .llvm_name = "attiny25",
1503 .features = featureSet(&[_]Feature{1504 .features = featureSet(&[_]Feature{
1504 .avr25,1505 .avr25,
1505 }),1506 }),
1506 };1507 };
1507 pub const attiny26 = Cpu{1508 pub const attiny26 = CpuModel{
1508 .name = "attiny26",1509 .name = "attiny26",
1509 .llvm_name = "attiny26",1510 .llvm_name = "attiny26",
1510 .features = featureSet(&[_]Feature{1511 .features = featureSet(&[_]Feature{
...@@ -1512,602 +1513,602 @@ pub const cpu = struct {...@@ -1512,602 +1513,602 @@ pub const cpu = struct {
1512 .lpmx,1513 .lpmx,
1513 }),1514 }),
1514 };1515 };
1515 pub const attiny261 = Cpu{1516 pub const attiny261 = CpuModel{
1516 .name = "attiny261",1517 .name = "attiny261",
1517 .llvm_name = "attiny261",1518 .llvm_name = "attiny261",
1518 .features = featureSet(&[_]Feature{1519 .features = featureSet(&[_]Feature{
1519 .avr25,1520 .avr25,
1520 }),1521 }),
1521 };1522 };
1522 pub const attiny261a = Cpu{1523 pub const attiny261a = CpuModel{
1523 .name = "attiny261a",1524 .name = "attiny261a",
1524 .llvm_name = "attiny261a",1525 .llvm_name = "attiny261a",
1525 .features = featureSet(&[_]Feature{1526 .features = featureSet(&[_]Feature{
1526 .avr25,1527 .avr25,
1527 }),1528 }),
1528 };1529 };
1529 pub const attiny28 = Cpu{1530 pub const attiny28 = CpuModel{
1530 .name = "attiny28",1531 .name = "attiny28",
1531 .llvm_name = "attiny28",1532 .llvm_name = "attiny28",
1532 .features = featureSet(&[_]Feature{1533 .features = featureSet(&[_]Feature{
1533 .avr1,1534 .avr1,
1534 }),1535 }),
1535 };1536 };
1536 pub const attiny4 = Cpu{1537 pub const attiny4 = CpuModel{
1537 .name = "attiny4",1538 .name = "attiny4",
1538 .llvm_name = "attiny4",1539 .llvm_name = "attiny4",
1539 .features = featureSet(&[_]Feature{1540 .features = featureSet(&[_]Feature{
1540 .avrtiny,1541 .avrtiny,
1541 }),1542 }),
1542 };1543 };
1543 pub const attiny40 = Cpu{1544 pub const attiny40 = CpuModel{
1544 .name = "attiny40",1545 .name = "attiny40",
1545 .llvm_name = "attiny40",1546 .llvm_name = "attiny40",
1546 .features = featureSet(&[_]Feature{1547 .features = featureSet(&[_]Feature{
1547 .avrtiny,1548 .avrtiny,
1548 }),1549 }),
1549 };1550 };
1550 pub const attiny4313 = Cpu{1551 pub const attiny4313 = CpuModel{
1551 .name = "attiny4313",1552 .name = "attiny4313",
1552 .llvm_name = "attiny4313",1553 .llvm_name = "attiny4313",
1553 .features = featureSet(&[_]Feature{1554 .features = featureSet(&[_]Feature{
1554 .avr25,1555 .avr25,
1555 }),1556 }),
1556 };1557 };
1557 pub const attiny43u = Cpu{1558 pub const attiny43u = CpuModel{
1558 .name = "attiny43u",1559 .name = "attiny43u",
1559 .llvm_name = "attiny43u",1560 .llvm_name = "attiny43u",
1560 .features = featureSet(&[_]Feature{1561 .features = featureSet(&[_]Feature{
1561 .avr25,1562 .avr25,
1562 }),1563 }),
1563 };1564 };
1564 pub const attiny44 = Cpu{1565 pub const attiny44 = CpuModel{
1565 .name = "attiny44",1566 .name = "attiny44",
1566 .llvm_name = "attiny44",1567 .llvm_name = "attiny44",
1567 .features = featureSet(&[_]Feature{1568 .features = featureSet(&[_]Feature{
1568 .avr25,1569 .avr25,
1569 }),1570 }),
1570 };1571 };
1571 pub const attiny44a = Cpu{1572 pub const attiny44a = CpuModel{
1572 .name = "attiny44a",1573 .name = "attiny44a",
1573 .llvm_name = "attiny44a",1574 .llvm_name = "attiny44a",
1574 .features = featureSet(&[_]Feature{1575 .features = featureSet(&[_]Feature{
1575 .avr25,1576 .avr25,
1576 }),1577 }),
1577 };1578 };
1578 pub const attiny45 = Cpu{1579 pub const attiny45 = CpuModel{
1579 .name = "attiny45",1580 .name = "attiny45",
1580 .llvm_name = "attiny45",1581 .llvm_name = "attiny45",
1581 .features = featureSet(&[_]Feature{1582 .features = featureSet(&[_]Feature{
1582 .avr25,1583 .avr25,
1583 }),1584 }),
1584 };1585 };
1585 pub const attiny461 = Cpu{1586 pub const attiny461 = CpuModel{
1586 .name = "attiny461",1587 .name = "attiny461",
1587 .llvm_name = "attiny461",1588 .llvm_name = "attiny461",
1588 .features = featureSet(&[_]Feature{1589 .features = featureSet(&[_]Feature{
1589 .avr25,1590 .avr25,
1590 }),1591 }),
1591 };1592 };
1592 pub const attiny461a = Cpu{1593 pub const attiny461a = CpuModel{
1593 .name = "attiny461a",1594 .name = "attiny461a",
1594 .llvm_name = "attiny461a",1595 .llvm_name = "attiny461a",
1595 .features = featureSet(&[_]Feature{1596 .features = featureSet(&[_]Feature{
1596 .avr25,1597 .avr25,
1597 }),1598 }),
1598 };1599 };
1599 pub const attiny48 = Cpu{1600 pub const attiny48 = CpuModel{
1600 .name = "attiny48",1601 .name = "attiny48",
1601 .llvm_name = "attiny48",1602 .llvm_name = "attiny48",
1602 .features = featureSet(&[_]Feature{1603 .features = featureSet(&[_]Feature{
1603 .avr25,1604 .avr25,
1604 }),1605 }),
1605 };1606 };
1606 pub const attiny5 = Cpu{1607 pub const attiny5 = CpuModel{
1607 .name = "attiny5",1608 .name = "attiny5",
1608 .llvm_name = "attiny5",1609 .llvm_name = "attiny5",
1609 .features = featureSet(&[_]Feature{1610 .features = featureSet(&[_]Feature{
1610 .avrtiny,1611 .avrtiny,
1611 }),1612 }),
1612 };1613 };
1613 pub const attiny828 = Cpu{1614 pub const attiny828 = CpuModel{
1614 .name = "attiny828",1615 .name = "attiny828",
1615 .llvm_name = "attiny828",1616 .llvm_name = "attiny828",
1616 .features = featureSet(&[_]Feature{1617 .features = featureSet(&[_]Feature{
1617 .avr25,1618 .avr25,
1618 }),1619 }),
1619 };1620 };
1620 pub const attiny84 = Cpu{1621 pub const attiny84 = CpuModel{
1621 .name = "attiny84",1622 .name = "attiny84",
1622 .llvm_name = "attiny84",1623 .llvm_name = "attiny84",
1623 .features = featureSet(&[_]Feature{1624 .features = featureSet(&[_]Feature{
1624 .avr25,1625 .avr25,
1625 }),1626 }),
1626 };1627 };
1627 pub const attiny84a = Cpu{1628 pub const attiny84a = CpuModel{
1628 .name = "attiny84a",1629 .name = "attiny84a",
1629 .llvm_name = "attiny84a",1630 .llvm_name = "attiny84a",
1630 .features = featureSet(&[_]Feature{1631 .features = featureSet(&[_]Feature{
1631 .avr25,1632 .avr25,
1632 }),1633 }),
1633 };1634 };
1634 pub const attiny85 = Cpu{1635 pub const attiny85 = CpuModel{
1635 .name = "attiny85",1636 .name = "attiny85",
1636 .llvm_name = "attiny85",1637 .llvm_name = "attiny85",
1637 .features = featureSet(&[_]Feature{1638 .features = featureSet(&[_]Feature{
1638 .avr25,1639 .avr25,
1639 }),1640 }),
1640 };1641 };
1641 pub const attiny861 = Cpu{1642 pub const attiny861 = CpuModel{
1642 .name = "attiny861",1643 .name = "attiny861",
1643 .llvm_name = "attiny861",1644 .llvm_name = "attiny861",
1644 .features = featureSet(&[_]Feature{1645 .features = featureSet(&[_]Feature{
1645 .avr25,1646 .avr25,
1646 }),1647 }),
1647 };1648 };
1648 pub const attiny861a = Cpu{1649 pub const attiny861a = CpuModel{
1649 .name = "attiny861a",1650 .name = "attiny861a",
1650 .llvm_name = "attiny861a",1651 .llvm_name = "attiny861a",
1651 .features = featureSet(&[_]Feature{1652 .features = featureSet(&[_]Feature{
1652 .avr25,1653 .avr25,
1653 }),1654 }),
1654 };1655 };
1655 pub const attiny87 = Cpu{1656 pub const attiny87 = CpuModel{
1656 .name = "attiny87",1657 .name = "attiny87",
1657 .llvm_name = "attiny87",1658 .llvm_name = "attiny87",
1658 .features = featureSet(&[_]Feature{1659 .features = featureSet(&[_]Feature{
1659 .avr25,1660 .avr25,
1660 }),1661 }),
1661 };1662 };
1662 pub const attiny88 = Cpu{1663 pub const attiny88 = CpuModel{
1663 .name = "attiny88",1664 .name = "attiny88",
1664 .llvm_name = "attiny88",1665 .llvm_name = "attiny88",
1665 .features = featureSet(&[_]Feature{1666 .features = featureSet(&[_]Feature{
1666 .avr25,1667 .avr25,
1667 }),1668 }),
1668 };1669 };
1669 pub const attiny9 = Cpu{1670 pub const attiny9 = CpuModel{
1670 .name = "attiny9",1671 .name = "attiny9",
1671 .llvm_name = "attiny9",1672 .llvm_name = "attiny9",
1672 .features = featureSet(&[_]Feature{1673 .features = featureSet(&[_]Feature{
1673 .avrtiny,1674 .avrtiny,
1674 }),1675 }),
1675 };1676 };
1676 pub const atxmega128a1 = Cpu{1677 pub const atxmega128a1 = CpuModel{
1677 .name = "atxmega128a1",1678 .name = "atxmega128a1",
1678 .llvm_name = "atxmega128a1",1679 .llvm_name = "atxmega128a1",
1679 .features = featureSet(&[_]Feature{1680 .features = featureSet(&[_]Feature{
1680 .xmega,1681 .xmega,
1681 }),1682 }),
1682 };1683 };
1683 pub const atxmega128a1u = Cpu{1684 pub const atxmega128a1u = CpuModel{
1684 .name = "atxmega128a1u",1685 .name = "atxmega128a1u",
1685 .llvm_name = "atxmega128a1u",1686 .llvm_name = "atxmega128a1u",
1686 .features = featureSet(&[_]Feature{1687 .features = featureSet(&[_]Feature{
1687 .xmegau,1688 .xmegau,
1688 }),1689 }),
1689 };1690 };
1690 pub const atxmega128a3 = Cpu{1691 pub const atxmega128a3 = CpuModel{
1691 .name = "atxmega128a3",1692 .name = "atxmega128a3",
1692 .llvm_name = "atxmega128a3",1693 .llvm_name = "atxmega128a3",
1693 .features = featureSet(&[_]Feature{1694 .features = featureSet(&[_]Feature{
1694 .xmega,1695 .xmega,
1695 }),1696 }),
1696 };1697 };
1697 pub const atxmega128a3u = Cpu{1698 pub const atxmega128a3u = CpuModel{
1698 .name = "atxmega128a3u",1699 .name = "atxmega128a3u",
1699 .llvm_name = "atxmega128a3u",1700 .llvm_name = "atxmega128a3u",
1700 .features = featureSet(&[_]Feature{1701 .features = featureSet(&[_]Feature{
1701 .xmegau,1702 .xmegau,
1702 }),1703 }),
1703 };1704 };
1704 pub const atxmega128a4u = Cpu{1705 pub const atxmega128a4u = CpuModel{
1705 .name = "atxmega128a4u",1706 .name = "atxmega128a4u",
1706 .llvm_name = "atxmega128a4u",1707 .llvm_name = "atxmega128a4u",
1707 .features = featureSet(&[_]Feature{1708 .features = featureSet(&[_]Feature{
1708 .xmegau,1709 .xmegau,
1709 }),1710 }),
1710 };1711 };
1711 pub const atxmega128b1 = Cpu{1712 pub const atxmega128b1 = CpuModel{
1712 .name = "atxmega128b1",1713 .name = "atxmega128b1",
1713 .llvm_name = "atxmega128b1",1714 .llvm_name = "atxmega128b1",
1714 .features = featureSet(&[_]Feature{1715 .features = featureSet(&[_]Feature{
1715 .xmegau,1716 .xmegau,
1716 }),1717 }),
1717 };1718 };
1718 pub const atxmega128b3 = Cpu{1719 pub const atxmega128b3 = CpuModel{
1719 .name = "atxmega128b3",1720 .name = "atxmega128b3",
1720 .llvm_name = "atxmega128b3",1721 .llvm_name = "atxmega128b3",
1721 .features = featureSet(&[_]Feature{1722 .features = featureSet(&[_]Feature{
1722 .xmegau,1723 .xmegau,
1723 }),1724 }),
1724 };1725 };
1725 pub const atxmega128c3 = Cpu{1726 pub const atxmega128c3 = CpuModel{
1726 .name = "atxmega128c3",1727 .name = "atxmega128c3",
1727 .llvm_name = "atxmega128c3",1728 .llvm_name = "atxmega128c3",
1728 .features = featureSet(&[_]Feature{1729 .features = featureSet(&[_]Feature{
1729 .xmegau,1730 .xmegau,
1730 }),1731 }),
1731 };1732 };
1732 pub const atxmega128d3 = Cpu{1733 pub const atxmega128d3 = CpuModel{
1733 .name = "atxmega128d3",1734 .name = "atxmega128d3",
1734 .llvm_name = "atxmega128d3",1735 .llvm_name = "atxmega128d3",
1735 .features = featureSet(&[_]Feature{1736 .features = featureSet(&[_]Feature{
1736 .xmega,1737 .xmega,
1737 }),1738 }),
1738 };1739 };
1739 pub const atxmega128d4 = Cpu{1740 pub const atxmega128d4 = CpuModel{
1740 .name = "atxmega128d4",1741 .name = "atxmega128d4",
1741 .llvm_name = "atxmega128d4",1742 .llvm_name = "atxmega128d4",
1742 .features = featureSet(&[_]Feature{1743 .features = featureSet(&[_]Feature{
1743 .xmega,1744 .xmega,
1744 }),1745 }),
1745 };1746 };
1746 pub const atxmega16a4 = Cpu{1747 pub const atxmega16a4 = CpuModel{
1747 .name = "atxmega16a4",1748 .name = "atxmega16a4",
1748 .llvm_name = "atxmega16a4",1749 .llvm_name = "atxmega16a4",
1749 .features = featureSet(&[_]Feature{1750 .features = featureSet(&[_]Feature{
1750 .xmega,1751 .xmega,
1751 }),1752 }),
1752 };1753 };
1753 pub const atxmega16a4u = Cpu{1754 pub const atxmega16a4u = CpuModel{
1754 .name = "atxmega16a4u",1755 .name = "atxmega16a4u",
1755 .llvm_name = "atxmega16a4u",1756 .llvm_name = "atxmega16a4u",
1756 .features = featureSet(&[_]Feature{1757 .features = featureSet(&[_]Feature{
1757 .xmegau,1758 .xmegau,
1758 }),1759 }),
1759 };1760 };
1760 pub const atxmega16c4 = Cpu{1761 pub const atxmega16c4 = CpuModel{
1761 .name = "atxmega16c4",1762 .name = "atxmega16c4",
1762 .llvm_name = "atxmega16c4",1763 .llvm_name = "atxmega16c4",
1763 .features = featureSet(&[_]Feature{1764 .features = featureSet(&[_]Feature{
1764 .xmegau,1765 .xmegau,
1765 }),1766 }),
1766 };1767 };
1767 pub const atxmega16d4 = Cpu{1768 pub const atxmega16d4 = CpuModel{
1768 .name = "atxmega16d4",1769 .name = "atxmega16d4",
1769 .llvm_name = "atxmega16d4",1770 .llvm_name = "atxmega16d4",
1770 .features = featureSet(&[_]Feature{1771 .features = featureSet(&[_]Feature{
1771 .xmega,1772 .xmega,
1772 }),1773 }),
1773 };1774 };
1774 pub const atxmega16e5 = Cpu{1775 pub const atxmega16e5 = CpuModel{
1775 .name = "atxmega16e5",1776 .name = "atxmega16e5",
1776 .llvm_name = "atxmega16e5",1777 .llvm_name = "atxmega16e5",
1777 .features = featureSet(&[_]Feature{1778 .features = featureSet(&[_]Feature{
1778 .xmega,1779 .xmega,
1779 }),1780 }),
1780 };1781 };
1781 pub const atxmega192a3 = Cpu{1782 pub const atxmega192a3 = CpuModel{
1782 .name = "atxmega192a3",1783 .name = "atxmega192a3",
1783 .llvm_name = "atxmega192a3",1784 .llvm_name = "atxmega192a3",
1784 .features = featureSet(&[_]Feature{1785 .features = featureSet(&[_]Feature{
1785 .xmega,1786 .xmega,
1786 }),1787 }),
1787 };1788 };
1788 pub const atxmega192a3u = Cpu{1789 pub const atxmega192a3u = CpuModel{
1789 .name = "atxmega192a3u",1790 .name = "atxmega192a3u",
1790 .llvm_name = "atxmega192a3u",1791 .llvm_name = "atxmega192a3u",
1791 .features = featureSet(&[_]Feature{1792 .features = featureSet(&[_]Feature{
1792 .xmegau,1793 .xmegau,
1793 }),1794 }),
1794 };1795 };
1795 pub const atxmega192c3 = Cpu{1796 pub const atxmega192c3 = CpuModel{
1796 .name = "atxmega192c3",1797 .name = "atxmega192c3",
1797 .llvm_name = "atxmega192c3",1798 .llvm_name = "atxmega192c3",
1798 .features = featureSet(&[_]Feature{1799 .features = featureSet(&[_]Feature{
1799 .xmegau,1800 .xmegau,
1800 }),1801 }),
1801 };1802 };
1802 pub const atxmega192d3 = Cpu{1803 pub const atxmega192d3 = CpuModel{
1803 .name = "atxmega192d3",1804 .name = "atxmega192d3",
1804 .llvm_name = "atxmega192d3",1805 .llvm_name = "atxmega192d3",
1805 .features = featureSet(&[_]Feature{1806 .features = featureSet(&[_]Feature{
1806 .xmega,1807 .xmega,
1807 }),1808 }),
1808 };1809 };
1809 pub const atxmega256a3 = Cpu{1810 pub const atxmega256a3 = CpuModel{
1810 .name = "atxmega256a3",1811 .name = "atxmega256a3",
1811 .llvm_name = "atxmega256a3",1812 .llvm_name = "atxmega256a3",
1812 .features = featureSet(&[_]Feature{1813 .features = featureSet(&[_]Feature{
1813 .xmega,1814 .xmega,
1814 }),1815 }),
1815 };1816 };
1816 pub const atxmega256a3b = Cpu{1817 pub const atxmega256a3b = CpuModel{
1817 .name = "atxmega256a3b",1818 .name = "atxmega256a3b",
1818 .llvm_name = "atxmega256a3b",1819 .llvm_name = "atxmega256a3b",
1819 .features = featureSet(&[_]Feature{1820 .features = featureSet(&[_]Feature{
1820 .xmega,1821 .xmega,
1821 }),1822 }),
1822 };1823 };
1823 pub const atxmega256a3bu = Cpu{1824 pub const atxmega256a3bu = CpuModel{
1824 .name = "atxmega256a3bu",1825 .name = "atxmega256a3bu",
1825 .llvm_name = "atxmega256a3bu",1826 .llvm_name = "atxmega256a3bu",
1826 .features = featureSet(&[_]Feature{1827 .features = featureSet(&[_]Feature{
1827 .xmegau,1828 .xmegau,
1828 }),1829 }),
1829 };1830 };
1830 pub const atxmega256a3u = Cpu{1831 pub const atxmega256a3u = CpuModel{
1831 .name = "atxmega256a3u",1832 .name = "atxmega256a3u",
1832 .llvm_name = "atxmega256a3u",1833 .llvm_name = "atxmega256a3u",
1833 .features = featureSet(&[_]Feature{1834 .features = featureSet(&[_]Feature{
1834 .xmegau,1835 .xmegau,
1835 }),1836 }),
1836 };1837 };
1837 pub const atxmega256c3 = Cpu{1838 pub const atxmega256c3 = CpuModel{
1838 .name = "atxmega256c3",1839 .name = "atxmega256c3",
1839 .llvm_name = "atxmega256c3",1840 .llvm_name = "atxmega256c3",
1840 .features = featureSet(&[_]Feature{1841 .features = featureSet(&[_]Feature{
1841 .xmegau,1842 .xmegau,
1842 }),1843 }),
1843 };1844 };
1844 pub const atxmega256d3 = Cpu{1845 pub const atxmega256d3 = CpuModel{
1845 .name = "atxmega256d3",1846 .name = "atxmega256d3",
1846 .llvm_name = "atxmega256d3",1847 .llvm_name = "atxmega256d3",
1847 .features = featureSet(&[_]Feature{1848 .features = featureSet(&[_]Feature{
1848 .xmega,1849 .xmega,
1849 }),1850 }),
1850 };1851 };
1851 pub const atxmega32a4 = Cpu{1852 pub const atxmega32a4 = CpuModel{
1852 .name = "atxmega32a4",1853 .name = "atxmega32a4",
1853 .llvm_name = "atxmega32a4",1854 .llvm_name = "atxmega32a4",
1854 .features = featureSet(&[_]Feature{1855 .features = featureSet(&[_]Feature{
1855 .xmega,1856 .xmega,
1856 }),1857 }),
1857 };1858 };
1858 pub const atxmega32a4u = Cpu{1859 pub const atxmega32a4u = CpuModel{
1859 .name = "atxmega32a4u",1860 .name = "atxmega32a4u",
1860 .llvm_name = "atxmega32a4u",1861 .llvm_name = "atxmega32a4u",
1861 .features = featureSet(&[_]Feature{1862 .features = featureSet(&[_]Feature{
1862 .xmegau,1863 .xmegau,
1863 }),1864 }),
1864 };1865 };
1865 pub const atxmega32c4 = Cpu{1866 pub const atxmega32c4 = CpuModel{
1866 .name = "atxmega32c4",1867 .name = "atxmega32c4",
1867 .llvm_name = "atxmega32c4",1868 .llvm_name = "atxmega32c4",
1868 .features = featureSet(&[_]Feature{1869 .features = featureSet(&[_]Feature{
1869 .xmegau,1870 .xmegau,
1870 }),1871 }),
1871 };1872 };
1872 pub const atxmega32d4 = Cpu{1873 pub const atxmega32d4 = CpuModel{
1873 .name = "atxmega32d4",1874 .name = "atxmega32d4",
1874 .llvm_name = "atxmega32d4",1875 .llvm_name = "atxmega32d4",
1875 .features = featureSet(&[_]Feature{1876 .features = featureSet(&[_]Feature{
1876 .xmega,1877 .xmega,
1877 }),1878 }),
1878 };1879 };
1879 pub const atxmega32e5 = Cpu{1880 pub const atxmega32e5 = CpuModel{
1880 .name = "atxmega32e5",1881 .name = "atxmega32e5",
1881 .llvm_name = "atxmega32e5",1882 .llvm_name = "atxmega32e5",
1882 .features = featureSet(&[_]Feature{1883 .features = featureSet(&[_]Feature{
1883 .xmega,1884 .xmega,
1884 }),1885 }),
1885 };1886 };
1886 pub const atxmega32x1 = Cpu{1887 pub const atxmega32x1 = CpuModel{
1887 .name = "atxmega32x1",1888 .name = "atxmega32x1",
1888 .llvm_name = "atxmega32x1",1889 .llvm_name = "atxmega32x1",
1889 .features = featureSet(&[_]Feature{1890 .features = featureSet(&[_]Feature{
1890 .xmega,1891 .xmega,
1891 }),1892 }),
1892 };1893 };
1893 pub const atxmega384c3 = Cpu{1894 pub const atxmega384c3 = CpuModel{
1894 .name = "atxmega384c3",1895 .name = "atxmega384c3",
1895 .llvm_name = "atxmega384c3",1896 .llvm_name = "atxmega384c3",
1896 .features = featureSet(&[_]Feature{1897 .features = featureSet(&[_]Feature{
1897 .xmegau,1898 .xmegau,
1898 }),1899 }),
1899 };1900 };
1900 pub const atxmega384d3 = Cpu{1901 pub const atxmega384d3 = CpuModel{
1901 .name = "atxmega384d3",1902 .name = "atxmega384d3",
1902 .llvm_name = "atxmega384d3",1903 .llvm_name = "atxmega384d3",
1903 .features = featureSet(&[_]Feature{1904 .features = featureSet(&[_]Feature{
1904 .xmega,1905 .xmega,
1905 }),1906 }),
1906 };1907 };
1907 pub const atxmega64a1 = Cpu{1908 pub const atxmega64a1 = CpuModel{
1908 .name = "atxmega64a1",1909 .name = "atxmega64a1",
1909 .llvm_name = "atxmega64a1",1910 .llvm_name = "atxmega64a1",
1910 .features = featureSet(&[_]Feature{1911 .features = featureSet(&[_]Feature{
1911 .xmega,1912 .xmega,
1912 }),1913 }),
1913 };1914 };
1914 pub const atxmega64a1u = Cpu{1915 pub const atxmega64a1u = CpuModel{
1915 .name = "atxmega64a1u",1916 .name = "atxmega64a1u",
1916 .llvm_name = "atxmega64a1u",1917 .llvm_name = "atxmega64a1u",
1917 .features = featureSet(&[_]Feature{1918 .features = featureSet(&[_]Feature{
1918 .xmegau,1919 .xmegau,
1919 }),1920 }),
1920 };1921 };
1921 pub const atxmega64a3 = Cpu{1922 pub const atxmega64a3 = CpuModel{
1922 .name = "atxmega64a3",1923 .name = "atxmega64a3",
1923 .llvm_name = "atxmega64a3",1924 .llvm_name = "atxmega64a3",
1924 .features = featureSet(&[_]Feature{1925 .features = featureSet(&[_]Feature{
1925 .xmega,1926 .xmega,
1926 }),1927 }),
1927 };1928 };
1928 pub const atxmega64a3u = Cpu{1929 pub const atxmega64a3u = CpuModel{
1929 .name = "atxmega64a3u",1930 .name = "atxmega64a3u",
1930 .llvm_name = "atxmega64a3u",1931 .llvm_name = "atxmega64a3u",
1931 .features = featureSet(&[_]Feature{1932 .features = featureSet(&[_]Feature{
1932 .xmegau,1933 .xmegau,
1933 }),1934 }),
1934 };1935 };
1935 pub const atxmega64a4u = Cpu{1936 pub const atxmega64a4u = CpuModel{
1936 .name = "atxmega64a4u",1937 .name = "atxmega64a4u",
1937 .llvm_name = "atxmega64a4u",1938 .llvm_name = "atxmega64a4u",
1938 .features = featureSet(&[_]Feature{1939 .features = featureSet(&[_]Feature{
1939 .xmegau,1940 .xmegau,
1940 }),1941 }),
1941 };1942 };
1942 pub const atxmega64b1 = Cpu{1943 pub const atxmega64b1 = CpuModel{
1943 .name = "atxmega64b1",1944 .name = "atxmega64b1",
1944 .llvm_name = "atxmega64b1",1945 .llvm_name = "atxmega64b1",
1945 .features = featureSet(&[_]Feature{1946 .features = featureSet(&[_]Feature{
1946 .xmegau,1947 .xmegau,
1947 }),1948 }),
1948 };1949 };
1949 pub const atxmega64b3 = Cpu{1950 pub const atxmega64b3 = CpuModel{
1950 .name = "atxmega64b3",1951 .name = "atxmega64b3",
1951 .llvm_name = "atxmega64b3",1952 .llvm_name = "atxmega64b3",
1952 .features = featureSet(&[_]Feature{1953 .features = featureSet(&[_]Feature{
1953 .xmegau,1954 .xmegau,
1954 }),1955 }),
1955 };1956 };
1956 pub const atxmega64c3 = Cpu{1957 pub const atxmega64c3 = CpuModel{
1957 .name = "atxmega64c3",1958 .name = "atxmega64c3",
1958 .llvm_name = "atxmega64c3",1959 .llvm_name = "atxmega64c3",
1959 .features = featureSet(&[_]Feature{1960 .features = featureSet(&[_]Feature{
1960 .xmegau,1961 .xmegau,
1961 }),1962 }),
1962 };1963 };
1963 pub const atxmega64d3 = Cpu{1964 pub const atxmega64d3 = CpuModel{
1964 .name = "atxmega64d3",1965 .name = "atxmega64d3",
1965 .llvm_name = "atxmega64d3",1966 .llvm_name = "atxmega64d3",
1966 .features = featureSet(&[_]Feature{1967 .features = featureSet(&[_]Feature{
1967 .xmega,1968 .xmega,
1968 }),1969 }),
1969 };1970 };
1970 pub const atxmega64d4 = Cpu{1971 pub const atxmega64d4 = CpuModel{
1971 .name = "atxmega64d4",1972 .name = "atxmega64d4",
1972 .llvm_name = "atxmega64d4",1973 .llvm_name = "atxmega64d4",
1973 .features = featureSet(&[_]Feature{1974 .features = featureSet(&[_]Feature{
1974 .xmega,1975 .xmega,
1975 }),1976 }),
1976 };1977 };
1977 pub const atxmega8e5 = Cpu{1978 pub const atxmega8e5 = CpuModel{
1978 .name = "atxmega8e5",1979 .name = "atxmega8e5",
1979 .llvm_name = "atxmega8e5",1980 .llvm_name = "atxmega8e5",
1980 .features = featureSet(&[_]Feature{1981 .features = featureSet(&[_]Feature{
1981 .xmega,1982 .xmega,
1982 }),1983 }),
1983 };1984 };
1984 pub const avr1 = Cpu{1985 pub const avr1 = CpuModel{
1985 .name = "avr1",1986 .name = "avr1",
1986 .llvm_name = "avr1",1987 .llvm_name = "avr1",
1987 .features = featureSet(&[_]Feature{1988 .features = featureSet(&[_]Feature{
1988 .avr1,1989 .avr1,
1989 }),1990 }),
1990 };1991 };
1991 pub const avr2 = Cpu{1992 pub const avr2 = CpuModel{
1992 .name = "avr2",1993 .name = "avr2",
1993 .llvm_name = "avr2",1994 .llvm_name = "avr2",
1994 .features = featureSet(&[_]Feature{1995 .features = featureSet(&[_]Feature{
1995 .avr2,1996 .avr2,
1996 }),1997 }),
1997 };1998 };
1998 pub const avr25 = Cpu{1999 pub const avr25 = CpuModel{
1999 .name = "avr25",2000 .name = "avr25",
2000 .llvm_name = "avr25",2001 .llvm_name = "avr25",
2001 .features = featureSet(&[_]Feature{2002 .features = featureSet(&[_]Feature{
2002 .avr25,2003 .avr25,
2003 }),2004 }),
2004 };2005 };
2005 pub const avr3 = Cpu{2006 pub const avr3 = CpuModel{
2006 .name = "avr3",2007 .name = "avr3",
2007 .llvm_name = "avr3",2008 .llvm_name = "avr3",
2008 .features = featureSet(&[_]Feature{2009 .features = featureSet(&[_]Feature{
2009 .avr3,2010 .avr3,
2010 }),2011 }),
2011 };2012 };
2012 pub const avr31 = Cpu{2013 pub const avr31 = CpuModel{
2013 .name = "avr31",2014 .name = "avr31",
2014 .llvm_name = "avr31",2015 .llvm_name = "avr31",
2015 .features = featureSet(&[_]Feature{2016 .features = featureSet(&[_]Feature{
2016 .avr31,2017 .avr31,
2017 }),2018 }),
2018 };2019 };
2019 pub const avr35 = Cpu{2020 pub const avr35 = CpuModel{
2020 .name = "avr35",2021 .name = "avr35",
2021 .llvm_name = "avr35",2022 .llvm_name = "avr35",
2022 .features = featureSet(&[_]Feature{2023 .features = featureSet(&[_]Feature{
2023 .avr35,2024 .avr35,
2024 }),2025 }),
2025 };2026 };
2026 pub const avr4 = Cpu{2027 pub const avr4 = CpuModel{
2027 .name = "avr4",2028 .name = "avr4",
2028 .llvm_name = "avr4",2029 .llvm_name = "avr4",
2029 .features = featureSet(&[_]Feature{2030 .features = featureSet(&[_]Feature{
2030 .avr4,2031 .avr4,
2031 }),2032 }),
2032 };2033 };
2033 pub const avr5 = Cpu{2034 pub const avr5 = CpuModel{
2034 .name = "avr5",2035 .name = "avr5",
2035 .llvm_name = "avr5",2036 .llvm_name = "avr5",
2036 .features = featureSet(&[_]Feature{2037 .features = featureSet(&[_]Feature{
2037 .avr5,2038 .avr5,
2038 }),2039 }),
2039 };2040 };
2040 pub const avr51 = Cpu{2041 pub const avr51 = CpuModel{
2041 .name = "avr51",2042 .name = "avr51",
2042 .llvm_name = "avr51",2043 .llvm_name = "avr51",
2043 .features = featureSet(&[_]Feature{2044 .features = featureSet(&[_]Feature{
2044 .avr51,2045 .avr51,
2045 }),2046 }),
2046 };2047 };
2047 pub const avr6 = Cpu{2048 pub const avr6 = CpuModel{
2048 .name = "avr6",2049 .name = "avr6",
2049 .llvm_name = "avr6",2050 .llvm_name = "avr6",
2050 .features = featureSet(&[_]Feature{2051 .features = featureSet(&[_]Feature{
2051 .avr6,2052 .avr6,
2052 }),2053 }),
2053 };2054 };
2054 pub const avrtiny = Cpu{2055 pub const avrtiny = CpuModel{
2055 .name = "avrtiny",2056 .name = "avrtiny",
2056 .llvm_name = "avrtiny",2057 .llvm_name = "avrtiny",
2057 .features = featureSet(&[_]Feature{2058 .features = featureSet(&[_]Feature{
2058 .avrtiny,2059 .avrtiny,
2059 }),2060 }),
2060 };2061 };
2061 pub const avrxmega1 = Cpu{2062 pub const avrxmega1 = CpuModel{
2062 .name = "avrxmega1",2063 .name = "avrxmega1",
2063 .llvm_name = "avrxmega1",2064 .llvm_name = "avrxmega1",
2064 .features = featureSet(&[_]Feature{2065 .features = featureSet(&[_]Feature{
2065 .xmega,2066 .xmega,
2066 }),2067 }),
2067 };2068 };
2068 pub const avrxmega2 = Cpu{2069 pub const avrxmega2 = CpuModel{
2069 .name = "avrxmega2",2070 .name = "avrxmega2",
2070 .llvm_name = "avrxmega2",2071 .llvm_name = "avrxmega2",
2071 .features = featureSet(&[_]Feature{2072 .features = featureSet(&[_]Feature{
2072 .xmega,2073 .xmega,
2073 }),2074 }),
2074 };2075 };
2075 pub const avrxmega3 = Cpu{2076 pub const avrxmega3 = CpuModel{
2076 .name = "avrxmega3",2077 .name = "avrxmega3",
2077 .llvm_name = "avrxmega3",2078 .llvm_name = "avrxmega3",
2078 .features = featureSet(&[_]Feature{2079 .features = featureSet(&[_]Feature{
2079 .xmega,2080 .xmega,
2080 }),2081 }),
2081 };2082 };
2082 pub const avrxmega4 = Cpu{2083 pub const avrxmega4 = CpuModel{
2083 .name = "avrxmega4",2084 .name = "avrxmega4",
2084 .llvm_name = "avrxmega4",2085 .llvm_name = "avrxmega4",
2085 .features = featureSet(&[_]Feature{2086 .features = featureSet(&[_]Feature{
2086 .xmega,2087 .xmega,
2087 }),2088 }),
2088 };2089 };
2089 pub const avrxmega5 = Cpu{2090 pub const avrxmega5 = CpuModel{
2090 .name = "avrxmega5",2091 .name = "avrxmega5",
2091 .llvm_name = "avrxmega5",2092 .llvm_name = "avrxmega5",
2092 .features = featureSet(&[_]Feature{2093 .features = featureSet(&[_]Feature{
2093 .xmega,2094 .xmega,
2094 }),2095 }),
2095 };2096 };
2096 pub const avrxmega6 = Cpu{2097 pub const avrxmega6 = CpuModel{
2097 .name = "avrxmega6",2098 .name = "avrxmega6",
2098 .llvm_name = "avrxmega6",2099 .llvm_name = "avrxmega6",
2099 .features = featureSet(&[_]Feature{2100 .features = featureSet(&[_]Feature{
2100 .xmega,2101 .xmega,
2101 }),2102 }),
2102 };2103 };
2103 pub const avrxmega7 = Cpu{2104 pub const avrxmega7 = CpuModel{
2104 .name = "avrxmega7",2105 .name = "avrxmega7",
2105 .llvm_name = "avrxmega7",2106 .llvm_name = "avrxmega7",
2106 .features = featureSet(&[_]Feature{2107 .features = featureSet(&[_]Feature{
2107 .xmega,2108 .xmega,
2108 }),2109 }),
2109 };2110 };
2110 pub const m3000 = Cpu{2111 pub const m3000 = CpuModel{
2111 .name = "m3000",2112 .name = "m3000",
2112 .llvm_name = "m3000",2113 .llvm_name = "m3000",
2113 .features = featureSet(&[_]Feature{2114 .features = featureSet(&[_]Feature{
...@@ -2119,7 +2120,7 @@ pub const cpu = struct {...@@ -2119,7 +2120,7 @@ pub const cpu = struct {
2119/// All avr CPUs, sorted alphabetically by name.2120/// All avr CPUs, sorted alphabetically by name.
2120/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage12121/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
2121/// compiler has inefficient memory and CPU usage, affecting build times.2122/// compiler has inefficient memory and CPU usage, affecting build times.
2122pub const all_cpus = &[_]*const Cpu{2123pub const all_cpus = &[_]*const CpuModel{
2123 &cpu.at43usb320,2124 &cpu.at43usb320,
2124 &cpu.at43usb355,2125 &cpu.at43usb355,
2125 &cpu.at76c711,2126 &cpu.at76c711,
lib/std/target/bpf.zig+11-10
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2const Cpu = std.Target.Cpu;2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
34
4pub const Feature = enum {5pub const Feature = enum {
5 alu32,6 alu32,
...@@ -7,12 +8,12 @@ pub const Feature = enum {...@@ -7,12 +8,12 @@ pub const Feature = enum {
7 dwarfris,8 dwarfris,
8};9};
910
10pub usingnamespace Cpu.Feature.feature_set_fns(Feature);11pub usingnamespace CpuFeature.feature_set_fns(Feature);
1112
12pub const all_features = blk: {13pub const all_features = blk: {
13 const len = @typeInfo(Feature).Enum.fields.len;14 const len = @typeInfo(Feature).Enum.fields.len;
14 std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);15 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
15 var result: [len]Cpu.Feature = undefined;16 var result: [len]CpuFeature = undefined;
16 result[@enumToInt(Feature.alu32)] = .{17 result[@enumToInt(Feature.alu32)] = .{
17 .llvm_name = "alu32",18 .llvm_name = "alu32",
18 .description = "Enable ALU32 instructions",19 .description = "Enable ALU32 instructions",
...@@ -37,27 +38,27 @@ pub const all_features = blk: {...@@ -37,27 +38,27 @@ pub const all_features = blk: {
37};38};
3839
39pub const cpu = struct {40pub const cpu = struct {
40 pub const generic = Cpu{41 pub const generic = CpuModel{
41 .name = "generic",42 .name = "generic",
42 .llvm_name = "generic",43 .llvm_name = "generic",
43 .features = featureSet(&[_]Feature{}),44 .features = featureSet(&[_]Feature{}),
44 };45 };
45 pub const probe = Cpu{46 pub const probe = CpuModel{
46 .name = "probe",47 .name = "probe",
47 .llvm_name = "probe",48 .llvm_name = "probe",
48 .features = featureSet(&[_]Feature{}),49 .features = featureSet(&[_]Feature{}),
49 };50 };
50 pub const v1 = Cpu{51 pub const v1 = CpuModel{
51 .name = "v1",52 .name = "v1",
52 .llvm_name = "v1",53 .llvm_name = "v1",
53 .features = featureSet(&[_]Feature{}),54 .features = featureSet(&[_]Feature{}),
54 };55 };
55 pub const v2 = Cpu{56 pub const v2 = CpuModel{
56 .name = "v2",57 .name = "v2",
57 .llvm_name = "v2",58 .llvm_name = "v2",
58 .features = featureSet(&[_]Feature{}),59 .features = featureSet(&[_]Feature{}),
59 };60 };
60 pub const v3 = Cpu{61 pub const v3 = CpuModel{
61 .name = "v3",62 .name = "v3",
62 .llvm_name = "v3",63 .llvm_name = "v3",
63 .features = featureSet(&[_]Feature{}),64 .features = featureSet(&[_]Feature{}),
...@@ -67,7 +68,7 @@ pub const cpu = struct {...@@ -67,7 +68,7 @@ pub const cpu = struct {
67/// All bpf CPUs, sorted alphabetically by name.68/// All bpf CPUs, sorted alphabetically by name.
68/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage169/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
69/// compiler has inefficient memory and CPU usage, affecting build times.70/// compiler has inefficient memory and CPU usage, affecting build times.
70pub const all_cpus = &[_]*const Cpu{71pub const all_cpus = &[_]*const CpuModel{
71 &cpu.generic,72 &cpu.generic,
72 &cpu.probe,73 &cpu.probe,
73 &cpu.v1,74 &cpu.v1,
lib/std/target/hexagon.zig+13-12
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2const Cpu = std.Target.Cpu;2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
34
4pub const Feature = enum {5pub const Feature = enum {
5 duplex,6 duplex,
...@@ -28,12 +29,12 @@ pub const Feature = enum {...@@ -28,12 +29,12 @@ pub const Feature = enum {
28 zreg,29 zreg,
29};30};
3031
31pub usingnamespace Cpu.Feature.feature_set_fns(Feature);32pub usingnamespace CpuFeature.feature_set_fns(Feature);
3233
33pub const all_features = blk: {34pub const all_features = blk: {
34 const len = @typeInfo(Feature).Enum.fields.len;35 const len = @typeInfo(Feature).Enum.fields.len;
35 std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);36 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
36 var result: [len]Cpu.Feature = undefined;37 var result: [len]CpuFeature = undefined;
37 result[@enumToInt(Feature.duplex)] = .{38 result[@enumToInt(Feature.duplex)] = .{
38 .llvm_name = "duplex",39 .llvm_name = "duplex",
39 .description = "Enable generation of duplex instruction",40 .description = "Enable generation of duplex instruction",
...@@ -186,7 +187,7 @@ pub const all_features = blk: {...@@ -186,7 +187,7 @@ pub const all_features = blk: {
186};187};
187188
188pub const cpu = struct {189pub const cpu = struct {
189 pub const generic = Cpu{190 pub const generic = CpuModel{
190 .name = "generic",191 .name = "generic",
191 .llvm_name = "generic",192 .llvm_name = "generic",
192 .features = featureSet(&[_]Feature{193 .features = featureSet(&[_]Feature{
...@@ -201,7 +202,7 @@ pub const cpu = struct {...@@ -201,7 +202,7 @@ pub const cpu = struct {
201 .v60,202 .v60,
202 }),203 }),
203 };204 };
204 pub const hexagonv5 = Cpu{205 pub const hexagonv5 = CpuModel{
205 .name = "hexagonv5",206 .name = "hexagonv5",
206 .llvm_name = "hexagonv5",207 .llvm_name = "hexagonv5",
207 .features = featureSet(&[_]Feature{208 .features = featureSet(&[_]Feature{
...@@ -214,7 +215,7 @@ pub const cpu = struct {...@@ -214,7 +215,7 @@ pub const cpu = struct {
214 .v5,215 .v5,
215 }),216 }),
216 };217 };
217 pub const hexagonv55 = Cpu{218 pub const hexagonv55 = CpuModel{
218 .name = "hexagonv55",219 .name = "hexagonv55",
219 .llvm_name = "hexagonv55",220 .llvm_name = "hexagonv55",
220 .features = featureSet(&[_]Feature{221 .features = featureSet(&[_]Feature{
...@@ -228,7 +229,7 @@ pub const cpu = struct {...@@ -228,7 +229,7 @@ pub const cpu = struct {
228 .v55,229 .v55,
229 }),230 }),
230 };231 };
231 pub const hexagonv60 = Cpu{232 pub const hexagonv60 = CpuModel{
232 .name = "hexagonv60",233 .name = "hexagonv60",
233 .llvm_name = "hexagonv60",234 .llvm_name = "hexagonv60",
234 .features = featureSet(&[_]Feature{235 .features = featureSet(&[_]Feature{
...@@ -243,7 +244,7 @@ pub const cpu = struct {...@@ -243,7 +244,7 @@ pub const cpu = struct {
243 .v60,244 .v60,
244 }),245 }),
245 };246 };
246 pub const hexagonv62 = Cpu{247 pub const hexagonv62 = CpuModel{
247 .name = "hexagonv62",248 .name = "hexagonv62",
248 .llvm_name = "hexagonv62",249 .llvm_name = "hexagonv62",
249 .features = featureSet(&[_]Feature{250 .features = featureSet(&[_]Feature{
...@@ -259,7 +260,7 @@ pub const cpu = struct {...@@ -259,7 +260,7 @@ pub const cpu = struct {
259 .v62,260 .v62,
260 }),261 }),
261 };262 };
262 pub const hexagonv65 = Cpu{263 pub const hexagonv65 = CpuModel{
263 .name = "hexagonv65",264 .name = "hexagonv65",
264 .llvm_name = "hexagonv65",265 .llvm_name = "hexagonv65",
265 .features = featureSet(&[_]Feature{266 .features = featureSet(&[_]Feature{
...@@ -277,7 +278,7 @@ pub const cpu = struct {...@@ -277,7 +278,7 @@ pub const cpu = struct {
277 .v65,278 .v65,
278 }),279 }),
279 };280 };
280 pub const hexagonv66 = Cpu{281 pub const hexagonv66 = CpuModel{
281 .name = "hexagonv66",282 .name = "hexagonv66",
282 .llvm_name = "hexagonv66",283 .llvm_name = "hexagonv66",
283 .features = featureSet(&[_]Feature{284 .features = featureSet(&[_]Feature{
...@@ -301,7 +302,7 @@ pub const cpu = struct {...@@ -301,7 +302,7 @@ pub const cpu = struct {
301/// All hexagon CPUs, sorted alphabetically by name.302/// All hexagon CPUs, sorted alphabetically by name.
302/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1303/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
303/// compiler has inefficient memory and CPU usage, affecting build times.304/// compiler has inefficient memory and CPU usage, affecting build times.
304pub const all_cpus = &[_]*const Cpu{305pub const all_cpus = &[_]*const CpuModel{
305 &cpu.generic,306 &cpu.generic,
306 &cpu.hexagonv5,307 &cpu.hexagonv5,
307 &cpu.hexagonv55,308 &cpu.hexagonv55,
lib/std/target/mips.zig+25-24
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2const Cpu = std.Target.Cpu;2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
34
4pub const Feature = enum {5pub const Feature = enum {
5 abs2008,6 abs2008,
...@@ -55,12 +56,12 @@ pub const Feature = enum {...@@ -55,12 +56,12 @@ pub const Feature = enum {
55 xgot,56 xgot,
56};57};
5758
58pub usingnamespace Cpu.Feature.feature_set_fns(Feature);59pub usingnamespace CpuFeature.feature_set_fns(Feature);
5960
60pub const all_features = blk: {61pub const all_features = blk: {
61 const len = @typeInfo(Feature).Enum.fields.len;62 const len = @typeInfo(Feature).Enum.fields.len;
62 std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);63 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
63 var result: [len]Cpu.Feature = undefined;64 var result: [len]CpuFeature = undefined;
64 result[@enumToInt(Feature.abs2008)] = .{65 result[@enumToInt(Feature.abs2008)] = .{
65 .llvm_name = "abs2008",66 .llvm_name = "abs2008",
66 .description = "Disable IEEE 754-2008 abs.fmt mode",67 .description = "Disable IEEE 754-2008 abs.fmt mode",
...@@ -386,119 +387,119 @@ pub const all_features = blk: {...@@ -386,119 +387,119 @@ pub const all_features = blk: {
386};387};
387388
388pub const cpu = struct {389pub const cpu = struct {
389 pub const generic = Cpu{390 pub const generic = CpuModel{
390 .name = "generic",391 .name = "generic",
391 .llvm_name = "generic",392 .llvm_name = "generic",
392 .features = featureSet(&[_]Feature{393 .features = featureSet(&[_]Feature{
393 .mips32,394 .mips32,
394 }),395 }),
395 };396 };
396 pub const mips1 = Cpu{397 pub const mips1 = CpuModel{
397 .name = "mips1",398 .name = "mips1",
398 .llvm_name = "mips1",399 .llvm_name = "mips1",
399 .features = featureSet(&[_]Feature{400 .features = featureSet(&[_]Feature{
400 .mips1,401 .mips1,
401 }),402 }),
402 };403 };
403 pub const mips2 = Cpu{404 pub const mips2 = CpuModel{
404 .name = "mips2",405 .name = "mips2",
405 .llvm_name = "mips2",406 .llvm_name = "mips2",
406 .features = featureSet(&[_]Feature{407 .features = featureSet(&[_]Feature{
407 .mips2,408 .mips2,
408 }),409 }),
409 };410 };
410 pub const mips3 = Cpu{411 pub const mips3 = CpuModel{
411 .name = "mips3",412 .name = "mips3",
412 .llvm_name = "mips3",413 .llvm_name = "mips3",
413 .features = featureSet(&[_]Feature{414 .features = featureSet(&[_]Feature{
414 .mips3,415 .mips3,
415 }),416 }),
416 };417 };
417 pub const mips32 = Cpu{418 pub const mips32 = CpuModel{
418 .name = "mips32",419 .name = "mips32",
419 .llvm_name = "mips32",420 .llvm_name = "mips32",
420 .features = featureSet(&[_]Feature{421 .features = featureSet(&[_]Feature{
421 .mips32,422 .mips32,
422 }),423 }),
423 };424 };
424 pub const mips32r2 = Cpu{425 pub const mips32r2 = CpuModel{
425 .name = "mips32r2",426 .name = "mips32r2",
426 .llvm_name = "mips32r2",427 .llvm_name = "mips32r2",
427 .features = featureSet(&[_]Feature{428 .features = featureSet(&[_]Feature{
428 .mips32r2,429 .mips32r2,
429 }),430 }),
430 };431 };
431 pub const mips32r3 = Cpu{432 pub const mips32r3 = CpuModel{
432 .name = "mips32r3",433 .name = "mips32r3",
433 .llvm_name = "mips32r3",434 .llvm_name = "mips32r3",
434 .features = featureSet(&[_]Feature{435 .features = featureSet(&[_]Feature{
435 .mips32r3,436 .mips32r3,
436 }),437 }),
437 };438 };
438 pub const mips32r5 = Cpu{439 pub const mips32r5 = CpuModel{
439 .name = "mips32r5",440 .name = "mips32r5",
440 .llvm_name = "mips32r5",441 .llvm_name = "mips32r5",
441 .features = featureSet(&[_]Feature{442 .features = featureSet(&[_]Feature{
442 .mips32r5,443 .mips32r5,
443 }),444 }),
444 };445 };
445 pub const mips32r6 = Cpu{446 pub const mips32r6 = CpuModel{
446 .name = "mips32r6",447 .name = "mips32r6",
447 .llvm_name = "mips32r6",448 .llvm_name = "mips32r6",
448 .features = featureSet(&[_]Feature{449 .features = featureSet(&[_]Feature{
449 .mips32r6,450 .mips32r6,
450 }),451 }),
451 };452 };
452 pub const mips4 = Cpu{453 pub const mips4 = CpuModel{
453 .name = "mips4",454 .name = "mips4",
454 .llvm_name = "mips4",455 .llvm_name = "mips4",
455 .features = featureSet(&[_]Feature{456 .features = featureSet(&[_]Feature{
456 .mips4,457 .mips4,
457 }),458 }),
458 };459 };
459 pub const mips5 = Cpu{460 pub const mips5 = CpuModel{
460 .name = "mips5",461 .name = "mips5",
461 .llvm_name = "mips5",462 .llvm_name = "mips5",
462 .features = featureSet(&[_]Feature{463 .features = featureSet(&[_]Feature{
463 .mips5,464 .mips5,
464 }),465 }),
465 };466 };
466 pub const mips64 = Cpu{467 pub const mips64 = CpuModel{
467 .name = "mips64",468 .name = "mips64",
468 .llvm_name = "mips64",469 .llvm_name = "mips64",
469 .features = featureSet(&[_]Feature{470 .features = featureSet(&[_]Feature{
470 .mips64,471 .mips64,
471 }),472 }),
472 };473 };
473 pub const mips64r2 = Cpu{474 pub const mips64r2 = CpuModel{
474 .name = "mips64r2",475 .name = "mips64r2",
475 .llvm_name = "mips64r2",476 .llvm_name = "mips64r2",
476 .features = featureSet(&[_]Feature{477 .features = featureSet(&[_]Feature{
477 .mips64r2,478 .mips64r2,
478 }),479 }),
479 };480 };
480 pub const mips64r3 = Cpu{481 pub const mips64r3 = CpuModel{
481 .name = "mips64r3",482 .name = "mips64r3",
482 .llvm_name = "mips64r3",483 .llvm_name = "mips64r3",
483 .features = featureSet(&[_]Feature{484 .features = featureSet(&[_]Feature{
484 .mips64r3,485 .mips64r3,
485 }),486 }),
486 };487 };
487 pub const mips64r5 = Cpu{488 pub const mips64r5 = CpuModel{
488 .name = "mips64r5",489 .name = "mips64r5",
489 .llvm_name = "mips64r5",490 .llvm_name = "mips64r5",
490 .features = featureSet(&[_]Feature{491 .features = featureSet(&[_]Feature{
491 .mips64r5,492 .mips64r5,
492 }),493 }),
493 };494 };
494 pub const mips64r6 = Cpu{495 pub const mips64r6 = CpuModel{
495 .name = "mips64r6",496 .name = "mips64r6",
496 .llvm_name = "mips64r6",497 .llvm_name = "mips64r6",
497 .features = featureSet(&[_]Feature{498 .features = featureSet(&[_]Feature{
498 .mips64r6,499 .mips64r6,
499 }),500 }),
500 };501 };
501 pub const octeon = Cpu{502 pub const octeon = CpuModel{
502 .name = "octeon",503 .name = "octeon",
503 .llvm_name = "octeon",504 .llvm_name = "octeon",
504 .features = featureSet(&[_]Feature{505 .features = featureSet(&[_]Feature{
...@@ -506,7 +507,7 @@ pub const cpu = struct {...@@ -506,7 +507,7 @@ pub const cpu = struct {
506 .mips64r2,507 .mips64r2,
507 }),508 }),
508 };509 };
509 pub const @"octeon+" = Cpu{510 pub const @"octeon+" = CpuModel{
510 .name = "octeon+",511 .name = "octeon+",
511 .llvm_name = "octeon+",512 .llvm_name = "octeon+",
512 .features = featureSet(&[_]Feature{513 .features = featureSet(&[_]Feature{
...@@ -515,7 +516,7 @@ pub const cpu = struct {...@@ -515,7 +516,7 @@ pub const cpu = struct {
515 .mips64r2,516 .mips64r2,
516 }),517 }),
517 };518 };
518 pub const p5600 = Cpu{519 pub const p5600 = CpuModel{
519 .name = "p5600",520 .name = "p5600",
520 .llvm_name = "p5600",521 .llvm_name = "p5600",
521 .features = featureSet(&[_]Feature{522 .features = featureSet(&[_]Feature{
...@@ -527,7 +528,7 @@ pub const cpu = struct {...@@ -527,7 +528,7 @@ pub const cpu = struct {
527/// All mips CPUs, sorted alphabetically by name.528/// All mips CPUs, sorted alphabetically by name.
528/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1529/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
529/// compiler has inefficient memory and CPU usage, affecting build times.530/// compiler has inefficient memory and CPU usage, affecting build times.
530pub const all_cpus = &[_]*const Cpu{531pub const all_cpus = &[_]*const CpuModel{
531 &cpu.generic,532 &cpu.generic,
532 &cpu.mips1,533 &cpu.mips1,
533 &cpu.mips2,534 &cpu.mips2,
lib/std/target/msp430.zig+9-8
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2const Cpu = std.Target.Cpu;2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
34
4pub const Feature = enum {5pub const Feature = enum {
5 ext,6 ext,
...@@ -8,12 +9,12 @@ pub const Feature = enum {...@@ -8,12 +9,12 @@ pub const Feature = enum {
8 hwmultf5,9 hwmultf5,
9};10};
1011
11pub usingnamespace Cpu.Feature.feature_set_fns(Feature);12pub usingnamespace CpuFeature.feature_set_fns(Feature);
1213
13pub const all_features = blk: {14pub const all_features = blk: {
14 const len = @typeInfo(Feature).Enum.fields.len;15 const len = @typeInfo(Feature).Enum.fields.len;
15 std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);16 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
16 var result: [len]Cpu.Feature = undefined;17 var result: [len]CpuFeature = undefined;
17 result[@enumToInt(Feature.ext)] = .{18 result[@enumToInt(Feature.ext)] = .{
18 .llvm_name = "ext",19 .llvm_name = "ext",
19 .description = "Enable MSP430-X extensions",20 .description = "Enable MSP430-X extensions",
...@@ -43,17 +44,17 @@ pub const all_features = blk: {...@@ -43,17 +44,17 @@ pub const all_features = blk: {
43};44};
4445
45pub const cpu = struct {46pub const cpu = struct {
46 pub const generic = Cpu{47 pub const generic = CpuModel{
47 .name = "generic",48 .name = "generic",
48 .llvm_name = "generic",49 .llvm_name = "generic",
49 .features = featureSet(&[_]Feature{}),50 .features = featureSet(&[_]Feature{}),
50 };51 };
51 pub const msp430 = Cpu{52 pub const msp430 = CpuModel{
52 .name = "msp430",53 .name = "msp430",
53 .llvm_name = "msp430",54 .llvm_name = "msp430",
54 .features = featureSet(&[_]Feature{}),55 .features = featureSet(&[_]Feature{}),
55 };56 };
56 pub const msp430x = Cpu{57 pub const msp430x = CpuModel{
57 .name = "msp430x",58 .name = "msp430x",
58 .llvm_name = "msp430x",59 .llvm_name = "msp430x",
59 .features = featureSet(&[_]Feature{60 .features = featureSet(&[_]Feature{
...@@ -65,7 +66,7 @@ pub const cpu = struct {...@@ -65,7 +66,7 @@ pub const cpu = struct {
65/// All msp430 CPUs, sorted alphabetically by name.66/// All msp430 CPUs, sorted alphabetically by name.
66/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage167/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
67/// compiler has inefficient memory and CPU usage, affecting build times.68/// compiler has inefficient memory and CPU usage, affecting build times.
68pub const all_cpus = &[_]*const Cpu{69pub const all_cpus = &[_]*const CpuModel{
69 &cpu.generic,70 &cpu.generic,
70 &cpu.msp430,71 &cpu.msp430,
71 &cpu.msp430x,72 &cpu.msp430x,
lib/std/target/nvptx.zig+21-20
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2const Cpu = std.Target.Cpu;2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
34
4pub const Feature = enum {5pub const Feature = enum {
5 ptx32,6 ptx32,
...@@ -29,12 +30,12 @@ pub const Feature = enum {...@@ -29,12 +30,12 @@ pub const Feature = enum {
29 sm_75,30 sm_75,
30};31};
3132
32pub usingnamespace Cpu.Feature.feature_set_fns(Feature);33pub usingnamespace CpuFeature.feature_set_fns(Feature);
3334
34pub const all_features = blk: {35pub const all_features = blk: {
35 const len = @typeInfo(Feature).Enum.fields.len;36 const len = @typeInfo(Feature).Enum.fields.len;
36 std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);37 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
37 var result: [len]Cpu.Feature = undefined;38 var result: [len]CpuFeature = undefined;
38 result[@enumToInt(Feature.ptx32)] = .{39 result[@enumToInt(Feature.ptx32)] = .{
39 .llvm_name = "ptx32",40 .llvm_name = "ptx32",
40 .description = "Use PTX version 3.2",41 .description = "Use PTX version 3.2",
...@@ -169,28 +170,28 @@ pub const all_features = blk: {...@@ -169,28 +170,28 @@ pub const all_features = blk: {
169};170};
170171
171pub const cpu = struct {172pub const cpu = struct {
172 pub const sm_20 = Cpu{173 pub const sm_20 = CpuModel{
173 .name = "sm_20",174 .name = "sm_20",
174 .llvm_name = "sm_20",175 .llvm_name = "sm_20",
175 .features = featureSet(&[_]Feature{176 .features = featureSet(&[_]Feature{
176 .sm_20,177 .sm_20,
177 }),178 }),
178 };179 };
179 pub const sm_21 = Cpu{180 pub const sm_21 = CpuModel{
180 .name = "sm_21",181 .name = "sm_21",
181 .llvm_name = "sm_21",182 .llvm_name = "sm_21",
182 .features = featureSet(&[_]Feature{183 .features = featureSet(&[_]Feature{
183 .sm_21,184 .sm_21,
184 }),185 }),
185 };186 };
186 pub const sm_30 = Cpu{187 pub const sm_30 = CpuModel{
187 .name = "sm_30",188 .name = "sm_30",
188 .llvm_name = "sm_30",189 .llvm_name = "sm_30",
189 .features = featureSet(&[_]Feature{190 .features = featureSet(&[_]Feature{
190 .sm_30,191 .sm_30,
191 }),192 }),
192 };193 };
193 pub const sm_32 = Cpu{194 pub const sm_32 = CpuModel{
194 .name = "sm_32",195 .name = "sm_32",
195 .llvm_name = "sm_32",196 .llvm_name = "sm_32",
196 .features = featureSet(&[_]Feature{197 .features = featureSet(&[_]Feature{
...@@ -198,14 +199,14 @@ pub const cpu = struct {...@@ -198,14 +199,14 @@ pub const cpu = struct {
198 .sm_32,199 .sm_32,
199 }),200 }),
200 };201 };
201 pub const sm_35 = Cpu{202 pub const sm_35 = CpuModel{
202 .name = "sm_35",203 .name = "sm_35",
203 .llvm_name = "sm_35",204 .llvm_name = "sm_35",
204 .features = featureSet(&[_]Feature{205 .features = featureSet(&[_]Feature{
205 .sm_35,206 .sm_35,
206 }),207 }),
207 };208 };
208 pub const sm_37 = Cpu{209 pub const sm_37 = CpuModel{
209 .name = "sm_37",210 .name = "sm_37",
210 .llvm_name = "sm_37",211 .llvm_name = "sm_37",
211 .features = featureSet(&[_]Feature{212 .features = featureSet(&[_]Feature{
...@@ -213,7 +214,7 @@ pub const cpu = struct {...@@ -213,7 +214,7 @@ pub const cpu = struct {
213 .sm_37,214 .sm_37,
214 }),215 }),
215 };216 };
216 pub const sm_50 = Cpu{217 pub const sm_50 = CpuModel{
217 .name = "sm_50",218 .name = "sm_50",
218 .llvm_name = "sm_50",219 .llvm_name = "sm_50",
219 .features = featureSet(&[_]Feature{220 .features = featureSet(&[_]Feature{
...@@ -221,7 +222,7 @@ pub const cpu = struct {...@@ -221,7 +222,7 @@ pub const cpu = struct {
221 .sm_50,222 .sm_50,
222 }),223 }),
223 };224 };
224 pub const sm_52 = Cpu{225 pub const sm_52 = CpuModel{
225 .name = "sm_52",226 .name = "sm_52",
226 .llvm_name = "sm_52",227 .llvm_name = "sm_52",
227 .features = featureSet(&[_]Feature{228 .features = featureSet(&[_]Feature{
...@@ -229,7 +230,7 @@ pub const cpu = struct {...@@ -229,7 +230,7 @@ pub const cpu = struct {
229 .sm_52,230 .sm_52,
230 }),231 }),
231 };232 };
232 pub const sm_53 = Cpu{233 pub const sm_53 = CpuModel{
233 .name = "sm_53",234 .name = "sm_53",
234 .llvm_name = "sm_53",235 .llvm_name = "sm_53",
235 .features = featureSet(&[_]Feature{236 .features = featureSet(&[_]Feature{
...@@ -237,7 +238,7 @@ pub const cpu = struct {...@@ -237,7 +238,7 @@ pub const cpu = struct {
237 .sm_53,238 .sm_53,
238 }),239 }),
239 };240 };
240 pub const sm_60 = Cpu{241 pub const sm_60 = CpuModel{
241 .name = "sm_60",242 .name = "sm_60",
242 .llvm_name = "sm_60",243 .llvm_name = "sm_60",
243 .features = featureSet(&[_]Feature{244 .features = featureSet(&[_]Feature{
...@@ -245,7 +246,7 @@ pub const cpu = struct {...@@ -245,7 +246,7 @@ pub const cpu = struct {
245 .sm_60,246 .sm_60,
246 }),247 }),
247 };248 };
248 pub const sm_61 = Cpu{249 pub const sm_61 = CpuModel{
249 .name = "sm_61",250 .name = "sm_61",
250 .llvm_name = "sm_61",251 .llvm_name = "sm_61",
251 .features = featureSet(&[_]Feature{252 .features = featureSet(&[_]Feature{
...@@ -253,7 +254,7 @@ pub const cpu = struct {...@@ -253,7 +254,7 @@ pub const cpu = struct {
253 .sm_61,254 .sm_61,
254 }),255 }),
255 };256 };
256 pub const sm_62 = Cpu{257 pub const sm_62 = CpuModel{
257 .name = "sm_62",258 .name = "sm_62",
258 .llvm_name = "sm_62",259 .llvm_name = "sm_62",
259 .features = featureSet(&[_]Feature{260 .features = featureSet(&[_]Feature{
...@@ -261,7 +262,7 @@ pub const cpu = struct {...@@ -261,7 +262,7 @@ pub const cpu = struct {
261 .sm_62,262 .sm_62,
262 }),263 }),
263 };264 };
264 pub const sm_70 = Cpu{265 pub const sm_70 = CpuModel{
265 .name = "sm_70",266 .name = "sm_70",
266 .llvm_name = "sm_70",267 .llvm_name = "sm_70",
267 .features = featureSet(&[_]Feature{268 .features = featureSet(&[_]Feature{
...@@ -269,7 +270,7 @@ pub const cpu = struct {...@@ -269,7 +270,7 @@ pub const cpu = struct {
269 .sm_70,270 .sm_70,
270 }),271 }),
271 };272 };
272 pub const sm_72 = Cpu{273 pub const sm_72 = CpuModel{
273 .name = "sm_72",274 .name = "sm_72",
274 .llvm_name = "sm_72",275 .llvm_name = "sm_72",
275 .features = featureSet(&[_]Feature{276 .features = featureSet(&[_]Feature{
...@@ -277,7 +278,7 @@ pub const cpu = struct {...@@ -277,7 +278,7 @@ pub const cpu = struct {
277 .sm_72,278 .sm_72,
278 }),279 }),
279 };280 };
280 pub const sm_75 = Cpu{281 pub const sm_75 = CpuModel{
281 .name = "sm_75",282 .name = "sm_75",
282 .llvm_name = "sm_75",283 .llvm_name = "sm_75",
283 .features = featureSet(&[_]Feature{284 .features = featureSet(&[_]Feature{
...@@ -290,7 +291,7 @@ pub const cpu = struct {...@@ -290,7 +291,7 @@ pub const cpu = struct {
290/// All nvptx CPUs, sorted alphabetically by name.291/// All nvptx CPUs, sorted alphabetically by name.
291/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1292/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
292/// compiler has inefficient memory and CPU usage, affecting build times.293/// compiler has inefficient memory and CPU usage, affecting build times.
293pub const all_cpus = &[_]*const Cpu{294pub const all_cpus = &[_]*const CpuModel{
294 &cpu.sm_20,295 &cpu.sm_20,
295 &cpu.sm_21,296 &cpu.sm_21,
296 &cpu.sm_30,297 &cpu.sm_30,
lib/std/target/powerpc.zig+44-43
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2const Cpu = std.Target.Cpu;2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
34
4pub const Feature = enum {5pub const Feature = enum {
5 @"64bit",6 @"64bit",
...@@ -56,12 +57,12 @@ pub const Feature = enum {...@@ -56,12 +57,12 @@ pub const Feature = enum {
56 vsx,57 vsx,
57};58};
5859
59pub usingnamespace Cpu.Feature.feature_set_fns(Feature);60pub usingnamespace CpuFeature.feature_set_fns(Feature);
6061
61pub const all_features = blk: {62pub const all_features = blk: {
62 const len = @typeInfo(Feature).Enum.fields.len;63 const len = @typeInfo(Feature).Enum.fields.len;
63 std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);64 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
64 var result: [len]Cpu.Feature = undefined;65 var result: [len]CpuFeature = undefined;
65 result[@enumToInt(Feature.@"64bit")] = .{66 result[@enumToInt(Feature.@"64bit")] = .{
66 .llvm_name = "64bit",67 .llvm_name = "64bit",
67 .description = "Enable 64-bit instructions",68 .description = "Enable 64-bit instructions",
...@@ -383,7 +384,7 @@ pub const all_features = blk: {...@@ -383,7 +384,7 @@ pub const all_features = blk: {
383};384};
384385
385pub const cpu = struct {386pub const cpu = struct {
386 pub const @"440" = Cpu{387 pub const @"440" = CpuModel{
387 .name = "440",388 .name = "440",
388 .llvm_name = "440",389 .llvm_name = "440",
389 .features = featureSet(&[_]Feature{390 .features = featureSet(&[_]Feature{
...@@ -395,7 +396,7 @@ pub const cpu = struct {...@@ -395,7 +396,7 @@ pub const cpu = struct {
395 .msync,396 .msync,
396 }),397 }),
397 };398 };
398 pub const @"450" = Cpu{399 pub const @"450" = CpuModel{
399 .name = "450",400 .name = "450",
400 .llvm_name = "450",401 .llvm_name = "450",
401 .features = featureSet(&[_]Feature{402 .features = featureSet(&[_]Feature{
...@@ -407,21 +408,21 @@ pub const cpu = struct {...@@ -407,21 +408,21 @@ pub const cpu = struct {
407 .msync,408 .msync,
408 }),409 }),
409 };410 };
410 pub const @"601" = Cpu{411 pub const @"601" = CpuModel{
411 .name = "601",412 .name = "601",
412 .llvm_name = "601",413 .llvm_name = "601",
413 .features = featureSet(&[_]Feature{414 .features = featureSet(&[_]Feature{
414 .fpu,415 .fpu,
415 }),416 }),
416 };417 };
417 pub const @"602" = Cpu{418 pub const @"602" = CpuModel{
418 .name = "602",419 .name = "602",
419 .llvm_name = "602",420 .llvm_name = "602",
420 .features = featureSet(&[_]Feature{421 .features = featureSet(&[_]Feature{
421 .fpu,422 .fpu,
422 }),423 }),
423 };424 };
424 pub const @"603" = Cpu{425 pub const @"603" = CpuModel{
425 .name = "603",426 .name = "603",
426 .llvm_name = "603",427 .llvm_name = "603",
427 .features = featureSet(&[_]Feature{428 .features = featureSet(&[_]Feature{
...@@ -429,7 +430,7 @@ pub const cpu = struct {...@@ -429,7 +430,7 @@ pub const cpu = struct {
429 .frsqrte,430 .frsqrte,
430 }),431 }),
431 };432 };
432 pub const @"603e" = Cpu{433 pub const @"603e" = CpuModel{
433 .name = "603e",434 .name = "603e",
434 .llvm_name = "603e",435 .llvm_name = "603e",
435 .features = featureSet(&[_]Feature{436 .features = featureSet(&[_]Feature{
...@@ -437,7 +438,7 @@ pub const cpu = struct {...@@ -437,7 +438,7 @@ pub const cpu = struct {
437 .frsqrte,438 .frsqrte,
438 }),439 }),
439 };440 };
440 pub const @"603ev" = Cpu{441 pub const @"603ev" = CpuModel{
441 .name = "603ev",442 .name = "603ev",
442 .llvm_name = "603ev",443 .llvm_name = "603ev",
443 .features = featureSet(&[_]Feature{444 .features = featureSet(&[_]Feature{
...@@ -445,7 +446,7 @@ pub const cpu = struct {...@@ -445,7 +446,7 @@ pub const cpu = struct {
445 .frsqrte,446 .frsqrte,
446 }),447 }),
447 };448 };
448 pub const @"604" = Cpu{449 pub const @"604" = CpuModel{
449 .name = "604",450 .name = "604",
450 .llvm_name = "604",451 .llvm_name = "604",
451 .features = featureSet(&[_]Feature{452 .features = featureSet(&[_]Feature{
...@@ -453,7 +454,7 @@ pub const cpu = struct {...@@ -453,7 +454,7 @@ pub const cpu = struct {
453 .frsqrte,454 .frsqrte,
454 }),455 }),
455 };456 };
456 pub const @"604e" = Cpu{457 pub const @"604e" = CpuModel{
457 .name = "604e",458 .name = "604e",
458 .llvm_name = "604e",459 .llvm_name = "604e",
459 .features = featureSet(&[_]Feature{460 .features = featureSet(&[_]Feature{
...@@ -461,7 +462,7 @@ pub const cpu = struct {...@@ -461,7 +462,7 @@ pub const cpu = struct {
461 .frsqrte,462 .frsqrte,
462 }),463 }),
463 };464 };
464 pub const @"620" = Cpu{465 pub const @"620" = CpuModel{
465 .name = "620",466 .name = "620",
466 .llvm_name = "620",467 .llvm_name = "620",
467 .features = featureSet(&[_]Feature{468 .features = featureSet(&[_]Feature{
...@@ -469,7 +470,7 @@ pub const cpu = struct {...@@ -469,7 +470,7 @@ pub const cpu = struct {
469 .frsqrte,470 .frsqrte,
470 }),471 }),
471 };472 };
472 pub const @"7400" = Cpu{473 pub const @"7400" = CpuModel{
473 .name = "7400",474 .name = "7400",
474 .llvm_name = "7400",475 .llvm_name = "7400",
475 .features = featureSet(&[_]Feature{476 .features = featureSet(&[_]Feature{
...@@ -478,7 +479,7 @@ pub const cpu = struct {...@@ -478,7 +479,7 @@ pub const cpu = struct {
478 .frsqrte,479 .frsqrte,
479 }),480 }),
480 };481 };
481 pub const @"7450" = Cpu{482 pub const @"7450" = CpuModel{
482 .name = "7450",483 .name = "7450",
483 .llvm_name = "7450",484 .llvm_name = "7450",
484 .features = featureSet(&[_]Feature{485 .features = featureSet(&[_]Feature{
...@@ -487,7 +488,7 @@ pub const cpu = struct {...@@ -487,7 +488,7 @@ pub const cpu = struct {
487 .frsqrte,488 .frsqrte,
488 }),489 }),
489 };490 };
490 pub const @"750" = Cpu{491 pub const @"750" = CpuModel{
491 .name = "750",492 .name = "750",
492 .llvm_name = "750",493 .llvm_name = "750",
493 .features = featureSet(&[_]Feature{494 .features = featureSet(&[_]Feature{
...@@ -495,7 +496,7 @@ pub const cpu = struct {...@@ -495,7 +496,7 @@ pub const cpu = struct {
495 .frsqrte,496 .frsqrte,
496 }),497 }),
497 };498 };
498 pub const @"970" = Cpu{499 pub const @"970" = CpuModel{
499 .name = "970",500 .name = "970",
500 .llvm_name = "970",501 .llvm_name = "970",
501 .features = featureSet(&[_]Feature{502 .features = featureSet(&[_]Feature{
...@@ -508,7 +509,7 @@ pub const cpu = struct {...@@ -508,7 +509,7 @@ pub const cpu = struct {
508 .stfiwx,509 .stfiwx,
509 }),510 }),
510 };511 };
511 pub const a2 = Cpu{512 pub const a2 = CpuModel{
512 .name = "a2",513 .name = "a2",
513 .llvm_name = "a2",514 .llvm_name = "a2",
514 .features = featureSet(&[_]Feature{515 .features = featureSet(&[_]Feature{
...@@ -533,7 +534,7 @@ pub const cpu = struct {...@@ -533,7 +534,7 @@ pub const cpu = struct {
533 .stfiwx,534 .stfiwx,
534 }),535 }),
535 };536 };
536 pub const a2q = Cpu{537 pub const a2q = CpuModel{
537 .name = "a2q",538 .name = "a2q",
538 .llvm_name = "a2q",539 .llvm_name = "a2q",
539 .features = featureSet(&[_]Feature{540 .features = featureSet(&[_]Feature{
...@@ -559,7 +560,7 @@ pub const cpu = struct {...@@ -559,7 +560,7 @@ pub const cpu = struct {
559 .stfiwx,560 .stfiwx,
560 }),561 }),
561 };562 };
562 pub const e500 = Cpu{563 pub const e500 = CpuModel{
563 .name = "e500",564 .name = "e500",
564 .llvm_name = "e500",565 .llvm_name = "e500",
565 .features = featureSet(&[_]Feature{566 .features = featureSet(&[_]Feature{
...@@ -569,7 +570,7 @@ pub const cpu = struct {...@@ -569,7 +570,7 @@ pub const cpu = struct {
569 .spe,570 .spe,
570 }),571 }),
571 };572 };
572 pub const e500mc = Cpu{573 pub const e500mc = CpuModel{
573 .name = "e500mc",574 .name = "e500mc",
574 .llvm_name = "e500mc",575 .llvm_name = "e500mc",
575 .features = featureSet(&[_]Feature{576 .features = featureSet(&[_]Feature{
...@@ -579,7 +580,7 @@ pub const cpu = struct {...@@ -579,7 +580,7 @@ pub const cpu = struct {
579 .stfiwx,580 .stfiwx,
580 }),581 }),
581 };582 };
582 pub const e5500 = Cpu{583 pub const e5500 = CpuModel{
583 .name = "e5500",584 .name = "e5500",
584 .llvm_name = "e5500",585 .llvm_name = "e5500",
585 .features = featureSet(&[_]Feature{586 .features = featureSet(&[_]Feature{
...@@ -591,7 +592,7 @@ pub const cpu = struct {...@@ -591,7 +592,7 @@ pub const cpu = struct {
591 .stfiwx,592 .stfiwx,
592 }),593 }),
593 };594 };
594 pub const future = Cpu{595 pub const future = CpuModel{
595 .name = "future",596 .name = "future",
596 .llvm_name = "future",597 .llvm_name = "future",
597 .features = featureSet(&[_]Feature{598 .features = featureSet(&[_]Feature{
...@@ -630,7 +631,7 @@ pub const cpu = struct {...@@ -630,7 +631,7 @@ pub const cpu = struct {
630 .vsx,631 .vsx,
631 }),632 }),
632 };633 };
633 pub const g3 = Cpu{634 pub const g3 = CpuModel{
634 .name = "g3",635 .name = "g3",
635 .llvm_name = "g3",636 .llvm_name = "g3",
636 .features = featureSet(&[_]Feature{637 .features = featureSet(&[_]Feature{
...@@ -638,7 +639,7 @@ pub const cpu = struct {...@@ -638,7 +639,7 @@ pub const cpu = struct {
638 .frsqrte,639 .frsqrte,
639 }),640 }),
640 };641 };
641 pub const g4 = Cpu{642 pub const g4 = CpuModel{
642 .name = "g4",643 .name = "g4",
643 .llvm_name = "g4",644 .llvm_name = "g4",
644 .features = featureSet(&[_]Feature{645 .features = featureSet(&[_]Feature{
...@@ -647,7 +648,7 @@ pub const cpu = struct {...@@ -647,7 +648,7 @@ pub const cpu = struct {
647 .frsqrte,648 .frsqrte,
648 }),649 }),
649 };650 };
650 pub const @"g4+" = Cpu{651 pub const @"g4+" = CpuModel{
651 .name = "g4+",652 .name = "g4+",
652 .llvm_name = "g4+",653 .llvm_name = "g4+",
653 .features = featureSet(&[_]Feature{654 .features = featureSet(&[_]Feature{
...@@ -656,7 +657,7 @@ pub const cpu = struct {...@@ -656,7 +657,7 @@ pub const cpu = struct {
656 .frsqrte,657 .frsqrte,
657 }),658 }),
658 };659 };
659 pub const g5 = Cpu{660 pub const g5 = CpuModel{
660 .name = "g5",661 .name = "g5",
661 .llvm_name = "g5",662 .llvm_name = "g5",
662 .features = featureSet(&[_]Feature{663 .features = featureSet(&[_]Feature{
...@@ -669,28 +670,28 @@ pub const cpu = struct {...@@ -669,28 +670,28 @@ pub const cpu = struct {
669 .stfiwx,670 .stfiwx,
670 }),671 }),
671 };672 };
672 pub const generic = Cpu{673 pub const generic = CpuModel{
673 .name = "generic",674 .name = "generic",
674 .llvm_name = "generic",675 .llvm_name = "generic",
675 .features = featureSet(&[_]Feature{676 .features = featureSet(&[_]Feature{
676 .hard_float,677 .hard_float,
677 }),678 }),
678 };679 };
679 pub const ppc = Cpu{680 pub const ppc = CpuModel{
680 .name = "ppc",681 .name = "ppc",
681 .llvm_name = "ppc",682 .llvm_name = "ppc",
682 .features = featureSet(&[_]Feature{683 .features = featureSet(&[_]Feature{
683 .hard_float,684 .hard_float,
684 }),685 }),
685 };686 };
686 pub const ppc32 = Cpu{687 pub const ppc32 = CpuModel{
687 .name = "ppc32",688 .name = "ppc32",
688 .llvm_name = "ppc32",689 .llvm_name = "ppc32",
689 .features = featureSet(&[_]Feature{690 .features = featureSet(&[_]Feature{
690 .hard_float,691 .hard_float,
691 }),692 }),
692 };693 };
693 pub const ppc64 = Cpu{694 pub const ppc64 = CpuModel{
694 .name = "ppc64",695 .name = "ppc64",
695 .llvm_name = "ppc64",696 .llvm_name = "ppc64",
696 .features = featureSet(&[_]Feature{697 .features = featureSet(&[_]Feature{
...@@ -703,7 +704,7 @@ pub const cpu = struct {...@@ -703,7 +704,7 @@ pub const cpu = struct {
703 .stfiwx,704 .stfiwx,
704 }),705 }),
705 };706 };
706 pub const ppc64le = Cpu{707 pub const ppc64le = CpuModel{
707 .name = "ppc64le",708 .name = "ppc64le",
708 .llvm_name = "ppc64le",709 .llvm_name = "ppc64le",
709 .features = featureSet(&[_]Feature{710 .features = featureSet(&[_]Feature{
...@@ -739,7 +740,7 @@ pub const cpu = struct {...@@ -739,7 +740,7 @@ pub const cpu = struct {
739 .vsx,740 .vsx,
740 }),741 }),
741 };742 };
742 pub const pwr3 = Cpu{743 pub const pwr3 = CpuModel{
743 .name = "pwr3",744 .name = "pwr3",
744 .llvm_name = "pwr3",745 .llvm_name = "pwr3",
745 .features = featureSet(&[_]Feature{746 .features = featureSet(&[_]Feature{
...@@ -751,7 +752,7 @@ pub const cpu = struct {...@@ -751,7 +752,7 @@ pub const cpu = struct {
751 .stfiwx,752 .stfiwx,
752 }),753 }),
753 };754 };
754 pub const pwr4 = Cpu{755 pub const pwr4 = CpuModel{
755 .name = "pwr4",756 .name = "pwr4",
756 .llvm_name = "pwr4",757 .llvm_name = "pwr4",
757 .features = featureSet(&[_]Feature{758 .features = featureSet(&[_]Feature{
...@@ -764,7 +765,7 @@ pub const cpu = struct {...@@ -764,7 +765,7 @@ pub const cpu = struct {
764 .stfiwx,765 .stfiwx,
765 }),766 }),
766 };767 };
767 pub const pwr5 = Cpu{768 pub const pwr5 = CpuModel{
768 .name = "pwr5",769 .name = "pwr5",
769 .llvm_name = "pwr5",770 .llvm_name = "pwr5",
770 .features = featureSet(&[_]Feature{771 .features = featureSet(&[_]Feature{
...@@ -779,7 +780,7 @@ pub const cpu = struct {...@@ -779,7 +780,7 @@ pub const cpu = struct {
779 .stfiwx,780 .stfiwx,
780 }),781 }),
781 };782 };
782 pub const pwr5x = Cpu{783 pub const pwr5x = CpuModel{
783 .name = "pwr5x",784 .name = "pwr5x",
784 .llvm_name = "pwr5x",785 .llvm_name = "pwr5x",
785 .features = featureSet(&[_]Feature{786 .features = featureSet(&[_]Feature{
...@@ -795,7 +796,7 @@ pub const cpu = struct {...@@ -795,7 +796,7 @@ pub const cpu = struct {
795 .stfiwx,796 .stfiwx,
796 }),797 }),
797 };798 };
798 pub const pwr6 = Cpu{799 pub const pwr6 = CpuModel{
799 .name = "pwr6",800 .name = "pwr6",
800 .llvm_name = "pwr6",801 .llvm_name = "pwr6",
801 .features = featureSet(&[_]Feature{802 .features = featureSet(&[_]Feature{
...@@ -815,7 +816,7 @@ pub const cpu = struct {...@@ -815,7 +816,7 @@ pub const cpu = struct {
815 .stfiwx,816 .stfiwx,
816 }),817 }),
817 };818 };
818 pub const pwr6x = Cpu{819 pub const pwr6x = CpuModel{
819 .name = "pwr6x",820 .name = "pwr6x",
820 .llvm_name = "pwr6x",821 .llvm_name = "pwr6x",
821 .features = featureSet(&[_]Feature{822 .features = featureSet(&[_]Feature{
...@@ -835,7 +836,7 @@ pub const cpu = struct {...@@ -835,7 +836,7 @@ pub const cpu = struct {
835 .stfiwx,836 .stfiwx,
836 }),837 }),
837 };838 };
838 pub const pwr7 = Cpu{839 pub const pwr7 = CpuModel{
839 .name = "pwr7",840 .name = "pwr7",
840 .llvm_name = "pwr7",841 .llvm_name = "pwr7",
841 .features = featureSet(&[_]Feature{842 .features = featureSet(&[_]Feature{
...@@ -864,7 +865,7 @@ pub const cpu = struct {...@@ -864,7 +865,7 @@ pub const cpu = struct {
864 .vsx,865 .vsx,
865 }),866 }),
866 };867 };
867 pub const pwr8 = Cpu{868 pub const pwr8 = CpuModel{
868 .name = "pwr8",869 .name = "pwr8",
869 .llvm_name = "pwr8",870 .llvm_name = "pwr8",
870 .features = featureSet(&[_]Feature{871 .features = featureSet(&[_]Feature{
...@@ -900,7 +901,7 @@ pub const cpu = struct {...@@ -900,7 +901,7 @@ pub const cpu = struct {
900 .vsx,901 .vsx,
901 }),902 }),
902 };903 };
903 pub const pwr9 = Cpu{904 pub const pwr9 = CpuModel{
904 .name = "pwr9",905 .name = "pwr9",
905 .llvm_name = "pwr9",906 .llvm_name = "pwr9",
906 .features = featureSet(&[_]Feature{907 .features = featureSet(&[_]Feature{
...@@ -947,7 +948,7 @@ pub const cpu = struct {...@@ -947,7 +948,7 @@ pub const cpu = struct {
947/// All powerpc CPUs, sorted alphabetically by name.948/// All powerpc CPUs, sorted alphabetically by name.
948/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1949/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
949/// compiler has inefficient memory and CPU usage, affecting build times.950/// compiler has inefficient memory and CPU usage, affecting build times.
950pub const all_cpus = &[_]*const Cpu{951pub const all_cpus = &[_]*const CpuModel{
951 &cpu.@"440",952 &cpu.@"440",
952 &cpu.@"450",953 &cpu.@"450",
953 &cpu.@"601",954 &cpu.@"601",
lib/std/target/riscv.zig+10-9
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2const Cpu = std.Target.Cpu;2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
34
4pub const Feature = enum {5pub const Feature = enum {
5 @"64bit",6 @"64bit",
...@@ -44,12 +45,12 @@ pub const Feature = enum {...@@ -44,12 +45,12 @@ pub const Feature = enum {
44 rvc_hints,45 rvc_hints,
45};46};
4647
47pub usingnamespace Cpu.Feature.feature_set_fns(Feature);48pub usingnamespace CpuFeature.feature_set_fns(Feature);
4849
49pub const all_features = blk: {50pub const all_features = blk: {
50 const len = @typeInfo(Feature).Enum.fields.len;51 const len = @typeInfo(Feature).Enum.fields.len;
51 std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);52 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
52 var result: [len]Cpu.Feature = undefined;53 var result: [len]CpuFeature = undefined;
53 result[@enumToInt(Feature.@"64bit")] = .{54 result[@enumToInt(Feature.@"64bit")] = .{
54 .llvm_name = "64bit",55 .llvm_name = "64bit",
55 .description = "Implements RV64",56 .description = "Implements RV64",
...@@ -261,7 +262,7 @@ pub const all_features = blk: {...@@ -261,7 +262,7 @@ pub const all_features = blk: {
261};262};
262263
263pub const cpu = struct {264pub const cpu = struct {
264 pub const baseline_rv32 = Cpu{265 pub const baseline_rv32 = CpuModel{
265 .name = "baseline_rv32",266 .name = "baseline_rv32",
266 .llvm_name = null,267 .llvm_name = null,
267 .features = featureSet(&[_]Feature{268 .features = featureSet(&[_]Feature{
...@@ -273,7 +274,7 @@ pub const cpu = struct {...@@ -273,7 +274,7 @@ pub const cpu = struct {
273 }),274 }),
274 };275 };
275276
276 pub const baseline_rv64 = Cpu{277 pub const baseline_rv64 = CpuModel{
277 .name = "baseline_rv64",278 .name = "baseline_rv64",
278 .llvm_name = null,279 .llvm_name = null,
279 .features = featureSet(&[_]Feature{280 .features = featureSet(&[_]Feature{
...@@ -286,14 +287,14 @@ pub const cpu = struct {...@@ -286,14 +287,14 @@ pub const cpu = struct {
286 }),287 }),
287 };288 };
288289
289 pub const generic_rv32 = Cpu{290 pub const generic_rv32 = CpuModel{
290 .name = "generic_rv32",291 .name = "generic_rv32",
291 .llvm_name = null,292 .llvm_name = null,
292 .features = featureSet(&[_]Feature{293 .features = featureSet(&[_]Feature{
293 .rvc_hints,294 .rvc_hints,
294 }),295 }),
295 };296 };
296 pub const generic_rv64 = Cpu{297 pub const generic_rv64 = CpuModel{
297 .name = "generic_rv64",298 .name = "generic_rv64",
298 .llvm_name = null,299 .llvm_name = null,
299 .features = featureSet(&[_]Feature{300 .features = featureSet(&[_]Feature{
...@@ -306,7 +307,7 @@ pub const cpu = struct {...@@ -306,7 +307,7 @@ pub const cpu = struct {
306/// All riscv CPUs, sorted alphabetically by name.307/// All riscv CPUs, sorted alphabetically by name.
307/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1308/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
308/// compiler has inefficient memory and CPU usage, affecting build times.309/// compiler has inefficient memory and CPU usage, affecting build times.
309pub const all_cpus = &[_]*const Cpu{310pub const all_cpus = &[_]*const CpuModel{
310 &cpu.baseline_rv32,311 &cpu.baseline_rv32,
311 &cpu.baseline_rv64,312 &cpu.baseline_rv64,
312 &cpu.generic_rv32,313 &cpu.generic_rv32,
lib/std/target/sparc.zig+46-45
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2const Cpu = std.Target.Cpu;2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
34
4pub const Feature = enum {5pub const Feature = enum {
5 deprecated_v8,6 deprecated_v8,
...@@ -23,12 +24,12 @@ pub const Feature = enum {...@@ -23,12 +24,12 @@ pub const Feature = enum {
23 vis3,24 vis3,
24};25};
2526
26pub usingnamespace Cpu.Feature.feature_set_fns(Feature);27pub usingnamespace CpuFeature.feature_set_fns(Feature);
2728
28pub const all_features = blk: {29pub const all_features = blk: {
29 const len = @typeInfo(Feature).Enum.fields.len;30 const len = @typeInfo(Feature).Enum.fields.len;
30 std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);31 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
31 var result: [len]Cpu.Feature = undefined;32 var result: [len]CpuFeature = undefined;
32 result[@enumToInt(Feature.deprecated_v8)] = .{33 result[@enumToInt(Feature.deprecated_v8)] = .{
33 .llvm_name = "deprecated-v8",34 .llvm_name = "deprecated-v8",
34 .description = "Enable deprecated V8 instructions in V9 mode",35 .description = "Enable deprecated V8 instructions in V9 mode",
...@@ -133,7 +134,7 @@ pub const all_features = blk: {...@@ -133,7 +134,7 @@ pub const all_features = blk: {
133};134};
134135
135pub const cpu = struct {136pub const cpu = struct {
136 pub const at697e = Cpu{137 pub const at697e = CpuModel{
137 .name = "at697e",138 .name = "at697e",
138 .llvm_name = "at697e",139 .llvm_name = "at697e",
139 .features = featureSet(&[_]Feature{140 .features = featureSet(&[_]Feature{
...@@ -141,7 +142,7 @@ pub const cpu = struct {...@@ -141,7 +142,7 @@ pub const cpu = struct {
141 .leon,142 .leon,
142 }),143 }),
143 };144 };
144 pub const at697f = Cpu{145 pub const at697f = CpuModel{
145 .name = "at697f",146 .name = "at697f",
146 .llvm_name = "at697f",147 .llvm_name = "at697f",
147 .features = featureSet(&[_]Feature{148 .features = featureSet(&[_]Feature{
...@@ -149,17 +150,17 @@ pub const cpu = struct {...@@ -149,17 +150,17 @@ pub const cpu = struct {
149 .leon,150 .leon,
150 }),151 }),
151 };152 };
152 pub const f934 = Cpu{153 pub const f934 = CpuModel{
153 .name = "f934",154 .name = "f934",
154 .llvm_name = "f934",155 .llvm_name = "f934",
155 .features = featureSet(&[_]Feature{}),156 .features = featureSet(&[_]Feature{}),
156 };157 };
157 pub const generic = Cpu{158 pub const generic = CpuModel{
158 .name = "generic",159 .name = "generic",
159 .llvm_name = "generic",160 .llvm_name = "generic",
160 .features = featureSet(&[_]Feature{}),161 .features = featureSet(&[_]Feature{}),
161 };162 };
162 pub const gr712rc = Cpu{163 pub const gr712rc = CpuModel{
163 .name = "gr712rc",164 .name = "gr712rc",
164 .llvm_name = "gr712rc",165 .llvm_name = "gr712rc",
165 .features = featureSet(&[_]Feature{166 .features = featureSet(&[_]Feature{
...@@ -167,7 +168,7 @@ pub const cpu = struct {...@@ -167,7 +168,7 @@ pub const cpu = struct {
167 .leon,168 .leon,
168 }),169 }),
169 };170 };
170 pub const gr740 = Cpu{171 pub const gr740 = CpuModel{
171 .name = "gr740",172 .name = "gr740",
172 .llvm_name = "gr740",173 .llvm_name = "gr740",
173 .features = featureSet(&[_]Feature{174 .features = featureSet(&[_]Feature{
...@@ -178,19 +179,19 @@ pub const cpu = struct {...@@ -178,19 +179,19 @@ pub const cpu = struct {
178 .leonpwrpsr,179 .leonpwrpsr,
179 }),180 }),
180 };181 };
181 pub const hypersparc = Cpu{182 pub const hypersparc = CpuModel{
182 .name = "hypersparc",183 .name = "hypersparc",
183 .llvm_name = "hypersparc",184 .llvm_name = "hypersparc",
184 .features = featureSet(&[_]Feature{}),185 .features = featureSet(&[_]Feature{}),
185 };186 };
186 pub const leon2 = Cpu{187 pub const leon2 = CpuModel{
187 .name = "leon2",188 .name = "leon2",
188 .llvm_name = "leon2",189 .llvm_name = "leon2",
189 .features = featureSet(&[_]Feature{190 .features = featureSet(&[_]Feature{
190 .leon,191 .leon,
191 }),192 }),
192 };193 };
193 pub const leon3 = Cpu{194 pub const leon3 = CpuModel{
194 .name = "leon3",195 .name = "leon3",
195 .llvm_name = "leon3",196 .llvm_name = "leon3",
196 .features = featureSet(&[_]Feature{197 .features = featureSet(&[_]Feature{
...@@ -198,7 +199,7 @@ pub const cpu = struct {...@@ -198,7 +199,7 @@ pub const cpu = struct {
198 .leon,199 .leon,
199 }),200 }),
200 };201 };
201 pub const leon4 = Cpu{202 pub const leon4 = CpuModel{
202 .name = "leon4",203 .name = "leon4",
203 .llvm_name = "leon4",204 .llvm_name = "leon4",
204 .features = featureSet(&[_]Feature{205 .features = featureSet(&[_]Feature{
...@@ -207,7 +208,7 @@ pub const cpu = struct {...@@ -207,7 +208,7 @@ pub const cpu = struct {
207 .leon,208 .leon,
208 }),209 }),
209 };210 };
210 pub const ma2080 = Cpu{211 pub const ma2080 = CpuModel{
211 .name = "ma2080",212 .name = "ma2080",
212 .llvm_name = "ma2080",213 .llvm_name = "ma2080",
213 .features = featureSet(&[_]Feature{214 .features = featureSet(&[_]Feature{
...@@ -215,7 +216,7 @@ pub const cpu = struct {...@@ -215,7 +216,7 @@ pub const cpu = struct {
215 .leon,216 .leon,
216 }),217 }),
217 };218 };
218 pub const ma2085 = Cpu{219 pub const ma2085 = CpuModel{
219 .name = "ma2085",220 .name = "ma2085",
220 .llvm_name = "ma2085",221 .llvm_name = "ma2085",
221 .features = featureSet(&[_]Feature{222 .features = featureSet(&[_]Feature{
...@@ -223,7 +224,7 @@ pub const cpu = struct {...@@ -223,7 +224,7 @@ pub const cpu = struct {
223 .leon,224 .leon,
224 }),225 }),
225 };226 };
226 pub const ma2100 = Cpu{227 pub const ma2100 = CpuModel{
227 .name = "ma2100",228 .name = "ma2100",
228 .llvm_name = "ma2100",229 .llvm_name = "ma2100",
229 .features = featureSet(&[_]Feature{230 .features = featureSet(&[_]Feature{
...@@ -231,7 +232,7 @@ pub const cpu = struct {...@@ -231,7 +232,7 @@ pub const cpu = struct {
231 .leon,232 .leon,
232 }),233 }),
233 };234 };
234 pub const ma2150 = Cpu{235 pub const ma2150 = CpuModel{
235 .name = "ma2150",236 .name = "ma2150",
236 .llvm_name = "ma2150",237 .llvm_name = "ma2150",
237 .features = featureSet(&[_]Feature{238 .features = featureSet(&[_]Feature{
...@@ -239,7 +240,7 @@ pub const cpu = struct {...@@ -239,7 +240,7 @@ pub const cpu = struct {
239 .leon,240 .leon,
240 }),241 }),
241 };242 };
242 pub const ma2155 = Cpu{243 pub const ma2155 = CpuModel{
243 .name = "ma2155",244 .name = "ma2155",
244 .llvm_name = "ma2155",245 .llvm_name = "ma2155",
245 .features = featureSet(&[_]Feature{246 .features = featureSet(&[_]Feature{
...@@ -247,7 +248,7 @@ pub const cpu = struct {...@@ -247,7 +248,7 @@ pub const cpu = struct {
247 .leon,248 .leon,
248 }),249 }),
249 };250 };
250 pub const ma2450 = Cpu{251 pub const ma2450 = CpuModel{
251 .name = "ma2450",252 .name = "ma2450",
252 .llvm_name = "ma2450",253 .llvm_name = "ma2450",
253 .features = featureSet(&[_]Feature{254 .features = featureSet(&[_]Feature{
...@@ -255,7 +256,7 @@ pub const cpu = struct {...@@ -255,7 +256,7 @@ pub const cpu = struct {
255 .leon,256 .leon,
256 }),257 }),
257 };258 };
258 pub const ma2455 = Cpu{259 pub const ma2455 = CpuModel{
259 .name = "ma2455",260 .name = "ma2455",
260 .llvm_name = "ma2455",261 .llvm_name = "ma2455",
261 .features = featureSet(&[_]Feature{262 .features = featureSet(&[_]Feature{
...@@ -263,7 +264,7 @@ pub const cpu = struct {...@@ -263,7 +264,7 @@ pub const cpu = struct {
263 .leon,264 .leon,
264 }),265 }),
265 };266 };
266 pub const ma2480 = Cpu{267 pub const ma2480 = CpuModel{
267 .name = "ma2480",268 .name = "ma2480",
268 .llvm_name = "ma2480",269 .llvm_name = "ma2480",
269 .features = featureSet(&[_]Feature{270 .features = featureSet(&[_]Feature{
...@@ -271,7 +272,7 @@ pub const cpu = struct {...@@ -271,7 +272,7 @@ pub const cpu = struct {
271 .leon,272 .leon,
272 }),273 }),
273 };274 };
274 pub const ma2485 = Cpu{275 pub const ma2485 = CpuModel{
275 .name = "ma2485",276 .name = "ma2485",
276 .llvm_name = "ma2485",277 .llvm_name = "ma2485",
277 .features = featureSet(&[_]Feature{278 .features = featureSet(&[_]Feature{
...@@ -279,7 +280,7 @@ pub const cpu = struct {...@@ -279,7 +280,7 @@ pub const cpu = struct {
279 .leon,280 .leon,
280 }),281 }),
281 };282 };
282 pub const ma2x5x = Cpu{283 pub const ma2x5x = CpuModel{
283 .name = "ma2x5x",284 .name = "ma2x5x",
284 .llvm_name = "ma2x5x",285 .llvm_name = "ma2x5x",
285 .features = featureSet(&[_]Feature{286 .features = featureSet(&[_]Feature{
...@@ -287,7 +288,7 @@ pub const cpu = struct {...@@ -287,7 +288,7 @@ pub const cpu = struct {
287 .leon,288 .leon,
288 }),289 }),
289 };290 };
290 pub const ma2x8x = Cpu{291 pub const ma2x8x = CpuModel{
291 .name = "ma2x8x",292 .name = "ma2x8x",
292 .llvm_name = "ma2x8x",293 .llvm_name = "ma2x8x",
293 .features = featureSet(&[_]Feature{294 .features = featureSet(&[_]Feature{
...@@ -295,7 +296,7 @@ pub const cpu = struct {...@@ -295,7 +296,7 @@ pub const cpu = struct {
295 .leon,296 .leon,
296 }),297 }),
297 };298 };
298 pub const myriad2 = Cpu{299 pub const myriad2 = CpuModel{
299 .name = "myriad2",300 .name = "myriad2",
300 .llvm_name = "myriad2",301 .llvm_name = "myriad2",
301 .features = featureSet(&[_]Feature{302 .features = featureSet(&[_]Feature{
...@@ -303,7 +304,7 @@ pub const cpu = struct {...@@ -303,7 +304,7 @@ pub const cpu = struct {
303 .leon,304 .leon,
304 }),305 }),
305 };306 };
306 pub const myriad2_1 = Cpu{307 pub const myriad2_1 = CpuModel{
307 .name = "myriad2_1",308 .name = "myriad2_1",
308 .llvm_name = "myriad2.1",309 .llvm_name = "myriad2.1",
309 .features = featureSet(&[_]Feature{310 .features = featureSet(&[_]Feature{
...@@ -311,7 +312,7 @@ pub const cpu = struct {...@@ -311,7 +312,7 @@ pub const cpu = struct {
311 .leon,312 .leon,
312 }),313 }),
313 };314 };
314 pub const myriad2_2 = Cpu{315 pub const myriad2_2 = CpuModel{
315 .name = "myriad2_2",316 .name = "myriad2_2",
316 .llvm_name = "myriad2.2",317 .llvm_name = "myriad2.2",
317 .features = featureSet(&[_]Feature{318 .features = featureSet(&[_]Feature{
...@@ -319,7 +320,7 @@ pub const cpu = struct {...@@ -319,7 +320,7 @@ pub const cpu = struct {
319 .leon,320 .leon,
320 }),321 }),
321 };322 };
322 pub const myriad2_3 = Cpu{323 pub const myriad2_3 = CpuModel{
323 .name = "myriad2_3",324 .name = "myriad2_3",
324 .llvm_name = "myriad2.3",325 .llvm_name = "myriad2.3",
325 .features = featureSet(&[_]Feature{326 .features = featureSet(&[_]Feature{
...@@ -327,7 +328,7 @@ pub const cpu = struct {...@@ -327,7 +328,7 @@ pub const cpu = struct {
327 .leon,328 .leon,
328 }),329 }),
329 };330 };
330 pub const niagara = Cpu{331 pub const niagara = CpuModel{
331 .name = "niagara",332 .name = "niagara",
332 .llvm_name = "niagara",333 .llvm_name = "niagara",
333 .features = featureSet(&[_]Feature{334 .features = featureSet(&[_]Feature{
...@@ -337,7 +338,7 @@ pub const cpu = struct {...@@ -337,7 +338,7 @@ pub const cpu = struct {
337 .vis2,338 .vis2,
338 }),339 }),
339 };340 };
340 pub const niagara2 = Cpu{341 pub const niagara2 = CpuModel{
341 .name = "niagara2",342 .name = "niagara2",
342 .llvm_name = "niagara2",343 .llvm_name = "niagara2",
343 .features = featureSet(&[_]Feature{344 .features = featureSet(&[_]Feature{
...@@ -348,7 +349,7 @@ pub const cpu = struct {...@@ -348,7 +349,7 @@ pub const cpu = struct {
348 .vis2,349 .vis2,
349 }),350 }),
350 };351 };
351 pub const niagara3 = Cpu{352 pub const niagara3 = CpuModel{
352 .name = "niagara3",353 .name = "niagara3",
353 .llvm_name = "niagara3",354 .llvm_name = "niagara3",
354 .features = featureSet(&[_]Feature{355 .features = featureSet(&[_]Feature{
...@@ -359,7 +360,7 @@ pub const cpu = struct {...@@ -359,7 +360,7 @@ pub const cpu = struct {
359 .vis2,360 .vis2,
360 }),361 }),
361 };362 };
362 pub const niagara4 = Cpu{363 pub const niagara4 = CpuModel{
363 .name = "niagara4",364 .name = "niagara4",
364 .llvm_name = "niagara4",365 .llvm_name = "niagara4",
365 .features = featureSet(&[_]Feature{366 .features = featureSet(&[_]Feature{
...@@ -371,32 +372,32 @@ pub const cpu = struct {...@@ -371,32 +372,32 @@ pub const cpu = struct {
371 .vis3,372 .vis3,
372 }),373 }),
373 };374 };
374 pub const sparclet = Cpu{375 pub const sparclet = CpuModel{
375 .name = "sparclet",376 .name = "sparclet",
376 .llvm_name = "sparclet",377 .llvm_name = "sparclet",
377 .features = featureSet(&[_]Feature{}),378 .features = featureSet(&[_]Feature{}),
378 };379 };
379 pub const sparclite = Cpu{380 pub const sparclite = CpuModel{
380 .name = "sparclite",381 .name = "sparclite",
381 .llvm_name = "sparclite",382 .llvm_name = "sparclite",
382 .features = featureSet(&[_]Feature{}),383 .features = featureSet(&[_]Feature{}),
383 };384 };
384 pub const sparclite86x = Cpu{385 pub const sparclite86x = CpuModel{
385 .name = "sparclite86x",386 .name = "sparclite86x",
386 .llvm_name = "sparclite86x",387 .llvm_name = "sparclite86x",
387 .features = featureSet(&[_]Feature{}),388 .features = featureSet(&[_]Feature{}),
388 };389 };
389 pub const supersparc = Cpu{390 pub const supersparc = CpuModel{
390 .name = "supersparc",391 .name = "supersparc",
391 .llvm_name = "supersparc",392 .llvm_name = "supersparc",
392 .features = featureSet(&[_]Feature{}),393 .features = featureSet(&[_]Feature{}),
393 };394 };
394 pub const tsc701 = Cpu{395 pub const tsc701 = CpuModel{
395 .name = "tsc701",396 .name = "tsc701",
396 .llvm_name = "tsc701",397 .llvm_name = "tsc701",
397 .features = featureSet(&[_]Feature{}),398 .features = featureSet(&[_]Feature{}),
398 };399 };
399 pub const ultrasparc = Cpu{400 pub const ultrasparc = CpuModel{
400 .name = "ultrasparc",401 .name = "ultrasparc",
401 .llvm_name = "ultrasparc",402 .llvm_name = "ultrasparc",
402 .features = featureSet(&[_]Feature{403 .features = featureSet(&[_]Feature{
...@@ -405,7 +406,7 @@ pub const cpu = struct {...@@ -405,7 +406,7 @@ pub const cpu = struct {
405 .vis,406 .vis,
406 }),407 }),
407 };408 };
408 pub const ultrasparc3 = Cpu{409 pub const ultrasparc3 = CpuModel{
409 .name = "ultrasparc3",410 .name = "ultrasparc3",
410 .llvm_name = "ultrasparc3",411 .llvm_name = "ultrasparc3",
411 .features = featureSet(&[_]Feature{412 .features = featureSet(&[_]Feature{
...@@ -415,7 +416,7 @@ pub const cpu = struct {...@@ -415,7 +416,7 @@ pub const cpu = struct {
415 .vis2,416 .vis2,
416 }),417 }),
417 };418 };
418 pub const ut699 = Cpu{419 pub const ut699 = CpuModel{
419 .name = "ut699",420 .name = "ut699",
420 .llvm_name = "ut699",421 .llvm_name = "ut699",
421 .features = featureSet(&[_]Feature{422 .features = featureSet(&[_]Feature{
...@@ -426,7 +427,7 @@ pub const cpu = struct {...@@ -426,7 +427,7 @@ pub const cpu = struct {
426 .no_fsmuld,427 .no_fsmuld,
427 }),428 }),
428 };429 };
429 pub const v7 = Cpu{430 pub const v7 = CpuModel{
430 .name = "v7",431 .name = "v7",
431 .llvm_name = "v7",432 .llvm_name = "v7",
432 .features = featureSet(&[_]Feature{433 .features = featureSet(&[_]Feature{
...@@ -434,12 +435,12 @@ pub const cpu = struct {...@@ -434,12 +435,12 @@ pub const cpu = struct {
434 .soft_mul_div,435 .soft_mul_div,
435 }),436 }),
436 };437 };
437 pub const v8 = Cpu{438 pub const v8 = CpuModel{
438 .name = "v8",439 .name = "v8",
439 .llvm_name = "v8",440 .llvm_name = "v8",
440 .features = featureSet(&[_]Feature{}),441 .features = featureSet(&[_]Feature{}),
441 };442 };
442 pub const v9 = Cpu{443 pub const v9 = CpuModel{
443 .name = "v9",444 .name = "v9",
444 .llvm_name = "v9",445 .llvm_name = "v9",
445 .features = featureSet(&[_]Feature{446 .features = featureSet(&[_]Feature{
...@@ -451,7 +452,7 @@ pub const cpu = struct {...@@ -451,7 +452,7 @@ pub const cpu = struct {
451/// All sparc CPUs, sorted alphabetically by name.452/// All sparc CPUs, sorted alphabetically by name.
452/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1453/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
453/// compiler has inefficient memory and CPU usage, affecting build times.454/// compiler has inefficient memory and CPU usage, affecting build times.
454pub const all_cpus = &[_]*const Cpu{455pub const all_cpus = &[_]*const CpuModel{
455 &cpu.at697e,456 &cpu.at697e,
456 &cpu.at697f,457 &cpu.at697f,
457 &cpu.f934,458 &cpu.f934,
lib/std/target/systemz.zig+19-18
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2const Cpu = std.Target.Cpu;2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
34
4pub const Feature = enum {5pub const Feature = enum {
5 deflate_conversion,6 deflate_conversion,
...@@ -39,12 +40,12 @@ pub const Feature = enum {...@@ -39,12 +40,12 @@ pub const Feature = enum {
39 vector_packed_decimal_enhancement,40 vector_packed_decimal_enhancement,
40};41};
4142
42pub usingnamespace Cpu.Feature.feature_set_fns(Feature);43pub usingnamespace CpuFeature.feature_set_fns(Feature);
4344
44pub const all_features = blk: {45pub const all_features = blk: {
45 const len = @typeInfo(Feature).Enum.fields.len;46 const len = @typeInfo(Feature).Enum.fields.len;
46 std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);47 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
47 var result: [len]Cpu.Feature = undefined;48 var result: [len]CpuFeature = undefined;
48 result[@enumToInt(Feature.deflate_conversion)] = .{49 result[@enumToInt(Feature.deflate_conversion)] = .{
49 .llvm_name = "deflate-conversion",50 .llvm_name = "deflate-conversion",
50 .description = "Assume that the deflate-conversion facility is installed",51 .description = "Assume that the deflate-conversion facility is installed",
...@@ -229,7 +230,7 @@ pub const all_features = blk: {...@@ -229,7 +230,7 @@ pub const all_features = blk: {
229};230};
230231
231pub const cpu = struct {232pub const cpu = struct {
232 pub const arch10 = Cpu{233 pub const arch10 = CpuModel{
233 .name = "arch10",234 .name = "arch10",
234 .llvm_name = "arch10",235 .llvm_name = "arch10",
235 .features = featureSet(&[_]Feature{236 .features = featureSet(&[_]Feature{
...@@ -252,7 +253,7 @@ pub const cpu = struct {...@@ -252,7 +253,7 @@ pub const cpu = struct {
252 .transactional_execution,253 .transactional_execution,
253 }),254 }),
254 };255 };
255 pub const arch11 = Cpu{256 pub const arch11 = CpuModel{
256 .name = "arch11",257 .name = "arch11",
257 .llvm_name = "arch11",258 .llvm_name = "arch11",
258 .features = featureSet(&[_]Feature{259 .features = featureSet(&[_]Feature{
...@@ -280,7 +281,7 @@ pub const cpu = struct {...@@ -280,7 +281,7 @@ pub const cpu = struct {
280 .vector,281 .vector,
281 }),282 }),
282 };283 };
283 pub const arch12 = Cpu{284 pub const arch12 = CpuModel{
284 .name = "arch12",285 .name = "arch12",
285 .llvm_name = "arch12",286 .llvm_name = "arch12",
286 .features = featureSet(&[_]Feature{287 .features = featureSet(&[_]Feature{
...@@ -315,7 +316,7 @@ pub const cpu = struct {...@@ -315,7 +316,7 @@ pub const cpu = struct {
315 .vector_packed_decimal,316 .vector_packed_decimal,
316 }),317 }),
317 };318 };
318 pub const arch13 = Cpu{319 pub const arch13 = CpuModel{
319 .name = "arch13",320 .name = "arch13",
320 .llvm_name = "arch13",321 .llvm_name = "arch13",
321 .features = featureSet(&[_]Feature{322 .features = featureSet(&[_]Feature{
...@@ -356,12 +357,12 @@ pub const cpu = struct {...@@ -356,12 +357,12 @@ pub const cpu = struct {
356 .vector_packed_decimal_enhancement,357 .vector_packed_decimal_enhancement,
357 }),358 }),
358 };359 };
359 pub const arch8 = Cpu{360 pub const arch8 = CpuModel{
360 .name = "arch8",361 .name = "arch8",
361 .llvm_name = "arch8",362 .llvm_name = "arch8",
362 .features = featureSet(&[_]Feature{}),363 .features = featureSet(&[_]Feature{}),
363 };364 };
364 pub const arch9 = Cpu{365 pub const arch9 = CpuModel{
365 .name = "arch9",366 .name = "arch9",
366 .llvm_name = "arch9",367 .llvm_name = "arch9",
367 .features = featureSet(&[_]Feature{368 .features = featureSet(&[_]Feature{
...@@ -377,17 +378,17 @@ pub const cpu = struct {...@@ -377,17 +378,17 @@ pub const cpu = struct {
377 .reset_reference_bits_multiple,378 .reset_reference_bits_multiple,
378 }),379 }),
379 };380 };
380 pub const generic = Cpu{381 pub const generic = CpuModel{
381 .name = "generic",382 .name = "generic",
382 .llvm_name = "generic",383 .llvm_name = "generic",
383 .features = featureSet(&[_]Feature{}),384 .features = featureSet(&[_]Feature{}),
384 };385 };
385 pub const z10 = Cpu{386 pub const z10 = CpuModel{
386 .name = "z10",387 .name = "z10",
387 .llvm_name = "z10",388 .llvm_name = "z10",
388 .features = featureSet(&[_]Feature{}),389 .features = featureSet(&[_]Feature{}),
389 };390 };
390 pub const z13 = Cpu{391 pub const z13 = CpuModel{
391 .name = "z13",392 .name = "z13",
392 .llvm_name = "z13",393 .llvm_name = "z13",
393 .features = featureSet(&[_]Feature{394 .features = featureSet(&[_]Feature{
...@@ -415,7 +416,7 @@ pub const cpu = struct {...@@ -415,7 +416,7 @@ pub const cpu = struct {
415 .vector,416 .vector,
416 }),417 }),
417 };418 };
418 pub const z14 = Cpu{419 pub const z14 = CpuModel{
419 .name = "z14",420 .name = "z14",
420 .llvm_name = "z14",421 .llvm_name = "z14",
421 .features = featureSet(&[_]Feature{422 .features = featureSet(&[_]Feature{
...@@ -450,7 +451,7 @@ pub const cpu = struct {...@@ -450,7 +451,7 @@ pub const cpu = struct {
450 .vector_packed_decimal,451 .vector_packed_decimal,
451 }),452 }),
452 };453 };
453 pub const z15 = Cpu{454 pub const z15 = CpuModel{
454 .name = "z15",455 .name = "z15",
455 .llvm_name = "z15",456 .llvm_name = "z15",
456 .features = featureSet(&[_]Feature{457 .features = featureSet(&[_]Feature{
...@@ -491,7 +492,7 @@ pub const cpu = struct {...@@ -491,7 +492,7 @@ pub const cpu = struct {
491 .vector_packed_decimal_enhancement,492 .vector_packed_decimal_enhancement,
492 }),493 }),
493 };494 };
494 pub const z196 = Cpu{495 pub const z196 = CpuModel{
495 .name = "z196",496 .name = "z196",
496 .llvm_name = "z196",497 .llvm_name = "z196",
497 .features = featureSet(&[_]Feature{498 .features = featureSet(&[_]Feature{
...@@ -507,7 +508,7 @@ pub const cpu = struct {...@@ -507,7 +508,7 @@ pub const cpu = struct {
507 .reset_reference_bits_multiple,508 .reset_reference_bits_multiple,
508 }),509 }),
509 };510 };
510 pub const zEC12 = Cpu{511 pub const zEC12 = CpuModel{
511 .name = "zEC12",512 .name = "zEC12",
512 .llvm_name = "zEC12",513 .llvm_name = "zEC12",
513 .features = featureSet(&[_]Feature{514 .features = featureSet(&[_]Feature{
...@@ -535,7 +536,7 @@ pub const cpu = struct {...@@ -535,7 +536,7 @@ pub const cpu = struct {
535/// All systemz CPUs, sorted alphabetically by name.536/// All systemz CPUs, sorted alphabetically by name.
536/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1537/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
537/// compiler has inefficient memory and CPU usage, affecting build times.538/// compiler has inefficient memory and CPU usage, affecting build times.
538pub const all_cpus = &[_]*const Cpu{539pub const all_cpus = &[_]*const CpuModel{
539 &cpu.arch10,540 &cpu.arch10,
540 &cpu.arch11,541 &cpu.arch11,
541 &cpu.arch12,542 &cpu.arch12,
lib/std/target/wasm.zig+9-8
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2const Cpu = std.Target.Cpu;2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
34
4pub const Feature = enum {5pub const Feature = enum {
5 atomics,6 atomics,
...@@ -14,12 +15,12 @@ pub const Feature = enum {...@@ -14,12 +15,12 @@ pub const Feature = enum {
14 unimplemented_simd128,15 unimplemented_simd128,
15};16};
1617
17pub usingnamespace Cpu.Feature.feature_set_fns(Feature);18pub usingnamespace CpuFeature.feature_set_fns(Feature);
1819
19pub const all_features = blk: {20pub const all_features = blk: {
20 const len = @typeInfo(Feature).Enum.fields.len;21 const len = @typeInfo(Feature).Enum.fields.len;
21 std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);22 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
22 var result: [len]Cpu.Feature = undefined;23 var result: [len]CpuFeature = undefined;
23 result[@enumToInt(Feature.atomics)] = .{24 result[@enumToInt(Feature.atomics)] = .{
24 .llvm_name = "atomics",25 .llvm_name = "atomics",
25 .description = "Enable Atomics",26 .description = "Enable Atomics",
...@@ -81,7 +82,7 @@ pub const all_features = blk: {...@@ -81,7 +82,7 @@ pub const all_features = blk: {
81};82};
8283
83pub const cpu = struct {84pub const cpu = struct {
84 pub const bleeding_edge = Cpu{85 pub const bleeding_edge = CpuModel{
85 .name = "bleeding_edge",86 .name = "bleeding_edge",
86 .llvm_name = "bleeding-edge",87 .llvm_name = "bleeding-edge",
87 .features = featureSet(&[_]Feature{88 .features = featureSet(&[_]Feature{
...@@ -92,12 +93,12 @@ pub const cpu = struct {...@@ -92,12 +93,12 @@ pub const cpu = struct {
92 .simd128,93 .simd128,
93 }),94 }),
94 };95 };
95 pub const generic = Cpu{96 pub const generic = CpuModel{
96 .name = "generic",97 .name = "generic",
97 .llvm_name = "generic",98 .llvm_name = "generic",
98 .features = featureSet(&[_]Feature{}),99 .features = featureSet(&[_]Feature{}),
99 };100 };
100 pub const mvp = Cpu{101 pub const mvp = CpuModel{
101 .name = "mvp",102 .name = "mvp",
102 .llvm_name = "mvp",103 .llvm_name = "mvp",
103 .features = featureSet(&[_]Feature{}),104 .features = featureSet(&[_]Feature{}),
...@@ -107,7 +108,7 @@ pub const cpu = struct {...@@ -107,7 +108,7 @@ pub const cpu = struct {
107/// All wasm CPUs, sorted alphabetically by name.108/// All wasm CPUs, sorted alphabetically by name.
108/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1109/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
109/// compiler has inefficient memory and CPU usage, affecting build times.110/// compiler has inefficient memory and CPU usage, affecting build times.
110pub const all_cpus = &[_]*const Cpu{111pub const all_cpus = &[_]*const CpuModel{
111 &cpu.bleeding_edge,112 &cpu.bleeding_edge,
112 &cpu.generic,113 &cpu.generic,
113 &cpu.mvp,114 &cpu.mvp,
lib/std/target/x86.zig+85-84
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2const Cpu = std.Target.Cpu;2const CpuFeature = std.Target.Cpu.Feature;
3const CpuModel = std.Target.Cpu.Model;
34
4pub const Feature = enum {5pub const Feature = enum {
5 @"3dnow",6 @"3dnow",
...@@ -129,12 +130,12 @@ pub const Feature = enum {...@@ -129,12 +130,12 @@ pub const Feature = enum {
129 xsaves,130 xsaves,
130};131};
131132
132pub usingnamespace Cpu.Feature.feature_set_fns(Feature);133pub usingnamespace CpuFeature.feature_set_fns(Feature);
133134
134pub const all_features = blk: {135pub const all_features = blk: {
135 const len = @typeInfo(Feature).Enum.fields.len;136 const len = @typeInfo(Feature).Enum.fields.len;
136 std.debug.assert(len <= Cpu.Feature.Set.needed_bit_count);137 std.debug.assert(len <= CpuFeature.Set.needed_bit_count);
137 var result: [len]Cpu.Feature = undefined;138 var result: [len]CpuFeature = undefined;
138 result[@enumToInt(Feature.@"3dnow")] = .{139 result[@enumToInt(Feature.@"3dnow")] = .{
139 .llvm_name = "3dnow",140 .llvm_name = "3dnow",
140 .description = "Enable 3DNow! instructions",141 .description = "Enable 3DNow! instructions",
...@@ -851,7 +852,7 @@ pub const all_features = blk: {...@@ -851,7 +852,7 @@ pub const all_features = blk: {
851};852};
852853
853pub const cpu = struct {854pub const cpu = struct {
854 pub const amdfam10 = Cpu{855 pub const amdfam10 = CpuModel{
855 .name = "amdfam10",856 .name = "amdfam10",
856 .llvm_name = "amdfam10",857 .llvm_name = "amdfam10",
857 .features = featureSet(&[_]Feature{858 .features = featureSet(&[_]Feature{
...@@ -872,7 +873,7 @@ pub const cpu = struct {...@@ -872,7 +873,7 @@ pub const cpu = struct {
872 .x87,873 .x87,
873 }),874 }),
874 };875 };
875 pub const athlon = Cpu{876 pub const athlon = CpuModel{
876 .name = "athlon",877 .name = "athlon",
877 .llvm_name = "athlon",878 .llvm_name = "athlon",
878 .features = featureSet(&[_]Feature{879 .features = featureSet(&[_]Feature{
...@@ -886,7 +887,7 @@ pub const cpu = struct {...@@ -886,7 +887,7 @@ pub const cpu = struct {
886 .x87,887 .x87,
887 }),888 }),
888 };889 };
889 pub const athlon_4 = Cpu{890 pub const athlon_4 = CpuModel{
890 .name = "athlon_4",891 .name = "athlon_4",
891 .llvm_name = "athlon-4",892 .llvm_name = "athlon-4",
892 .features = featureSet(&[_]Feature{893 .features = featureSet(&[_]Feature{
...@@ -902,7 +903,7 @@ pub const cpu = struct {...@@ -902,7 +903,7 @@ pub const cpu = struct {
902 .x87,903 .x87,
903 }),904 }),
904 };905 };
905 pub const athlon_fx = Cpu{906 pub const athlon_fx = CpuModel{
906 .name = "athlon_fx",907 .name = "athlon_fx",
907 .llvm_name = "athlon-fx",908 .llvm_name = "athlon-fx",
908 .features = featureSet(&[_]Feature{909 .features = featureSet(&[_]Feature{
...@@ -920,7 +921,7 @@ pub const cpu = struct {...@@ -920,7 +921,7 @@ pub const cpu = struct {
920 .x87,921 .x87,
921 }),922 }),
922 };923 };
923 pub const athlon_mp = Cpu{924 pub const athlon_mp = CpuModel{
924 .name = "athlon_mp",925 .name = "athlon_mp",
925 .llvm_name = "athlon-mp",926 .llvm_name = "athlon-mp",
926 .features = featureSet(&[_]Feature{927 .features = featureSet(&[_]Feature{
...@@ -936,7 +937,7 @@ pub const cpu = struct {...@@ -936,7 +937,7 @@ pub const cpu = struct {
936 .x87,937 .x87,
937 }),938 }),
938 };939 };
939 pub const athlon_tbird = Cpu{940 pub const athlon_tbird = CpuModel{
940 .name = "athlon_tbird",941 .name = "athlon_tbird",
941 .llvm_name = "athlon-tbird",942 .llvm_name = "athlon-tbird",
942 .features = featureSet(&[_]Feature{943 .features = featureSet(&[_]Feature{
...@@ -950,7 +951,7 @@ pub const cpu = struct {...@@ -950,7 +951,7 @@ pub const cpu = struct {
950 .x87,951 .x87,
951 }),952 }),
952 };953 };
953 pub const athlon_xp = Cpu{954 pub const athlon_xp = CpuModel{
954 .name = "athlon_xp",955 .name = "athlon_xp",
955 .llvm_name = "athlon-xp",956 .llvm_name = "athlon-xp",
956 .features = featureSet(&[_]Feature{957 .features = featureSet(&[_]Feature{
...@@ -966,7 +967,7 @@ pub const cpu = struct {...@@ -966,7 +967,7 @@ pub const cpu = struct {
966 .x87,967 .x87,
967 }),968 }),
968 };969 };
969 pub const athlon64 = Cpu{970 pub const athlon64 = CpuModel{
970 .name = "athlon64",971 .name = "athlon64",
971 .llvm_name = "athlon64",972 .llvm_name = "athlon64",
972 .features = featureSet(&[_]Feature{973 .features = featureSet(&[_]Feature{
...@@ -984,7 +985,7 @@ pub const cpu = struct {...@@ -984,7 +985,7 @@ pub const cpu = struct {
984 .x87,985 .x87,
985 }),986 }),
986 };987 };
987 pub const athlon64_sse3 = Cpu{988 pub const athlon64_sse3 = CpuModel{
988 .name = "athlon64_sse3",989 .name = "athlon64_sse3",
989 .llvm_name = "athlon64-sse3",990 .llvm_name = "athlon64-sse3",
990 .features = featureSet(&[_]Feature{991 .features = featureSet(&[_]Feature{
...@@ -1003,7 +1004,7 @@ pub const cpu = struct {...@@ -1003,7 +1004,7 @@ pub const cpu = struct {
1003 .x87,1004 .x87,
1004 }),1005 }),
1005 };1006 };
1006 pub const atom = Cpu{1007 pub const atom = CpuModel{
1007 .name = "atom",1008 .name = "atom",
1008 .llvm_name = "atom",1009 .llvm_name = "atom",
1009 .features = featureSet(&[_]Feature{1010 .features = featureSet(&[_]Feature{
...@@ -1028,7 +1029,7 @@ pub const cpu = struct {...@@ -1028,7 +1029,7 @@ pub const cpu = struct {
1028 .x87,1029 .x87,
1029 }),1030 }),
1030 };1031 };
1031 pub const barcelona = Cpu{1032 pub const barcelona = CpuModel{
1032 .name = "barcelona",1033 .name = "barcelona",
1033 .llvm_name = "barcelona",1034 .llvm_name = "barcelona",
1034 .features = featureSet(&[_]Feature{1035 .features = featureSet(&[_]Feature{
...@@ -1049,7 +1050,7 @@ pub const cpu = struct {...@@ -1049,7 +1050,7 @@ pub const cpu = struct {
1049 .x87,1050 .x87,
1050 }),1051 }),
1051 };1052 };
1052 pub const bdver1 = Cpu{1053 pub const bdver1 = CpuModel{
1053 .name = "bdver1",1054 .name = "bdver1",
1054 .llvm_name = "bdver1",1055 .llvm_name = "bdver1",
1055 .features = featureSet(&[_]Feature{1056 .features = featureSet(&[_]Feature{
...@@ -1077,7 +1078,7 @@ pub const cpu = struct {...@@ -1077,7 +1078,7 @@ pub const cpu = struct {
1077 .xsave,1078 .xsave,
1078 }),1079 }),
1079 };1080 };
1080 pub const bdver2 = Cpu{1081 pub const bdver2 = CpuModel{
1081 .name = "bdver2",1082 .name = "bdver2",
1082 .llvm_name = "bdver2",1083 .llvm_name = "bdver2",
1083 .features = featureSet(&[_]Feature{1084 .features = featureSet(&[_]Feature{
...@@ -1110,7 +1111,7 @@ pub const cpu = struct {...@@ -1110,7 +1111,7 @@ pub const cpu = struct {
1110 .xsave,1111 .xsave,
1111 }),1112 }),
1112 };1113 };
1113 pub const bdver3 = Cpu{1114 pub const bdver3 = CpuModel{
1114 .name = "bdver3",1115 .name = "bdver3",
1115 .llvm_name = "bdver3",1116 .llvm_name = "bdver3",
1116 .features = featureSet(&[_]Feature{1117 .features = featureSet(&[_]Feature{
...@@ -1145,7 +1146,7 @@ pub const cpu = struct {...@@ -1145,7 +1146,7 @@ pub const cpu = struct {
1145 .xsaveopt,1146 .xsaveopt,
1146 }),1147 }),
1147 };1148 };
1148 pub const bdver4 = Cpu{1149 pub const bdver4 = CpuModel{
1149 .name = "bdver4",1150 .name = "bdver4",
1150 .llvm_name = "bdver4",1151 .llvm_name = "bdver4",
1151 .features = featureSet(&[_]Feature{1152 .features = featureSet(&[_]Feature{
...@@ -1183,7 +1184,7 @@ pub const cpu = struct {...@@ -1183,7 +1184,7 @@ pub const cpu = struct {
1183 .xsaveopt,1184 .xsaveopt,
1184 }),1185 }),
1185 };1186 };
1186 pub const bonnell = Cpu{1187 pub const bonnell = CpuModel{
1187 .name = "bonnell",1188 .name = "bonnell",
1188 .llvm_name = "bonnell",1189 .llvm_name = "bonnell",
1189 .features = featureSet(&[_]Feature{1190 .features = featureSet(&[_]Feature{
...@@ -1208,7 +1209,7 @@ pub const cpu = struct {...@@ -1208,7 +1209,7 @@ pub const cpu = struct {
1208 .x87,1209 .x87,
1209 }),1210 }),
1210 };1211 };
1211 pub const broadwell = Cpu{1212 pub const broadwell = CpuModel{
1212 .name = "broadwell",1213 .name = "broadwell",
1213 .llvm_name = "broadwell",1214 .llvm_name = "broadwell",
1214 .features = featureSet(&[_]Feature{1215 .features = featureSet(&[_]Feature{
...@@ -1253,7 +1254,7 @@ pub const cpu = struct {...@@ -1253,7 +1254,7 @@ pub const cpu = struct {
1253 .xsaveopt,1254 .xsaveopt,
1254 }),1255 }),
1255 };1256 };
1256 pub const btver1 = Cpu{1257 pub const btver1 = CpuModel{
1257 .name = "btver1",1258 .name = "btver1",
1258 .llvm_name = "btver1",1259 .llvm_name = "btver1",
1259 .features = featureSet(&[_]Feature{1260 .features = featureSet(&[_]Feature{
...@@ -1278,7 +1279,7 @@ pub const cpu = struct {...@@ -1278,7 +1279,7 @@ pub const cpu = struct {
1278 .x87,1279 .x87,
1279 }),1280 }),
1280 };1281 };
1281 pub const btver2 = Cpu{1282 pub const btver2 = CpuModel{
1282 .name = "btver2",1283 .name = "btver2",
1283 .llvm_name = "btver2",1284 .llvm_name = "btver2",
1284 .features = featureSet(&[_]Feature{1285 .features = featureSet(&[_]Feature{
...@@ -1313,7 +1314,7 @@ pub const cpu = struct {...@@ -1313,7 +1314,7 @@ pub const cpu = struct {
1313 .xsaveopt,1314 .xsaveopt,
1314 }),1315 }),
1315 };1316 };
1316 pub const c3 = Cpu{1317 pub const c3 = CpuModel{
1317 .name = "c3",1318 .name = "c3",
1318 .llvm_name = "c3",1319 .llvm_name = "c3",
1319 .features = featureSet(&[_]Feature{1320 .features = featureSet(&[_]Feature{
...@@ -1323,7 +1324,7 @@ pub const cpu = struct {...@@ -1323,7 +1324,7 @@ pub const cpu = struct {
1323 .x87,1324 .x87,
1324 }),1325 }),
1325 };1326 };
1326 pub const c3_2 = Cpu{1327 pub const c3_2 = CpuModel{
1327 .name = "c3_2",1328 .name = "c3_2",
1328 .llvm_name = "c3-2",1329 .llvm_name = "c3-2",
1329 .features = featureSet(&[_]Feature{1330 .features = featureSet(&[_]Feature{
...@@ -1337,7 +1338,7 @@ pub const cpu = struct {...@@ -1337,7 +1338,7 @@ pub const cpu = struct {
1337 .x87,1338 .x87,
1338 }),1339 }),
1339 };1340 };
1340 pub const cannonlake = Cpu{1341 pub const cannonlake = CpuModel{
1341 .name = "cannonlake",1342 .name = "cannonlake",
1342 .llvm_name = "cannonlake",1343 .llvm_name = "cannonlake",
1343 .features = featureSet(&[_]Feature{1344 .features = featureSet(&[_]Feature{
...@@ -1397,7 +1398,7 @@ pub const cpu = struct {...@@ -1397,7 +1398,7 @@ pub const cpu = struct {
1397 .xsaves,1398 .xsaves,
1398 }),1399 }),
1399 };1400 };
1400 pub const cascadelake = Cpu{1401 pub const cascadelake = CpuModel{
1401 .name = "cascadelake",1402 .name = "cascadelake",
1402 .llvm_name = "cascadelake",1403 .llvm_name = "cascadelake",
1403 .features = featureSet(&[_]Feature{1404 .features = featureSet(&[_]Feature{
...@@ -1456,7 +1457,7 @@ pub const cpu = struct {...@@ -1456,7 +1457,7 @@ pub const cpu = struct {
1456 .xsaves,1457 .xsaves,
1457 }),1458 }),
1458 };1459 };
1459 pub const cooperlake = Cpu{1460 pub const cooperlake = CpuModel{
1460 .name = "cooperlake",1461 .name = "cooperlake",
1461 .llvm_name = "cooperlake",1462 .llvm_name = "cooperlake",
1462 .features = featureSet(&[_]Feature{1463 .features = featureSet(&[_]Feature{
...@@ -1516,7 +1517,7 @@ pub const cpu = struct {...@@ -1516,7 +1517,7 @@ pub const cpu = struct {
1516 .xsaves,1517 .xsaves,
1517 }),1518 }),
1518 };1519 };
1519 pub const core_avx_i = Cpu{1520 pub const core_avx_i = CpuModel{
1520 .name = "core_avx_i",1521 .name = "core_avx_i",
1521 .llvm_name = "core-avx-i",1522 .llvm_name = "core-avx-i",
1522 .features = featureSet(&[_]Feature{1523 .features = featureSet(&[_]Feature{
...@@ -1549,7 +1550,7 @@ pub const cpu = struct {...@@ -1549,7 +1550,7 @@ pub const cpu = struct {
1549 .xsaveopt,1550 .xsaveopt,
1550 }),1551 }),
1551 };1552 };
1552 pub const core_avx2 = Cpu{1553 pub const core_avx2 = CpuModel{
1553 .name = "core_avx2",1554 .name = "core_avx2",
1554 .llvm_name = "core-avx2",1555 .llvm_name = "core-avx2",
1555 .features = featureSet(&[_]Feature{1556 .features = featureSet(&[_]Feature{
...@@ -1591,7 +1592,7 @@ pub const cpu = struct {...@@ -1591,7 +1592,7 @@ pub const cpu = struct {
1591 .xsaveopt,1592 .xsaveopt,
1592 }),1593 }),
1593 };1594 };
1594 pub const core2 = Cpu{1595 pub const core2 = CpuModel{
1595 .name = "core2",1596 .name = "core2",
1596 .llvm_name = "core2",1597 .llvm_name = "core2",
1597 .features = featureSet(&[_]Feature{1598 .features = featureSet(&[_]Feature{
...@@ -1610,7 +1611,7 @@ pub const cpu = struct {...@@ -1610,7 +1611,7 @@ pub const cpu = struct {
1610 .x87,1611 .x87,
1611 }),1612 }),
1612 };1613 };
1613 pub const corei7 = Cpu{1614 pub const corei7 = CpuModel{
1614 .name = "corei7",1615 .name = "corei7",
1615 .llvm_name = "corei7",1616 .llvm_name = "corei7",
1616 .features = featureSet(&[_]Feature{1617 .features = featureSet(&[_]Feature{
...@@ -1629,7 +1630,7 @@ pub const cpu = struct {...@@ -1629,7 +1630,7 @@ pub const cpu = struct {
1629 .x87,1630 .x87,
1630 }),1631 }),
1631 };1632 };
1632 pub const corei7_avx = Cpu{1633 pub const corei7_avx = CpuModel{
1633 .name = "corei7_avx",1634 .name = "corei7_avx",
1634 .llvm_name = "corei7-avx",1635 .llvm_name = "corei7-avx",
1635 .features = featureSet(&[_]Feature{1636 .features = featureSet(&[_]Feature{
...@@ -1659,7 +1660,7 @@ pub const cpu = struct {...@@ -1659,7 +1660,7 @@ pub const cpu = struct {
1659 .xsaveopt,1660 .xsaveopt,
1660 }),1661 }),
1661 };1662 };
1662 pub const generic = Cpu{1663 pub const generic = CpuModel{
1663 .name = "generic",1664 .name = "generic",
1664 .llvm_name = "generic",1665 .llvm_name = "generic",
1665 .features = featureSet(&[_]Feature{1666 .features = featureSet(&[_]Feature{
...@@ -1669,7 +1670,7 @@ pub const cpu = struct {...@@ -1669,7 +1670,7 @@ pub const cpu = struct {
1669 .x87,1670 .x87,
1670 }),1671 }),
1671 };1672 };
1672 pub const geode = Cpu{1673 pub const geode = CpuModel{
1673 .name = "geode",1674 .name = "geode",
1674 .llvm_name = "geode",1675 .llvm_name = "geode",
1675 .features = featureSet(&[_]Feature{1676 .features = featureSet(&[_]Feature{
...@@ -1680,7 +1681,7 @@ pub const cpu = struct {...@@ -1680,7 +1681,7 @@ pub const cpu = struct {
1680 .x87,1681 .x87,
1681 }),1682 }),
1682 };1683 };
1683 pub const goldmont = Cpu{1684 pub const goldmont = CpuModel{
1684 .name = "goldmont",1685 .name = "goldmont",
1685 .llvm_name = "goldmont",1686 .llvm_name = "goldmont",
1686 .features = featureSet(&[_]Feature{1687 .features = featureSet(&[_]Feature{
...@@ -1717,7 +1718,7 @@ pub const cpu = struct {...@@ -1717,7 +1718,7 @@ pub const cpu = struct {
1717 .xsaves,1718 .xsaves,
1718 }),1719 }),
1719 };1720 };
1720 pub const goldmont_plus = Cpu{1721 pub const goldmont_plus = CpuModel{
1721 .name = "goldmont_plus",1722 .name = "goldmont_plus",
1722 .llvm_name = "goldmont-plus",1723 .llvm_name = "goldmont-plus",
1723 .features = featureSet(&[_]Feature{1724 .features = featureSet(&[_]Feature{
...@@ -1756,7 +1757,7 @@ pub const cpu = struct {...@@ -1756,7 +1757,7 @@ pub const cpu = struct {
1756 .xsaves,1757 .xsaves,
1757 }),1758 }),
1758 };1759 };
1759 pub const haswell = Cpu{1760 pub const haswell = CpuModel{
1760 .name = "haswell",1761 .name = "haswell",
1761 .llvm_name = "haswell",1762 .llvm_name = "haswell",
1762 .features = featureSet(&[_]Feature{1763 .features = featureSet(&[_]Feature{
...@@ -1798,7 +1799,7 @@ pub const cpu = struct {...@@ -1798,7 +1799,7 @@ pub const cpu = struct {
1798 .xsaveopt,1799 .xsaveopt,
1799 }),1800 }),
1800 };1801 };
1801 pub const _i386 = Cpu{1802 pub const _i386 = CpuModel{
1802 .name = "_i386",1803 .name = "_i386",
1803 .llvm_name = "i386",1804 .llvm_name = "i386",
1804 .features = featureSet(&[_]Feature{1805 .features = featureSet(&[_]Feature{
...@@ -1807,7 +1808,7 @@ pub const cpu = struct {...@@ -1807,7 +1808,7 @@ pub const cpu = struct {
1807 .x87,1808 .x87,
1808 }),1809 }),
1809 };1810 };
1810 pub const _i486 = Cpu{1811 pub const _i486 = CpuModel{
1811 .name = "_i486",1812 .name = "_i486",
1812 .llvm_name = "i486",1813 .llvm_name = "i486",
1813 .features = featureSet(&[_]Feature{1814 .features = featureSet(&[_]Feature{
...@@ -1816,7 +1817,7 @@ pub const cpu = struct {...@@ -1816,7 +1817,7 @@ pub const cpu = struct {
1816 .x87,1817 .x87,
1817 }),1818 }),
1818 };1819 };
1819 pub const _i586 = Cpu{1820 pub const _i586 = CpuModel{
1820 .name = "_i586",1821 .name = "_i586",
1821 .llvm_name = "i586",1822 .llvm_name = "i586",
1822 .features = featureSet(&[_]Feature{1823 .features = featureSet(&[_]Feature{
...@@ -1826,7 +1827,7 @@ pub const cpu = struct {...@@ -1826,7 +1827,7 @@ pub const cpu = struct {
1826 .x87,1827 .x87,
1827 }),1828 }),
1828 };1829 };
1829 pub const _i686 = Cpu{1830 pub const _i686 = CpuModel{
1830 .name = "_i686",1831 .name = "_i686",
1831 .llvm_name = "i686",1832 .llvm_name = "i686",
1832 .features = featureSet(&[_]Feature{1833 .features = featureSet(&[_]Feature{
...@@ -1837,7 +1838,7 @@ pub const cpu = struct {...@@ -1837,7 +1838,7 @@ pub const cpu = struct {
1837 .x87,1838 .x87,
1838 }),1839 }),
1839 };1840 };
1840 pub const icelake_client = Cpu{1841 pub const icelake_client = CpuModel{
1841 .name = "icelake_client",1842 .name = "icelake_client",
1842 .llvm_name = "icelake-client",1843 .llvm_name = "icelake-client",
1843 .features = featureSet(&[_]Feature{1844 .features = featureSet(&[_]Feature{
...@@ -1906,7 +1907,7 @@ pub const cpu = struct {...@@ -1906,7 +1907,7 @@ pub const cpu = struct {
1906 .xsaves,1907 .xsaves,
1907 }),1908 }),
1908 };1909 };
1909 pub const icelake_server = Cpu{1910 pub const icelake_server = CpuModel{
1910 .name = "icelake_server",1911 .name = "icelake_server",
1911 .llvm_name = "icelake-server",1912 .llvm_name = "icelake-server",
1912 .features = featureSet(&[_]Feature{1913 .features = featureSet(&[_]Feature{
...@@ -1977,7 +1978,7 @@ pub const cpu = struct {...@@ -1977,7 +1978,7 @@ pub const cpu = struct {
1977 .xsaves,1978 .xsaves,
1978 }),1979 }),
1979 };1980 };
1980 pub const ivybridge = Cpu{1981 pub const ivybridge = CpuModel{
1981 .name = "ivybridge",1982 .name = "ivybridge",
1982 .llvm_name = "ivybridge",1983 .llvm_name = "ivybridge",
1983 .features = featureSet(&[_]Feature{1984 .features = featureSet(&[_]Feature{
...@@ -2010,7 +2011,7 @@ pub const cpu = struct {...@@ -2010,7 +2011,7 @@ pub const cpu = struct {
2010 .xsaveopt,2011 .xsaveopt,
2011 }),2012 }),
2012 };2013 };
2013 pub const k6 = Cpu{2014 pub const k6 = CpuModel{
2014 .name = "k6",2015 .name = "k6",
2015 .llvm_name = "k6",2016 .llvm_name = "k6",
2016 .features = featureSet(&[_]Feature{2017 .features = featureSet(&[_]Feature{
...@@ -2021,7 +2022,7 @@ pub const cpu = struct {...@@ -2021,7 +2022,7 @@ pub const cpu = struct {
2021 .x87,2022 .x87,
2022 }),2023 }),
2023 };2024 };
2024 pub const k6_2 = Cpu{2025 pub const k6_2 = CpuModel{
2025 .name = "k6_2",2026 .name = "k6_2",
2026 .llvm_name = "k6-2",2027 .llvm_name = "k6-2",
2027 .features = featureSet(&[_]Feature{2028 .features = featureSet(&[_]Feature{
...@@ -2032,7 +2033,7 @@ pub const cpu = struct {...@@ -2032,7 +2033,7 @@ pub const cpu = struct {
2032 .x87,2033 .x87,
2033 }),2034 }),
2034 };2035 };
2035 pub const k6_3 = Cpu{2036 pub const k6_3 = CpuModel{
2036 .name = "k6_3",2037 .name = "k6_3",
2037 .llvm_name = "k6-3",2038 .llvm_name = "k6-3",
2038 .features = featureSet(&[_]Feature{2039 .features = featureSet(&[_]Feature{
...@@ -2043,7 +2044,7 @@ pub const cpu = struct {...@@ -2043,7 +2044,7 @@ pub const cpu = struct {
2043 .x87,2044 .x87,
2044 }),2045 }),
2045 };2046 };
2046 pub const k8 = Cpu{2047 pub const k8 = CpuModel{
2047 .name = "k8",2048 .name = "k8",
2048 .llvm_name = "k8",2049 .llvm_name = "k8",
2049 .features = featureSet(&[_]Feature{2050 .features = featureSet(&[_]Feature{
...@@ -2061,7 +2062,7 @@ pub const cpu = struct {...@@ -2061,7 +2062,7 @@ pub const cpu = struct {
2061 .x87,2062 .x87,
2062 }),2063 }),
2063 };2064 };
2064 pub const k8_sse3 = Cpu{2065 pub const k8_sse3 = CpuModel{
2065 .name = "k8_sse3",2066 .name = "k8_sse3",
2066 .llvm_name = "k8-sse3",2067 .llvm_name = "k8-sse3",
2067 .features = featureSet(&[_]Feature{2068 .features = featureSet(&[_]Feature{
...@@ -2080,7 +2081,7 @@ pub const cpu = struct {...@@ -2080,7 +2081,7 @@ pub const cpu = struct {
2080 .x87,2081 .x87,
2081 }),2082 }),
2082 };2083 };
2083 pub const knl = Cpu{2084 pub const knl = CpuModel{
2084 .name = "knl",2085 .name = "knl",
2085 .llvm_name = "knl",2086 .llvm_name = "knl",
2086 .features = featureSet(&[_]Feature{2087 .features = featureSet(&[_]Feature{
...@@ -2123,7 +2124,7 @@ pub const cpu = struct {...@@ -2123,7 +2124,7 @@ pub const cpu = struct {
2123 .xsaveopt,2124 .xsaveopt,
2124 }),2125 }),
2125 };2126 };
2126 pub const knm = Cpu{2127 pub const knm = CpuModel{
2127 .name = "knm",2128 .name = "knm",
2128 .llvm_name = "knm",2129 .llvm_name = "knm",
2129 .features = featureSet(&[_]Feature{2130 .features = featureSet(&[_]Feature{
...@@ -2167,14 +2168,14 @@ pub const cpu = struct {...@@ -2167,14 +2168,14 @@ pub const cpu = struct {
2167 .xsaveopt,2168 .xsaveopt,
2168 }),2169 }),
2169 };2170 };
2170 pub const lakemont = Cpu{2171 pub const lakemont = CpuModel{
2171 .name = "lakemont",2172 .name = "lakemont",
2172 .llvm_name = "lakemont",2173 .llvm_name = "lakemont",
2173 .features = featureSet(&[_]Feature{2174 .features = featureSet(&[_]Feature{
2174 .vzeroupper,2175 .vzeroupper,
2175 }),2176 }),
2176 };2177 };
2177 pub const nehalem = Cpu{2178 pub const nehalem = CpuModel{
2178 .name = "nehalem",2179 .name = "nehalem",
2179 .llvm_name = "nehalem",2180 .llvm_name = "nehalem",
2180 .features = featureSet(&[_]Feature{2181 .features = featureSet(&[_]Feature{
...@@ -2193,7 +2194,7 @@ pub const cpu = struct {...@@ -2193,7 +2194,7 @@ pub const cpu = struct {
2193 .x87,2194 .x87,
2194 }),2195 }),
2195 };2196 };
2196 pub const nocona = Cpu{2197 pub const nocona = CpuModel{
2197 .name = "nocona",2198 .name = "nocona",
2198 .llvm_name = "nocona",2199 .llvm_name = "nocona",
2199 .features = featureSet(&[_]Feature{2200 .features = featureSet(&[_]Feature{
...@@ -2210,7 +2211,7 @@ pub const cpu = struct {...@@ -2210,7 +2211,7 @@ pub const cpu = struct {
2210 .x87,2211 .x87,
2211 }),2212 }),
2212 };2213 };
2213 pub const opteron = Cpu{2214 pub const opteron = CpuModel{
2214 .name = "opteron",2215 .name = "opteron",
2215 .llvm_name = "opteron",2216 .llvm_name = "opteron",
2216 .features = featureSet(&[_]Feature{2217 .features = featureSet(&[_]Feature{
...@@ -2228,7 +2229,7 @@ pub const cpu = struct {...@@ -2228,7 +2229,7 @@ pub const cpu = struct {
2228 .x87,2229 .x87,
2229 }),2230 }),
2230 };2231 };
2231 pub const opteron_sse3 = Cpu{2232 pub const opteron_sse3 = CpuModel{
2232 .name = "opteron_sse3",2233 .name = "opteron_sse3",
2233 .llvm_name = "opteron-sse3",2234 .llvm_name = "opteron-sse3",
2234 .features = featureSet(&[_]Feature{2235 .features = featureSet(&[_]Feature{
...@@ -2247,7 +2248,7 @@ pub const cpu = struct {...@@ -2247,7 +2248,7 @@ pub const cpu = struct {
2247 .x87,2248 .x87,
2248 }),2249 }),
2249 };2250 };
2250 pub const penryn = Cpu{2251 pub const penryn = CpuModel{
2251 .name = "penryn",2252 .name = "penryn",
2252 .llvm_name = "penryn",2253 .llvm_name = "penryn",
2253 .features = featureSet(&[_]Feature{2254 .features = featureSet(&[_]Feature{
...@@ -2266,7 +2267,7 @@ pub const cpu = struct {...@@ -2266,7 +2267,7 @@ pub const cpu = struct {
2266 .x87,2267 .x87,
2267 }),2268 }),
2268 };2269 };
2269 pub const pentium = Cpu{2270 pub const pentium = CpuModel{
2270 .name = "pentium",2271 .name = "pentium",
2271 .llvm_name = "pentium",2272 .llvm_name = "pentium",
2272 .features = featureSet(&[_]Feature{2273 .features = featureSet(&[_]Feature{
...@@ -2276,7 +2277,7 @@ pub const cpu = struct {...@@ -2276,7 +2277,7 @@ pub const cpu = struct {
2276 .x87,2277 .x87,
2277 }),2278 }),
2278 };2279 };
2279 pub const pentium_m = Cpu{2280 pub const pentium_m = CpuModel{
2280 .name = "pentium_m",2281 .name = "pentium_m",
2281 .llvm_name = "pentium-m",2282 .llvm_name = "pentium-m",
2282 .features = featureSet(&[_]Feature{2283 .features = featureSet(&[_]Feature{
...@@ -2291,7 +2292,7 @@ pub const cpu = struct {...@@ -2291,7 +2292,7 @@ pub const cpu = struct {
2291 .x87,2292 .x87,
2292 }),2293 }),
2293 };2294 };
2294 pub const pentium_mmx = Cpu{2295 pub const pentium_mmx = CpuModel{
2295 .name = "pentium_mmx",2296 .name = "pentium_mmx",
2296 .llvm_name = "pentium-mmx",2297 .llvm_name = "pentium-mmx",
2297 .features = featureSet(&[_]Feature{2298 .features = featureSet(&[_]Feature{
...@@ -2302,7 +2303,7 @@ pub const cpu = struct {...@@ -2302,7 +2303,7 @@ pub const cpu = struct {
2302 .x87,2303 .x87,
2303 }),2304 }),
2304 };2305 };
2305 pub const pentium2 = Cpu{2306 pub const pentium2 = CpuModel{
2306 .name = "pentium2",2307 .name = "pentium2",
2307 .llvm_name = "pentium2",2308 .llvm_name = "pentium2",
2308 .features = featureSet(&[_]Feature{2309 .features = featureSet(&[_]Feature{
...@@ -2316,7 +2317,7 @@ pub const cpu = struct {...@@ -2316,7 +2317,7 @@ pub const cpu = struct {
2316 .x87,2317 .x87,
2317 }),2318 }),
2318 };2319 };
2319 pub const pentium3 = Cpu{2320 pub const pentium3 = CpuModel{
2320 .name = "pentium3",2321 .name = "pentium3",
2321 .llvm_name = "pentium3",2322 .llvm_name = "pentium3",
2322 .features = featureSet(&[_]Feature{2323 .features = featureSet(&[_]Feature{
...@@ -2331,7 +2332,7 @@ pub const cpu = struct {...@@ -2331,7 +2332,7 @@ pub const cpu = struct {
2331 .x87,2332 .x87,
2332 }),2333 }),
2333 };2334 };
2334 pub const pentium3m = Cpu{2335 pub const pentium3m = CpuModel{
2335 .name = "pentium3m",2336 .name = "pentium3m",
2336 .llvm_name = "pentium3m",2337 .llvm_name = "pentium3m",
2337 .features = featureSet(&[_]Feature{2338 .features = featureSet(&[_]Feature{
...@@ -2346,7 +2347,7 @@ pub const cpu = struct {...@@ -2346,7 +2347,7 @@ pub const cpu = struct {
2346 .x87,2347 .x87,
2347 }),2348 }),
2348 };2349 };
2349 pub const pentium4 = Cpu{2350 pub const pentium4 = CpuModel{
2350 .name = "pentium4",2351 .name = "pentium4",
2351 .llvm_name = "pentium4",2352 .llvm_name = "pentium4",
2352 .features = featureSet(&[_]Feature{2353 .features = featureSet(&[_]Feature{
...@@ -2361,7 +2362,7 @@ pub const cpu = struct {...@@ -2361,7 +2362,7 @@ pub const cpu = struct {
2361 .x87,2362 .x87,
2362 }),2363 }),
2363 };2364 };
2364 pub const pentium4m = Cpu{2365 pub const pentium4m = CpuModel{
2365 .name = "pentium4m",2366 .name = "pentium4m",
2366 .llvm_name = "pentium4m",2367 .llvm_name = "pentium4m",
2367 .features = featureSet(&[_]Feature{2368 .features = featureSet(&[_]Feature{
...@@ -2376,7 +2377,7 @@ pub const cpu = struct {...@@ -2376,7 +2377,7 @@ pub const cpu = struct {
2376 .x87,2377 .x87,
2377 }),2378 }),
2378 };2379 };
2379 pub const pentiumpro = Cpu{2380 pub const pentiumpro = CpuModel{
2380 .name = "pentiumpro",2381 .name = "pentiumpro",
2381 .llvm_name = "pentiumpro",2382 .llvm_name = "pentiumpro",
2382 .features = featureSet(&[_]Feature{2383 .features = featureSet(&[_]Feature{
...@@ -2388,7 +2389,7 @@ pub const cpu = struct {...@@ -2388,7 +2389,7 @@ pub const cpu = struct {
2388 .x87,2389 .x87,
2389 }),2390 }),
2390 };2391 };
2391 pub const prescott = Cpu{2392 pub const prescott = CpuModel{
2392 .name = "prescott",2393 .name = "prescott",
2393 .llvm_name = "prescott",2394 .llvm_name = "prescott",
2394 .features = featureSet(&[_]Feature{2395 .features = featureSet(&[_]Feature{
...@@ -2403,7 +2404,7 @@ pub const cpu = struct {...@@ -2403,7 +2404,7 @@ pub const cpu = struct {
2403 .x87,2404 .x87,
2404 }),2405 }),
2405 };2406 };
2406 pub const sandybridge = Cpu{2407 pub const sandybridge = CpuModel{
2407 .name = "sandybridge",2408 .name = "sandybridge",
2408 .llvm_name = "sandybridge",2409 .llvm_name = "sandybridge",
2409 .features = featureSet(&[_]Feature{2410 .features = featureSet(&[_]Feature{
...@@ -2433,7 +2434,7 @@ pub const cpu = struct {...@@ -2433,7 +2434,7 @@ pub const cpu = struct {
2433 .xsaveopt,2434 .xsaveopt,
2434 }),2435 }),
2435 };2436 };
2436 pub const silvermont = Cpu{2437 pub const silvermont = CpuModel{
2437 .name = "silvermont",2438 .name = "silvermont",
2438 .llvm_name = "silvermont",2439 .llvm_name = "silvermont",
2439 .features = featureSet(&[_]Feature{2440 .features = featureSet(&[_]Feature{
...@@ -2462,7 +2463,7 @@ pub const cpu = struct {...@@ -2462,7 +2463,7 @@ pub const cpu = struct {
2462 .x87,2463 .x87,
2463 }),2464 }),
2464 };2465 };
2465 pub const skx = Cpu{2466 pub const skx = CpuModel{
2466 .name = "skx",2467 .name = "skx",
2467 .llvm_name = "skx",2468 .llvm_name = "skx",
2468 .features = featureSet(&[_]Feature{2469 .features = featureSet(&[_]Feature{
...@@ -2520,7 +2521,7 @@ pub const cpu = struct {...@@ -2520,7 +2521,7 @@ pub const cpu = struct {
2520 .xsaves,2521 .xsaves,
2521 }),2522 }),
2522 };2523 };
2523 pub const skylake = Cpu{2524 pub const skylake = CpuModel{
2524 .name = "skylake",2525 .name = "skylake",
2525 .llvm_name = "skylake",2526 .llvm_name = "skylake",
2526 .features = featureSet(&[_]Feature{2527 .features = featureSet(&[_]Feature{
...@@ -2571,7 +2572,7 @@ pub const cpu = struct {...@@ -2571,7 +2572,7 @@ pub const cpu = struct {
2571 .xsaves,2572 .xsaves,
2572 }),2573 }),
2573 };2574 };
2574 pub const skylake_avx512 = Cpu{2575 pub const skylake_avx512 = CpuModel{
2575 .name = "skylake_avx512",2576 .name = "skylake_avx512",
2576 .llvm_name = "skylake-avx512",2577 .llvm_name = "skylake-avx512",
2577 .features = featureSet(&[_]Feature{2578 .features = featureSet(&[_]Feature{
...@@ -2629,7 +2630,7 @@ pub const cpu = struct {...@@ -2629,7 +2630,7 @@ pub const cpu = struct {
2629 .xsaves,2630 .xsaves,
2630 }),2631 }),
2631 };2632 };
2632 pub const slm = Cpu{2633 pub const slm = CpuModel{
2633 .name = "slm",2634 .name = "slm",
2634 .llvm_name = "slm",2635 .llvm_name = "slm",
2635 .features = featureSet(&[_]Feature{2636 .features = featureSet(&[_]Feature{
...@@ -2658,7 +2659,7 @@ pub const cpu = struct {...@@ -2658,7 +2659,7 @@ pub const cpu = struct {
2658 .x87,2659 .x87,
2659 }),2660 }),
2660 };2661 };
2661 pub const tigerlake = Cpu{2662 pub const tigerlake = CpuModel{
2662 .name = "tigerlake",2663 .name = "tigerlake",
2663 .llvm_name = "tigerlake",2664 .llvm_name = "tigerlake",
2664 .features = featureSet(&[_]Feature{2665 .features = featureSet(&[_]Feature{
...@@ -2731,7 +2732,7 @@ pub const cpu = struct {...@@ -2731,7 +2732,7 @@ pub const cpu = struct {
2731 .xsaves,2732 .xsaves,
2732 }),2733 }),
2733 };2734 };
2734 pub const tremont = Cpu{2735 pub const tremont = CpuModel{
2735 .name = "tremont",2736 .name = "tremont",
2736 .llvm_name = "tremont",2737 .llvm_name = "tremont",
2737 .features = featureSet(&[_]Feature{2738 .features = featureSet(&[_]Feature{
...@@ -2775,7 +2776,7 @@ pub const cpu = struct {...@@ -2775,7 +2776,7 @@ pub const cpu = struct {
2775 .xsaves,2776 .xsaves,
2776 }),2777 }),
2777 };2778 };
2778 pub const westmere = Cpu{2779 pub const westmere = CpuModel{
2779 .name = "westmere",2780 .name = "westmere",
2780 .llvm_name = "westmere",2781 .llvm_name = "westmere",
2781 .features = featureSet(&[_]Feature{2782 .features = featureSet(&[_]Feature{
...@@ -2795,7 +2796,7 @@ pub const cpu = struct {...@@ -2795,7 +2796,7 @@ pub const cpu = struct {
2795 .x87,2796 .x87,
2796 }),2797 }),
2797 };2798 };
2798 pub const winchip_c6 = Cpu{2799 pub const winchip_c6 = CpuModel{
2799 .name = "winchip_c6",2800 .name = "winchip_c6",
2800 .llvm_name = "winchip-c6",2801 .llvm_name = "winchip-c6",
2801 .features = featureSet(&[_]Feature{2802 .features = featureSet(&[_]Feature{
...@@ -2805,7 +2806,7 @@ pub const cpu = struct {...@@ -2805,7 +2806,7 @@ pub const cpu = struct {
2805 .x87,2806 .x87,
2806 }),2807 }),
2807 };2808 };
2808 pub const winchip2 = Cpu{2809 pub const winchip2 = CpuModel{
2809 .name = "winchip2",2810 .name = "winchip2",
2810 .llvm_name = "winchip2",2811 .llvm_name = "winchip2",
2811 .features = featureSet(&[_]Feature{2812 .features = featureSet(&[_]Feature{
...@@ -2815,7 +2816,7 @@ pub const cpu = struct {...@@ -2815,7 +2816,7 @@ pub const cpu = struct {
2815 .x87,2816 .x87,
2816 }),2817 }),
2817 };2818 };
2818 pub const x86_64 = Cpu{2819 pub const x86_64 = CpuModel{
2819 .name = "x86_64",2820 .name = "x86_64",
2820 .llvm_name = "x86-64",2821 .llvm_name = "x86-64",
2821 .features = featureSet(&[_]Feature{2822 .features = featureSet(&[_]Feature{
...@@ -2833,7 +2834,7 @@ pub const cpu = struct {...@@ -2833,7 +2834,7 @@ pub const cpu = struct {
2833 .x87,2834 .x87,
2834 }),2835 }),
2835 };2836 };
2836 pub const yonah = Cpu{2837 pub const yonah = CpuModel{
2837 .name = "yonah",2838 .name = "yonah",
2838 .llvm_name = "yonah",2839 .llvm_name = "yonah",
2839 .features = featureSet(&[_]Feature{2840 .features = featureSet(&[_]Feature{
...@@ -2848,7 +2849,7 @@ pub const cpu = struct {...@@ -2848,7 +2849,7 @@ pub const cpu = struct {
2848 .x87,2849 .x87,
2849 }),2850 }),
2850 };2851 };
2851 pub const znver1 = Cpu{2852 pub const znver1 = CpuModel{
2852 .name = "znver1",2853 .name = "znver1",
2853 .llvm_name = "znver1",2854 .llvm_name = "znver1",
2854 .features = featureSet(&[_]Feature{2855 .features = featureSet(&[_]Feature{
...@@ -2893,7 +2894,7 @@ pub const cpu = struct {...@@ -2893,7 +2894,7 @@ pub const cpu = struct {
2893 .xsaves,2894 .xsaves,
2894 }),2895 }),
2895 };2896 };
2896 pub const znver2 = Cpu{2897 pub const znver2 = CpuModel{
2897 .name = "znver2",2898 .name = "znver2",
2898 .llvm_name = "znver2",2899 .llvm_name = "znver2",
2899 .features = featureSet(&[_]Feature{2900 .features = featureSet(&[_]Feature{
...@@ -2946,7 +2947,7 @@ pub const cpu = struct {...@@ -2946,7 +2947,7 @@ pub const cpu = struct {
2946/// All x86 CPUs, sorted alphabetically by name.2947/// All x86 CPUs, sorted alphabetically by name.
2947/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage12948/// TODO: Replace this with usage of `std.meta.declList`. It does work, but stage1
2948/// compiler has inefficient memory and CPU usage, affecting build times.2949/// compiler has inefficient memory and CPU usage, affecting build times.
2949pub const all_cpus = &[_]*const Cpu{2950pub const all_cpus = &[_]*const CpuModel{
2950 &cpu.amdfam10,2951 &cpu.amdfam10,
2951 &cpu.athlon,2952 &cpu.athlon,
2952 &cpu.athlon_4,2953 &cpu.athlon_4,
lib/std/thread.zig+3-3
...@@ -148,7 +148,7 @@ pub const Thread = struct {...@@ -148,7 +148,7 @@ pub const Thread = struct {
148 const default_stack_size = 16 * 1024 * 1024;148 const default_stack_size = 16 * 1024 * 1024;
149149
150 const Context = @TypeOf(context);150 const Context = @TypeOf(context);
151 comptime assert(@ArgType(@TypeOf(startFn), 0) == Context);151 comptime assert(@typeInfo(@TypeOf(startFn)).Fn.args[0].arg_type.? == Context);
152152
153 if (builtin.os == builtin.Os.windows) {153 if (builtin.os == builtin.Os.windows) {
154 const WinThread = struct {154 const WinThread = struct {
...@@ -158,7 +158,7 @@ pub const Thread = struct {...@@ -158,7 +158,7 @@ pub const Thread = struct {
158 };158 };
159 fn threadMain(raw_arg: windows.LPVOID) callconv(.C) windows.DWORD {159 fn threadMain(raw_arg: windows.LPVOID) callconv(.C) windows.DWORD {
160 const arg = if (@sizeOf(Context) == 0) {} else @ptrCast(*Context, @alignCast(@alignOf(Context), raw_arg)).*;160 const arg = if (@sizeOf(Context) == 0) {} else @ptrCast(*Context, @alignCast(@alignOf(Context), raw_arg)).*;
161 switch (@typeId(@TypeOf(startFn).ReturnType)) {161 switch (@typeInfo(@TypeOf(startFn).ReturnType)) {
162 .Int => {162 .Int => {
163 return startFn(arg);163 return startFn(arg);
164 },164 },
...@@ -201,7 +201,7 @@ pub const Thread = struct {...@@ -201,7 +201,7 @@ pub const Thread = struct {
201 fn linuxThreadMain(ctx_addr: usize) callconv(.C) u8 {201 fn linuxThreadMain(ctx_addr: usize) callconv(.C) u8 {
202 const arg = if (@sizeOf(Context) == 0) {} else @intToPtr(*const Context, ctx_addr).*;202 const arg = if (@sizeOf(Context) == 0) {} else @intToPtr(*const Context, ctx_addr).*;
203203
204 switch (@typeId(@TypeOf(startFn).ReturnType)) {204 switch (@typeInfo(@TypeOf(startFn).ReturnType)) {
205 .Int => {205 .Int => {
206 return startFn(arg);206 return startFn(arg);
207 },207 },
lib/std/time.zig+14-9
...@@ -8,6 +8,7 @@ const math = std.math;...@@ -8,6 +8,7 @@ const math = std.math;
8pub const epoch = @import("time/epoch.zig");8pub const epoch = @import("time/epoch.zig");
99
10/// Spurious wakeups are possible and no precision of timing is guaranteed.10/// Spurious wakeups are possible and no precision of timing is guaranteed.
11/// TODO integrate with evented I/O
11pub fn sleep(nanoseconds: u64) void {12pub fn sleep(nanoseconds: u64) void {
12 if (builtin.os == .windows) {13 if (builtin.os == .windows) {
13 const ns_per_ms = ns_per_s / ms_per_s;14 const ns_per_ms = ns_per_s / ms_per_s;
...@@ -152,15 +153,9 @@ pub const Timer = struct {...@@ -152,15 +153,9 @@ pub const Timer = struct {
152 }153 }
153154
154 /// Reads the timer value since start or the last reset in nanoseconds155 /// Reads the timer value since start or the last reset in nanoseconds
155 pub fn read(self: *Timer) u64 {156 pub fn read(self: Timer) u64 {
156 var clock = clockNative() - self.start_time;157 var clock = clockNative() - self.start_time;
157 if (builtin.os == .windows) {158 return self.nativeDurationToNanos(clock);
158 return @divFloor(clock * ns_per_s, self.frequency);
159 }
160 if (comptime std.Target.current.isDarwin()) {
161 return @divFloor(clock * self.frequency.numer, self.frequency.denom);
162 }
163 return clock;
164 }159 }
165160
166 /// Resets the timer value to 0/now.161 /// Resets the timer value to 0/now.
...@@ -171,7 +166,7 @@ pub const Timer = struct {...@@ -171,7 +166,7 @@ pub const Timer = struct {
171 /// Returns the current value of the timer in nanoseconds, then resets it166 /// Returns the current value of the timer in nanoseconds, then resets it
172 pub fn lap(self: *Timer) u64 {167 pub fn lap(self: *Timer) u64 {
173 var now = clockNative();168 var now = clockNative();
174 var lap_time = self.read();169 var lap_time = self.nativeDurationToNanos(now - self.start_time);
175 self.start_time = now;170 self.start_time = now;
176 return lap_time;171 return lap_time;
177 }172 }
...@@ -187,6 +182,16 @@ pub const Timer = struct {...@@ -187,6 +182,16 @@ pub const Timer = struct {
187 os.clock_gettime(monotonic_clock_id, &ts) catch unreachable;182 os.clock_gettime(monotonic_clock_id, &ts) catch unreachable;
188 return @intCast(u64, ts.tv_sec) * @as(u64, ns_per_s) + @intCast(u64, ts.tv_nsec);183 return @intCast(u64, ts.tv_sec) * @as(u64, ns_per_s) + @intCast(u64, ts.tv_nsec);
189 }184 }
185
186 fn nativeDurationToNanos(self: Timer, duration: u64) u64 {
187 if (builtin.os == .windows) {
188 return @divFloor(duration * ns_per_s, self.frequency);
189 }
190 if (comptime std.Target.current.isDarwin()) {
191 return @divFloor(duration * self.frequency.numer, self.frequency.denom);
192 }
193 return duration;
194 }
190};195};
191196
192test "sleep" {197test "sleep" {
lib/std/unicode.zig+6-6
...@@ -243,7 +243,7 @@ pub const Utf16LeIterator = struct {...@@ -243,7 +243,7 @@ pub const Utf16LeIterator = struct {
243243
244 pub fn init(s: []const u16) Utf16LeIterator {244 pub fn init(s: []const u16) Utf16LeIterator {
245 return Utf16LeIterator{245 return Utf16LeIterator{
246 .bytes = @sliceToBytes(s),246 .bytes = mem.sliceAsBytes(s),
247 .i = 0,247 .i = 0,
248 };248 };
249 }249 }
...@@ -496,7 +496,7 @@ pub fn utf16leToUtf8(utf8: []u8, utf16le: []const u16) !usize {...@@ -496,7 +496,7 @@ pub fn utf16leToUtf8(utf8: []u8, utf16le: []const u16) !usize {
496496
497test "utf16leToUtf8" {497test "utf16leToUtf8" {
498 var utf16le: [2]u16 = undefined;498 var utf16le: [2]u16 = undefined;
499 const utf16le_as_bytes = @sliceToBytes(utf16le[0..]);499 const utf16le_as_bytes = mem.sliceAsBytes(utf16le[0..]);
500500
501 {501 {
502 mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 'A');502 mem.writeIntSliceLittle(u16, utf16le_as_bytes[0..], 'A');
...@@ -606,12 +606,12 @@ test "utf8ToUtf16Le" {...@@ -606,12 +606,12 @@ test "utf8ToUtf16Le" {
606 {606 {
607 const length = try utf8ToUtf16Le(utf16le[0..], "𐐷");607 const length = try utf8ToUtf16Le(utf16le[0..], "𐐷");
608 testing.expectEqual(@as(usize, 2), length);608 testing.expectEqual(@as(usize, 2), length);
609 testing.expectEqualSlices(u8, "\x01\xd8\x37\xdc", @sliceToBytes(utf16le[0..]));609 testing.expectEqualSlices(u8, "\x01\xd8\x37\xdc", mem.sliceAsBytes(utf16le[0..]));
610 }610 }
611 {611 {
612 const length = try utf8ToUtf16Le(utf16le[0..], "\u{10FFFF}");612 const length = try utf8ToUtf16Le(utf16le[0..], "\u{10FFFF}");
613 testing.expectEqual(@as(usize, 2), length);613 testing.expectEqual(@as(usize, 2), length);
614 testing.expectEqualSlices(u8, "\xff\xdb\xff\xdf", @sliceToBytes(utf16le[0..]));614 testing.expectEqualSlices(u8, "\xff\xdb\xff\xdf", mem.sliceAsBytes(utf16le[0..]));
615 }615 }
616}616}
617617
...@@ -619,13 +619,13 @@ test "utf8ToUtf16LeWithNull" {...@@ -619,13 +619,13 @@ test "utf8ToUtf16LeWithNull" {
619 {619 {
620 const utf16 = try utf8ToUtf16LeWithNull(testing.allocator, "𐐷");620 const utf16 = try utf8ToUtf16LeWithNull(testing.allocator, "𐐷");
621 defer testing.allocator.free(utf16);621 defer testing.allocator.free(utf16);
622 testing.expectEqualSlices(u8, "\x01\xd8\x37\xdc", @sliceToBytes(utf16[0..]));622 testing.expectEqualSlices(u8, "\x01\xd8\x37\xdc", mem.sliceAsBytes(utf16[0..]));
623 testing.expect(utf16[2] == 0);623 testing.expect(utf16[2] == 0);
624 }624 }
625 {625 {
626 const utf16 = try utf8ToUtf16LeWithNull(testing.allocator, "\u{10FFFF}");626 const utf16 = try utf8ToUtf16LeWithNull(testing.allocator, "\u{10FFFF}");
627 defer testing.allocator.free(utf16);627 defer testing.allocator.free(utf16);
628 testing.expectEqualSlices(u8, "\xff\xdb\xff\xdf", @sliceToBytes(utf16[0..]));628 testing.expectEqualSlices(u8, "\xff\xdb\xff\xdf", mem.sliceAsBytes(utf16[0..]));
629 testing.expect(utf16[2] == 0);629 testing.expect(utf16[2] == 0);
630 }630 }
631}631}
lib/std/zig.zig+1
...@@ -5,6 +5,7 @@ pub const parse = @import("zig/parse.zig").parse;...@@ -5,6 +5,7 @@ pub const parse = @import("zig/parse.zig").parse;
5pub const parseStringLiteral = @import("zig/parse_string_literal.zig").parseStringLiteral;5pub const parseStringLiteral = @import("zig/parse_string_literal.zig").parseStringLiteral;
6pub const render = @import("zig/render.zig").render;6pub const render = @import("zig/render.zig").render;
7pub const ast = @import("zig/ast.zig");7pub const ast = @import("zig/ast.zig");
8pub const system = @import("zig/system.zig");
89
9test "std.zig tests" {10test "std.zig tests" {
10 _ = @import("zig/ast.zig");11 _ = @import("zig/ast.zig");
lib/std/zig/ast.zig+17-19
...@@ -460,10 +460,9 @@ pub const Node = struct {...@@ -460,10 +460,9 @@ pub const Node = struct {
460 }460 }
461461
462 pub fn iterate(base: *Node, index: usize) ?*Node {462 pub fn iterate(base: *Node, index: usize) ?*Node {
463 comptime var i = 0;463 inline for (@typeInfo(Id).Enum.fields) |f| {
464 inline while (i < @memberCount(Id)) : (i += 1) {464 if (base.id == @field(Id, f.name)) {
465 if (base.id == @field(Id, @memberName(Id, i))) {465 const T = @field(Node, f.name);
466 const T = @field(Node, @memberName(Id, i));
467 return @fieldParentPtr(T, "base", base).iterate(index);466 return @fieldParentPtr(T, "base", base).iterate(index);
468 }467 }
469 }468 }
...@@ -471,10 +470,9 @@ pub const Node = struct {...@@ -471,10 +470,9 @@ pub const Node = struct {
471 }470 }
472471
473 pub fn firstToken(base: *const Node) TokenIndex {472 pub fn firstToken(base: *const Node) TokenIndex {
474 comptime var i = 0;473 inline for (@typeInfo(Id).Enum.fields) |f| {
475 inline while (i < @memberCount(Id)) : (i += 1) {474 if (base.id == @field(Id, f.name)) {
476 if (base.id == @field(Id, @memberName(Id, i))) {475 const T = @field(Node, f.name);
477 const T = @field(Node, @memberName(Id, i));
478 return @fieldParentPtr(T, "base", base).firstToken();476 return @fieldParentPtr(T, "base", base).firstToken();
479 }477 }
480 }478 }
...@@ -482,10 +480,9 @@ pub const Node = struct {...@@ -482,10 +480,9 @@ pub const Node = struct {
482 }480 }
483481
484 pub fn lastToken(base: *const Node) TokenIndex {482 pub fn lastToken(base: *const Node) TokenIndex {
485 comptime var i = 0;483 inline for (@typeInfo(Id).Enum.fields) |f| {
486 inline while (i < @memberCount(Id)) : (i += 1) {484 if (base.id == @field(Id, f.name)) {
487 if (base.id == @field(Id, @memberName(Id, i))) {485 const T = @field(Node, f.name);
488 const T = @field(Node, @memberName(Id, i));
489 return @fieldParentPtr(T, "base", base).lastToken();486 return @fieldParentPtr(T, "base", base).lastToken();
490 }487 }
491 }488 }
...@@ -493,10 +490,9 @@ pub const Node = struct {...@@ -493,10 +490,9 @@ pub const Node = struct {
493 }490 }
494491
495 pub fn typeToId(comptime T: type) Id {492 pub fn typeToId(comptime T: type) Id {
496 comptime var i = 0;493 inline for (@typeInfo(Id).Enum.fields) |f| {
497 inline while (i < @memberCount(Id)) : (i += 1) {494 if (T == @field(Node, f.name)) {
498 if (T == @field(Node, @memberName(Id, i))) {495 return @field(Id, f.name);
499 return @field(Id, @memberName(Id, i));
500 }496 }
501 }497 }
502 unreachable;498 unreachable;
...@@ -1567,7 +1563,9 @@ pub const Node = struct {...@@ -1567,7 +1563,9 @@ pub const Node = struct {
1567 pub const Op = union(enum) {1563 pub const Op = union(enum) {
1568 AddressOf,1564 AddressOf,
1569 ArrayType: ArrayInfo,1565 ArrayType: ArrayInfo,
1570 Await,1566 Await: struct {
1567 noasync_token: ?TokenIndex = null,
1568 },
1571 BitNot,1569 BitNot,
1572 BoolNot,1570 BoolNot,
1573 Cancel,1571 Cancel,
...@@ -2184,10 +2182,10 @@ pub const Node = struct {...@@ -2184,10 +2182,10 @@ pub const Node = struct {
2184 pub fn iterate(self: *Asm, index: usize) ?*Node {2182 pub fn iterate(self: *Asm, index: usize) ?*Node {
2185 var i = index;2183 var i = index;
21862184
2187 if (i < self.outputs.len) return &self.outputs.at(index).*.base;2185 if (i < self.outputs.len) return &self.outputs.at(i).*.base;
2188 i -= self.outputs.len;2186 i -= self.outputs.len;
21892187
2190 if (i < self.inputs.len) return &self.inputs.at(index).*.base;2188 if (i < self.inputs.len) return &self.inputs.at(i).*.base;
2191 i -= self.inputs.len;2189 i -= self.inputs.len;
21922190
2193 return null;2191 return null;
lib/std/zig/parse.zig+14-2
...@@ -1129,7 +1129,7 @@ fn parseErrorUnionExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No...@@ -1129,7 +1129,7 @@ fn parseErrorUnionExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*No
1129/// / KEYWORD_noasync PrimaryTypeExpr SuffixOp* FnCallArguments1129/// / KEYWORD_noasync PrimaryTypeExpr SuffixOp* FnCallArguments
1130/// / PrimaryTypeExpr (SuffixOp / FnCallArguments)*1130/// / PrimaryTypeExpr (SuffixOp / FnCallArguments)*
1131fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {1131fn parseSuffixExpr(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
1132 var maybe_async = eatAnnotatedToken(it, .Keyword_async) orelse eatAnnotatedToken(it, .Keyword_noasync);1132 const maybe_async = eatAnnotatedToken(it, .Keyword_async) orelse eatAnnotatedToken(it, .Keyword_noasync);
1133 if (maybe_async) |async_token| {1133 if (maybe_async) |async_token| {
1134 const token_fn = eatToken(it, .Keyword_fn);1134 const token_fn = eatToken(it, .Keyword_fn);
1135 if (async_token.ptr.id == .Keyword_async and token_fn != null) {1135 if (async_token.ptr.id == .Keyword_async and token_fn != null) {
...@@ -2179,7 +2179,19 @@ fn parsePrefixOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {...@@ -2179,7 +2179,19 @@ fn parsePrefixOp(arena: *Allocator, it: *TokenIterator, tree: *Tree) !?*Node {
2179 .MinusPercent => ops{ .NegationWrap = {} },2179 .MinusPercent => ops{ .NegationWrap = {} },
2180 .Ampersand => ops{ .AddressOf = {} },2180 .Ampersand => ops{ .AddressOf = {} },
2181 .Keyword_try => ops{ .Try = {} },2181 .Keyword_try => ops{ .Try = {} },
2182 .Keyword_await => ops{ .Await = {} },2182 .Keyword_await => ops{ .Await = .{} },
2183 .Keyword_noasync => if (eatToken(it, .Keyword_await)) |await_tok| {
2184 const node = try arena.create(Node.PrefixOp);
2185 node.* = Node.PrefixOp{
2186 .op_token = await_tok,
2187 .op = .{ .Await = .{ .noasync_token = token.index } },
2188 .rhs = undefined, // set by caller
2189 };
2190 return &node.base;
2191 } else {
2192 putBackToken(it, token.index);
2193 return null;
2194 },
2183 else => {2195 else => {
2184 putBackToken(it, token.index);2196 putBackToken(it, token.index);
2185 return null;2197 return null;
lib/std/zig/parser_test.zig+12-1
...@@ -1,3 +1,12 @@...@@ -1,3 +1,12 @@
1test "zig fmt: noasync await" {
2 try testCanonical(
3 \\fn foo() void {
4 \\ x = noasync await y;
5 \\}
6 \\
7 );
8}
9
1test "zig fmt: trailing comma in container declaration" {10test "zig fmt: trailing comma in container declaration" {
2 try testCanonical(11 try testCanonical(
3 \\const X = struct { foo: i32 };12 \\const X = struct { foo: i32 };
...@@ -83,10 +92,12 @@ test "zig fmt: convert extern/nakedcc/stdcallcc into callconv(...)" {...@@ -83,10 +92,12 @@ test "zig fmt: convert extern/nakedcc/stdcallcc into callconv(...)" {
83 \\nakedcc fn foo1() void {}92 \\nakedcc fn foo1() void {}
84 \\stdcallcc fn foo2() void {}93 \\stdcallcc fn foo2() void {}
85 \\extern fn foo3() void {}94 \\extern fn foo3() void {}
95 \\extern "mylib" fn foo4() void {}
86 ,96 ,
87 \\fn foo1() callconv(.Naked) void {}97 \\fn foo1() callconv(.Naked) void {}
88 \\fn foo2() callconv(.Stdcall) void {}98 \\fn foo2() callconv(.Stdcall) void {}
89 \\fn foo3() callconv(.C) void {}99 \\fn foo3() callconv(.C) void {}
100 \\fn foo4() callconv(.C) void {}
90 \\101 \\
91 );102 );
92}103}
...@@ -1399,7 +1410,7 @@ test "zig fmt: same-line comment after non-block if expression" {...@@ -1399,7 +1410,7 @@ test "zig fmt: same-line comment after non-block if expression" {
1399test "zig fmt: same-line comment on comptime expression" {1410test "zig fmt: same-line comment on comptime expression" {
1400 try testCanonical(1411 try testCanonical(
1401 \\test "" {1412 \\test "" {
1402 \\ comptime assert(@typeId(T) == builtin.TypeId.Int); // must pass an integer to absInt1413 \\ comptime assert(@typeInfo(T) == .Int); // must pass an integer to absInt
1403 \\}1414 \\}
1404 \\1415 \\
1405 );1416 );
lib/std/zig/render.zig+9-3
...@@ -1,5 +1,4 @@...@@ -1,5 +1,4 @@
1const std = @import("../std.zig");1const std = @import("../std.zig");
2const builtin = @import("builtin");
3const assert = std.debug.assert;2const assert = std.debug.assert;
4const mem = std.mem;3const mem = std.mem;
5const ast = std.zig.ast;4const ast = std.zig.ast;
...@@ -14,7 +13,7 @@ pub const Error = error{...@@ -14,7 +13,7 @@ pub const Error = error{
1413
15/// Returns whether anything changed14/// Returns whether anything changed
16pub fn render(allocator: *mem.Allocator, stream: var, tree: *ast.Tree) (@TypeOf(stream).Child.Error || Error)!bool {15pub fn render(allocator: *mem.Allocator, stream: var, tree: *ast.Tree) (@TypeOf(stream).Child.Error || Error)!bool {
17 comptime assert(@typeId(@TypeOf(stream)) == builtin.TypeId.Pointer);16 comptime assert(@typeInfo(@TypeOf(stream)) == .Pointer);
1817
19 var anything_changed: bool = false;18 var anything_changed: bool = false;
2019
...@@ -584,12 +583,18 @@ fn renderExpression(...@@ -584,12 +583,18 @@ fn renderExpression(
584 },583 },
585584
586 .Try,585 .Try,
587 .Await,
588 .Cancel,586 .Cancel,
589 .Resume,587 .Resume,
590 => {588 => {
591 try renderToken(tree, stream, prefix_op_node.op_token, indent, start_col, Space.Space);589 try renderToken(tree, stream, prefix_op_node.op_token, indent, start_col, Space.Space);
592 },590 },
591
592 .Await => |await_info| {
593 if (await_info.noasync_token) |tok| {
594 try renderToken(tree, stream, tok, indent, start_col, Space.Space);
595 }
596 try renderToken(tree, stream, prefix_op_node.op_token, indent, start_col, Space.Space);
597 },
593 }598 }
594599
595 return renderExpression(allocator, stream, tree, indent, start_col, prefix_op_node.rhs, space);600 return renderExpression(allocator, stream, tree, indent, start_col, prefix_op_node.rhs, space);
...@@ -1390,6 +1395,7 @@ fn renderExpression(...@@ -1390,6 +1395,7 @@ fn renderExpression(
1390 try renderToken(tree, stream, extern_export_inline_token, indent, start_col, Space.Space); // extern/export1395 try renderToken(tree, stream, extern_export_inline_token, indent, start_col, Space.Space); // extern/export
1391 } else {1396 } else {
1392 cc_rewrite_str = ".C";1397 cc_rewrite_str = ".C";
1398 fn_proto.lib_name = null;
1393 }1399 }
1394 }1400 }
13951401
lib/std/zig/system.zig created+163
...@@ -0,0 +1,163 @@
1const std = @import("../std.zig");
2const mem = std.mem;
3const Allocator = std.mem.Allocator;
4const ArrayList = std.ArrayList;
5const assert = std.debug.assert;
6const process = std.process;
7
8const is_windows = std.Target.current.isWindows();
9
10pub const NativePaths = struct {
11 include_dirs: ArrayList([:0]u8),
12 lib_dirs: ArrayList([:0]u8),
13 rpaths: ArrayList([:0]u8),
14 warnings: ArrayList([:0]u8),
15
16 pub fn detect(allocator: *Allocator) !NativePaths {
17 var self: NativePaths = .{
18 .include_dirs = ArrayList([:0]u8).init(allocator),
19 .lib_dirs = ArrayList([:0]u8).init(allocator),
20 .rpaths = ArrayList([:0]u8).init(allocator),
21 .warnings = ArrayList([:0]u8).init(allocator),
22 };
23 errdefer self.deinit();
24
25 var is_nix = false;
26 if (process.getEnvVarOwned(allocator, "NIX_CFLAGS_COMPILE")) |nix_cflags_compile| {
27 defer allocator.free(nix_cflags_compile);
28
29 is_nix = true;
30 var it = mem.tokenize(nix_cflags_compile, " ");
31 while (true) {
32 const word = it.next() orelse break;
33 if (mem.eql(u8, word, "-isystem")) {
34 const include_path = it.next() orelse {
35 try self.addWarning("Expected argument after -isystem in NIX_CFLAGS_COMPILE");
36 break;
37 };
38 try self.addIncludeDir(include_path);
39 } else {
40 try self.addWarningFmt("Unrecognized C flag from NIX_CFLAGS_COMPILE: {}", .{word});
41 break;
42 }
43 }
44 } else |err| switch (err) {
45 error.InvalidUtf8 => {},
46 error.EnvironmentVariableNotFound => {},
47 error.OutOfMemory => |e| return e,
48 }
49 if (process.getEnvVarOwned(allocator, "NIX_LDFLAGS")) |nix_ldflags| {
50 defer allocator.free(nix_ldflags);
51
52 is_nix = true;
53 var it = mem.tokenize(nix_ldflags, " ");
54 while (true) {
55 const word = it.next() orelse break;
56 if (mem.eql(u8, word, "-rpath")) {
57 const rpath = it.next() orelse {
58 try self.addWarning("Expected argument after -rpath in NIX_LDFLAGS");
59 break;
60 };
61 try self.addRPath(rpath);
62 } else if (word.len > 2 and word[0] == '-' and word[1] == 'L') {
63 const lib_path = word[2..];
64 try self.addLibDir(lib_path);
65 } else {
66 try self.addWarningFmt("Unrecognized C flag from NIX_LDFLAGS: {}", .{word});
67 break;
68 }
69 }
70 } else |err| switch (err) {
71 error.InvalidUtf8 => {},
72 error.EnvironmentVariableNotFound => {},
73 error.OutOfMemory => |e| return e,
74 }
75 if (is_nix) {
76 return self;
77 }
78
79 if (!is_windows) {
80 const triple = try std.Target.current.linuxTriple(allocator);
81
82 // TODO: $ ld --verbose | grep SEARCH_DIR
83 // the output contains some paths that end with lib64, maybe include them too?
84 // TODO: what is the best possible order of things?
85 // TODO: some of these are suspect and should only be added on some systems. audit needed.
86
87 try self.addIncludeDir("/usr/local/include");
88 try self.addLibDir("/usr/local/lib");
89 try self.addLibDir("/usr/local/lib64");
90
91 try self.addIncludeDirFmt("/usr/include/{}", .{triple});
92 try self.addLibDirFmt("/usr/lib/{}", .{triple});
93
94 try self.addIncludeDir("/usr/include");
95 try self.addLibDir("/lib");
96 try self.addLibDir("/lib64");
97 try self.addLibDir("/usr/lib");
98 try self.addLibDir("/usr/lib64");
99
100 // example: on a 64-bit debian-based linux distro, with zlib installed from apt:
101 // zlib.h is in /usr/include (added above)
102 // libz.so.1 is in /lib/x86_64-linux-gnu (added here)
103 try self.addLibDirFmt("/lib/{}", .{triple});
104 }
105
106 return self;
107 }
108
109 pub fn deinit(self: *NativePaths) void {
110 deinitArray(&self.include_dirs);
111 deinitArray(&self.lib_dirs);
112 deinitArray(&self.rpaths);
113 deinitArray(&self.warnings);
114 self.* = undefined;
115 }
116
117 fn deinitArray(array: *ArrayList([:0]u8)) void {
118 for (array.toSlice()) |item| {
119 array.allocator.free(item);
120 }
121 array.deinit();
122 }
123
124 pub fn addIncludeDir(self: *NativePaths, s: []const u8) !void {
125 return self.appendArray(&self.include_dirs, s);
126 }
127
128 pub fn addIncludeDirFmt(self: *NativePaths, comptime fmt: []const u8, args: var) !void {
129 const item = try std.fmt.allocPrint0(self.include_dirs.allocator, fmt, args);
130 errdefer self.include_dirs.allocator.free(item);
131 try self.include_dirs.append(item);
132 }
133
134 pub fn addLibDir(self: *NativePaths, s: []const u8) !void {
135 return self.appendArray(&self.lib_dirs, s);
136 }
137
138 pub fn addLibDirFmt(self: *NativePaths, comptime fmt: []const u8, args: var) !void {
139 const item = try std.fmt.allocPrint0(self.lib_dirs.allocator, fmt, args);
140 errdefer self.lib_dirs.allocator.free(item);
141 try self.lib_dirs.append(item);
142 }
143
144 pub fn addWarning(self: *NativePaths, s: []const u8) !void {
145 return self.appendArray(&self.warnings, s);
146 }
147
148 pub fn addWarningFmt(self: *NativePaths, comptime fmt: []const u8, args: var) !void {
149 const item = try std.fmt.allocPrint0(self.warnings.allocator, fmt, args);
150 errdefer self.warnings.allocator.free(item);
151 try self.warnings.append(item);
152 }
153
154 pub fn addRPath(self: *NativePaths, s: []const u8) !void {
155 return self.appendArray(&self.rpaths, s);
156 }
157
158 fn appendArray(self: *NativePaths, array: *ArrayList([:0]u8), s: []const u8) !void {
159 const item = try std.mem.dupeZ(array.allocator, u8, s);
160 errdefer array.allocator.free(item);
161 try array.append(item);
162 }
163};
lib/std/zig/tokenizer.zig+2-6
...@@ -414,10 +414,8 @@ pub const Tokenizer = struct {...@@ -414,10 +414,8 @@ pub const Tokenizer = struct {
414414
415 pub fn next(self: *Tokenizer) Token {415 pub fn next(self: *Tokenizer) Token {
416 if (self.pending_invalid_token) |token| {416 if (self.pending_invalid_token) |token| {
417 // TODO: Audit this pattern once #2915 is closed
418 const copy = token;
419 self.pending_invalid_token = null;417 self.pending_invalid_token = null;
420 return copy;418 return token;
421 }419 }
422 const start_index = self.index;420 const start_index = self.index;
423 var state = State.Start;421 var state = State.Start;
...@@ -1270,10 +1268,8 @@ pub const Tokenizer = struct {...@@ -1270,10 +1268,8 @@ pub const Tokenizer = struct {
12701268
1271 if (result.id == Token.Id.Eof) {1269 if (result.id == Token.Id.Eof) {
1272 if (self.pending_invalid_token) |token| {1270 if (self.pending_invalid_token) |token| {
1273 // TODO: Audit this pattern once #2915 is closed
1274 const copy = token;
1275 self.pending_invalid_token = null;1271 self.pending_invalid_token = null;
1276 return copy;1272 return token;
1277 }1273 }
1278 }1274 }
12791275
src-self-hosted/c.zig-1
...@@ -4,5 +4,4 @@ pub usingnamespace @cImport({...@@ -4,5 +4,4 @@ pub usingnamespace @cImport({
4 @cInclude("inttypes.h");4 @cInclude("inttypes.h");
5 @cInclude("config.h");5 @cInclude("config.h");
6 @cInclude("zig_llvm.h");6 @cInclude("zig_llvm.h");
7 @cInclude("windows_sdk.h");
8});7});
src-self-hosted/introspect.zig+8
...@@ -6,6 +6,14 @@ const fs = std.fs;...@@ -6,6 +6,14 @@ const fs = std.fs;
66
7const warn = std.debug.warn;7const warn = std.debug.warn;
88
9pub fn detectDynamicLinker(allocator: *mem.Allocator, target: std.Target) ![:0]u8 {
10 if (target == .Native) {
11 return @import("libc_installation.zig").detectNativeDynamicLinker(allocator);
12 } else {
13 return target.getStandardDynamicLinkerPath(allocator);
14 }
15}
16
9/// Caller must free result17/// Caller must free result
10pub fn testZigInstallPrefix(allocator: *mem.Allocator, test_path: []const u8) ![]u8 {18pub fn testZigInstallPrefix(allocator: *mem.Allocator, test_path: []const u8) ![]u8 {
11 const test_zig_dir = try fs.path.join(allocator, &[_][]const u8{ test_path, "lib", "zig" });19 const test_zig_dir = try fs.path.join(allocator, &[_][]const u8{ test_path, "lib", "zig" });
src-self-hosted/ir.zig+17-22
...@@ -76,20 +76,18 @@ pub const Inst = struct {...@@ -76,20 +76,18 @@ pub const Inst = struct {
76 }76 }
7777
78 pub fn typeToId(comptime T: type) Id {78 pub fn typeToId(comptime T: type) Id {
79 comptime var i = 0;79 inline for (@typeInfo(Id).Enum.fields) |f| {
80 inline while (i < @memberCount(Id)) : (i += 1) {80 if (T == @field(Inst, f.name)) {
81 if (T == @field(Inst, @memberName(Id, i))) {81 return @field(Id, f.name);
82 return @field(Id, @memberName(Id, i));
83 }82 }
84 }83 }
85 unreachable;84 unreachable;
86 }85 }
8786
88 pub fn dump(base: *const Inst) void {87 pub fn dump(base: *const Inst) void {
89 comptime var i = 0;88 inline for (@typeInfo(Id).Enum.fields) |f| {
90 inline while (i < @memberCount(Id)) : (i += 1) {89 if (base.id == @field(Id, f.name)) {
91 if (base.id == @field(Id, @memberName(Id, i))) {90 const T = @field(Inst, f.name);
92 const T = @field(Inst, @memberName(Id, i));
93 std.debug.warn("#{} = {}(", .{ base.debug_id, @tagName(base.id) });91 std.debug.warn("#{} = {}(", .{ base.debug_id, @tagName(base.id) });
94 @fieldParentPtr(T, "base", base).dump();92 @fieldParentPtr(T, "base", base).dump();
95 std.debug.warn(")", .{});93 std.debug.warn(")", .{});
...@@ -100,10 +98,9 @@ pub const Inst = struct {...@@ -100,10 +98,9 @@ pub const Inst = struct {
100 }98 }
10199
102 pub fn hasSideEffects(base: *const Inst) bool {100 pub fn hasSideEffects(base: *const Inst) bool {
103 comptime var i = 0;101 inline for (@typeInfo(Id).Enum.fields) |f| {
104 inline while (i < @memberCount(Id)) : (i += 1) {102 if (base.id == @field(Id, f.name)) {
105 if (base.id == @field(Id, @memberName(Id, i))) {103 const T = @field(Inst, f.name);
106 const T = @field(Inst, @memberName(Id, i));
107 return @fieldParentPtr(T, "base", base).hasSideEffects();104 return @fieldParentPtr(T, "base", base).hasSideEffects();
108 }105 }
109 }106 }
...@@ -1805,21 +1802,19 @@ pub const Builder = struct {...@@ -1805,21 +1802,19 @@ pub const Builder = struct {
1805 };1802 };
18061803
1807 // Look at the params and ref() other instructions1804 // Look at the params and ref() other instructions
1808 comptime var i = 0;1805 inline for (@typeInfo(I.Params).Struct.fields) |f| {
1809 inline while (i < @memberCount(I.Params)) : (i += 1) {1806 switch (f.fiedl_type) {
1810 const FieldType = comptime @TypeOf(@field(@as(I.Params, undefined), @memberName(I.Params, i)));1807 *Inst => @field(inst.params, f.name).ref(self),
1811 switch (FieldType) {1808 *BasicBlock => @field(inst.params, f.name).ref(self),
1812 *Inst => @field(inst.params, @memberName(I.Params, i)).ref(self),1809 ?*Inst => if (@field(inst.params, f.name)) |other| other.ref(self),
1813 *BasicBlock => @field(inst.params, @memberName(I.Params, i)).ref(self),
1814 ?*Inst => if (@field(inst.params, @memberName(I.Params, i))) |other| other.ref(self),
1815 []*Inst => {1810 []*Inst => {
1816 // TODO https://github.com/ziglang/zig/issues/12691811 // TODO https://github.com/ziglang/zig/issues/1269
1817 for (@field(inst.params, @memberName(I.Params, i))) |other|1812 for (@field(inst.params, f.name)) |other|
1818 other.ref(self);1813 other.ref(self);
1819 },1814 },
1820 []*BasicBlock => {1815 []*BasicBlock => {
1821 // TODO https://github.com/ziglang/zig/issues/12691816 // TODO https://github.com/ziglang/zig/issues/1269
1822 for (@field(inst.params, @memberName(I.Params, i))) |other|1817 for (@field(inst.params, f.name)) |other|
1823 other.ref(self);1818 other.ref(self);
1824 },1819 },
1825 Type.Pointer.Mut,1820 Type.Pointer.Mut,
...@@ -1831,7 +1826,7 @@ pub const Builder = struct {...@@ -1831,7 +1826,7 @@ pub const Builder = struct {
1831 => {},1826 => {},
1832 // it's ok to add more types here, just make sure that1827 // it's ok to add more types here, just make sure that
1833 // any instructions and basic blocks are ref'd appropriately1828 // any instructions and basic blocks are ref'd appropriately
1834 else => @compileError("unrecognized type in Params: " ++ @typeName(FieldType)),1829 else => @compileError("unrecognized type in Params: " ++ @typeName(f.field_type)),
1835 }1830 }
1836 }1831 }
18371832
src-self-hosted/libc_installation.zig+533-259
...@@ -1,20 +1,29 @@...@@ -1,20 +1,29 @@
1const std = @import("std");1const std = @import("std");
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const event = std.event;
4const util = @import("util.zig");3const util = @import("util.zig");
5const Target = std.Target;4const Target = std.Target;
6const c = @import("c.zig");
7const fs = std.fs;5const fs = std.fs;
8const Allocator = std.mem.Allocator;6const Allocator = std.mem.Allocator;
7const Batch = std.event.Batch;
8
9const is_darwin = Target.current.isDarwin();
10const is_windows = Target.current.isWindows();
11const is_freebsd = Target.current.isFreeBSD();
12const is_netbsd = Target.current.isNetBSD();
13const is_linux = Target.current.isLinux();
14const is_dragonfly = Target.current.isDragonFlyBSD();
15const is_gnu = Target.current.isGnu();
16
17usingnamespace @import("windows_sdk.zig");
918
10/// See the render function implementation for documentation of the fields.19/// See the render function implementation for documentation of the fields.
11pub const LibCInstallation = struct {20pub const LibCInstallation = struct {
12 include_dir: []const u8,21 include_dir: ?[:0]const u8 = null,
13 lib_dir: ?[]const u8,22 sys_include_dir: ?[:0]const u8 = null,
14 static_lib_dir: ?[]const u8,23 crt_dir: ?[:0]const u8 = null,
15 msvc_lib_dir: ?[]const u8,24 static_crt_dir: ?[:0]const u8 = null,
16 kernel32_lib_dir: ?[]const u8,25 msvc_lib_dir: ?[:0]const u8 = null,
17 dynamic_linker_path: ?[]const u8,26 kernel32_lib_dir: ?[:0]const u8 = null,
1827
19 pub const FindError = error{28 pub const FindError = error{
20 OutOfMemory,29 OutOfMemory,
...@@ -27,31 +36,24 @@ pub const LibCInstallation = struct {...@@ -27,31 +36,24 @@ pub const LibCInstallation = struct {
27 LibCStdLibHeaderNotFound,36 LibCStdLibHeaderNotFound,
28 LibCKernel32LibNotFound,37 LibCKernel32LibNotFound,
29 UnsupportedArchitecture,38 UnsupportedArchitecture,
39 WindowsSdkNotFound,
30 };40 };
3141
32 pub fn parse(42 pub fn parse(
33 self: *LibCInstallation,
34 allocator: *Allocator,43 allocator: *Allocator,
35 libc_file: []const u8,44 libc_file: []const u8,
36 stderr: *std.io.OutStream(fs.File.WriteError),45 stderr: *std.io.OutStream(fs.File.WriteError),
37 ) !void {46 ) !LibCInstallation {
38 self.initEmpty();47 var self: LibCInstallation = .{};
3948
40 const keys = [_][]const u8{49 const fields = std.meta.fields(LibCInstallation);
41 "include_dir",
42 "lib_dir",
43 "static_lib_dir",
44 "msvc_lib_dir",
45 "kernel32_lib_dir",
46 "dynamic_linker_path",
47 };
48 const FoundKey = struct {50 const FoundKey = struct {
49 found: bool,51 found: bool,
50 allocated: ?[]u8,52 allocated: ?[:0]u8,
51 };53 };
52 var found_keys = [1]FoundKey{FoundKey{ .found = false, .allocated = null }} ** keys.len;54 var found_keys = [1]FoundKey{FoundKey{ .found = false, .allocated = null }} ** fields.len;
53 errdefer {55 errdefer {
54 self.initEmpty();56 self = .{};
55 for (found_keys) |found_key| {57 for (found_keys) |found_key| {
56 if (found_key.allocated) |s| allocator.free(s);58 if (found_key.allocated) |s| allocator.free(s);
57 }59 }
...@@ -69,152 +71,216 @@ pub const LibCInstallation = struct {...@@ -69,152 +71,216 @@ pub const LibCInstallation = struct {
69 return error.ParseError;71 return error.ParseError;
70 };72 };
71 const value = line_it.rest();73 const value = line_it.rest();
72 inline for (keys) |key, i| {74 inline for (fields) |field, i| {
73 if (std.mem.eql(u8, name, key)) {75 if (std.mem.eql(u8, name, field.name)) {
74 found_keys[i].found = true;76 found_keys[i].found = true;
75 switch (@typeInfo(@TypeOf(@field(self, key)))) {77 if (value.len == 0) {
76 .Optional => {78 @field(self, field.name) = null;
77 if (value.len == 0) {79 } else {
78 @field(self, key) = null;80 found_keys[i].allocated = try std.mem.dupeZ(allocator, u8, value);
79 } else {81 @field(self, field.name) = found_keys[i].allocated;
80 found_keys[i].allocated = try std.mem.dupe(allocator, u8, value);
81 @field(self, key) = found_keys[i].allocated;
82 }
83 },
84 else => {
85 if (value.len == 0) {
86 try stderr.print("field cannot be empty: {}\n", .{key});
87 return error.ParseError;
88 }
89 const dupe = try std.mem.dupe(allocator, u8, value);
90 found_keys[i].allocated = dupe;
91 @field(self, key) = dupe;
92 },
93 }82 }
94 break;83 break;
95 }84 }
96 }85 }
97 }86 }
98 for (found_keys) |found_key, i| {87 inline for (fields) |field, i| {
99 if (!found_key.found) {88 if (!found_keys[i].found) {
100 try stderr.print("missing field: {}\n", .{keys[i]});89 try stderr.print("missing field: {}\n", .{field.name});
101 return error.ParseError;90 return error.ParseError;
102 }91 }
103 }92 }
93 if (self.include_dir == null) {
94 try stderr.print("include_dir may not be empty\n", .{});
95 return error.ParseError;
96 }
97 if (self.sys_include_dir == null) {
98 try stderr.print("sys_include_dir may not be empty\n", .{});
99 return error.ParseError;
100 }
101 if (self.crt_dir == null and !is_darwin) {
102 try stderr.print("crt_dir may not be empty for {}\n", .{@tagName(Target.current.getOs())});
103 return error.ParseError;
104 }
105 if (self.static_crt_dir == null and is_windows and is_gnu) {
106 try stderr.print("static_crt_dir may not be empty for {}-{}\n", .{
107 @tagName(Target.current.getOs()),
108 @tagName(Target.current.getAbi()),
109 });
110 return error.ParseError;
111 }
112 if (self.msvc_lib_dir == null and is_windows and !is_gnu) {
113 try stderr.print("msvc_lib_dir may not be empty for {}-{}\n", .{
114 @tagName(Target.current.getOs()),
115 @tagName(Target.current.getAbi()),
116 });
117 return error.ParseError;
118 }
119 if (self.kernel32_lib_dir == null and is_windows and !is_gnu) {
120 try stderr.print("kernel32_lib_dir may not be empty for {}-{}\n", .{
121 @tagName(Target.current.getOs()),
122 @tagName(Target.current.getAbi()),
123 });
124 return error.ParseError;
125 }
126
127 return self;
104 }128 }
105129
106 pub fn render(self: *const LibCInstallation, out: *std.io.OutStream(fs.File.WriteError)) !void {130 pub fn render(self: LibCInstallation, out: *std.io.OutStream(fs.File.WriteError)) !void {
107 @setEvalBranchQuota(4000);131 @setEvalBranchQuota(4000);
108 const lib_dir = self.lib_dir orelse "";132 const include_dir = self.include_dir orelse "";
109 const static_lib_dir = self.static_lib_dir orelse "";133 const sys_include_dir = self.sys_include_dir orelse "";
134 const crt_dir = self.crt_dir orelse "";
135 const static_crt_dir = self.static_crt_dir orelse "";
110 const msvc_lib_dir = self.msvc_lib_dir orelse "";136 const msvc_lib_dir = self.msvc_lib_dir orelse "";
111 const kernel32_lib_dir = self.kernel32_lib_dir orelse "";137 const kernel32_lib_dir = self.kernel32_lib_dir orelse "";
112 const dynamic_linker_path = self.dynamic_linker_path orelse util.getDynamicLinkerPath(Target{ .Native = {} });138
113 try out.print(139 try out.print(
114 \\# The directory that contains `stdlib.h`.140 \\# The directory that contains `stdlib.h`.
115 \\# On Linux, can be found with: `cc -E -Wp,-v -xc /dev/null`141 \\# On POSIX-like systems, include directories be found with: `cc -E -Wp,-v -xc /dev/null`
116 \\include_dir={}142 \\include_dir={}
117 \\143 \\
118 \\# The directory that contains `crt1.o`.144 \\# The system-specific include directory. May be the same as `include_dir`.
119 \\# On Linux, can be found with `cc -print-file-name=crt1.o`.145 \\# On Windows it's the directory that includes `vcruntime.h`.
146 \\# On POSIX it's the directory that includes `sys/errno.h`.
147 \\sys_include_dir={}
148 \\
149 \\# The directory that contains `crt1.o` or `crt2.o`.
150 \\# On POSIX, can be found with `cc -print-file-name=crt1.o`.
120 \\# Not needed when targeting MacOS.151 \\# Not needed when targeting MacOS.
121 \\lib_dir={}152 \\crt_dir={}
122 \\153 \\
123 \\# The directory that contains `crtbegin.o`.154 \\# The directory that contains `crtbegin.o`.
124 \\# On Linux, can be found with `cc -print-file-name=crtbegin.o`.155 \\# On POSIX, can be found with `cc -print-file-name=crtbegin.o`.
125 \\# Not needed when targeting MacOS or Windows.156 \\# Only needed when targeting MinGW-w64 on Windows.
126 \\static_lib_dir={}157 \\static_crt_dir={}
127 \\158 \\
128 \\# The directory that contains `vcruntime.lib`.159 \\# The directory that contains `vcruntime.lib`.
129 \\# Only needed when targeting Windows.160 \\# Only needed when targeting MSVC on Windows.
130 \\msvc_lib_dir={}161 \\msvc_lib_dir={}
131 \\162 \\
132 \\# The directory that contains `kernel32.lib`.163 \\# The directory that contains `kernel32.lib`.
133 \\# Only needed when targeting Windows.164 \\# Only needed when targeting MSVC on Windows.
134 \\kernel32_lib_dir={}165 \\kernel32_lib_dir={}
135 \\166 \\
136 \\# The full path to the dynamic linker, on the target system.167 , .{
137 \\# Only needed when targeting Linux.168 include_dir,
138 \\dynamic_linker_path={}169 sys_include_dir,
139 \\170 crt_dir,
140 , .{ self.include_dir, lib_dir, static_lib_dir, msvc_lib_dir, kernel32_lib_dir, dynamic_linker_path });171 static_crt_dir,
172 msvc_lib_dir,
173 kernel32_lib_dir,
174 });
141 }175 }
142176
177 pub const FindNativeOptions = struct {
178 allocator: *Allocator,
179
180 /// If enabled, will print human-friendly errors to stderr.
181 verbose: bool = false,
182 };
183
143 /// Finds the default, native libc.184 /// Finds the default, native libc.
144 pub fn findNative(self: *LibCInstallation, allocator: *Allocator) !void {185 pub fn findNative(args: FindNativeOptions) FindError!LibCInstallation {
145 self.initEmpty();186 var self: LibCInstallation = .{};
146 var group = event.Group(FindError!void).init(allocator);187
147 errdefer group.wait() catch {};188 if (is_windows) {
148 var windows_sdk: ?*c.ZigWindowsSDK = null;189 if (is_gnu) {
149 errdefer if (windows_sdk) |sdk| c.zig_free_windows_sdk(@ptrCast(?[*]c.ZigWindowsSDK, sdk));190 var batch = Batch(FindError!void, 3, .auto_async).init();
150191 batch.add(&async self.findNativeIncludeDirPosix(args));
151 switch (builtin.os) {192 batch.add(&async self.findNativeCrtDirPosix(args));
152 .windows => {193 batch.add(&async self.findNativeStaticCrtDirPosix(args));
153 var sdk: *c.ZigWindowsSDK = undefined;194 try batch.wait();
154 switch (c.zig_find_windows_sdk(@ptrCast(?[*]?[*]c.ZigWindowsSDK, &sdk))) {195 } else {
155 c.ZigFindWindowsSdkError.None => {196 var sdk: *ZigWindowsSDK = undefined;
156 windows_sdk = sdk;197 switch (zig_find_windows_sdk(&sdk)) {
157198 .None => {
158 if (sdk.msvc_lib_dir_ptr != 0) {199 defer zig_free_windows_sdk(sdk);
159 self.msvc_lib_dir = try std.mem.dupe(allocator, u8, sdk.msvc_lib_dir_ptr[0..sdk.msvc_lib_dir_len]);200
160 }201 var batch = Batch(FindError!void, 5, .auto_async).init();
161 try group.call(findNativeKernel32LibDir, .{ allocator, self, sdk });202 batch.add(&async self.findNativeMsvcIncludeDir(args, sdk));
162 try group.call(findNativeIncludeDirWindows, .{ self, allocator, sdk });203 batch.add(&async self.findNativeMsvcLibDir(args, sdk));
163 try group.call(findNativeLibDirWindows, .{ self, allocator, sdk });204 batch.add(&async self.findNativeKernel32LibDir(args, sdk));
205 batch.add(&async self.findNativeIncludeDirWindows(args, sdk));
206 batch.add(&async self.findNativeCrtDirWindows(args, sdk));
207 try batch.wait();
164 },208 },
165 c.ZigFindWindowsSdkError.OutOfMemory => return error.OutOfMemory,209 .OutOfMemory => return error.OutOfMemory,
166 c.ZigFindWindowsSdkError.NotFound => return error.NotFound,210 .NotFound => return error.WindowsSdkNotFound,
167 c.ZigFindWindowsSdkError.PathTooLong => return error.NotFound,211 .PathTooLong => return error.WindowsSdkNotFound,
168 }212 }
169 },213 }
170 .linux => {214 } else {
171 try group.call(findNativeIncludeDirLinux, .{ self, allocator });215 try blk: {
172 try group.call(findNativeLibDirLinux, .{ self, allocator });216 var batch = Batch(FindError!void, 2, .auto_async).init();
173 try group.call(findNativeStaticLibDir, .{ self, allocator });217 errdefer batch.wait() catch {};
174 try group.call(findNativeDynamicLinker, .{ self, allocator });218 batch.add(&async self.findNativeIncludeDirPosix(args));
175 },219 if (is_freebsd or is_netbsd) {
176 .macosx, .freebsd, .netbsd => {220 self.crt_dir = try std.mem.dupeZ(args.allocator, u8, "/usr/lib");
177 self.include_dir = try std.mem.dupe(allocator, u8, "/usr/include");221 } else if (is_linux or is_dragonfly) {
178 },222 batch.add(&async self.findNativeCrtDirPosix(args));
179 else => @compileError("unimplemented: find libc for this OS"),223 }
224 break :blk batch.wait();
225 };
226 }
227 return self;
228 }
229
230 /// Must be the same allocator passed to `parse` or `findNative`.
231 pub fn deinit(self: *LibCInstallation, allocator: *Allocator) void {
232 const fields = std.meta.fields(LibCInstallation);
233 inline for (fields) |field| {
234 if (@field(self, field.name)) |payload| {
235 allocator.free(payload);
236 }
180 }237 }
181 return group.wait();238 self.* = undefined;
182 }239 }
183240
184 async fn findNativeIncludeDirLinux(self: *LibCInstallation, allocator: *Allocator) FindError!void {241 fn findNativeIncludeDirPosix(self: *LibCInstallation, args: FindNativeOptions) FindError!void {
185 const cc_exe = std.os.getenv("CC") orelse "cc";242 const allocator = args.allocator;
243 const dev_null = if (is_windows) "nul" else "/dev/null";
244 const cc_exe = std.os.getenvZ("CC") orelse default_cc_exe;
186 const argv = [_][]const u8{245 const argv = [_][]const u8{
187 cc_exe,246 cc_exe,
188 "-E",247 "-E",
189 "-Wp,-v",248 "-Wp,-v",
190 "-xc",249 "-xc",
191 "/dev/null",250 dev_null,
192 };251 };
193 // TODO make this use event loop252 const exec_res = std.ChildProcess.exec2(.{
194 const errorable_result = std.ChildProcess.exec(allocator, &argv, null, null, 1024 * 1024);253 .allocator = allocator,
195 const exec_result = if (std.debug.runtime_safety) blk: {254 .argv = &argv,
196 break :blk errorable_result catch unreachable;255 .max_output_bytes = 1024 * 1024,
197 } else blk: {256 // Some C compilers, such as Clang, are known to rely on argv[0] to find the path
198 break :blk errorable_result catch |err| switch (err) {257 // to their own executable, without even bothering to resolve PATH. This results in the message:
199 error.OutOfMemory => return error.OutOfMemory,258 // error: unable to execute command: Executable "" doesn't exist!
200 else => return error.UnableToSpawnCCompiler,259 // So we use the expandArg0 variant of ChildProcess to give them a helping hand.
201 };260 .expand_arg0 = .expand,
261 }) catch |err| switch (err) {
262 error.OutOfMemory => return error.OutOfMemory,
263 else => {
264 printVerboseInvocation(&argv, null, args.verbose, null);
265 return error.UnableToSpawnCCompiler;
266 },
202 };267 };
203 defer {268 defer {
204 allocator.free(exec_result.stdout);269 allocator.free(exec_res.stdout);
205 allocator.free(exec_result.stderr);270 allocator.free(exec_res.stderr);
206 }271 }
207272 switch (exec_res.term) {
208 switch (exec_result.term) {273 .Exited => |code| if (code != 0) {
209 .Exited => |code| {274 printVerboseInvocation(&argv, null, args.verbose, exec_res.stderr);
210 if (code != 0) return error.CCompilerExitCode;275 return error.CCompilerExitCode;
211 },276 },
212 else => {277 else => {
278 printVerboseInvocation(&argv, null, args.verbose, exec_res.stderr);
213 return error.CCompilerCrashed;279 return error.CCompilerCrashed;
214 },280 },
215 }281 }
216282
217 var it = std.mem.tokenize(exec_result.stderr, "\n\r");283 var it = std.mem.tokenize(exec_res.stderr, "\n\r");
218 var search_paths = std.ArrayList([]const u8).init(allocator);284 var search_paths = std.ArrayList([]const u8).init(allocator);
219 defer search_paths.deinit();285 defer search_paths.deinit();
220 while (it.next()) |line| {286 while (it.next()) |line| {
...@@ -226,16 +292,44 @@ pub const LibCInstallation = struct {...@@ -226,16 +292,44 @@ pub const LibCInstallation = struct {
226 return error.CCompilerCannotFindHeaders;292 return error.CCompilerCannotFindHeaders;
227 }293 }
228294
229 // search in reverse order295 const include_dir_example_file = "stdlib.h";
296 const sys_include_dir_example_file = if (is_windows) "sys\\types.h" else "sys/errno.h";
297
230 var path_i: usize = 0;298 var path_i: usize = 0;
231 while (path_i < search_paths.len) : (path_i += 1) {299 while (path_i < search_paths.len) : (path_i += 1) {
300 // search in reverse order
232 const search_path_untrimmed = search_paths.at(search_paths.len - path_i - 1);301 const search_path_untrimmed = search_paths.at(search_paths.len - path_i - 1);
233 const search_path = std.mem.trimLeft(u8, search_path_untrimmed, " ");302 const search_path = std.mem.trimLeft(u8, search_path_untrimmed, " ");
234 const stdlib_path = try fs.path.join(allocator, &[_][]const u8{ search_path, "stdlib.h" });303 var search_dir = fs.cwd().openDirList(search_path) catch |err| switch (err) {
235 defer allocator.free(stdlib_path);304 error.FileNotFound,
305 error.NotDir,
306 error.NoDevice,
307 => continue,
308
309 else => return error.FileSystem,
310 };
311 defer search_dir.close();
312
313 if (self.include_dir == null) {
314 if (search_dir.accessZ(include_dir_example_file, .{})) |_| {
315 self.include_dir = try std.mem.dupeZ(allocator, u8, search_path);
316 } else |err| switch (err) {
317 error.FileNotFound => {},
318 else => return error.FileSystem,
319 }
320 }
321
322 if (self.sys_include_dir == null) {
323 if (search_dir.accessZ(sys_include_dir_example_file, .{})) |_| {
324 self.sys_include_dir = try std.mem.dupeZ(allocator, u8, search_path);
325 } else |err| switch (err) {
326 error.FileNotFound => {},
327 else => return error.FileSystem,
328 }
329 }
236330
237 if (try fileExists(stdlib_path)) {331 if (self.include_dir != null and self.sys_include_dir != null) {
238 self.include_dir = try std.mem.dupe(allocator, u8, search_path);332 // Success.
239 return;333 return;
240 }334 }
241 }335 }
...@@ -243,7 +337,13 @@ pub const LibCInstallation = struct {...@@ -243,7 +337,13 @@ pub const LibCInstallation = struct {
243 return error.LibCStdLibHeaderNotFound;337 return error.LibCStdLibHeaderNotFound;
244 }338 }
245339
246 async fn findNativeIncludeDirWindows(self: *LibCInstallation, allocator: *Allocator, sdk: *c.ZigWindowsSDK) !void {340 fn findNativeIncludeDirWindows(
341 self: *LibCInstallation,
342 args: FindNativeOptions,
343 sdk: *ZigWindowsSDK,
344 ) FindError!void {
345 const allocator = args.allocator;
346
247 var search_buf: [2]Search = undefined;347 var search_buf: [2]Search = undefined;
248 const searches = fillSearch(&search_buf, sdk);348 const searches = fillSearch(&search_buf, sdk);
249349
...@@ -255,180 +355,363 @@ pub const LibCInstallation = struct {...@@ -255,180 +355,363 @@ pub const LibCInstallation = struct {
255 const stream = &std.io.BufferOutStream.init(&result_buf).stream;355 const stream = &std.io.BufferOutStream.init(&result_buf).stream;
256 try stream.print("{}\\Include\\{}\\ucrt", .{ search.path, search.version });356 try stream.print("{}\\Include\\{}\\ucrt", .{ search.path, search.version });
257357
258 const stdlib_path = try fs.path.join(358 var dir = fs.cwd().openDirList(result_buf.toSliceConst()) catch |err| switch (err) {
259 allocator,359 error.FileNotFound,
260 [_][]const u8{ result_buf.toSliceConst(), "stdlib.h" },360 error.NotDir,
261 );361 error.NoDevice,
262 defer allocator.free(stdlib_path);362 => continue,
263363
264 if (try fileExists(stdlib_path)) {364 else => return error.FileSystem,
265 self.include_dir = result_buf.toOwnedSlice();365 };
266 return;366 defer dir.close();
267 }367
368 dir.accessZ("stdlib.h", .{}) catch |err| switch (err) {
369 error.FileNotFound => continue,
370 else => return error.FileSystem,
371 };
372
373 self.include_dir = result_buf.toOwnedSlice();
374 return;
268 }375 }
269376
270 return error.LibCStdLibHeaderNotFound;377 return error.LibCStdLibHeaderNotFound;
271 }378 }
272379
273 async fn findNativeLibDirWindows(self: *LibCInstallation, allocator: *Allocator, sdk: *c.ZigWindowsSDK) FindError!void {380 fn findNativeCrtDirWindows(
381 self: *LibCInstallation,
382 args: FindNativeOptions,
383 sdk: *ZigWindowsSDK,
384 ) FindError!void {
385 const allocator = args.allocator;
386
274 var search_buf: [2]Search = undefined;387 var search_buf: [2]Search = undefined;
275 const searches = fillSearch(&search_buf, sdk);388 const searches = fillSearch(&search_buf, sdk);
276389
277 var result_buf = try std.Buffer.initSize(allocator, 0);390 var result_buf = try std.Buffer.initSize(allocator, 0);
278 defer result_buf.deinit();391 defer result_buf.deinit();
279392
393 const arch_sub_dir = switch (builtin.arch) {
394 .i386 => "x86",
395 .x86_64 => "x64",
396 .arm, .armeb => "arm",
397 else => return error.UnsupportedArchitecture,
398 };
399
280 for (searches) |search| {400 for (searches) |search| {
281 result_buf.shrink(0);401 result_buf.shrink(0);
282 const stream = &std.io.BufferOutStream.init(&result_buf).stream;402 const stream = &std.io.BufferOutStream.init(&result_buf).stream;
283 try stream.print("{}\\Lib\\{}\\ucrt\\", .{ search.path, search.version });403 try stream.print("{}\\Lib\\{}\\ucrt\\{}", .{ search.path, search.version, arch_sub_dir });
284 switch (builtin.arch) {
285 .i386 => try stream.write("x86"),
286 .x86_64 => try stream.write("x64"),
287 .aarch64 => try stream.write("arm"),
288 else => return error.UnsupportedArchitecture,
289 }
290 const ucrt_lib_path = try fs.path.join(
291 allocator,
292 [_][]const u8{ result_buf.toSliceConst(), "ucrt.lib" },
293 );
294 defer allocator.free(ucrt_lib_path);
295 if (try fileExists(ucrt_lib_path)) {
296 self.lib_dir = result_buf.toOwnedSlice();
297 return;
298 }
299 }
300 return error.LibCRuntimeNotFound;
301 }
302404
303 async fn findNativeLibDirLinux(self: *LibCInstallation, allocator: *Allocator) FindError!void {405 var dir = fs.cwd().openDirList(result_buf.toSliceConst()) catch |err| switch (err) {
304 self.lib_dir = try ccPrintFileName(allocator, "crt1.o", true);406 error.FileNotFound,
305 }407 error.NotDir,
408 error.NoDevice,
409 => continue,
306410
307 async fn findNativeStaticLibDir(self: *LibCInstallation, allocator: *Allocator) FindError!void {411 else => return error.FileSystem,
308 self.static_lib_dir = try ccPrintFileName(allocator, "crtbegin.o", true);412 };
309 }413 defer dir.close();
310414
311 async fn findNativeDynamicLinker(self: *LibCInstallation, allocator: *Allocator) FindError!void {415 dir.accessZ("ucrt.lib", .{}) catch |err| switch (err) {
312 var dyn_tests = [_]DynTest{416 error.FileNotFound => continue,
313 DynTest{417 else => return error.FileSystem,
314 .name = "ld-linux-x86-64.so.2",418 };
315 .result = null,419
316 },420 self.crt_dir = result_buf.toOwnedSlice();
317 DynTest{421 return;
318 .name = "ld-musl-x86_64.so.1",
319 .result = null,
320 },
321 };
322 var group = event.Group(FindError!void).init(allocator);
323 errdefer group.wait() catch {};
324 for (dyn_tests) |*dyn_test| {
325 try group.call(testNativeDynamicLinker, .{ self, allocator, dyn_test });
326 }
327 try group.wait();
328 for (dyn_tests) |*dyn_test| {
329 if (dyn_test.result) |result| {
330 self.dynamic_linker_path = result;
331 return;
332 }
333 }422 }
423 return error.LibCRuntimeNotFound;
334 }424 }
335425
336 const DynTest = struct {426 fn findNativeCrtDirPosix(self: *LibCInstallation, args: FindNativeOptions) FindError!void {
337 name: []const u8,427 self.crt_dir = try ccPrintFileName(.{
338 result: ?[]const u8,428 .allocator = args.allocator,
339 };429 .search_basename = "crt1.o",
430 .want_dirname = .only_dir,
431 .verbose = args.verbose,
432 });
433 }
340434
341 async fn testNativeDynamicLinker(self: *LibCInstallation, allocator: *Allocator, dyn_test: *DynTest) FindError!void {435 fn findNativeStaticCrtDirPosix(self: *LibCInstallation, args: FindNativeOptions) FindError!void {
342 if (ccPrintFileName(allocator, dyn_test.name, false)) |result| {436 self.static_crt_dir = try ccPrintFileName(.{
343 dyn_test.result = result;437 .allocator = args.allocator,
344 return;438 .search_basename = "crtbegin.o",
345 } else |err| switch (err) {439 .want_dirname = .only_dir,
346 error.LibCRuntimeNotFound => return,440 .verbose = args.verbose,
347 else => return err,441 });
348 }
349 }442 }
350443
351 async fn findNativeKernel32LibDir(self: *LibCInstallation, allocator: *Allocator, sdk: *c.ZigWindowsSDK) FindError!void {444 fn findNativeKernel32LibDir(
445 self: *LibCInstallation,
446 args: FindNativeOptions,
447 sdk: *ZigWindowsSDK,
448 ) FindError!void {
449 const allocator = args.allocator;
450
352 var search_buf: [2]Search = undefined;451 var search_buf: [2]Search = undefined;
353 const searches = fillSearch(&search_buf, sdk);452 const searches = fillSearch(&search_buf, sdk);
354453
355 var result_buf = try std.Buffer.initSize(allocator, 0);454 var result_buf = try std.Buffer.initSize(allocator, 0);
356 defer result_buf.deinit();455 defer result_buf.deinit();
357456
457 const arch_sub_dir = switch (builtin.arch) {
458 .i386 => "x86",
459 .x86_64 => "x64",
460 .arm, .armeb => "arm",
461 else => return error.UnsupportedArchitecture,
462 };
463
358 for (searches) |search| {464 for (searches) |search| {
359 result_buf.shrink(0);465 result_buf.shrink(0);
360 const stream = &std.io.BufferOutStream.init(&result_buf).stream;466 const stream = &std.io.BufferOutStream.init(&result_buf).stream;
361 try stream.print("{}\\Lib\\{}\\um\\", .{ search.path, search.version });467 try stream.print("{}\\Lib\\{}\\um\\{}", .{ search.path, search.version, arch_sub_dir });
362 switch (builtin.arch) {468
363 .i386 => try stream.write("x86\\"),469 var dir = fs.cwd().openDirList(result_buf.toSliceConst()) catch |err| switch (err) {
364 .x86_64 => try stream.write("x64\\"),470 error.FileNotFound,
365 .aarch64 => try stream.write("arm\\"),471 error.NotDir,
366 else => return error.UnsupportedArchitecture,472 error.NoDevice,
367 }473 => continue,
368 const kernel32_path = try fs.path.join(474
369 allocator,475 else => return error.FileSystem,
370 [_][]const u8{ result_buf.toSliceConst(), "kernel32.lib" },476 };
371 );477 defer dir.close();
372 defer allocator.free(kernel32_path);478
373 if (try fileExists(kernel32_path)) {479 dir.accessZ("kernel32.lib", .{}) catch |err| switch (err) {
374 self.kernel32_lib_dir = result_buf.toOwnedSlice();480 error.FileNotFound => continue,
375 return;481 else => return error.FileSystem,
376 }482 };
483
484 self.kernel32_lib_dir = result_buf.toOwnedSlice();
485 return;
377 }486 }
378 return error.LibCKernel32LibNotFound;487 return error.LibCKernel32LibNotFound;
379 }488 }
380489
381 fn initEmpty(self: *LibCInstallation) void {490 fn findNativeMsvcIncludeDir(
382 self.* = LibCInstallation{491 self: *LibCInstallation,
383 .include_dir = @as([*]const u8, undefined)[0..0],492 args: FindNativeOptions,
384 .lib_dir = null,493 sdk: *ZigWindowsSDK,
385 .static_lib_dir = null,494 ) FindError!void {
386 .msvc_lib_dir = null,495 const allocator = args.allocator;
387 .kernel32_lib_dir = null,496
388 .dynamic_linker_path = null,497 const msvc_lib_dir_ptr = sdk.msvc_lib_dir_ptr orelse return error.LibCStdLibHeaderNotFound;
498 const msvc_lib_dir = msvc_lib_dir_ptr[0..sdk.msvc_lib_dir_len];
499 const up1 = fs.path.dirname(msvc_lib_dir) orelse return error.LibCStdLibHeaderNotFound;
500 const up2 = fs.path.dirname(up1) orelse return error.LibCStdLibHeaderNotFound;
501
502 var result_buf = try std.Buffer.init(allocator, up2);
503 defer result_buf.deinit();
504
505 try result_buf.append("\\include");
506
507 var dir = fs.cwd().openDirList(result_buf.toSliceConst()) catch |err| switch (err) {
508 error.FileNotFound,
509 error.NotDir,
510 error.NoDevice,
511 => return error.LibCStdLibHeaderNotFound,
512
513 else => return error.FileSystem,
514 };
515 defer dir.close();
516
517 dir.accessZ("vcruntime.h", .{}) catch |err| switch (err) {
518 error.FileNotFound => return error.LibCStdLibHeaderNotFound,
519 else => return error.FileSystem,
389 };520 };
521
522 self.sys_include_dir = result_buf.toOwnedSlice();
523 }
524
525 fn findNativeMsvcLibDir(
526 self: *LibCInstallation,
527 args: FindNativeOptions,
528 sdk: *ZigWindowsSDK,
529 ) FindError!void {
530 const allocator = args.allocator;
531 const msvc_lib_dir_ptr = sdk.msvc_lib_dir_ptr orelse return error.LibCRuntimeNotFound;
532 self.msvc_lib_dir = try std.mem.dupeZ(allocator, u8, msvc_lib_dir_ptr[0..sdk.msvc_lib_dir_len]);
390 }533 }
391};534};
392535
536const default_cc_exe = if (is_windows) "cc.exe" else "cc";
537
538pub const CCPrintFileNameOptions = struct {
539 allocator: *Allocator,
540 search_basename: []const u8,
541 want_dirname: enum { full_path, only_dir },
542 verbose: bool = false,
543};
544
393/// caller owns returned memory545/// caller owns returned memory
394fn ccPrintFileName(allocator: *Allocator, o_file: []const u8, want_dirname: bool) ![]u8 {546fn ccPrintFileName(args: CCPrintFileNameOptions) ![:0]u8 {
395 const cc_exe = std.os.getenv("CC") orelse "cc";547 const allocator = args.allocator;
396 const arg1 = try std.fmt.allocPrint(allocator, "-print-file-name={}", .{o_file});548
549 const cc_exe = std.os.getenvZ("CC") orelse default_cc_exe;
550 const arg1 = try std.fmt.allocPrint(allocator, "-print-file-name={}", .{args.search_basename});
397 defer allocator.free(arg1);551 defer allocator.free(arg1);
398 const argv = [_][]const u8{ cc_exe, arg1 };552 const argv = [_][]const u8{ cc_exe, arg1 };
399553
400 // TODO This simulates evented I/O for the child process exec554 const exec_res = std.ChildProcess.exec2(.{
401 event.Loop.startCpuBoundOperation();555 .allocator = allocator,
402 const errorable_result = std.ChildProcess.exec(allocator, &argv, null, null, 1024 * 1024);556 .argv = &argv,
403 const exec_result = if (std.debug.runtime_safety) blk: {557 .max_output_bytes = 1024 * 1024,
404 break :blk errorable_result catch unreachable;558 // Some C compilers, such as Clang, are known to rely on argv[0] to find the path
405 } else blk: {559 // to their own executable, without even bothering to resolve PATH. This results in the message:
406 break :blk errorable_result catch |err| switch (err) {560 // error: unable to execute command: Executable "" doesn't exist!
407 error.OutOfMemory => return error.OutOfMemory,561 // So we use the expandArg0 variant of ChildProcess to give them a helping hand.
408 else => return error.UnableToSpawnCCompiler,562 .expand_arg0 = .expand,
409 };563 }) catch |err| switch (err) {
564 error.OutOfMemory => return error.OutOfMemory,
565 else => return error.UnableToSpawnCCompiler,
410 };566 };
411 defer {567 defer {
412 allocator.free(exec_result.stdout);568 allocator.free(exec_res.stdout);
413 allocator.free(exec_result.stderr);569 allocator.free(exec_res.stderr);
414 }570 }
415 switch (exec_result.term) {571 switch (exec_res.term) {
416 .Exited => |code| {572 .Exited => |code| if (code != 0) {
417 if (code != 0) return error.CCompilerExitCode;573 printVerboseInvocation(&argv, args.search_basename, args.verbose, exec_res.stderr);
574 return error.CCompilerExitCode;
418 },575 },
419 else => {576 else => {
577 printVerboseInvocation(&argv, args.search_basename, args.verbose, exec_res.stderr);
420 return error.CCompilerCrashed;578 return error.CCompilerCrashed;
421 },579 },
422 }580 }
423 var it = std.mem.tokenize(exec_result.stdout, "\n\r");581
582 var it = std.mem.tokenize(exec_res.stdout, "\n\r");
424 const line = it.next() orelse return error.LibCRuntimeNotFound;583 const line = it.next() orelse return error.LibCRuntimeNotFound;
425 const dirname = fs.path.dirname(line) orelse return error.LibCRuntimeNotFound;584 // When this command fails, it returns exit code 0 and duplicates the input file name.
585 // So we detect failure by checking if the output matches exactly the input.
586 if (std.mem.eql(u8, line, args.search_basename)) return error.LibCRuntimeNotFound;
587 switch (args.want_dirname) {
588 .full_path => return std.mem.dupeZ(allocator, u8, line),
589 .only_dir => {
590 const dirname = fs.path.dirname(line) orelse return error.LibCRuntimeNotFound;
591 return std.mem.dupeZ(allocator, u8, dirname);
592 },
593 }
594}
595
596fn printVerboseInvocation(
597 argv: []const []const u8,
598 search_basename: ?[]const u8,
599 verbose: bool,
600 stderr: ?[]const u8,
601) void {
602 if (!verbose) return;
426603
427 if (want_dirname) {604 if (search_basename) |s| {
428 return std.mem.dupe(allocator, u8, dirname);605 std.debug.warn("Zig attempted to find the file '{}' by executing this command:\n", .{s});
429 } else {606 } else {
430 return std.mem.dupe(allocator, u8, line);607 std.debug.warn("Zig attempted to find the path to native system libc headers by executing this command:\n", .{});
608 }
609 for (argv) |arg, i| {
610 if (i != 0) std.debug.warn(" ", .{});
611 std.debug.warn("{}", .{arg});
612 }
613 std.debug.warn("\n", .{});
614 if (stderr) |s| {
615 std.debug.warn("Output:\n==========\n{}\n==========\n", .{s});
616 }
617}
618
619/// Caller owns returned memory.
620pub fn detectNativeDynamicLinker(allocator: *Allocator) error{
621 OutOfMemory,
622 TargetHasNoDynamicLinker,
623 UnknownDynamicLinkerPath,
624}![:0]u8 {
625 if (!comptime Target.current.hasDynamicLinker()) {
626 return error.TargetHasNoDynamicLinker;
627 }
628
629 // The current target's ABI cannot be relied on for this. For example, we may build the zig
630 // compiler for target riscv64-linux-musl and provide a tarball for users to download.
631 // A user could then run that zig compiler on riscv64-linux-gnu. This use case is well-defined
632 // and supported by Zig. But that means that we must detect the system ABI here rather than
633 // relying on `std.Target.current`.
634
635 const LdInfo = struct {
636 ld_path: []u8,
637 abi: Target.Abi,
638 };
639 var ld_info_list = std.ArrayList(LdInfo).init(allocator);
640 defer {
641 for (ld_info_list.toSlice()) |ld_info| allocator.free(ld_info.ld_path);
642 ld_info_list.deinit();
643 }
644
645 const all_abis = comptime blk: {
646 const fields = std.meta.fields(Target.Abi);
647 var array: [fields.len]Target.Abi = undefined;
648 inline for (fields) |field, i| {
649 array[i] = @field(Target.Abi, field.name);
650 }
651 break :blk array;
652 };
653 for (all_abis) |abi| {
654 // This may be a nonsensical parameter. We detect this with error.UnknownDynamicLinkerPath and
655 // skip adding it to `ld_info_list`.
656 const target: Target = .{
657 .Cross = .{
658 .cpu = Target.Cpu.baseline(Target.current.getArch()),
659 .os = Target.current.getOs(),
660 .abi = abi,
661 },
662 };
663 const standard_ld_path = target.getStandardDynamicLinkerPath(allocator) catch |err| switch (err) {
664 error.OutOfMemory => return error.OutOfMemory,
665 error.UnknownDynamicLinkerPath, error.TargetHasNoDynamicLinker => continue,
666 };
667 errdefer allocator.free(standard_ld_path);
668 try ld_info_list.append(.{
669 .ld_path = standard_ld_path,
670 .abi = abi,
671 });
672 }
673
674 // Best case scenario: the zig compiler is dynamically linked, and we can iterate
675 // over our own shared objects and find a dynamic linker.
676 {
677 const lib_paths = try std.process.getSelfExeSharedLibPaths(allocator);
678 defer allocator.free(lib_paths);
679
680 // This is O(N^M) but typical case here is N=2 and M=10.
681 for (lib_paths) |lib_path| {
682 for (ld_info_list.toSlice()) |ld_info| {
683 const standard_ld_basename = fs.path.basename(ld_info.ld_path);
684 if (std.mem.endsWith(u8, lib_path, standard_ld_basename)) {
685 return std.mem.dupeZ(allocator, u8, lib_path);
686 }
687 }
688 }
689 }
690
691 // If Zig is statically linked, such as via distributed binary static builds, the above
692 // trick won't work. What are we left with? Try to run the system C compiler and get
693 // it to tell us the dynamic linker path.
694 // TODO: instead of this, look at the shared libs of /usr/bin/env.
695 for (ld_info_list.toSlice()) |ld_info| {
696 const standard_ld_basename = fs.path.basename(ld_info.ld_path);
697
698 const full_ld_path = ccPrintFileName(.{
699 .allocator = allocator,
700 .search_basename = standard_ld_basename,
701 .want_dirname = .full_path,
702 }) catch |err| switch (err) {
703 error.OutOfMemory => return error.OutOfMemory,
704 error.LibCRuntimeNotFound,
705 error.CCompilerExitCode,
706 error.CCompilerCrashed,
707 error.UnableToSpawnCCompiler,
708 => continue,
709 };
710 return full_ld_path;
431 }711 }
712
713 // Finally, we fall back on the standard path.
714 return Target.current.getStandardDynamicLinkerPath(allocator);
432}715}
433716
434const Search = struct {717const Search = struct {
...@@ -436,34 +719,25 @@ const Search = struct {...@@ -436,34 +719,25 @@ const Search = struct {
436 version: []const u8,719 version: []const u8,
437};720};
438721
439fn fillSearch(search_buf: *[2]Search, sdk: *c.ZigWindowsSDK) []Search {722fn fillSearch(search_buf: *[2]Search, sdk: *ZigWindowsSDK) []Search {
440 var search_end: usize = 0;723 var search_end: usize = 0;
441 if (sdk.path10_ptr != 0) {724 if (sdk.path10_ptr) |path10_ptr| {
442 if (sdk.version10_ptr != 0) {725 if (sdk.version10_ptr) |version10_ptr| {
443 search_buf[search_end] = Search{726 search_buf[search_end] = Search{
444 .path = sdk.path10_ptr[0..sdk.path10_len],727 .path = path10_ptr[0..sdk.path10_len],
445 .version = sdk.version10_ptr[0..sdk.version10_len],728 .version = version10_ptr[0..sdk.version10_len],
446 };729 };
447 search_end += 1;730 search_end += 1;
448 }731 }
449 }732 }
450 if (sdk.path81_ptr != 0) {733 if (sdk.path81_ptr) |path81_ptr| {
451 if (sdk.version81_ptr != 0) {734 if (sdk.version81_ptr) |version81_ptr| {
452 search_buf[search_end] = Search{735 search_buf[search_end] = Search{
453 .path = sdk.path81_ptr[0..sdk.path81_len],736 .path = path81_ptr[0..sdk.path81_len],
454 .version = sdk.version81_ptr[0..sdk.version81_len],737 .version = version81_ptr[0..sdk.version81_len],
455 };738 };
456 search_end += 1;739 search_end += 1;
457 }740 }
458 }741 }
459 return search_buf[0..search_end];742 return search_buf[0..search_end];
460}743}
461
462fn fileExists(path: []const u8) !bool {
463 if (fs.File.access(path)) |_| {
464 return true;
465 } else |err| switch (err) {
466 error.FileNotFound => return false,
467 else => return error.FileSystem,
468 }
469}
src-self-hosted/print_targets.zig+34-50
...@@ -113,37 +113,14 @@ pub fn cmdTargets(...@@ -113,37 +113,14 @@ pub fn cmdTargets(
113 try jws.beginObject();113 try jws.beginObject();
114114
115 try jws.objectField("arch");115 try jws.objectField("arch");
116 try jws.beginObject();116 try jws.beginArray();
117 {117 {
118 inline for (@typeInfo(Target.Arch).Union.fields) |field| {118 inline for (@typeInfo(Target.Cpu.Arch).Enum.fields) |field| {
119 try jws.objectField(field.name);
120 if (field.field_type == void) {
121 try jws.emitNull();
122 } else {
123 try jws.emitString(@typeName(field.field_type));
124 }
125 }
126 }
127 try jws.endObject();
128
129 try jws.objectField("subArch");
130 try jws.beginObject();
131 const sub_arch_list = [_]type{
132 Target.Arch.Arm32,
133 Target.Arch.Arm64,
134 Target.Arch.Kalimba,
135 Target.Arch.Mips,
136 };
137 inline for (sub_arch_list) |SubArch| {
138 try jws.objectField(@typeName(SubArch));
139 try jws.beginArray();
140 inline for (@typeInfo(SubArch).Enum.fields) |field| {
141 try jws.arrayElem();119 try jws.arrayElem();
142 try jws.emitString(field.name);120 try jws.emitString(field.name);
143 }121 }
144 try jws.endArray();
145 }122 }
146 try jws.endObject();123 try jws.endArray();
147124
148 try jws.objectField("os");125 try jws.objectField("os");
149 try jws.beginArray();126 try jws.beginArray();
...@@ -179,15 +156,15 @@ pub fn cmdTargets(...@@ -179,15 +156,15 @@ pub fn cmdTargets(
179156
180 try jws.objectField("cpus");157 try jws.objectField("cpus");
181 try jws.beginObject();158 try jws.beginObject();
182 inline for (@typeInfo(Target.Arch).Union.fields) |field| {159 inline for (@typeInfo(Target.Cpu.Arch).Enum.fields) |field| {
183 try jws.objectField(field.name);160 try jws.objectField(field.name);
184 try jws.beginObject();161 try jws.beginObject();
185 const arch = @unionInit(Target.Arch, field.name, undefined);162 const arch = @field(Target.Cpu.Arch, field.name);
186 for (arch.allCpus()) |cpu| {163 for (arch.allCpuModels()) |model| {
187 try jws.objectField(cpu.name);164 try jws.objectField(model.name);
188 try jws.beginArray();165 try jws.beginArray();
189 for (arch.allFeaturesList()) |feature, i| {166 for (arch.allFeaturesList()) |feature, i| {
190 if (cpu.features.isEnabled(@intCast(u8, i))) {167 if (model.features.isEnabled(@intCast(u8, i))) {
191 try jws.arrayElem();168 try jws.arrayElem();
192 try jws.emitString(feature.name);169 try jws.emitString(feature.name);
193 }170 }
...@@ -200,10 +177,10 @@ pub fn cmdTargets(...@@ -200,10 +177,10 @@ pub fn cmdTargets(
200177
201 try jws.objectField("cpuFeatures");178 try jws.objectField("cpuFeatures");
202 try jws.beginObject();179 try jws.beginObject();
203 inline for (@typeInfo(Target.Arch).Union.fields) |field| {180 inline for (@typeInfo(Target.Cpu.Arch).Enum.fields) |field| {
204 try jws.objectField(field.name);181 try jws.objectField(field.name);
205 try jws.beginArray();182 try jws.beginArray();
206 const arch = @unionInit(Target.Arch, field.name, undefined);183 const arch = @field(Target.Cpu.Arch, field.name);
207 for (arch.allFeaturesList()) |feature| {184 for (arch.allFeaturesList()) |feature| {
208 try jws.arrayElem();185 try jws.arrayElem();
209 try jws.emitString(feature.name);186 try jws.emitString(feature.name);
...@@ -220,27 +197,34 @@ pub fn cmdTargets(...@@ -220,27 +197,34 @@ pub fn cmdTargets(
220 try jws.objectField("triple");197 try jws.objectField("triple");
221 try jws.emitString(triple);198 try jws.emitString(triple);
222 }199 }
223 try jws.objectField("arch");
224 try jws.emitString(@tagName(native_target.getArch()));
225 try jws.objectField("os");
226 try jws.emitString(@tagName(native_target.getOs()));
227 try jws.objectField("abi");
228 try jws.emitString(@tagName(native_target.getAbi()));
229 try jws.objectField("cpuName");
230 const cpu_features = native_target.getCpuFeatures();
231 try jws.emitString(cpu_features.cpu.name);
232 {200 {
233 try jws.objectField("cpuFeatures");201 try jws.objectField("cpu");
234 try jws.beginArray();202 try jws.beginObject();
235 for (native_target.getArch().allFeaturesList()) |feature, i_usize| {203 try jws.objectField("arch");
236 const index = @intCast(Target.Cpu.Feature.Set.Index, i_usize);204 try jws.emitString(@tagName(native_target.getArch()));
237 if (cpu_features.features.isEnabled(index)) {205
238 try jws.arrayElem();206 try jws.objectField("name");
239 try jws.emitString(feature.name);207 const cpu = native_target.getCpu();
208 try jws.emitString(cpu.model.name);
209
210 {
211 try jws.objectField("features");
212 try jws.beginArray();
213 for (native_target.getArch().allFeaturesList()) |feature, i_usize| {
214 const index = @intCast(Target.Cpu.Feature.Set.Index, i_usize);
215 if (cpu.features.isEnabled(index)) {
216 try jws.arrayElem();
217 try jws.emitString(feature.name);
218 }
240 }219 }
220 try jws.endArray();
241 }221 }
242 try jws.endArray();222 try jws.endObject();
243 }223 }
224 try jws.objectField("os");
225 try jws.emitString(@tagName(native_target.getOs()));
226 try jws.objectField("abi");
227 try jws.emitString(@tagName(native_target.getAbi()));
244 // TODO implement native glibc version detection in self-hosted228 // TODO implement native glibc version detection in self-hosted
245 try jws.endObject();229 try jws.endObject();
246230
src-self-hosted/stage1.zig deleted-832
...@@ -1,832 +0,0 @@
1// This is Zig code that is used by both stage1 and stage2.
2// The prototypes in src/userland.h must match these definitions.
3
4const std = @import("std");
5const io = std.io;
6const mem = std.mem;
7const fs = std.fs;
8const process = std.process;
9const Allocator = mem.Allocator;
10const ArrayList = std.ArrayList;
11const Buffer = std.Buffer;
12const Target = std.Target;
13const self_hosted_main = @import("main.zig");
14const errmsg = @import("errmsg.zig");
15const DepTokenizer = @import("dep_tokenizer.zig").Tokenizer;
16const assert = std.debug.assert;
17
18var stderr_file: fs.File = undefined;
19var stderr: *io.OutStream(fs.File.WriteError) = undefined;
20var stdout: *io.OutStream(fs.File.WriteError) = undefined;
21
22comptime {
23 _ = @import("dep_tokenizer.zig");
24}
25
26// ABI warning
27export fn stage2_zen(ptr: *[*]const u8, len: *usize) void {
28 const info_zen = @import("main.zig").info_zen;
29 ptr.* = info_zen;
30 len.* = info_zen.len;
31}
32
33// ABI warning
34export fn stage2_panic(ptr: [*]const u8, len: usize) void {
35 @panic(ptr[0..len]);
36}
37
38// ABI warning
39const Error = extern enum {
40 None,
41 OutOfMemory,
42 InvalidFormat,
43 SemanticAnalyzeFail,
44 AccessDenied,
45 Interrupted,
46 SystemResources,
47 FileNotFound,
48 FileSystem,
49 FileTooBig,
50 DivByZero,
51 Overflow,
52 PathAlreadyExists,
53 Unexpected,
54 ExactDivRemainder,
55 NegativeDenominator,
56 ShiftedOutOneBits,
57 CCompileErrors,
58 EndOfFile,
59 IsDir,
60 NotDir,
61 UnsupportedOperatingSystem,
62 SharingViolation,
63 PipeBusy,
64 PrimitiveTypeNotFound,
65 CacheUnavailable,
66 PathTooLong,
67 CCompilerCannotFindFile,
68 NoCCompilerInstalled,
69 ReadingDepFile,
70 InvalidDepFile,
71 MissingArchitecture,
72 MissingOperatingSystem,
73 UnknownArchitecture,
74 UnknownOperatingSystem,
75 UnknownABI,
76 InvalidFilename,
77 DiskQuota,
78 DiskSpace,
79 UnexpectedWriteFailure,
80 UnexpectedSeekFailure,
81 UnexpectedFileTruncationFailure,
82 Unimplemented,
83 OperationAborted,
84 BrokenPipe,
85 NoSpaceLeft,
86 NotLazy,
87 IsAsync,
88 ImportOutsidePkgPath,
89 UnknownCpu,
90 UnknownSubArchitecture,
91 UnknownCpuFeature,
92 InvalidCpuFeatures,
93 InvalidLlvmCpuFeaturesFormat,
94 UnknownApplicationBinaryInterface,
95};
96
97const FILE = std.c.FILE;
98const ast = std.zig.ast;
99const translate_c = @import("translate_c.zig");
100
101/// Args should have a null terminating last arg.
102export fn stage2_translate_c(
103 out_ast: **ast.Tree,
104 out_errors_ptr: *[*]translate_c.ClangErrMsg,
105 out_errors_len: *usize,
106 args_begin: [*]?[*]const u8,
107 args_end: [*]?[*]const u8,
108 resources_path: [*:0]const u8,
109) Error {
110 var errors = @as([*]translate_c.ClangErrMsg, undefined)[0..0];
111 out_ast.* = translate_c.translate(std.heap.c_allocator, args_begin, args_end, &errors, resources_path) catch |err| switch (err) {
112 error.SemanticAnalyzeFail => {
113 out_errors_ptr.* = errors.ptr;
114 out_errors_len.* = errors.len;
115 return Error.CCompileErrors;
116 },
117 error.OutOfMemory => return Error.OutOfMemory,
118 };
119 return Error.None;
120}
121
122export fn stage2_free_clang_errors(errors_ptr: [*]translate_c.ClangErrMsg, errors_len: usize) void {
123 translate_c.freeErrors(errors_ptr[0..errors_len]);
124}
125
126export fn stage2_render_ast(tree: *ast.Tree, output_file: *FILE) Error {
127 const c_out_stream = &std.io.COutStream.init(output_file).stream;
128 _ = std.zig.render(std.heap.c_allocator, c_out_stream, tree) catch |e| switch (e) {
129 error.WouldBlock => unreachable, // stage1 opens stuff in exclusively blocking mode
130 error.SystemResources => return Error.SystemResources,
131 error.OperationAborted => return Error.OperationAborted,
132 error.BrokenPipe => return Error.BrokenPipe,
133 error.DiskQuota => return Error.DiskQuota,
134 error.FileTooBig => return Error.FileTooBig,
135 error.NoSpaceLeft => return Error.NoSpaceLeft,
136 error.AccessDenied => return Error.AccessDenied,
137 error.OutOfMemory => return Error.OutOfMemory,
138 error.Unexpected => return Error.Unexpected,
139 error.InputOutput => return Error.FileSystem,
140 };
141 return Error.None;
142}
143
144// TODO: just use the actual self-hosted zig fmt. Until https://github.com/ziglang/zig/issues/2377,
145// we use a blocking implementation.
146export fn stage2_fmt(argc: c_int, argv: [*]const [*:0]const u8) c_int {
147 if (std.debug.runtime_safety) {
148 fmtMain(argc, argv) catch unreachable;
149 } else {
150 fmtMain(argc, argv) catch |e| {
151 std.debug.warn("{}\n", .{@errorName(e)});
152 return -1;
153 };
154 }
155 return 0;
156}
157
158fn fmtMain(argc: c_int, argv: [*]const [*:0]const u8) !void {
159 const allocator = std.heap.c_allocator;
160 var args_list = std.ArrayList([]const u8).init(allocator);
161 const argc_usize = @intCast(usize, argc);
162 var arg_i: usize = 0;
163 while (arg_i < argc_usize) : (arg_i += 1) {
164 try args_list.append(mem.toSliceConst(u8, argv[arg_i]));
165 }
166
167 stdout = &std.io.getStdOut().outStream().stream;
168 stderr_file = std.io.getStdErr();
169 stderr = &stderr_file.outStream().stream;
170
171 const args = args_list.toSliceConst()[2..];
172
173 var color: errmsg.Color = .Auto;
174 var stdin_flag: bool = false;
175 var check_flag: bool = false;
176 var input_files = ArrayList([]const u8).init(allocator);
177
178 {
179 var i: usize = 0;
180 while (i < args.len) : (i += 1) {
181 const arg = args[i];
182 if (mem.startsWith(u8, arg, "-")) {
183 if (mem.eql(u8, arg, "--help")) {
184 try stdout.write(self_hosted_main.usage_fmt);
185 process.exit(0);
186 } else if (mem.eql(u8, arg, "--color")) {
187 if (i + 1 >= args.len) {
188 try stderr.write("expected [auto|on|off] after --color\n");
189 process.exit(1);
190 }
191 i += 1;
192 const next_arg = args[i];
193 if (mem.eql(u8, next_arg, "auto")) {
194 color = .Auto;
195 } else if (mem.eql(u8, next_arg, "on")) {
196 color = .On;
197 } else if (mem.eql(u8, next_arg, "off")) {
198 color = .Off;
199 } else {
200 try stderr.print("expected [auto|on|off] after --color, found '{}'\n", .{next_arg});
201 process.exit(1);
202 }
203 } else if (mem.eql(u8, arg, "--stdin")) {
204 stdin_flag = true;
205 } else if (mem.eql(u8, arg, "--check")) {
206 check_flag = true;
207 } else {
208 try stderr.print("unrecognized parameter: '{}'", .{arg});
209 process.exit(1);
210 }
211 } else {
212 try input_files.append(arg);
213 }
214 }
215 }
216
217 if (stdin_flag) {
218 if (input_files.len != 0) {
219 try stderr.write("cannot use --stdin with positional arguments\n");
220 process.exit(1);
221 }
222
223 const stdin_file = io.getStdIn();
224 var stdin = stdin_file.inStream();
225
226 const source_code = try stdin.stream.readAllAlloc(allocator, self_hosted_main.max_src_size);
227 defer allocator.free(source_code);
228
229 const tree = std.zig.parse(allocator, source_code) catch |err| {
230 try stderr.print("error parsing stdin: {}\n", .{err});
231 process.exit(1);
232 };
233 defer tree.deinit();
234
235 var error_it = tree.errors.iterator(0);
236 while (error_it.next()) |parse_error| {
237 try printErrMsgToFile(allocator, parse_error, tree, "<stdin>", stderr_file, color);
238 }
239 if (tree.errors.len != 0) {
240 process.exit(1);
241 }
242 if (check_flag) {
243 const anything_changed = try std.zig.render(allocator, io.null_out_stream, tree);
244 const code = if (anything_changed) @as(u8, 1) else @as(u8, 0);
245 process.exit(code);
246 }
247
248 _ = try std.zig.render(allocator, stdout, tree);
249 return;
250 }
251
252 if (input_files.len == 0) {
253 try stderr.write("expected at least one source file argument\n");
254 process.exit(1);
255 }
256
257 var fmt = Fmt{
258 .seen = Fmt.SeenMap.init(allocator),
259 .any_error = false,
260 .color = color,
261 .allocator = allocator,
262 };
263
264 for (input_files.toSliceConst()) |file_path| {
265 try fmtPath(&fmt, file_path, check_flag);
266 }
267 if (fmt.any_error) {
268 process.exit(1);
269 }
270}
271
272const FmtError = error{
273 SystemResources,
274 OperationAborted,
275 IoPending,
276 BrokenPipe,
277 Unexpected,
278 WouldBlock,
279 FileClosed,
280 DestinationAddressRequired,
281 DiskQuota,
282 FileTooBig,
283 InputOutput,
284 NoSpaceLeft,
285 AccessDenied,
286 OutOfMemory,
287 RenameAcrossMountPoints,
288 ReadOnlyFileSystem,
289 LinkQuotaExceeded,
290 FileBusy,
291} || fs.File.OpenError;
292
293fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void {
294 if (fmt.seen.exists(file_path)) return;
295 try fmt.seen.put(file_path);
296
297 const source_code = io.readFileAlloc(fmt.allocator, file_path) catch |err| switch (err) {
298 error.IsDir, error.AccessDenied => {
299 // TODO make event based (and dir.next())
300 var dir = try fs.cwd().openDirList(file_path);
301 defer dir.close();
302
303 var dir_it = dir.iterate();
304
305 while (try dir_it.next()) |entry| {
306 if (entry.kind == .Directory or mem.endsWith(u8, entry.name, ".zig")) {
307 const full_path = try fs.path.join(fmt.allocator, &[_][]const u8{ file_path, entry.name });
308 try fmtPath(fmt, full_path, check_mode);
309 }
310 }
311 return;
312 },
313 else => {
314 // TODO lock stderr printing
315 try stderr.print("unable to open '{}': {}\n", .{ file_path, err });
316 fmt.any_error = true;
317 return;
318 },
319 };
320 defer fmt.allocator.free(source_code);
321
322 const tree = std.zig.parse(fmt.allocator, source_code) catch |err| {
323 try stderr.print("error parsing file '{}': {}\n", .{ file_path, err });
324 fmt.any_error = true;
325 return;
326 };
327 defer tree.deinit();
328
329 var error_it = tree.errors.iterator(0);
330 while (error_it.next()) |parse_error| {
331 try printErrMsgToFile(fmt.allocator, parse_error, tree, file_path, stderr_file, fmt.color);
332 }
333 if (tree.errors.len != 0) {
334 fmt.any_error = true;
335 return;
336 }
337
338 if (check_mode) {
339 const anything_changed = try std.zig.render(fmt.allocator, io.null_out_stream, tree);
340 if (anything_changed) {
341 try stderr.print("{}\n", .{file_path});
342 fmt.any_error = true;
343 }
344 } else {
345 const baf = try io.BufferedAtomicFile.create(fmt.allocator, file_path);
346 defer baf.destroy();
347
348 const anything_changed = try std.zig.render(fmt.allocator, baf.stream(), tree);
349 if (anything_changed) {
350 try stderr.print("{}\n", .{file_path});
351 try baf.finish();
352 }
353 }
354}
355
356const Fmt = struct {
357 seen: SeenMap,
358 any_error: bool,
359 color: errmsg.Color,
360 allocator: *mem.Allocator,
361
362 const SeenMap = std.BufSet;
363};
364
365fn printErrMsgToFile(
366 allocator: *mem.Allocator,
367 parse_error: *const ast.Error,
368 tree: *ast.Tree,
369 path: []const u8,
370 file: fs.File,
371 color: errmsg.Color,
372) !void {
373 const color_on = switch (color) {
374 .Auto => file.isTty(),
375 .On => true,
376 .Off => false,
377 };
378 const lok_token = parse_error.loc();
379 const span = errmsg.Span{
380 .first = lok_token,
381 .last = lok_token,
382 };
383
384 const first_token = tree.tokens.at(span.first);
385 const last_token = tree.tokens.at(span.last);
386 const start_loc = tree.tokenLocationPtr(0, first_token);
387 const end_loc = tree.tokenLocationPtr(first_token.end, last_token);
388
389 var text_buf = try std.Buffer.initSize(allocator, 0);
390 var out_stream = &std.io.BufferOutStream.init(&text_buf).stream;
391 try parse_error.render(&tree.tokens, out_stream);
392 const text = text_buf.toOwnedSlice();
393
394 const stream = &file.outStream().stream;
395 try stream.print("{}:{}:{}: error: {}\n", .{ path, start_loc.line + 1, start_loc.column + 1, text });
396
397 if (!color_on) return;
398
399 // Print \r and \t as one space each so that column counts line up
400 for (tree.source[start_loc.line_start..start_loc.line_end]) |byte| {
401 try stream.writeByte(switch (byte) {
402 '\r', '\t' => ' ',
403 else => byte,
404 });
405 }
406 try stream.writeByte('\n');
407 try stream.writeByteNTimes(' ', start_loc.column);
408 try stream.writeByteNTimes('~', last_token.end - first_token.start);
409 try stream.writeByte('\n');
410}
411
412export fn stage2_DepTokenizer_init(input: [*]const u8, len: usize) stage2_DepTokenizer {
413 const t = std.heap.c_allocator.create(DepTokenizer) catch @panic("failed to create .d tokenizer");
414 t.* = DepTokenizer.init(std.heap.c_allocator, input[0..len]);
415 return stage2_DepTokenizer{
416 .handle = t,
417 };
418}
419
420export fn stage2_DepTokenizer_deinit(self: *stage2_DepTokenizer) void {
421 self.handle.deinit();
422}
423
424export fn stage2_DepTokenizer_next(self: *stage2_DepTokenizer) stage2_DepNextResult {
425 const otoken = self.handle.next() catch {
426 const textz = std.Buffer.init(&self.handle.arena.allocator, self.handle.error_text) catch @panic("failed to create .d tokenizer error text");
427 return stage2_DepNextResult{
428 .type_id = .error_,
429 .textz = textz.toSlice().ptr,
430 };
431 };
432 const token = otoken orelse {
433 return stage2_DepNextResult{
434 .type_id = .null_,
435 .textz = undefined,
436 };
437 };
438 const textz = std.Buffer.init(&self.handle.arena.allocator, token.bytes) catch @panic("failed to create .d tokenizer token text");
439 return stage2_DepNextResult{
440 .type_id = switch (token.id) {
441 .target => .target,
442 .prereq => .prereq,
443 },
444 .textz = textz.toSlice().ptr,
445 };
446}
447
448const stage2_DepTokenizer = extern struct {
449 handle: *DepTokenizer,
450};
451
452const stage2_DepNextResult = extern struct {
453 type_id: TypeId,
454
455 // when type_id == error --> error text
456 // when type_id == null --> undefined
457 // when type_id == target --> target pathname
458 // when type_id == prereq --> prereq pathname
459 textz: [*]const u8,
460
461 const TypeId = extern enum {
462 error_,
463 null_,
464 target,
465 prereq,
466 };
467};
468
469// ABI warning
470export fn stage2_attach_segfault_handler() void {
471 if (std.debug.runtime_safety and std.debug.have_segfault_handling_support) {
472 std.debug.attachSegfaultHandler();
473 }
474}
475
476// ABI warning
477export fn stage2_progress_create() *std.Progress {
478 const ptr = std.heap.c_allocator.create(std.Progress) catch @panic("out of memory");
479 ptr.* = std.Progress{};
480 return ptr;
481}
482
483// ABI warning
484export fn stage2_progress_destroy(progress: *std.Progress) void {
485 std.heap.c_allocator.destroy(progress);
486}
487
488// ABI warning
489export fn stage2_progress_start_root(
490 progress: *std.Progress,
491 name_ptr: [*]const u8,
492 name_len: usize,
493 estimated_total_items: usize,
494) *std.Progress.Node {
495 return progress.start(
496 name_ptr[0..name_len],
497 if (estimated_total_items == 0) null else estimated_total_items,
498 ) catch @panic("timer unsupported");
499}
500
501// ABI warning
502export fn stage2_progress_disable_tty(progress: *std.Progress) void {
503 progress.terminal = null;
504}
505
506// ABI warning
507export fn stage2_progress_start(
508 node: *std.Progress.Node,
509 name_ptr: [*]const u8,
510 name_len: usize,
511 estimated_total_items: usize,
512) *std.Progress.Node {
513 const child_node = std.heap.c_allocator.create(std.Progress.Node) catch @panic("out of memory");
514 child_node.* = node.start(
515 name_ptr[0..name_len],
516 if (estimated_total_items == 0) null else estimated_total_items,
517 );
518 child_node.activate();
519 return child_node;
520}
521
522// ABI warning
523export fn stage2_progress_end(node: *std.Progress.Node) void {
524 node.end();
525 if (&node.context.root != node) {
526 std.heap.c_allocator.destroy(node);
527 }
528}
529
530// ABI warning
531export fn stage2_progress_complete_one(node: *std.Progress.Node) void {
532 node.completeOne();
533}
534
535// ABI warning
536export fn stage2_progress_update_node(node: *std.Progress.Node, done_count: usize, total_count: usize) void {
537 node.completed_items = done_count;
538 node.estimated_total_items = total_count;
539 node.activate();
540 node.context.maybeRefresh();
541}
542
543fn cpuFeaturesFromLLVM(
544 arch: Target.Arch,
545 llvm_cpu_name_z: ?[*:0]const u8,
546 llvm_cpu_features_opt: ?[*:0]const u8,
547) !Target.CpuFeatures {
548 var result = arch.getBaselineCpuFeatures();
549
550 if (llvm_cpu_name_z) |cpu_name_z| {
551 const llvm_cpu_name = mem.toSliceConst(u8, cpu_name_z);
552
553 for (arch.allCpus()) |cpu| {
554 const this_llvm_name = cpu.llvm_name orelse continue;
555 if (mem.eql(u8, this_llvm_name, llvm_cpu_name)) {
556 // Here we use the non-dependencies-populated set,
557 // so that subtracting features later in this function
558 // affect the prepopulated set.
559 result = Target.CpuFeatures{
560 .cpu = cpu,
561 .features = cpu.features,
562 };
563 break;
564 }
565 }
566 }
567
568 const all_features = arch.allFeaturesList();
569
570 if (llvm_cpu_features_opt) |llvm_cpu_features| {
571 var it = mem.tokenize(mem.toSliceConst(u8, llvm_cpu_features), ",");
572 while (it.next()) |decorated_llvm_feat| {
573 var op: enum {
574 add,
575 sub,
576 } = undefined;
577 var llvm_feat: []const u8 = undefined;
578 if (mem.startsWith(u8, decorated_llvm_feat, "+")) {
579 op = .add;
580 llvm_feat = decorated_llvm_feat[1..];
581 } else if (mem.startsWith(u8, decorated_llvm_feat, "-")) {
582 op = .sub;
583 llvm_feat = decorated_llvm_feat[1..];
584 } else {
585 return error.InvalidLlvmCpuFeaturesFormat;
586 }
587 for (all_features) |feature, index_usize| {
588 const this_llvm_name = feature.llvm_name orelse continue;
589 if (mem.eql(u8, llvm_feat, this_llvm_name)) {
590 const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize);
591 switch (op) {
592 .add => result.features.addFeature(index),
593 .sub => result.features.removeFeature(index),
594 }
595 break;
596 }
597 }
598 }
599 }
600
601 result.features.populateDependencies(all_features);
602 return result;
603}
604
605// ABI warning
606export fn stage2_cmd_targets(zig_triple: [*:0]const u8) c_int {
607 cmdTargets(zig_triple) catch |err| {
608 std.debug.warn("unable to list targets: {}\n", .{@errorName(err)});
609 return -1;
610 };
611 return 0;
612}
613
614fn cmdTargets(zig_triple: [*:0]const u8) !void {
615 var target = try Target.parse(mem.toSliceConst(u8, zig_triple));
616 target.Cross.cpu_features = blk: {
617 const llvm = @import("llvm.zig");
618 const llvm_cpu_name = llvm.GetHostCPUName();
619 const llvm_cpu_features = llvm.GetNativeFeatures();
620 break :blk try cpuFeaturesFromLLVM(target.Cross.arch, llvm_cpu_name, llvm_cpu_features);
621 };
622 return @import("print_targets.zig").cmdTargets(
623 std.heap.c_allocator,
624 &[0][]u8{},
625 &std.io.getStdOut().outStream().stream,
626 target,
627 );
628}
629
630const Stage2CpuFeatures = struct {
631 allocator: *mem.Allocator,
632 cpu_features: Target.CpuFeatures,
633
634 llvm_features_str: ?[*:0]const u8,
635
636 builtin_str: [:0]const u8,
637 cache_hash: [:0]const u8,
638
639 const Self = @This();
640
641 fn createFromNative(allocator: *mem.Allocator) !*Self {
642 const arch = Target.current.getArch();
643 const llvm = @import("llvm.zig");
644 const llvm_cpu_name = llvm.GetHostCPUName();
645 const llvm_cpu_features = llvm.GetNativeFeatures();
646 const cpu_features = try cpuFeaturesFromLLVM(arch, llvm_cpu_name, llvm_cpu_features);
647 return createFromCpuFeatures(allocator, arch, cpu_features);
648 }
649
650 fn createFromCpuFeatures(
651 allocator: *mem.Allocator,
652 arch: Target.Arch,
653 cpu_features: Target.CpuFeatures,
654 ) !*Self {
655 const self = try allocator.create(Self);
656 errdefer allocator.destroy(self);
657
658 const cache_hash = try std.fmt.allocPrint0(allocator, "{}\n{}", .{
659 cpu_features.cpu.name,
660 cpu_features.features.asBytes(),
661 });
662 errdefer allocator.free(cache_hash);
663
664 const generic_arch_name = arch.genericName();
665 var builtin_str_buffer = try std.Buffer.allocPrint(allocator,
666 \\CpuFeatures{{
667 \\ .cpu = &Target.{}.cpu.{},
668 \\ .features = Target.{}.featureSet(&[_]Target.{}.Feature{{
669 \\
670 , .{
671 generic_arch_name,
672 cpu_features.cpu.name,
673 generic_arch_name,
674 generic_arch_name,
675 });
676 defer builtin_str_buffer.deinit();
677
678 var llvm_features_buffer = try std.Buffer.initSize(allocator, 0);
679 defer llvm_features_buffer.deinit();
680
681 for (arch.allFeaturesList()) |feature, index_usize| {
682 const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize);
683 const is_enabled = cpu_features.features.isEnabled(index);
684
685 if (feature.llvm_name) |llvm_name| {
686 const plus_or_minus = "-+"[@boolToInt(is_enabled)];
687 try llvm_features_buffer.appendByte(plus_or_minus);
688 try llvm_features_buffer.append(llvm_name);
689 try llvm_features_buffer.append(",");
690 }
691
692 if (is_enabled) {
693 // TODO some kind of "zig identifier escape" function rather than
694 // unconditionally using @"" syntax
695 try builtin_str_buffer.append(" .@\"");
696 try builtin_str_buffer.append(feature.name);
697 try builtin_str_buffer.append("\",\n");
698 }
699 }
700
701 try builtin_str_buffer.append(
702 \\ }),
703 \\};
704 \\
705 );
706
707 assert(mem.endsWith(u8, llvm_features_buffer.toSliceConst(), ","));
708 llvm_features_buffer.shrink(llvm_features_buffer.len() - 1);
709
710 self.* = Self{
711 .allocator = allocator,
712 .cpu_features = cpu_features,
713 .llvm_features_str = llvm_features_buffer.toOwnedSlice().ptr,
714 .builtin_str = builtin_str_buffer.toOwnedSlice(),
715 .cache_hash = cache_hash,
716 };
717 return self;
718 }
719
720 fn destroy(self: *Self) void {
721 self.allocator.free(self.cache_hash);
722 self.allocator.free(self.builtin_str);
723 // TODO if (self.llvm_features_str) |llvm_features_str| self.allocator.free(llvm_features_str);
724 self.allocator.destroy(self);
725 }
726};
727
728// ABI warning
729export fn stage2_cpu_features_parse(
730 result: **Stage2CpuFeatures,
731 zig_triple: ?[*:0]const u8,
732 cpu_name: ?[*:0]const u8,
733 cpu_features: ?[*:0]const u8,
734) Error {
735 result.* = stage2ParseCpuFeatures(zig_triple, cpu_name, cpu_features) catch |err| switch (err) {
736 error.OutOfMemory => return .OutOfMemory,
737 error.UnknownArchitecture => return .UnknownArchitecture,
738 error.UnknownSubArchitecture => return .UnknownSubArchitecture,
739 error.UnknownOperatingSystem => return .UnknownOperatingSystem,
740 error.UnknownApplicationBinaryInterface => return .UnknownApplicationBinaryInterface,
741 error.MissingOperatingSystem => return .MissingOperatingSystem,
742 error.MissingArchitecture => return .MissingArchitecture,
743 error.InvalidLlvmCpuFeaturesFormat => return .InvalidLlvmCpuFeaturesFormat,
744 error.InvalidCpuFeatures => return .InvalidCpuFeatures,
745 };
746 return .None;
747}
748
749fn stage2ParseCpuFeatures(
750 zig_triple_oz: ?[*:0]const u8,
751 cpu_name_oz: ?[*:0]const u8,
752 cpu_features_oz: ?[*:0]const u8,
753) !*Stage2CpuFeatures {
754 const zig_triple_z = zig_triple_oz orelse return Stage2CpuFeatures.createFromNative(std.heap.c_allocator);
755 const target = try Target.parse(mem.toSliceConst(u8, zig_triple_z));
756 const arch = target.Cross.arch;
757
758 const cpu = if (cpu_name_oz) |cpu_name_z| blk: {
759 const cpu_name = mem.toSliceConst(u8, cpu_name_z);
760 break :blk arch.parseCpu(cpu_name) catch |err| switch (err) {
761 error.UnknownCpu => {
762 std.debug.warn("Unknown CPU: '{}'\nAvailable CPUs for architecture '{}':\n", .{
763 cpu_name,
764 @tagName(arch),
765 });
766 for (arch.allCpus()) |cpu| {
767 std.debug.warn(" {}\n", .{cpu.name});
768 }
769 process.exit(1);
770 },
771 else => |e| return e,
772 };
773 } else target.Cross.cpu_features.cpu;
774
775 var set = if (cpu_features_oz) |cpu_features_z| blk: {
776 const cpu_features = mem.toSliceConst(u8, cpu_features_z);
777 break :blk arch.parseCpuFeatureSet(cpu, cpu_features) catch |err| switch (err) {
778 error.UnknownCpuFeature => {
779 std.debug.warn(
780 \\Unknown CPU features specified.
781 \\Available CPU features for architecture '{}':
782 \\
783 , .{@tagName(arch)});
784 for (arch.allFeaturesList()) |feature| {
785 std.debug.warn(" {}\n", .{feature.name});
786 }
787 process.exit(1);
788 },
789 else => |e| return e,
790 };
791 } else cpu.features;
792
793 if (arch.subArchFeature()) |index| {
794 set.addFeature(index);
795 }
796 set.populateDependencies(arch.allFeaturesList());
797
798 return Stage2CpuFeatures.createFromCpuFeatures(std.heap.c_allocator, arch, .{
799 .cpu = cpu,
800 .features = set,
801 });
802}
803
804// ABI warning
805export fn stage2_cpu_features_get_cache_hash(
806 cpu_features: *const Stage2CpuFeatures,
807 ptr: *[*:0]const u8,
808 len: *usize,
809) void {
810 ptr.* = cpu_features.cache_hash.ptr;
811 len.* = cpu_features.cache_hash.len;
812}
813
814// ABI warning
815export fn stage2_cpu_features_get_builtin_str(
816 cpu_features: *const Stage2CpuFeatures,
817 ptr: *[*:0]const u8,
818 len: *usize,
819) void {
820 ptr.* = cpu_features.builtin_str.ptr;
821 len.* = cpu_features.builtin_str.len;
822}
823
824// ABI warning
825export fn stage2_cpu_features_get_llvm_cpu(cpu_features: *const Stage2CpuFeatures) ?[*:0]const u8 {
826 return if (cpu_features.cpu_features.cpu.llvm_name) |s| s.ptr else null;
827}
828
829// ABI warning
830export fn stage2_cpu_features_get_llvm_features(cpu_features: *const Stage2CpuFeatures) ?[*:0]const u8 {
831 return cpu_features.llvm_features_str;
832}
src-self-hosted/stage2.zig created+1064
...@@ -0,0 +1,1064 @@
1// This is Zig code that is used by both stage1 and stage2.
2// The prototypes in src/userland.h must match these definitions.
3
4const std = @import("std");
5const io = std.io;
6const mem = std.mem;
7const fs = std.fs;
8const process = std.process;
9const Allocator = mem.Allocator;
10const ArrayList = std.ArrayList;
11const Buffer = std.Buffer;
12const Target = std.Target;
13const self_hosted_main = @import("main.zig");
14const errmsg = @import("errmsg.zig");
15const DepTokenizer = @import("dep_tokenizer.zig").Tokenizer;
16const assert = std.debug.assert;
17const LibCInstallation = @import("libc_installation.zig").LibCInstallation;
18
19var stderr_file: fs.File = undefined;
20var stderr: *io.OutStream(fs.File.WriteError) = undefined;
21var stdout: *io.OutStream(fs.File.WriteError) = undefined;
22
23comptime {
24 _ = @import("dep_tokenizer.zig");
25}
26
27// ABI warning
28export fn stage2_zen(ptr: *[*]const u8, len: *usize) void {
29 const info_zen = @import("main.zig").info_zen;
30 ptr.* = info_zen;
31 len.* = info_zen.len;
32}
33
34// ABI warning
35export fn stage2_panic(ptr: [*]const u8, len: usize) void {
36 @panic(ptr[0..len]);
37}
38
39// ABI warning
40const Error = extern enum {
41 None,
42 OutOfMemory,
43 InvalidFormat,
44 SemanticAnalyzeFail,
45 AccessDenied,
46 Interrupted,
47 SystemResources,
48 FileNotFound,
49 FileSystem,
50 FileTooBig,
51 DivByZero,
52 Overflow,
53 PathAlreadyExists,
54 Unexpected,
55 ExactDivRemainder,
56 NegativeDenominator,
57 ShiftedOutOneBits,
58 CCompileErrors,
59 EndOfFile,
60 IsDir,
61 NotDir,
62 UnsupportedOperatingSystem,
63 SharingViolation,
64 PipeBusy,
65 PrimitiveTypeNotFound,
66 CacheUnavailable,
67 PathTooLong,
68 CCompilerCannotFindFile,
69 NoCCompilerInstalled,
70 ReadingDepFile,
71 InvalidDepFile,
72 MissingArchitecture,
73 MissingOperatingSystem,
74 UnknownArchitecture,
75 UnknownOperatingSystem,
76 UnknownABI,
77 InvalidFilename,
78 DiskQuota,
79 DiskSpace,
80 UnexpectedWriteFailure,
81 UnexpectedSeekFailure,
82 UnexpectedFileTruncationFailure,
83 Unimplemented,
84 OperationAborted,
85 BrokenPipe,
86 NoSpaceLeft,
87 NotLazy,
88 IsAsync,
89 ImportOutsidePkgPath,
90 UnknownCpu,
91 UnknownCpuFeature,
92 InvalidCpuFeatures,
93 InvalidLlvmCpuFeaturesFormat,
94 UnknownApplicationBinaryInterface,
95 ASTUnitFailure,
96 BadPathName,
97 SymLinkLoop,
98 ProcessFdQuotaExceeded,
99 SystemFdQuotaExceeded,
100 NoDevice,
101 DeviceBusy,
102 UnableToSpawnCCompiler,
103 CCompilerExitCode,
104 CCompilerCrashed,
105 CCompilerCannotFindHeaders,
106 LibCRuntimeNotFound,
107 LibCStdLibHeaderNotFound,
108 LibCKernel32LibNotFound,
109 UnsupportedArchitecture,
110 WindowsSdkNotFound,
111 UnknownDynamicLinkerPath,
112 TargetHasNoDynamicLinker,
113};
114
115const FILE = std.c.FILE;
116const ast = std.zig.ast;
117const translate_c = @import("translate_c.zig");
118
119/// Args should have a null terminating last arg.
120export fn stage2_translate_c(
121 out_ast: **ast.Tree,
122 out_errors_ptr: *[*]translate_c.ClangErrMsg,
123 out_errors_len: *usize,
124 args_begin: [*]?[*]const u8,
125 args_end: [*]?[*]const u8,
126 resources_path: [*:0]const u8,
127) Error {
128 var errors = @as([*]translate_c.ClangErrMsg, undefined)[0..0];
129 out_ast.* = translate_c.translate(std.heap.c_allocator, args_begin, args_end, &errors, resources_path) catch |err| switch (err) {
130 error.SemanticAnalyzeFail => {
131 out_errors_ptr.* = errors.ptr;
132 out_errors_len.* = errors.len;
133 return .CCompileErrors;
134 },
135 error.ASTUnitFailure => return .ASTUnitFailure,
136 error.OutOfMemory => return .OutOfMemory,
137 };
138 return .None;
139}
140
141export fn stage2_free_clang_errors(errors_ptr: [*]translate_c.ClangErrMsg, errors_len: usize) void {
142 translate_c.freeErrors(errors_ptr[0..errors_len]);
143}
144
145export fn stage2_render_ast(tree: *ast.Tree, output_file: *FILE) Error {
146 const c_out_stream = &std.io.COutStream.init(output_file).stream;
147 _ = std.zig.render(std.heap.c_allocator, c_out_stream, tree) catch |e| switch (e) {
148 error.WouldBlock => unreachable, // stage1 opens stuff in exclusively blocking mode
149 error.SystemResources => return .SystemResources,
150 error.OperationAborted => return .OperationAborted,
151 error.BrokenPipe => return .BrokenPipe,
152 error.DiskQuota => return .DiskQuota,
153 error.FileTooBig => return .FileTooBig,
154 error.NoSpaceLeft => return .NoSpaceLeft,
155 error.AccessDenied => return .AccessDenied,
156 error.OutOfMemory => return .OutOfMemory,
157 error.Unexpected => return .Unexpected,
158 error.InputOutput => return .FileSystem,
159 };
160 return .None;
161}
162
163// TODO: just use the actual self-hosted zig fmt. Until https://github.com/ziglang/zig/issues/2377,
164// we use a blocking implementation.
165export fn stage2_fmt(argc: c_int, argv: [*]const [*:0]const u8) c_int {
166 if (std.debug.runtime_safety) {
167 fmtMain(argc, argv) catch unreachable;
168 } else {
169 fmtMain(argc, argv) catch |e| {
170 std.debug.warn("{}\n", .{@errorName(e)});
171 return -1;
172 };
173 }
174 return 0;
175}
176
177fn fmtMain(argc: c_int, argv: [*]const [*:0]const u8) !void {
178 const allocator = std.heap.c_allocator;
179 var args_list = std.ArrayList([]const u8).init(allocator);
180 const argc_usize = @intCast(usize, argc);
181 var arg_i: usize = 0;
182 while (arg_i < argc_usize) : (arg_i += 1) {
183 try args_list.append(mem.toSliceConst(u8, argv[arg_i]));
184 }
185
186 stdout = &std.io.getStdOut().outStream().stream;
187 stderr_file = std.io.getStdErr();
188 stderr = &stderr_file.outStream().stream;
189
190 const args = args_list.toSliceConst()[2..];
191
192 var color: errmsg.Color = .Auto;
193 var stdin_flag: bool = false;
194 var check_flag: bool = false;
195 var input_files = ArrayList([]const u8).init(allocator);
196
197 {
198 var i: usize = 0;
199 while (i < args.len) : (i += 1) {
200 const arg = args[i];
201 if (mem.startsWith(u8, arg, "-")) {
202 if (mem.eql(u8, arg, "--help")) {
203 try stdout.write(self_hosted_main.usage_fmt);
204 process.exit(0);
205 } else if (mem.eql(u8, arg, "--color")) {
206 if (i + 1 >= args.len) {
207 try stderr.write("expected [auto|on|off] after --color\n");
208 process.exit(1);
209 }
210 i += 1;
211 const next_arg = args[i];
212 if (mem.eql(u8, next_arg, "auto")) {
213 color = .Auto;
214 } else if (mem.eql(u8, next_arg, "on")) {
215 color = .On;
216 } else if (mem.eql(u8, next_arg, "off")) {
217 color = .Off;
218 } else {
219 try stderr.print("expected [auto|on|off] after --color, found '{}'\n", .{next_arg});
220 process.exit(1);
221 }
222 } else if (mem.eql(u8, arg, "--stdin")) {
223 stdin_flag = true;
224 } else if (mem.eql(u8, arg, "--check")) {
225 check_flag = true;
226 } else {
227 try stderr.print("unrecognized parameter: '{}'", .{arg});
228 process.exit(1);
229 }
230 } else {
231 try input_files.append(arg);
232 }
233 }
234 }
235
236 if (stdin_flag) {
237 if (input_files.len != 0) {
238 try stderr.write("cannot use --stdin with positional arguments\n");
239 process.exit(1);
240 }
241
242 const stdin_file = io.getStdIn();
243 var stdin = stdin_file.inStream();
244
245 const source_code = try stdin.stream.readAllAlloc(allocator, self_hosted_main.max_src_size);
246 defer allocator.free(source_code);
247
248 const tree = std.zig.parse(allocator, source_code) catch |err| {
249 try stderr.print("error parsing stdin: {}\n", .{err});
250 process.exit(1);
251 };
252 defer tree.deinit();
253
254 var error_it = tree.errors.iterator(0);
255 while (error_it.next()) |parse_error| {
256 try printErrMsgToFile(allocator, parse_error, tree, "<stdin>", stderr_file, color);
257 }
258 if (tree.errors.len != 0) {
259 process.exit(1);
260 }
261 if (check_flag) {
262 const anything_changed = try std.zig.render(allocator, io.null_out_stream, tree);
263 const code = if (anything_changed) @as(u8, 1) else @as(u8, 0);
264 process.exit(code);
265 }
266
267 _ = try std.zig.render(allocator, stdout, tree);
268 return;
269 }
270
271 if (input_files.len == 0) {
272 try stderr.write("expected at least one source file argument\n");
273 process.exit(1);
274 }
275
276 var fmt = Fmt{
277 .seen = Fmt.SeenMap.init(allocator),
278 .any_error = false,
279 .color = color,
280 .allocator = allocator,
281 };
282
283 for (input_files.toSliceConst()) |file_path| {
284 try fmtPath(&fmt, file_path, check_flag);
285 }
286 if (fmt.any_error) {
287 process.exit(1);
288 }
289}
290
291const FmtError = error{
292 SystemResources,
293 OperationAborted,
294 IoPending,
295 BrokenPipe,
296 Unexpected,
297 WouldBlock,
298 FileClosed,
299 DestinationAddressRequired,
300 DiskQuota,
301 FileTooBig,
302 InputOutput,
303 NoSpaceLeft,
304 AccessDenied,
305 OutOfMemory,
306 RenameAcrossMountPoints,
307 ReadOnlyFileSystem,
308 LinkQuotaExceeded,
309 FileBusy,
310} || fs.File.OpenError;
311
312fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool) FmtError!void {
313 if (fmt.seen.exists(file_path)) return;
314 try fmt.seen.put(file_path);
315
316 const source_code = io.readFileAlloc(fmt.allocator, file_path) catch |err| switch (err) {
317 error.IsDir, error.AccessDenied => {
318 // TODO make event based (and dir.next())
319 var dir = try fs.cwd().openDirList(file_path);
320 defer dir.close();
321
322 var dir_it = dir.iterate();
323
324 while (try dir_it.next()) |entry| {
325 if (entry.kind == .Directory or mem.endsWith(u8, entry.name, ".zig")) {
326 const full_path = try fs.path.join(fmt.allocator, &[_][]const u8{ file_path, entry.name });
327 try fmtPath(fmt, full_path, check_mode);
328 }
329 }
330 return;
331 },
332 else => {
333 // TODO lock stderr printing
334 try stderr.print("unable to open '{}': {}\n", .{ file_path, err });
335 fmt.any_error = true;
336 return;
337 },
338 };
339 defer fmt.allocator.free(source_code);
340
341 const tree = std.zig.parse(fmt.allocator, source_code) catch |err| {
342 try stderr.print("error parsing file '{}': {}\n", .{ file_path, err });
343 fmt.any_error = true;
344 return;
345 };
346 defer tree.deinit();
347
348 var error_it = tree.errors.iterator(0);
349 while (error_it.next()) |parse_error| {
350 try printErrMsgToFile(fmt.allocator, parse_error, tree, file_path, stderr_file, fmt.color);
351 }
352 if (tree.errors.len != 0) {
353 fmt.any_error = true;
354 return;
355 }
356
357 if (check_mode) {
358 const anything_changed = try std.zig.render(fmt.allocator, io.null_out_stream, tree);
359 if (anything_changed) {
360 try stderr.print("{}\n", .{file_path});
361 fmt.any_error = true;
362 }
363 } else {
364 const baf = try io.BufferedAtomicFile.create(fmt.allocator, file_path);
365 defer baf.destroy();
366
367 const anything_changed = try std.zig.render(fmt.allocator, baf.stream(), tree);
368 if (anything_changed) {
369 try stderr.print("{}\n", .{file_path});
370 try baf.finish();
371 }
372 }
373}
374
375const Fmt = struct {
376 seen: SeenMap,
377 any_error: bool,
378 color: errmsg.Color,
379 allocator: *mem.Allocator,
380
381 const SeenMap = std.BufSet;
382};
383
384fn printErrMsgToFile(
385 allocator: *mem.Allocator,
386 parse_error: *const ast.Error,
387 tree: *ast.Tree,
388 path: []const u8,
389 file: fs.File,
390 color: errmsg.Color,
391) !void {
392 const color_on = switch (color) {
393 .Auto => file.isTty(),
394 .On => true,
395 .Off => false,
396 };
397 const lok_token = parse_error.loc();
398 const span = errmsg.Span{
399 .first = lok_token,
400 .last = lok_token,
401 };
402
403 const first_token = tree.tokens.at(span.first);
404 const last_token = tree.tokens.at(span.last);
405 const start_loc = tree.tokenLocationPtr(0, first_token);
406 const end_loc = tree.tokenLocationPtr(first_token.end, last_token);
407
408 var text_buf = try std.Buffer.initSize(allocator, 0);
409 var out_stream = &std.io.BufferOutStream.init(&text_buf).stream;
410 try parse_error.render(&tree.tokens, out_stream);
411 const text = text_buf.toOwnedSlice();
412
413 const stream = &file.outStream().stream;
414 try stream.print("{}:{}:{}: error: {}\n", .{ path, start_loc.line + 1, start_loc.column + 1, text });
415
416 if (!color_on) return;
417
418 // Print \r and \t as one space each so that column counts line up
419 for (tree.source[start_loc.line_start..start_loc.line_end]) |byte| {
420 try stream.writeByte(switch (byte) {
421 '\r', '\t' => ' ',
422 else => byte,
423 });
424 }
425 try stream.writeByte('\n');
426 try stream.writeByteNTimes(' ', start_loc.column);
427 try stream.writeByteNTimes('~', last_token.end - first_token.start);
428 try stream.writeByte('\n');
429}
430
431export fn stage2_DepTokenizer_init(input: [*]const u8, len: usize) stage2_DepTokenizer {
432 const t = std.heap.c_allocator.create(DepTokenizer) catch @panic("failed to create .d tokenizer");
433 t.* = DepTokenizer.init(std.heap.c_allocator, input[0..len]);
434 return stage2_DepTokenizer{
435 .handle = t,
436 };
437}
438
439export fn stage2_DepTokenizer_deinit(self: *stage2_DepTokenizer) void {
440 self.handle.deinit();
441}
442
443export fn stage2_DepTokenizer_next(self: *stage2_DepTokenizer) stage2_DepNextResult {
444 const otoken = self.handle.next() catch {
445 const textz = std.Buffer.init(&self.handle.arena.allocator, self.handle.error_text) catch @panic("failed to create .d tokenizer error text");
446 return stage2_DepNextResult{
447 .type_id = .error_,
448 .textz = textz.toSlice().ptr,
449 };
450 };
451 const token = otoken orelse {
452 return stage2_DepNextResult{
453 .type_id = .null_,
454 .textz = undefined,
455 };
456 };
457 const textz = std.Buffer.init(&self.handle.arena.allocator, token.bytes) catch @panic("failed to create .d tokenizer token text");
458 return stage2_DepNextResult{
459 .type_id = switch (token.id) {
460 .target => .target,
461 .prereq => .prereq,
462 },
463 .textz = textz.toSlice().ptr,
464 };
465}
466
467const stage2_DepTokenizer = extern struct {
468 handle: *DepTokenizer,
469};
470
471const stage2_DepNextResult = extern struct {
472 type_id: TypeId,
473
474 // when type_id == error --> error text
475 // when type_id == null --> undefined
476 // when type_id == target --> target pathname
477 // when type_id == prereq --> prereq pathname
478 textz: [*]const u8,
479
480 const TypeId = extern enum {
481 error_,
482 null_,
483 target,
484 prereq,
485 };
486};
487
488// ABI warning
489export fn stage2_attach_segfault_handler() void {
490 if (std.debug.runtime_safety and std.debug.have_segfault_handling_support) {
491 std.debug.attachSegfaultHandler();
492 }
493}
494
495// ABI warning
496export fn stage2_progress_create() *std.Progress {
497 const ptr = std.heap.c_allocator.create(std.Progress) catch @panic("out of memory");
498 ptr.* = std.Progress{};
499 return ptr;
500}
501
502// ABI warning
503export fn stage2_progress_destroy(progress: *std.Progress) void {
504 std.heap.c_allocator.destroy(progress);
505}
506
507// ABI warning
508export fn stage2_progress_start_root(
509 progress: *std.Progress,
510 name_ptr: [*]const u8,
511 name_len: usize,
512 estimated_total_items: usize,
513) *std.Progress.Node {
514 return progress.start(
515 name_ptr[0..name_len],
516 if (estimated_total_items == 0) null else estimated_total_items,
517 ) catch @panic("timer unsupported");
518}
519
520// ABI warning
521export fn stage2_progress_disable_tty(progress: *std.Progress) void {
522 progress.terminal = null;
523}
524
525// ABI warning
526export fn stage2_progress_start(
527 node: *std.Progress.Node,
528 name_ptr: [*]const u8,
529 name_len: usize,
530 estimated_total_items: usize,
531) *std.Progress.Node {
532 const child_node = std.heap.c_allocator.create(std.Progress.Node) catch @panic("out of memory");
533 child_node.* = node.start(
534 name_ptr[0..name_len],
535 if (estimated_total_items == 0) null else estimated_total_items,
536 );
537 child_node.activate();
538 return child_node;
539}
540
541// ABI warning
542export fn stage2_progress_end(node: *std.Progress.Node) void {
543 node.end();
544 if (&node.context.root != node) {
545 std.heap.c_allocator.destroy(node);
546 }
547}
548
549// ABI warning
550export fn stage2_progress_complete_one(node: *std.Progress.Node) void {
551 node.completeOne();
552}
553
554// ABI warning
555export fn stage2_progress_update_node(node: *std.Progress.Node, done_count: usize, total_count: usize) void {
556 node.completed_items = done_count;
557 node.estimated_total_items = total_count;
558 node.activate();
559 node.context.maybeRefresh();
560}
561
562fn detectNativeCpuWithLLVM(
563 arch: Target.Cpu.Arch,
564 llvm_cpu_name_z: ?[*:0]const u8,
565 llvm_cpu_features_opt: ?[*:0]const u8,
566) !Target.Cpu {
567 var result = Target.Cpu.baseline(arch);
568
569 if (llvm_cpu_name_z) |cpu_name_z| {
570 const llvm_cpu_name = mem.toSliceConst(u8, cpu_name_z);
571
572 for (arch.allCpuModels()) |model| {
573 const this_llvm_name = model.llvm_name orelse continue;
574 if (mem.eql(u8, this_llvm_name, llvm_cpu_name)) {
575 // Here we use the non-dependencies-populated set,
576 // so that subtracting features later in this function
577 // affect the prepopulated set.
578 result = Target.Cpu{
579 .arch = arch,
580 .model = model,
581 .features = model.features,
582 };
583 break;
584 }
585 }
586 }
587
588 const all_features = arch.allFeaturesList();
589
590 if (llvm_cpu_features_opt) |llvm_cpu_features| {
591 var it = mem.tokenize(mem.toSliceConst(u8, llvm_cpu_features), ",");
592 while (it.next()) |decorated_llvm_feat| {
593 var op: enum {
594 add,
595 sub,
596 } = undefined;
597 var llvm_feat: []const u8 = undefined;
598 if (mem.startsWith(u8, decorated_llvm_feat, "+")) {
599 op = .add;
600 llvm_feat = decorated_llvm_feat[1..];
601 } else if (mem.startsWith(u8, decorated_llvm_feat, "-")) {
602 op = .sub;
603 llvm_feat = decorated_llvm_feat[1..];
604 } else {
605 return error.InvalidLlvmCpuFeaturesFormat;
606 }
607 for (all_features) |feature, index_usize| {
608 const this_llvm_name = feature.llvm_name orelse continue;
609 if (mem.eql(u8, llvm_feat, this_llvm_name)) {
610 const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize);
611 switch (op) {
612 .add => result.features.addFeature(index),
613 .sub => result.features.removeFeature(index),
614 }
615 break;
616 }
617 }
618 }
619 }
620
621 result.features.populateDependencies(all_features);
622 return result;
623}
624
625// ABI warning
626export fn stage2_cmd_targets(zig_triple: [*:0]const u8) c_int {
627 cmdTargets(zig_triple) catch |err| {
628 std.debug.warn("unable to list targets: {}\n", .{@errorName(err)});
629 return -1;
630 };
631 return 0;
632}
633
634fn cmdTargets(zig_triple: [*:0]const u8) !void {
635 var target = try Target.parse(.{ .arch_os_abi = mem.toSliceConst(u8, zig_triple) });
636 target.Cross.cpu = blk: {
637 const llvm = @import("llvm.zig");
638 const llvm_cpu_name = llvm.GetHostCPUName();
639 const llvm_cpu_features = llvm.GetNativeFeatures();
640 break :blk try detectNativeCpuWithLLVM(target.getArch(), llvm_cpu_name, llvm_cpu_features);
641 };
642 return @import("print_targets.zig").cmdTargets(
643 std.heap.c_allocator,
644 &[0][]u8{},
645 &std.io.getStdOut().outStream().stream,
646 target,
647 );
648}
649
650// ABI warning
651export fn stage2_target_parse(
652 target: *Stage2Target,
653 zig_triple: ?[*:0]const u8,
654 mcpu: ?[*:0]const u8,
655) Error {
656 stage2TargetParse(target, zig_triple, mcpu) catch |err| switch (err) {
657 error.OutOfMemory => return .OutOfMemory,
658 error.UnknownArchitecture => return .UnknownArchitecture,
659 error.UnknownOperatingSystem => return .UnknownOperatingSystem,
660 error.UnknownApplicationBinaryInterface => return .UnknownApplicationBinaryInterface,
661 error.MissingOperatingSystem => return .MissingOperatingSystem,
662 error.MissingArchitecture => return .MissingArchitecture,
663 error.InvalidLlvmCpuFeaturesFormat => return .InvalidLlvmCpuFeaturesFormat,
664 error.UnexpectedExtraField => return .SemanticAnalyzeFail,
665 };
666 return .None;
667}
668
669fn stage2TargetParse(
670 stage1_target: *Stage2Target,
671 zig_triple_oz: ?[*:0]const u8,
672 mcpu_oz: ?[*:0]const u8,
673) !void {
674 const target: Target = if (zig_triple_oz) |zig_triple_z| blk: {
675 const zig_triple = mem.toSliceConst(u8, zig_triple_z);
676 const mcpu = if (mcpu_oz) |mcpu_z| mem.toSliceConst(u8, mcpu_z) else "baseline";
677 var diags: std.Target.ParseOptions.Diagnostics = .{};
678 break :blk Target.parse(.{
679 .arch_os_abi = zig_triple,
680 .cpu_features = mcpu,
681 .diagnostics = &diags,
682 }) catch |err| switch (err) {
683 error.UnknownCpu => {
684 std.debug.warn("Unknown CPU: '{}'\nAvailable CPUs for architecture '{}':\n", .{
685 diags.cpu_name.?,
686 @tagName(diags.arch.?),
687 });
688 for (diags.arch.?.allCpuModels()) |cpu| {
689 std.debug.warn(" {}\n", .{cpu.name});
690 }
691 process.exit(1);
692 },
693 error.UnknownCpuFeature => {
694 std.debug.warn(
695 \\Unknown CPU feature: '{}'
696 \\Available CPU features for architecture '{}':
697 \\
698 , .{
699 diags.unknown_feature_name,
700 @tagName(diags.arch.?),
701 });
702 for (diags.arch.?.allFeaturesList()) |feature| {
703 std.debug.warn(" {}: {}\n", .{ feature.name, feature.description });
704 }
705 process.exit(1);
706 },
707 else => |e| return e,
708 };
709 } else Target.Native;
710
711 try stage1_target.fromTarget(target);
712}
713
714fn initStage1TargetCpuFeatures(stage1_target: *Stage2Target, cpu: Target.Cpu) !void {
715 const allocator = std.heap.c_allocator;
716 const cache_hash = try std.fmt.allocPrint0(allocator, "{}\n{}", .{
717 cpu.model.name,
718 cpu.features.asBytes(),
719 });
720 errdefer allocator.free(cache_hash);
721
722 const generic_arch_name = cpu.arch.genericName();
723 var builtin_str_buffer = try std.Buffer.allocPrint(allocator,
724 \\Cpu{{
725 \\ .arch = .{},
726 \\ .model = &Target.{}.cpu.{},
727 \\ .features = Target.{}.featureSet(&[_]Target.{}.Feature{{
728 \\
729 , .{
730 @tagName(cpu.arch),
731 generic_arch_name,
732 cpu.model.name,
733 generic_arch_name,
734 generic_arch_name,
735 });
736 defer builtin_str_buffer.deinit();
737
738 var llvm_features_buffer = try std.Buffer.initSize(allocator, 0);
739 defer llvm_features_buffer.deinit();
740
741 for (cpu.arch.allFeaturesList()) |feature, index_usize| {
742 const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize);
743 const is_enabled = cpu.features.isEnabled(index);
744
745 if (feature.llvm_name) |llvm_name| {
746 const plus_or_minus = "-+"[@boolToInt(is_enabled)];
747 try llvm_features_buffer.appendByte(plus_or_minus);
748 try llvm_features_buffer.append(llvm_name);
749 try llvm_features_buffer.append(",");
750 }
751
752 if (is_enabled) {
753 // TODO some kind of "zig identifier escape" function rather than
754 // unconditionally using @"" syntax
755 try builtin_str_buffer.append(" .@\"");
756 try builtin_str_buffer.append(feature.name);
757 try builtin_str_buffer.append("\",\n");
758 }
759 }
760
761 try builtin_str_buffer.append(
762 \\ }),
763 \\};
764 \\
765 );
766
767 assert(mem.endsWith(u8, llvm_features_buffer.toSliceConst(), ","));
768 llvm_features_buffer.shrink(llvm_features_buffer.len() - 1);
769
770 stage1_target.llvm_cpu_name = if (cpu.model.llvm_name) |s| s.ptr else null;
771 stage1_target.llvm_cpu_features = llvm_features_buffer.toOwnedSlice().ptr;
772 stage1_target.builtin_str = builtin_str_buffer.toOwnedSlice().ptr;
773 stage1_target.cache_hash = cache_hash.ptr;
774}
775
776// ABI warning
777const Stage2LibCInstallation = extern struct {
778 include_dir: [*:0]const u8,
779 include_dir_len: usize,
780 sys_include_dir: [*:0]const u8,
781 sys_include_dir_len: usize,
782 crt_dir: [*:0]const u8,
783 crt_dir_len: usize,
784 static_crt_dir: [*:0]const u8,
785 static_crt_dir_len: usize,
786 msvc_lib_dir: [*:0]const u8,
787 msvc_lib_dir_len: usize,
788 kernel32_lib_dir: [*:0]const u8,
789 kernel32_lib_dir_len: usize,
790
791 fn initFromStage2(self: *Stage2LibCInstallation, libc: LibCInstallation) void {
792 if (libc.include_dir) |s| {
793 self.include_dir = s.ptr;
794 self.include_dir_len = s.len;
795 } else {
796 self.include_dir = "";
797 self.include_dir_len = 0;
798 }
799 if (libc.sys_include_dir) |s| {
800 self.sys_include_dir = s.ptr;
801 self.sys_include_dir_len = s.len;
802 } else {
803 self.sys_include_dir = "";
804 self.sys_include_dir_len = 0;
805 }
806 if (libc.crt_dir) |s| {
807 self.crt_dir = s.ptr;
808 self.crt_dir_len = s.len;
809 } else {
810 self.crt_dir = "";
811 self.crt_dir_len = 0;
812 }
813 if (libc.static_crt_dir) |s| {
814 self.static_crt_dir = s.ptr;
815 self.static_crt_dir_len = s.len;
816 } else {
817 self.static_crt_dir = "";
818 self.static_crt_dir_len = 0;
819 }
820 if (libc.msvc_lib_dir) |s| {
821 self.msvc_lib_dir = s.ptr;
822 self.msvc_lib_dir_len = s.len;
823 } else {
824 self.msvc_lib_dir = "";
825 self.msvc_lib_dir_len = 0;
826 }
827 if (libc.kernel32_lib_dir) |s| {
828 self.kernel32_lib_dir = s.ptr;
829 self.kernel32_lib_dir_len = s.len;
830 } else {
831 self.kernel32_lib_dir = "";
832 self.kernel32_lib_dir_len = 0;
833 }
834 }
835
836 fn toStage2(self: Stage2LibCInstallation) LibCInstallation {
837 var libc: LibCInstallation = .{};
838 if (self.include_dir_len != 0) {
839 libc.include_dir = self.include_dir[0..self.include_dir_len :0];
840 }
841 if (self.sys_include_dir_len != 0) {
842 libc.sys_include_dir = self.sys_include_dir[0..self.sys_include_dir_len :0];
843 }
844 if (self.crt_dir_len != 0) {
845 libc.crt_dir = self.crt_dir[0..self.crt_dir_len :0];
846 }
847 if (self.static_crt_dir_len != 0) {
848 libc.static_crt_dir = self.static_crt_dir[0..self.static_crt_dir_len :0];
849 }
850 if (self.msvc_lib_dir_len != 0) {
851 libc.msvc_lib_dir = self.msvc_lib_dir[0..self.msvc_lib_dir_len :0];
852 }
853 if (self.kernel32_lib_dir_len != 0) {
854 libc.kernel32_lib_dir = self.kernel32_lib_dir[0..self.kernel32_lib_dir_len :0];
855 }
856 return libc;
857 }
858};
859
860// ABI warning
861export fn stage2_libc_parse(stage1_libc: *Stage2LibCInstallation, libc_file_z: [*:0]const u8) Error {
862 stderr_file = std.io.getStdErr();
863 stderr = &stderr_file.outStream().stream;
864 const libc_file = mem.toSliceConst(u8, libc_file_z);
865 var libc = LibCInstallation.parse(std.heap.c_allocator, libc_file, stderr) catch |err| switch (err) {
866 error.ParseError => return .SemanticAnalyzeFail,
867 error.DiskQuota => return .DiskQuota,
868 error.FileTooBig => return .FileTooBig,
869 error.InputOutput => return .FileSystem,
870 error.NoSpaceLeft => return .NoSpaceLeft,
871 error.AccessDenied => return .AccessDenied,
872 error.BrokenPipe => return .BrokenPipe,
873 error.SystemResources => return .SystemResources,
874 error.OperationAborted => return .OperationAborted,
875 error.WouldBlock => unreachable,
876 error.Unexpected => return .Unexpected,
877 error.EndOfStream => return .EndOfFile,
878 error.IsDir => return .IsDir,
879 error.ConnectionResetByPeer => unreachable,
880 error.OutOfMemory => return .OutOfMemory,
881 error.Unseekable => unreachable,
882 error.SharingViolation => return .SharingViolation,
883 error.PathAlreadyExists => unreachable,
884 error.FileNotFound => return .FileNotFound,
885 error.PipeBusy => return .PipeBusy,
886 error.NameTooLong => return .PathTooLong,
887 error.InvalidUtf8 => return .BadPathName,
888 error.BadPathName => return .BadPathName,
889 error.SymLinkLoop => return .SymLinkLoop,
890 error.ProcessFdQuotaExceeded => return .ProcessFdQuotaExceeded,
891 error.SystemFdQuotaExceeded => return .SystemFdQuotaExceeded,
892 error.NoDevice => return .NoDevice,
893 error.NotDir => return .NotDir,
894 error.DeviceBusy => return .DeviceBusy,
895 };
896 stage1_libc.initFromStage2(libc);
897 return .None;
898}
899
900// ABI warning
901export fn stage2_libc_find_native(stage1_libc: *Stage2LibCInstallation) Error {
902 var libc = LibCInstallation.findNative(.{
903 .allocator = std.heap.c_allocator,
904 .verbose = true,
905 }) catch |err| switch (err) {
906 error.OutOfMemory => return .OutOfMemory,
907 error.FileSystem => return .FileSystem,
908 error.UnableToSpawnCCompiler => return .UnableToSpawnCCompiler,
909 error.CCompilerExitCode => return .CCompilerExitCode,
910 error.CCompilerCrashed => return .CCompilerCrashed,
911 error.CCompilerCannotFindHeaders => return .CCompilerCannotFindHeaders,
912 error.LibCRuntimeNotFound => return .LibCRuntimeNotFound,
913 error.LibCStdLibHeaderNotFound => return .LibCStdLibHeaderNotFound,
914 error.LibCKernel32LibNotFound => return .LibCKernel32LibNotFound,
915 error.UnsupportedArchitecture => return .UnsupportedArchitecture,
916 error.WindowsSdkNotFound => return .WindowsSdkNotFound,
917 };
918 stage1_libc.initFromStage2(libc);
919 return .None;
920}
921
922// ABI warning
923export fn stage2_libc_render(stage1_libc: *Stage2LibCInstallation, output_file: *FILE) Error {
924 var libc = stage1_libc.toStage2();
925 const c_out_stream = &std.io.COutStream.init(output_file).stream;
926 libc.render(c_out_stream) catch |err| switch (err) {
927 error.WouldBlock => unreachable, // stage1 opens stuff in exclusively blocking mode
928 error.SystemResources => return .SystemResources,
929 error.OperationAborted => return .OperationAborted,
930 error.BrokenPipe => return .BrokenPipe,
931 error.DiskQuota => return .DiskQuota,
932 error.FileTooBig => return .FileTooBig,
933 error.NoSpaceLeft => return .NoSpaceLeft,
934 error.AccessDenied => return .AccessDenied,
935 error.Unexpected => return .Unexpected,
936 error.InputOutput => return .FileSystem,
937 };
938 return .None;
939}
940
941// ABI warning
942const Stage2Target = extern struct {
943 arch: c_int,
944 vendor: c_int,
945
946 abi: c_int,
947 os: c_int,
948
949 is_native: bool,
950
951 glibc_version: ?*Stage2GLibCVersion, // null means default
952
953 llvm_cpu_name: ?[*:0]const u8,
954 llvm_cpu_features: ?[*:0]const u8,
955 builtin_str: ?[*:0]const u8,
956 cache_hash: ?[*:0]const u8,
957
958 fn toTarget(in_target: Stage2Target) Target {
959 if (in_target.is_native) return .Native;
960
961 const in_arch = in_target.arch - 1; // skip over ZigLLVM_UnknownArch
962 const in_os = in_target.os;
963 const in_abi = in_target.abi;
964
965 return .{
966 .Cross = .{
967 .cpu = Target.Cpu.baseline(enumInt(Target.Cpu.Arch, in_arch)),
968 .os = enumInt(Target.Os, in_os),
969 .abi = enumInt(Target.Abi, in_abi),
970 },
971 };
972 }
973
974 fn fromTarget(self: *Stage2Target, target: Target) !void {
975 const cpu = switch (target) {
976 .Native => blk: {
977 // TODO self-host CPU model and feature detection instead of relying on LLVM
978 const llvm = @import("llvm.zig");
979 const llvm_cpu_name = llvm.GetHostCPUName();
980 const llvm_cpu_features = llvm.GetNativeFeatures();
981 break :blk try detectNativeCpuWithLLVM(target.getArch(), llvm_cpu_name, llvm_cpu_features);
982 },
983 .Cross => target.getCpu(),
984 };
985 self.* = .{
986 .arch = @enumToInt(target.getArch()) + 1, // skip over ZigLLVM_UnknownArch
987 .vendor = 0,
988 .os = @enumToInt(target.getOs()),
989 .abi = @enumToInt(target.getAbi()),
990 .llvm_cpu_name = null,
991 .llvm_cpu_features = null,
992 .builtin_str = null,
993 .cache_hash = null,
994 .is_native = target == .Native,
995 .glibc_version = null,
996 };
997 try initStage1TargetCpuFeatures(self, cpu);
998 }
999};
1000
1001// ABI warning
1002const Stage2GLibCVersion = extern struct {
1003 major: u32,
1004 minor: u32,
1005 patch: u32,
1006};
1007
1008// ABI warning
1009export fn stage2_detect_dynamic_linker(in_target: *const Stage2Target, out_ptr: *[*:0]u8, out_len: *usize) Error {
1010 const target = in_target.toTarget();
1011 const result = @import("introspect.zig").detectDynamicLinker(
1012 std.heap.c_allocator,
1013 target,
1014 ) catch |err| switch (err) {
1015 error.OutOfMemory => return .OutOfMemory,
1016 error.UnknownDynamicLinkerPath => return .UnknownDynamicLinkerPath,
1017 error.TargetHasNoDynamicLinker => return .TargetHasNoDynamicLinker,
1018 };
1019 out_ptr.* = result.ptr;
1020 out_len.* = result.len;
1021 return .None;
1022}
1023
1024fn enumInt(comptime Enum: type, int: c_int) Enum {
1025 return @intToEnum(Enum, @intCast(@TagType(Enum), int));
1026}
1027
1028// ABI warning
1029const Stage2NativePaths = extern struct {
1030 include_dirs_ptr: [*][*:0]u8,
1031 include_dirs_len: usize,
1032 lib_dirs_ptr: [*][*:0]u8,
1033 lib_dirs_len: usize,
1034 rpaths_ptr: [*][*:0]u8,
1035 rpaths_len: usize,
1036 warnings_ptr: [*][*:0]u8,
1037 warnings_len: usize,
1038};
1039// ABI warning
1040export fn stage2_detect_native_paths(stage1_paths: *Stage2NativePaths) Error {
1041 stage2DetectNativePaths(stage1_paths) catch |err| switch (err) {
1042 error.OutOfMemory => return .OutOfMemory,
1043 };
1044 return .None;
1045}
1046
1047fn stage2DetectNativePaths(stage1_paths: *Stage2NativePaths) !void {
1048 var paths = try std.zig.system.NativePaths.detect(std.heap.c_allocator);
1049 errdefer paths.deinit();
1050
1051 try convertSlice(paths.include_dirs.toSlice(), &stage1_paths.include_dirs_ptr, &stage1_paths.include_dirs_len);
1052 try convertSlice(paths.lib_dirs.toSlice(), &stage1_paths.lib_dirs_ptr, &stage1_paths.lib_dirs_len);
1053 try convertSlice(paths.rpaths.toSlice(), &stage1_paths.rpaths_ptr, &stage1_paths.rpaths_len);
1054 try convertSlice(paths.warnings.toSlice(), &stage1_paths.warnings_ptr, &stage1_paths.warnings_len);
1055}
1056
1057fn convertSlice(slice: [][:0]u8, ptr: *[*][*:0]u8, len: *usize) !void {
1058 len.* = slice.len;
1059 const new_slice = try std.heap.c_allocator.alloc([*:0]u8, slice.len);
1060 for (slice) |item, i| {
1061 new_slice[i] = item.ptr;
1062 }
1063 ptr.* = new_slice.ptr;
1064}
src-self-hosted/translate_c.zig+5-5
...@@ -264,7 +264,7 @@ pub fn translate(...@@ -264,7 +264,7 @@ pub fn translate(
264 &errors.len,264 &errors.len,
265 resources_path,265 resources_path,
266 ) orelse {266 ) orelse {
267 if (errors.len == 0) return error.OutOfMemory;267 if (errors.len == 0) return error.ASTUnitFailure;
268 return error.SemanticAnalyzeFail;268 return error.SemanticAnalyzeFail;
269 };269 };
270 defer ZigClangASTUnit_delete(ast_unit);270 defer ZigClangASTUnit_delete(ast_unit);
...@@ -5382,15 +5382,15 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5382,15 +5382,15 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5382 return error.ParseError;5382 return error.ParseError;
5383 }5383 }
53845384
5385 //if (@typeId(@TypeOf(x)) == .Pointer)5385 //if (@typeInfo(@TypeOf(x)) == .Pointer)
5386 // @ptrCast(dest, x)5386 // @ptrCast(dest, x)
5387 //else if (@typeId(@TypeOf(x)) == .Integer)5387 //else if (@typeInfo(@TypeOf(x)) == .Integer)
5388 // @intToPtr(dest, x)5388 // @intToPtr(dest, x)
5389 //else5389 //else
5390 // @as(dest, x)5390 // @as(dest, x)
53915391
5392 const if_1 = try transCreateNodeIf(c);5392 const if_1 = try transCreateNodeIf(c);
5393 const type_id_1 = try transCreateNodeBuiltinFnCall(c, "@typeId");5393 const type_id_1 = try transCreateNodeBuiltinFnCall(c, "@typeInfo");
5394 const type_of_1 = try transCreateNodeBuiltinFnCall(c, "@TypeOf");5394 const type_of_1 = try transCreateNodeBuiltinFnCall(c, "@TypeOf");
5395 try type_id_1.params.push(&type_of_1.base);5395 try type_id_1.params.push(&type_of_1.base);
5396 try type_of_1.params.push(node_to_cast);5396 try type_of_1.params.push(node_to_cast);
...@@ -5417,7 +5417,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,...@@ -5417,7 +5417,7 @@ fn parseCPrimaryExpr(c: *Context, it: *CTokenList.Iterator, source: []const u8,
5417 if_1.@"else" = else_1;5417 if_1.@"else" = else_1;
54185418
5419 const if_2 = try transCreateNodeIf(c);5419 const if_2 = try transCreateNodeIf(c);
5420 const type_id_2 = try transCreateNodeBuiltinFnCall(c, "@typeId");5420 const type_id_2 = try transCreateNodeBuiltinFnCall(c, "@typeInfo");
5421 const type_of_2 = try transCreateNodeBuiltinFnCall(c, "@TypeOf");5421 const type_of_2 = try transCreateNodeBuiltinFnCall(c, "@TypeOf");
5422 try type_id_2.params.push(&type_of_2.base);5422 try type_id_2.params.push(&type_of_2.base);
5423 try type_of_2.params.push(node_to_cast);5423 try type_of_2.params.push(node_to_cast);
src-self-hosted/type.zig+1-1
...@@ -1042,7 +1042,7 @@ fn hashAny(x: var, comptime seed: u64) u32 {...@@ -1042,7 +1042,7 @@ fn hashAny(x: var, comptime seed: u64) u32 {
1042 switch (@typeInfo(@TypeOf(x))) {1042 switch (@typeInfo(@TypeOf(x))) {
1043 .Int => |info| {1043 .Int => |info| {
1044 comptime var rng = comptime std.rand.DefaultPrng.init(seed);1044 comptime var rng = comptime std.rand.DefaultPrng.init(seed);
1045 const unsigned_x = @bitCast(@IntType(false, info.bits), x);1045 const unsigned_x = @bitCast(std.meta.IntType(false, info.bits), x);
1046 if (info.bits <= 32) {1046 if (info.bits <= 32) {
1047 return @as(u32, unsigned_x) *% comptime rng.random.scalar(u32);1047 return @as(u32, unsigned_x) *% comptime rng.random.scalar(u32);
1048 } else {1048 } else {
src-self-hosted/util.zig-138
...@@ -2,144 +2,6 @@ const std = @import("std");...@@ -2,144 +2,6 @@ const std = @import("std");
2const Target = std.Target;2const Target = std.Target;
3const llvm = @import("llvm.zig");3const llvm = @import("llvm.zig");
44
5pub const FloatAbi = enum {
6 Hard,
7 Soft,
8 SoftFp,
9};
10
11/// TODO expose the arch and subarch separately
12pub fn isArmOrThumb(self: Target) bool {
13 return switch (self.getArch()) {
14 .arm,
15 .armeb,
16 .aarch64,
17 .aarch64_be,
18 .thumb,
19 .thumbeb,
20 => true,
21 else => false,
22 };
23}
24
25pub fn getFloatAbi(self: Target) FloatAbi {
26 return switch (self.getAbi()) {
27 .gnueabihf,
28 .eabihf,
29 .musleabihf,
30 => .Hard,
31 else => .Soft,
32 };
33}
34
35pub fn getDynamicLinkerPath(self: Target) ?[]const u8 {
36 const env = self.getAbi();
37 const arch = self.getArch();
38 const os = self.getOs();
39 switch (os) {
40 .freebsd => {
41 return "/libexec/ld-elf.so.1";
42 },
43 .linux => {
44 switch (env) {
45 .android => {
46 if (self.getArchPtrBitWidth() == 64) {
47 return "/system/bin/linker64";
48 } else {
49 return "/system/bin/linker";
50 }
51 },
52 .gnux32 => {
53 if (arch == .x86_64) {
54 return "/libx32/ld-linux-x32.so.2";
55 }
56 },
57 .musl,
58 .musleabi,
59 .musleabihf,
60 => {
61 if (arch == .x86_64) {
62 return "/lib/ld-musl-x86_64.so.1";
63 }
64 },
65 else => {},
66 }
67 switch (arch) {
68 .i386,
69 .sparc,
70 .sparcel,
71 => return "/lib/ld-linux.so.2",
72
73 .aarch64 => return "/lib/ld-linux-aarch64.so.1",
74
75 .aarch64_be => return "/lib/ld-linux-aarch64_be.so.1",
76
77 .arm,
78 .thumb,
79 => return switch (getFloatAbi(self)) {
80 .Hard => return "/lib/ld-linux-armhf.so.3",
81 else => return "/lib/ld-linux.so.3",
82 },
83
84 .armeb,
85 .thumbeb,
86 => return switch (getFloatAbi(self)) {
87 .Hard => return "/lib/ld-linux-armhf.so.3",
88 else => return "/lib/ld-linux.so.3",
89 },
90
91 .mips,
92 .mipsel,
93 .mips64,
94 .mips64el,
95 => return null,
96
97 .powerpc => return "/lib/ld.so.1",
98 .powerpc64 => return "/lib64/ld64.so.2",
99 .powerpc64le => return "/lib64/ld64.so.2",
100 .s390x => return "/lib64/ld64.so.1",
101 .sparcv9 => return "/lib64/ld-linux.so.2",
102 .x86_64 => return "/lib64/ld-linux-x86-64.so.2",
103
104 .arc,
105 .avr,
106 .bpfel,
107 .bpfeb,
108 .hexagon,
109 .msp430,
110 .r600,
111 .amdgcn,
112 .riscv32,
113 .riscv64,
114 .tce,
115 .tcele,
116 .xcore,
117 .nvptx,
118 .nvptx64,
119 .le32,
120 .le64,
121 .amdil,
122 .amdil64,
123 .hsail,
124 .hsail64,
125 .spir,
126 .spir64,
127 .kalimba,
128 .shave,
129 .lanai,
130 .wasm32,
131 .wasm64,
132 .renderscript32,
133 .renderscript64,
134 .aarch64_32,
135 .ve,
136 => return null,
137 }
138 },
139 else => return null,
140 }
141}
142
143pub fn getDarwinArchString(self: Target) [:0]const u8 {5pub fn getDarwinArchString(self: Target) [:0]const u8 {
144 const arch = self.getArch();6 const arch = self.getArch();
145 switch (arch) {7 switch (arch) {
src-self-hosted/windows_sdk.zig created+22
...@@ -0,0 +1,22 @@
1// C API bindings for src/windows_sdk.h
2
3pub const ZigWindowsSDK = extern struct {
4 path10_ptr: ?[*]const u8,
5 path10_len: usize,
6 version10_ptr: ?[*]const u8,
7 version10_len: usize,
8 path81_ptr: ?[*]const u8,
9 path81_len: usize,
10 version81_ptr: ?[*]const u8,
11 version81_len: usize,
12 msvc_lib_dir_ptr: ?[*]const u8,
13 msvc_lib_dir_len: usize,
14};
15pub const ZigFindWindowsSdkError = extern enum {
16 None,
17 OutOfMemory,
18 NotFound,
19 PathTooLong,
20};
21pub extern fn zig_find_windows_sdk(out_sdk: **ZigWindowsSDK) ZigFindWindowsSdkError;
22pub extern fn zig_free_windows_sdk(sdk: *ZigWindowsSDK) void;
src/all_types.hpp+21-84
...@@ -18,7 +18,6 @@...@@ -18,7 +18,6 @@
18#include "bigfloat.hpp"18#include "bigfloat.hpp"
19#include "target.hpp"19#include "target.hpp"
20#include "tokenizer.hpp"20#include "tokenizer.hpp"
21#include "libc_installation.hpp"
2221
23struct AstNode;22struct AstNode;
24struct ZigFn;23struct ZigFn;
...@@ -370,12 +369,22 @@ enum LazyValueId {...@@ -370,12 +369,22 @@ enum LazyValueId {
370 LazyValueIdFnType,369 LazyValueIdFnType,
371 LazyValueIdErrUnionType,370 LazyValueIdErrUnionType,
372 LazyValueIdArrayType,371 LazyValueIdArrayType,
372 LazyValueIdTypeInfoDecls,
373};373};
374374
375struct LazyValue {375struct LazyValue {
376 LazyValueId id;376 LazyValueId id;
377};377};
378378
379struct LazyValueTypeInfoDecls {
380 LazyValue base;
381
382 IrAnalyze *ira;
383
384 ScopeDecls *decls_scope;
385 IrInst *source_instr;
386};
387
379struct LazyValueAlignOf {388struct LazyValueAlignOf {
380 LazyValue base;389 LazyValue base;
381390
...@@ -1139,6 +1148,7 @@ struct AstNodeErrorType {...@@ -1139,6 +1148,7 @@ struct AstNodeErrorType {
1139};1148};
11401149
1141struct AstNodeAwaitExpr {1150struct AstNodeAwaitExpr {
1151 Token *noasync_token;
1142 AstNode *expr;1152 AstNode *expr;
1143};1153};
11441154
...@@ -1685,9 +1695,6 @@ enum BuiltinFnId {...@@ -1685,9 +1695,6 @@ enum BuiltinFnId {
1685 BuiltinFnIdMemset,1695 BuiltinFnIdMemset,
1686 BuiltinFnIdSizeof,1696 BuiltinFnIdSizeof,
1687 BuiltinFnIdAlignOf,1697 BuiltinFnIdAlignOf,
1688 BuiltinFnIdMemberCount,
1689 BuiltinFnIdMemberType,
1690 BuiltinFnIdMemberName,
1691 BuiltinFnIdField,1698 BuiltinFnIdField,
1692 BuiltinFnIdTypeInfo,1699 BuiltinFnIdTypeInfo,
1693 BuiltinFnIdType,1700 BuiltinFnIdType,
...@@ -1740,8 +1747,6 @@ enum BuiltinFnId {...@@ -1740,8 +1747,6 @@ enum BuiltinFnId {
1740 BuiltinFnIdIntCast,1747 BuiltinFnIdIntCast,
1741 BuiltinFnIdFloatCast,1748 BuiltinFnIdFloatCast,
1742 BuiltinFnIdErrSetCast,1749 BuiltinFnIdErrSetCast,
1743 BuiltinFnIdToBytes,
1744 BuiltinFnIdFromBytes,
1745 BuiltinFnIdIntToFloat,1750 BuiltinFnIdIntToFloat,
1746 BuiltinFnIdFloatToInt,1751 BuiltinFnIdFloatToInt,
1747 BuiltinFnIdBoolToInt,1752 BuiltinFnIdBoolToInt,
...@@ -1749,7 +1754,6 @@ enum BuiltinFnId {...@@ -1749,7 +1754,6 @@ enum BuiltinFnId {
1749 BuiltinFnIdIntToErr,1754 BuiltinFnIdIntToErr,
1750 BuiltinFnIdEnumToInt,1755 BuiltinFnIdEnumToInt,
1751 BuiltinFnIdIntToEnum,1756 BuiltinFnIdIntToEnum,
1752 BuiltinFnIdIntType,
1753 BuiltinFnIdVectorType,1757 BuiltinFnIdVectorType,
1754 BuiltinFnIdShuffle,1758 BuiltinFnIdShuffle,
1755 BuiltinFnIdSplat,1759 BuiltinFnIdSplat,
...@@ -1768,7 +1772,6 @@ enum BuiltinFnId {...@@ -1768,7 +1772,6 @@ enum BuiltinFnId {
1768 BuiltinFnIdByteOffsetOf,1772 BuiltinFnIdByteOffsetOf,
1769 BuiltinFnIdBitOffsetOf,1773 BuiltinFnIdBitOffsetOf,
1770 BuiltinFnIdAsyncCall,1774 BuiltinFnIdAsyncCall,
1771 BuiltinFnIdTypeId,
1772 BuiltinFnIdShlExact,1775 BuiltinFnIdShlExact,
1773 BuiltinFnIdShrExact,1776 BuiltinFnIdShrExact,
1774 BuiltinFnIdSetEvalBranchQuota,1777 BuiltinFnIdSetEvalBranchQuota,
...@@ -1776,7 +1779,6 @@ enum BuiltinFnId {...@@ -1776,7 +1779,6 @@ enum BuiltinFnId {
1776 BuiltinFnIdOpaqueType,1779 BuiltinFnIdOpaqueType,
1777 BuiltinFnIdThis,1780 BuiltinFnIdThis,
1778 BuiltinFnIdSetAlignStack,1781 BuiltinFnIdSetAlignStack,
1779 BuiltinFnIdArgType,
1780 BuiltinFnIdExport,1782 BuiltinFnIdExport,
1781 BuiltinFnIdErrorReturnTrace,1783 BuiltinFnIdErrorReturnTrace,
1782 BuiltinFnIdAtomicRmw,1784 BuiltinFnIdAtomicRmw,
...@@ -1810,7 +1812,6 @@ enum PanicMsgId {...@@ -1810,7 +1812,6 @@ enum PanicMsgId {
1810 PanicMsgIdDivisionByZero,1812 PanicMsgIdDivisionByZero,
1811 PanicMsgIdRemainderDivisionByZero,1813 PanicMsgIdRemainderDivisionByZero,
1812 PanicMsgIdExactDivisionRemainder,1814 PanicMsgIdExactDivisionRemainder,
1813 PanicMsgIdSliceWidenRemainder,
1814 PanicMsgIdUnwrapOptionalFail,1815 PanicMsgIdUnwrapOptionalFail,
1815 PanicMsgIdInvalidErrorCode,1816 PanicMsgIdInvalidErrorCode,
1816 PanicMsgIdIncorrectAlignment,1817 PanicMsgIdIncorrectAlignment,
...@@ -1955,12 +1956,6 @@ enum CodeModel {...@@ -1955,12 +1956,6 @@ enum CodeModel {
1955 CodeModelLarge,1956 CodeModelLarge,
1956};1957};
19571958
1958enum EmitFileType {
1959 EmitFileTypeBinary,
1960 EmitFileTypeAssembly,
1961 EmitFileTypeLLVMIr,
1962};
1963
1964struct LinkLib {1959struct LinkLib {
1965 Buf *name;1960 Buf *name;
1966 Buf *path;1961 Buf *path;
...@@ -2131,13 +2126,15 @@ struct CodeGen {...@@ -2131,13 +2126,15 @@ struct CodeGen {
21312126
2132 Buf llvm_triple_str;2127 Buf llvm_triple_str;
2133 Buf global_asm;2128 Buf global_asm;
2134 Buf output_file_path;
2135 Buf o_file_output_path;2129 Buf o_file_output_path;
2130 Buf bin_file_output_path;
2131 Buf asm_file_output_path;
2132 Buf llvm_ir_file_output_path;
2136 Buf *cache_dir;2133 Buf *cache_dir;
2137 // As an input parameter, mutually exclusive with enable_cache. But it gets2134 // As an input parameter, mutually exclusive with enable_cache. But it gets
2138 // populated in codegen_build_and_link.2135 // populated in codegen_build_and_link.
2139 Buf *output_dir;2136 Buf *output_dir;
2140 Buf **libc_include_dir_list;2137 const char **libc_include_dir_list;
2141 size_t libc_include_dir_len;2138 size_t libc_include_dir_len;
21422139
2143 Buf *zig_c_headers_dir; // Cannot be overridden; derived from zig_lib_dir.2140 Buf *zig_c_headers_dir; // Cannot be overridden; derived from zig_lib_dir.
...@@ -2218,14 +2215,13 @@ struct CodeGen {...@@ -2218,14 +2215,13 @@ struct CodeGen {
2218 ZigList<const char *> lib_dirs;2215 ZigList<const char *> lib_dirs;
2219 ZigList<const char *> framework_dirs;2216 ZigList<const char *> framework_dirs;
22202217
2221 ZigLibCInstallation *libc;2218 Stage2LibCInstallation *libc;
22222219
2223 size_t version_major;2220 size_t version_major;
2224 size_t version_minor;2221 size_t version_minor;
2225 size_t version_patch;2222 size_t version_patch;
2226 const char *linker_script;2223 const char *linker_script;
22272224
2228 EmitFileType emit_file_type;
2229 BuildMode build_mode;2225 BuildMode build_mode;
2230 OutType out_type;2226 OutType out_type;
2231 const ZigTarget *zig_target;2227 const ZigTarget *zig_target;
...@@ -2247,7 +2243,9 @@ struct CodeGen {...@@ -2247,7 +2243,9 @@ struct CodeGen {
2247 bool function_sections;2243 bool function_sections;
2248 bool enable_dump_analysis;2244 bool enable_dump_analysis;
2249 bool enable_doc_generation;2245 bool enable_doc_generation;
2250 bool disable_bin_generation;2246 bool emit_bin;
2247 bool emit_asm;
2248 bool emit_llvm_ir;
2251 bool test_is_evented;2249 bool test_is_evented;
2252 CodeModel code_model;2250 CodeModel code_model;
22532251
...@@ -2625,7 +2623,6 @@ enum IrInstSrcId {...@@ -2625,7 +2623,6 @@ enum IrInstSrcId {
2625 IrInstSrcIdIntToFloat,2623 IrInstSrcIdIntToFloat,
2626 IrInstSrcIdFloatToInt,2624 IrInstSrcIdFloatToInt,
2627 IrInstSrcIdBoolToInt,2625 IrInstSrcIdBoolToInt,
2628 IrInstSrcIdIntType,
2629 IrInstSrcIdVectorType,2626 IrInstSrcIdVectorType,
2630 IrInstSrcIdShuffleVector,2627 IrInstSrcIdShuffleVector,
2631 IrInstSrcIdSplat,2628 IrInstSrcIdSplat,
...@@ -2633,9 +2630,6 @@ enum IrInstSrcId {...@@ -2633,9 +2630,6 @@ enum IrInstSrcId {
2633 IrInstSrcIdMemset,2630 IrInstSrcIdMemset,
2634 IrInstSrcIdMemcpy,2631 IrInstSrcIdMemcpy,
2635 IrInstSrcIdSlice,2632 IrInstSrcIdSlice,
2636 IrInstSrcIdMemberCount,
2637 IrInstSrcIdMemberType,
2638 IrInstSrcIdMemberName,
2639 IrInstSrcIdBreakpoint,2633 IrInstSrcIdBreakpoint,
2640 IrInstSrcIdReturnAddress,2634 IrInstSrcIdReturnAddress,
2641 IrInstSrcIdFrameAddress,2635 IrInstSrcIdFrameAddress,
...@@ -2672,7 +2666,6 @@ enum IrInstSrcId {...@@ -2672,7 +2666,6 @@ enum IrInstSrcId {
2672 IrInstSrcIdTypeInfo,2666 IrInstSrcIdTypeInfo,
2673 IrInstSrcIdType,2667 IrInstSrcIdType,
2674 IrInstSrcIdHasField,2668 IrInstSrcIdHasField,
2675 IrInstSrcIdTypeId,
2676 IrInstSrcIdSetEvalBranchQuota,2669 IrInstSrcIdSetEvalBranchQuota,
2677 IrInstSrcIdPtrType,2670 IrInstSrcIdPtrType,
2678 IrInstSrcIdAlignCast,2671 IrInstSrcIdAlignCast,
...@@ -2691,8 +2684,6 @@ enum IrInstSrcId {...@@ -2691,8 +2684,6 @@ enum IrInstSrcId {
2691 IrInstSrcIdSaveErrRetAddr,2684 IrInstSrcIdSaveErrRetAddr,
2692 IrInstSrcIdAddImplicitReturnType,2685 IrInstSrcIdAddImplicitReturnType,
2693 IrInstSrcIdErrSetCast,2686 IrInstSrcIdErrSetCast,
2694 IrInstSrcIdToBytes,
2695 IrInstSrcIdFromBytes,
2696 IrInstSrcIdCheckRuntimeScope,2687 IrInstSrcIdCheckRuntimeScope,
2697 IrInstSrcIdHasDecl,2688 IrInstSrcIdHasDecl,
2698 IrInstSrcIdUndeclaredIdent,2689 IrInstSrcIdUndeclaredIdent,
...@@ -2731,7 +2722,6 @@ enum IrInstGenId {...@@ -2731,7 +2722,6 @@ enum IrInstGenId {
2731 IrInstGenIdCall,2722 IrInstGenIdCall,
2732 IrInstGenIdReturn,2723 IrInstGenIdReturn,
2733 IrInstGenIdCast,2724 IrInstGenIdCast,
2734 IrInstGenIdResizeSlice,
2735 IrInstGenIdUnreachable,2725 IrInstGenIdUnreachable,
2736 IrInstGenIdAsm,2726 IrInstGenIdAsm,
2737 IrInstGenIdTestNonNull,2727 IrInstGenIdTestNonNull,
...@@ -3263,13 +3253,6 @@ struct IrInstGenCast {...@@ -3263,13 +3253,6 @@ struct IrInstGenCast {
3263 CastOp cast_op;3253 CastOp cast_op;
3264};3254};
32653255
3266struct IrInstGenResizeSlice {
3267 IrInstGen base;
3268
3269 IrInstGen *operand;
3270 IrInstGen *result_loc;
3271};
3272
3273struct IrInstSrcContainerInitList {3256struct IrInstSrcContainerInitList {
3274 IrInstSrc base;3257 IrInstSrc base;
32753258
...@@ -3621,21 +3604,6 @@ struct IrInstSrcErrSetCast {...@@ -3621,21 +3604,6 @@ struct IrInstSrcErrSetCast {
3621 IrInstSrc *target;3604 IrInstSrc *target;
3622};3605};
36233606
3624struct IrInstSrcToBytes {
3625 IrInstSrc base;
3626
3627 IrInstSrc *target;
3628 ResultLoc *result_loc;
3629};
3630
3631struct IrInstSrcFromBytes {
3632 IrInstSrc base;
3633
3634 IrInstSrc *dest_child_type;
3635 IrInstSrc *target;
3636 ResultLoc *result_loc;
3637};
3638
3639struct IrInstSrcIntToFloat {3607struct IrInstSrcIntToFloat {
3640 IrInstSrc base;3608 IrInstSrc base;
36413609
...@@ -3656,13 +3624,6 @@ struct IrInstSrcBoolToInt {...@@ -3656,13 +3624,6 @@ struct IrInstSrcBoolToInt {
3656 IrInstSrc *target;3624 IrInstSrc *target;
3657};3625};
36583626
3659struct IrInstSrcIntType {
3660 IrInstSrc base;
3661
3662 IrInstSrc *is_signed;
3663 IrInstSrc *bit_count;
3664};
3665
3666struct IrInstSrcVectorType {3627struct IrInstSrcVectorType {
3667 IrInstSrc base;3628 IrInstSrc base;
36683629
...@@ -3735,26 +3696,6 @@ struct IrInstGenSlice {...@@ -3735,26 +3696,6 @@ struct IrInstGenSlice {
3735 bool safety_check_on;3696 bool safety_check_on;
3736};3697};
37373698
3738struct IrInstSrcMemberCount {
3739 IrInstSrc base;
3740
3741 IrInstSrc *container;
3742};
3743
3744struct IrInstSrcMemberType {
3745 IrInstSrc base;
3746
3747 IrInstSrc *container_type;
3748 IrInstSrc *member_index;
3749};
3750
3751struct IrInstSrcMemberName {
3752 IrInstSrc base;
3753
3754 IrInstSrc *container_type;
3755 IrInstSrc *member_index;
3756};
3757
3758struct IrInstSrcBreakpoint {3699struct IrInstSrcBreakpoint {
3759 IrInstSrc base;3700 IrInstSrc base;
3760};3701};
...@@ -4162,12 +4103,6 @@ struct IrInstSrcHasField {...@@ -4162,12 +4103,6 @@ struct IrInstSrcHasField {
4162 IrInstSrc *field_name;4103 IrInstSrc *field_name;
4163};4104};
41644105
4165struct IrInstSrcTypeId {
4166 IrInstSrc base;
4167
4168 IrInstSrc *type_value;
4169};
4170
4171struct IrInstSrcSetEvalBranchQuota {4106struct IrInstSrcSetEvalBranchQuota {
4172 IrInstSrc base;4107 IrInstSrc base;
41734108
...@@ -4499,6 +4434,7 @@ struct IrInstSrcAwait {...@@ -4499,6 +4434,7 @@ struct IrInstSrcAwait {
44994434
4500 IrInstSrc *frame;4435 IrInstSrc *frame;
4501 ResultLoc *result_loc;4436 ResultLoc *result_loc;
4437 bool is_noasync;
4502};4438};
45034439
4504struct IrInstGenAwait {4440struct IrInstGenAwait {
...@@ -4507,6 +4443,7 @@ struct IrInstGenAwait {...@@ -4507,6 +4443,7 @@ struct IrInstGenAwait {
4507 IrInstGen *frame;4443 IrInstGen *frame;
4508 IrInstGen *result_loc;4444 IrInstGen *result_loc;
4509 ZigFn *target_fn;4445 ZigFn *target_fn;
4446 bool is_noasync;
4510};4447};
45114448
4512struct IrInstSrcResume {4449struct IrInstSrcResume {
src/analyze.cpp+10-4
...@@ -1150,6 +1150,7 @@ Error type_val_resolve_zero_bits(CodeGen *g, ZigValue *type_val, ZigType *parent...@@ -1150,6 +1150,7 @@ Error type_val_resolve_zero_bits(CodeGen *g, ZigValue *type_val, ZigType *parent
1150 case LazyValueIdInvalid:1150 case LazyValueIdInvalid:
1151 case LazyValueIdAlignOf:1151 case LazyValueIdAlignOf:
1152 case LazyValueIdSizeOf:1152 case LazyValueIdSizeOf:
1153 case LazyValueIdTypeInfoDecls:
1153 zig_unreachable();1154 zig_unreachable();
1154 case LazyValueIdPtrType: {1155 case LazyValueIdPtrType: {
1155 LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(type_val->data.x_lazy);1156 LazyValuePtrType *lazy_ptr_type = reinterpret_cast<LazyValuePtrType *>(type_val->data.x_lazy);
...@@ -1209,6 +1210,7 @@ Error type_val_resolve_is_opaque_type(CodeGen *g, ZigValue *type_val, bool *is_o...@@ -1209,6 +1210,7 @@ Error type_val_resolve_is_opaque_type(CodeGen *g, ZigValue *type_val, bool *is_o
1209 case LazyValueIdInvalid:1210 case LazyValueIdInvalid:
1210 case LazyValueIdAlignOf:1211 case LazyValueIdAlignOf:
1211 case LazyValueIdSizeOf:1212 case LazyValueIdSizeOf:
1213 case LazyValueIdTypeInfoDecls:
1212 zig_unreachable();1214 zig_unreachable();
1213 case LazyValueIdSliceType:1215 case LazyValueIdSliceType:
1214 case LazyValueIdPtrType:1216 case LazyValueIdPtrType:
...@@ -1230,6 +1232,7 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ZigValue *type...@@ -1230,6 +1232,7 @@ static ReqCompTime type_val_resolve_requires_comptime(CodeGen *g, ZigValue *type
1230 case LazyValueIdInvalid:1232 case LazyValueIdInvalid:
1231 case LazyValueIdAlignOf:1233 case LazyValueIdAlignOf:
1232 case LazyValueIdSizeOf:1234 case LazyValueIdSizeOf:
1235 case LazyValueIdTypeInfoDecls:
1233 zig_unreachable();1236 zig_unreachable();
1234 case LazyValueIdSliceType: {1237 case LazyValueIdSliceType: {
1235 LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(type_val->data.x_lazy);1238 LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(type_val->data.x_lazy);
...@@ -1303,6 +1306,7 @@ start_over:...@@ -1303,6 +1306,7 @@ start_over:
1303 case LazyValueIdInvalid:1306 case LazyValueIdInvalid:
1304 case LazyValueIdAlignOf:1307 case LazyValueIdAlignOf:
1305 case LazyValueIdSizeOf:1308 case LazyValueIdSizeOf:
1309 case LazyValueIdTypeInfoDecls:
1306 zig_unreachable();1310 zig_unreachable();
1307 case LazyValueIdSliceType: {1311 case LazyValueIdSliceType: {
1308 LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(type_val->data.x_lazy);1312 LazyValueSliceType *lazy_slice_type = reinterpret_cast<LazyValueSliceType *>(type_val->data.x_lazy);
...@@ -1370,6 +1374,7 @@ Error type_val_resolve_abi_align(CodeGen *g, AstNode *source_node, ZigValue *typ...@@ -1370,6 +1374,7 @@ Error type_val_resolve_abi_align(CodeGen *g, AstNode *source_node, ZigValue *typ
1370 case LazyValueIdInvalid:1374 case LazyValueIdInvalid:
1371 case LazyValueIdAlignOf:1375 case LazyValueIdAlignOf:
1372 case LazyValueIdSizeOf:1376 case LazyValueIdSizeOf:
1377 case LazyValueIdTypeInfoDecls:
1373 zig_unreachable();1378 zig_unreachable();
1374 case LazyValueIdSliceType:1379 case LazyValueIdSliceType:
1375 case LazyValueIdPtrType:1380 case LazyValueIdPtrType:
...@@ -1412,6 +1417,7 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, ZigV...@@ -1412,6 +1417,7 @@ static OnePossibleValue type_val_resolve_has_one_possible_value(CodeGen *g, ZigV
1412 case LazyValueIdInvalid:1417 case LazyValueIdInvalid:
1413 case LazyValueIdAlignOf:1418 case LazyValueIdAlignOf:
1414 case LazyValueIdSizeOf:1419 case LazyValueIdSizeOf:
1420 case LazyValueIdTypeInfoDecls:
1415 zig_unreachable();1421 zig_unreachable();
1416 case LazyValueIdSliceType: // it has the len field1422 case LazyValueIdSliceType: // it has the len field
1417 case LazyValueIdOptType: // it has the optional bit1423 case LazyValueIdOptType: // it has the optional bit
...@@ -4710,8 +4716,7 @@ static void analyze_fn_async(CodeGen *g, ZigFn *fn, bool resolve_frame) {...@@ -4710,8 +4716,7 @@ static void analyze_fn_async(CodeGen *g, ZigFn *fn, bool resolve_frame) {
4710 }4716 }
4711 for (size_t i = 0; i < fn->await_list.length; i += 1) {4717 for (size_t i = 0; i < fn->await_list.length; i += 1) {
4712 IrInstGenAwait *await = fn->await_list.at(i);4718 IrInstGenAwait *await = fn->await_list.at(i);
4713 // TODO If this is a noasync await, it doesn't count4719 if (await->is_noasync) continue;
4714 // https://github.com/ziglang/zig/issues/3157
4715 switch (analyze_callee_async(g, fn, await->target_fn, await->base.base.source_node, must_not_be_async,4720 switch (analyze_callee_async(g, fn, await->target_fn, await->base.base.source_node, must_not_be_async,
4716 CallModifierNone))4721 CallModifierNone))
4717 {4722 {
...@@ -6315,8 +6320,9 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {...@@ -6315,8 +6320,9 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
6315 // The funtion call result of foo() must be spilled.6320 // The funtion call result of foo() must be spilled.
6316 for (size_t i = 0; i < fn->await_list.length; i += 1) {6321 for (size_t i = 0; i < fn->await_list.length; i += 1) {
6317 IrInstGenAwait *await = fn->await_list.at(i);6322 IrInstGenAwait *await = fn->await_list.at(i);
6318 // TODO If this is a noasync await, it doesn't suspend6323 if (await->is_noasync) {
6319 // https://github.com/ziglang/zig/issues/31576324 continue;
6325 }
6320 if (await->base.value->special != ConstValSpecialRuntime) {6326 if (await->base.value->special != ConstValSpecialRuntime) {
6321 // Known at comptime. No spill, no suspend.6327 // Known at comptime. No spill, no suspend.
6322 continue;6328 continue;
src/cache_hash.cpp+1-1
...@@ -5,7 +5,7 @@...@@ -5,7 +5,7 @@
5 * See http://opensource.org/licenses/MIT5 * See http://opensource.org/licenses/MIT
6 */6 */
77
8#include "userland.h"8#include "stage2.h"
9#include "cache_hash.hpp"9#include "cache_hash.hpp"
10#include "all_types.hpp"10#include "all_types.hpp"
11#include "buffer.hpp"11#include "buffer.hpp"
src/codegen.cpp+161-293
...@@ -18,7 +18,7 @@...@@ -18,7 +18,7 @@
18#include "target.hpp"18#include "target.hpp"
19#include "util.hpp"19#include "util.hpp"
20#include "zig_llvm.h"20#include "zig_llvm.h"
21#include "userland.h"21#include "stage2.h"
22#include "dump_analysis.hpp"22#include "dump_analysis.hpp"
23#include "softfloat.hpp"23#include "softfloat.hpp"
24#include "mem_profile.hpp"24#include "mem_profile.hpp"
...@@ -121,10 +121,6 @@ void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patc...@@ -121,10 +121,6 @@ void codegen_set_lib_version(CodeGen *g, size_t major, size_t minor, size_t patc
121 g->version_patch = patch;121 g->version_patch = patch;
122}122}
123123
124void codegen_set_emit_file_type(CodeGen *g, EmitFileType emit_file_type) {
125 g->emit_file_type = emit_file_type;
126}
127
128void codegen_set_each_lib_rpath(CodeGen *g, bool each_lib_rpath) {124void codegen_set_each_lib_rpath(CodeGen *g, bool each_lib_rpath) {
129 g->each_lib_rpath = each_lib_rpath;125 g->each_lib_rpath = each_lib_rpath;
130}126}
...@@ -975,8 +971,6 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) {...@@ -975,8 +971,6 @@ static Buf *panic_msg_buf(PanicMsgId msg_id) {
975 return buf_create_from_str("remainder division by zero or negative value");971 return buf_create_from_str("remainder division by zero or negative value");
976 case PanicMsgIdExactDivisionRemainder:972 case PanicMsgIdExactDivisionRemainder:
977 return buf_create_from_str("exact division produced remainder");973 return buf_create_from_str("exact division produced remainder");
978 case PanicMsgIdSliceWidenRemainder:
979 return buf_create_from_str("slice widening size mismatch");
980 case PanicMsgIdUnwrapOptionalFail:974 case PanicMsgIdUnwrapOptionalFail:
981 return buf_create_from_str("attempt to unwrap null");975 return buf_create_from_str("attempt to unwrap null");
982 case PanicMsgIdUnreachable:976 case PanicMsgIdUnreachable:
...@@ -3085,74 +3079,6 @@ static void add_error_range_check(CodeGen *g, ZigType *err_set_type, ZigType *in...@@ -3085,74 +3079,6 @@ static void add_error_range_check(CodeGen *g, ZigType *err_set_type, ZigType *in
3085 }3079 }
3086}3080}
30873081
3088static LLVMValueRef ir_render_resize_slice(CodeGen *g, IrExecutableGen *executable,
3089 IrInstGenResizeSlice *instruction)
3090{
3091 ZigType *actual_type = instruction->operand->value->type;
3092 ZigType *wanted_type = instruction->base.value->type;
3093 LLVMValueRef expr_val = ir_llvm_value(g, instruction->operand);
3094 assert(expr_val);
3095
3096 LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc);
3097 assert(wanted_type->id == ZigTypeIdStruct);
3098 assert(wanted_type->data.structure.special == StructSpecialSlice);
3099 assert(actual_type->id == ZigTypeIdStruct);
3100 assert(actual_type->data.structure.special == StructSpecialSlice);
3101
3102 ZigType *actual_pointer_type = actual_type->data.structure.fields[0]->type_entry;
3103 ZigType *actual_child_type = actual_pointer_type->data.pointer.child_type;
3104 ZigType *wanted_pointer_type = wanted_type->data.structure.fields[0]->type_entry;
3105 ZigType *wanted_child_type = wanted_pointer_type->data.pointer.child_type;
3106
3107
3108 size_t actual_ptr_index = actual_type->data.structure.fields[slice_ptr_index]->gen_index;
3109 size_t actual_len_index = actual_type->data.structure.fields[slice_len_index]->gen_index;
3110 size_t wanted_ptr_index = wanted_type->data.structure.fields[slice_ptr_index]->gen_index;
3111 size_t wanted_len_index = wanted_type->data.structure.fields[slice_len_index]->gen_index;
3112
3113 LLVMValueRef src_ptr_ptr = LLVMBuildStructGEP(g->builder, expr_val, (unsigned)actual_ptr_index, "");
3114 LLVMValueRef src_ptr = gen_load_untyped(g, src_ptr_ptr, 0, false, "");
3115 LLVMValueRef src_ptr_casted = LLVMBuildBitCast(g->builder, src_ptr,
3116 get_llvm_type(g, wanted_type->data.structure.fields[0]->type_entry), "");
3117 LLVMValueRef dest_ptr_ptr = LLVMBuildStructGEP(g->builder, result_loc,
3118 (unsigned)wanted_ptr_index, "");
3119 gen_store_untyped(g, src_ptr_casted, dest_ptr_ptr, 0, false);
3120
3121 LLVMValueRef src_len_ptr = LLVMBuildStructGEP(g->builder, expr_val, (unsigned)actual_len_index, "");
3122 LLVMValueRef src_len = gen_load_untyped(g, src_len_ptr, 0, false, "");
3123 uint64_t src_size = type_size(g, actual_child_type);
3124 uint64_t dest_size = type_size(g, wanted_child_type);
3125
3126 LLVMValueRef new_len;
3127 if (dest_size == 1) {
3128 LLVMValueRef src_size_val = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, src_size, false);
3129 new_len = LLVMBuildMul(g->builder, src_len, src_size_val, "");
3130 } else if (src_size == 1) {
3131 LLVMValueRef dest_size_val = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, dest_size, false);
3132 if (ir_want_runtime_safety(g, &instruction->base)) {
3133 LLVMValueRef remainder_val = LLVMBuildURem(g->builder, src_len, dest_size_val, "");
3134 LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_usize->llvm_type);
3135 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, remainder_val, zero, "");
3136 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "SliceWidenOk");
3137 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "SliceWidenFail");
3138 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
3139
3140 LLVMPositionBuilderAtEnd(g->builder, fail_block);
3141 gen_safety_crash(g, PanicMsgIdSliceWidenRemainder);
3142
3143 LLVMPositionBuilderAtEnd(g->builder, ok_block);
3144 }
3145 new_len = LLVMBuildExactUDiv(g->builder, src_len, dest_size_val, "");
3146 } else {
3147 zig_unreachable();
3148 }
3149
3150 LLVMValueRef dest_len_ptr = LLVMBuildStructGEP(g->builder, result_loc, (unsigned)wanted_len_index, "");
3151 gen_store_untyped(g, new_len, dest_len_ptr, 0, false);
3152
3153 return result_loc;
3154}
3155
3156static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutableGen *executable,3082static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutableGen *executable,
3157 IrInstGenCast *cast_instruction)3083 IrInstGenCast *cast_instruction)
3158{3084{
...@@ -5014,6 +4940,12 @@ static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutableGen *executable, IrIns...@@ -5014,6 +4940,12 @@ static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutableGen *executable, IrIns
5014 if (!type_has_bits(instruction->base.value->type)) {4940 if (!type_has_bits(instruction->base.value->type)) {
5015 return nullptr;4941 return nullptr;
5016 }4942 }
4943 if (instruction->operand->id == IrInstGenIdCall) {
4944 IrInstGenCall *call = reinterpret_cast<IrInstGenCall *>(instruction->operand);
4945 if (call->result_loc != nullptr) {
4946 return ir_llvm_value(g, call->result_loc);
4947 }
4948 }
5017 LLVMValueRef value = ir_llvm_value(g, instruction->operand);4949 LLVMValueRef value = ir_llvm_value(g, instruction->operand);
5018 if (handle_is_ptr(instruction->operand->value->type)) {4950 if (handle_is_ptr(instruction->operand->value->type)) {
5019 return value;4951 return value;
...@@ -6177,7 +6109,9 @@ static LLVMValueRef ir_render_await(CodeGen *g, IrExecutableGen *executable, IrI...@@ -6177,7 +6109,9 @@ static LLVMValueRef ir_render_await(CodeGen *g, IrExecutableGen *executable, IrI
6177 LLVMValueRef result_loc = (instruction->result_loc == nullptr) ?6109 LLVMValueRef result_loc = (instruction->result_loc == nullptr) ?
6178 nullptr : ir_llvm_value(g, instruction->result_loc);6110 nullptr : ir_llvm_value(g, instruction->result_loc);
61796111
6180 if (instruction->target_fn != nullptr && !fn_is_async(instruction->target_fn)) {6112 if (instruction->is_noasync ||
6113 (instruction->target_fn != nullptr && !fn_is_async(instruction->target_fn)))
6114 {
6181 return gen_await_early_return(g, &instruction->base, target_frame_ptr, result_type,6115 return gen_await_early_return(g, &instruction->base, target_frame_ptr, result_type,
6182 ptr_result_type, result_loc, true);6116 ptr_result_type, result_loc, true);
6183 }6117 }
...@@ -6476,8 +6410,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutableGen *executabl...@@ -6476,8 +6410,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutableGen *executabl
6476 return ir_render_assert_zero(g, executable, (IrInstGenAssertZero *)instruction);6410 return ir_render_assert_zero(g, executable, (IrInstGenAssertZero *)instruction);
6477 case IrInstGenIdAssertNonNull:6411 case IrInstGenIdAssertNonNull:
6478 return ir_render_assert_non_null(g, executable, (IrInstGenAssertNonNull *)instruction);6412 return ir_render_assert_non_null(g, executable, (IrInstGenAssertNonNull *)instruction);
6479 case IrInstGenIdResizeSlice:
6480 return ir_render_resize_slice(g, executable, (IrInstGenResizeSlice *)instruction);
6481 case IrInstGenIdPtrOfArrayToSlice:6413 case IrInstGenIdPtrOfArrayToSlice:
6482 return ir_render_ptr_of_array_to_slice(g, executable, (IrInstGenPtrOfArrayToSlice *)instruction);6414 return ir_render_ptr_of_array_to_slice(g, executable, (IrInstGenPtrOfArrayToSlice *)instruction);
6483 case IrInstGenIdSuspendBegin:6415 case IrInstGenIdSuspendBegin:
...@@ -6528,7 +6460,7 @@ static void ir_render(CodeGen *g, ZigFn *fn_entry) {...@@ -6528,7 +6460,7 @@ static void ir_render(CodeGen *g, ZigFn *fn_entry) {
6528 set_debug_location(g, instruction);6460 set_debug_location(g, instruction);
6529 }6461 }
6530 instruction->llvm_value = ir_render_instruction(g, executable, instruction);6462 instruction->llvm_value = ir_render_instruction(g, executable, instruction);
6531 if (instruction->spill != nullptr) {6463 if (instruction->spill != nullptr && instruction->llvm_value != nullptr) {
6532 LLVMValueRef spill_ptr = ir_llvm_value(g, instruction->spill);6464 LLVMValueRef spill_ptr = ir_llvm_value(g, instruction->spill);
6533 gen_assign_raw(g, spill_ptr, instruction->spill->value->type, instruction->llvm_value);6465 gen_assign_raw(g, spill_ptr, instruction->spill->value->type, instruction->llvm_value);
6534 instruction->llvm_value = nullptr;6466 instruction->llvm_value = nullptr;
...@@ -7912,50 +7844,44 @@ static void zig_llvm_emit_output(CodeGen *g) {...@@ -7912,50 +7844,44 @@ static void zig_llvm_emit_output(CodeGen *g) {
79127844
7913 bool is_small = g->build_mode == BuildModeSmallRelease;7845 bool is_small = g->build_mode == BuildModeSmallRelease;
79147846
7915 Buf *output_path = &g->o_file_output_path;
7916 char *err_msg = nullptr;7847 char *err_msg = nullptr;
7917 switch (g->emit_file_type) {7848 const char *asm_filename = nullptr;
7918 case EmitFileTypeBinary:7849 const char *bin_filename = nullptr;
7919 if (g->disable_bin_generation)7850 const char *llvm_ir_filename = nullptr;
7920 return;7851
7921 if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path),7852 if (g->emit_bin) bin_filename = buf_ptr(&g->o_file_output_path);
7922 ZigLLVM_EmitBinary, &err_msg, g->build_mode == BuildModeDebug, is_small,7853 if (g->emit_asm) asm_filename = buf_ptr(&g->asm_file_output_path);
7923 g->enable_time_report))7854 if (g->emit_llvm_ir) llvm_ir_filename = buf_ptr(&g->llvm_ir_file_output_path);
7924 {7855
7925 zig_panic("unable to write object file %s: %s", buf_ptr(output_path), err_msg);7856 // Unfortunately, LLVM shits the bed when we ask for both binary and assembly. So we call the entire
7926 }7857 // pipeline multiple times if this is requested.
7927 validate_inline_fns(g);7858 if (asm_filename != nullptr && bin_filename != nullptr) {
7928 g->link_objects.append(output_path);7859 if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, &err_msg, g->build_mode == BuildModeDebug,
7929 if (g->bundle_compiler_rt && (g->out_type == OutTypeObj ||7860 is_small, g->enable_time_report, nullptr, bin_filename, llvm_ir_filename))
7930 (g->out_type == OutTypeLib && !g->is_dynamic)))7861 {
7931 {7862 fprintf(stderr, "LLVM failed to emit file: %s\n", err_msg);
7932 zig_link_add_compiler_rt(g, g->sub_progress_node);7863 exit(1);
7933 }7864 }
7934 break;7865 bin_filename = nullptr;
7866 llvm_ir_filename = nullptr;
7867 }
79357868
7936 case EmitFileTypeAssembly:7869 if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, &err_msg, g->build_mode == BuildModeDebug,
7937 if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path),7870 is_small, g->enable_time_report, asm_filename, bin_filename, llvm_ir_filename))
7938 ZigLLVM_EmitAssembly, &err_msg, g->build_mode == BuildModeDebug, is_small,7871 {
7939 g->enable_time_report))7872 fprintf(stderr, "LLVM failed to emit file: %s\n", err_msg);
7940 {7873 exit(1);
7941 zig_panic("unable to write assembly file %s: %s", buf_ptr(output_path), err_msg);7874 }
7942 }
7943 validate_inline_fns(g);
7944 break;
79457875
7946 case EmitFileTypeLLVMIr:7876 validate_inline_fns(g);
7947 if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path),
7948 ZigLLVM_EmitLLVMIr, &err_msg, g->build_mode == BuildModeDebug, is_small,
7949 g->enable_time_report))
7950 {
7951 zig_panic("unable to write llvm-ir file %s: %s", buf_ptr(output_path), err_msg);
7952 }
7953 validate_inline_fns(g);
7954 break;
79557877
7956 default:7878 if (g->emit_bin) {
7957 zig_unreachable();7879 g->link_objects.append(&g->o_file_output_path);
7880 if (g->bundle_compiler_rt && (g->out_type == OutTypeObj || (g->out_type == OutTypeLib && !g->is_dynamic))) {
7881 zig_link_add_compiler_rt(g, g->sub_progress_node);
7882 }
7958 }7883 }
7884
7959 LLVMDisposeModule(g->module);7885 LLVMDisposeModule(g->module);
7960 g->module = nullptr;7886 g->module = nullptr;
7961 LLVMDisposeTargetData(g->target_data_ref);7887 LLVMDisposeTargetData(g->target_data_ref);
...@@ -8221,9 +8147,6 @@ static void define_builtin_fns(CodeGen *g) {...@@ -8221,9 +8147,6 @@ static void define_builtin_fns(CodeGen *g) {
8221 create_builtin_fn(g, BuiltinFnIdMemset, "memset", 3);8147 create_builtin_fn(g, BuiltinFnIdMemset, "memset", 3);
8222 create_builtin_fn(g, BuiltinFnIdSizeof, "sizeOf", 1);8148 create_builtin_fn(g, BuiltinFnIdSizeof, "sizeOf", 1);
8223 create_builtin_fn(g, BuiltinFnIdAlignOf, "alignOf", 1);8149 create_builtin_fn(g, BuiltinFnIdAlignOf, "alignOf", 1);
8224 create_builtin_fn(g, BuiltinFnIdMemberCount, "memberCount", 1);
8225 create_builtin_fn(g, BuiltinFnIdMemberType, "memberType", 2);
8226 create_builtin_fn(g, BuiltinFnIdMemberName, "memberName", 2);
8227 create_builtin_fn(g, BuiltinFnIdField, "field", 2);8150 create_builtin_fn(g, BuiltinFnIdField, "field", 2);
8228 create_builtin_fn(g, BuiltinFnIdTypeInfo, "typeInfo", 1);8151 create_builtin_fn(g, BuiltinFnIdTypeInfo, "typeInfo", 1);
8229 create_builtin_fn(g, BuiltinFnIdType, "Type", 1);8152 create_builtin_fn(g, BuiltinFnIdType, "Type", 1);
...@@ -8261,7 +8184,6 @@ static void define_builtin_fns(CodeGen *g) {...@@ -8261,7 +8184,6 @@ static void define_builtin_fns(CodeGen *g) {
8261 create_builtin_fn(g, BuiltinFnIdIntToEnum, "intToEnum", 2);8184 create_builtin_fn(g, BuiltinFnIdIntToEnum, "intToEnum", 2);
8262 create_builtin_fn(g, BuiltinFnIdCompileErr, "compileError", 1);8185 create_builtin_fn(g, BuiltinFnIdCompileErr, "compileError", 1);
8263 create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX);8186 create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX);
8264 create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int
8265 create_builtin_fn(g, BuiltinFnIdVectorType, "Vector", 2);8187 create_builtin_fn(g, BuiltinFnIdVectorType, "Vector", 2);
8266 create_builtin_fn(g, BuiltinFnIdShuffle, "shuffle", 4);8188 create_builtin_fn(g, BuiltinFnIdShuffle, "shuffle", 4);
8267 create_builtin_fn(g, BuiltinFnIdSplat, "splat", 2);8189 create_builtin_fn(g, BuiltinFnIdSplat, "splat", 2);
...@@ -8299,22 +8221,18 @@ static void define_builtin_fns(CodeGen *g) {...@@ -8299,22 +8221,18 @@ static void define_builtin_fns(CodeGen *g) {
8299 create_builtin_fn(g, BuiltinFnIdRound, "round", 1);8221 create_builtin_fn(g, BuiltinFnIdRound, "round", 1);
8300 create_builtin_fn(g, BuiltinFnIdMulAdd, "mulAdd", 4);8222 create_builtin_fn(g, BuiltinFnIdMulAdd, "mulAdd", 4);
8301 create_builtin_fn(g, BuiltinFnIdAsyncCall, "asyncCall", SIZE_MAX);8223 create_builtin_fn(g, BuiltinFnIdAsyncCall, "asyncCall", SIZE_MAX);
8302 create_builtin_fn(g, BuiltinFnIdTypeId, "typeId", 1);
8303 create_builtin_fn(g, BuiltinFnIdShlExact, "shlExact", 2);8224 create_builtin_fn(g, BuiltinFnIdShlExact, "shlExact", 2);
8304 create_builtin_fn(g, BuiltinFnIdShrExact, "shrExact", 2);8225 create_builtin_fn(g, BuiltinFnIdShrExact, "shrExact", 2);
8305 create_builtin_fn(g, BuiltinFnIdSetEvalBranchQuota, "setEvalBranchQuota", 1);8226 create_builtin_fn(g, BuiltinFnIdSetEvalBranchQuota, "setEvalBranchQuota", 1);
8306 create_builtin_fn(g, BuiltinFnIdAlignCast, "alignCast", 2);8227 create_builtin_fn(g, BuiltinFnIdAlignCast, "alignCast", 2);
8307 create_builtin_fn(g, BuiltinFnIdOpaqueType, "OpaqueType", 0);8228 create_builtin_fn(g, BuiltinFnIdOpaqueType, "OpaqueType", 0);
8308 create_builtin_fn(g, BuiltinFnIdSetAlignStack, "setAlignStack", 1);8229 create_builtin_fn(g, BuiltinFnIdSetAlignStack, "setAlignStack", 1);
8309 create_builtin_fn(g, BuiltinFnIdArgType, "ArgType", 2);
8310 create_builtin_fn(g, BuiltinFnIdExport, "export", 2);8230 create_builtin_fn(g, BuiltinFnIdExport, "export", 2);
8311 create_builtin_fn(g, BuiltinFnIdErrorReturnTrace, "errorReturnTrace", 0);8231 create_builtin_fn(g, BuiltinFnIdErrorReturnTrace, "errorReturnTrace", 0);
8312 create_builtin_fn(g, BuiltinFnIdAtomicRmw, "atomicRmw", 5);8232 create_builtin_fn(g, BuiltinFnIdAtomicRmw, "atomicRmw", 5);
8313 create_builtin_fn(g, BuiltinFnIdAtomicLoad, "atomicLoad", 3);8233 create_builtin_fn(g, BuiltinFnIdAtomicLoad, "atomicLoad", 3);
8314 create_builtin_fn(g, BuiltinFnIdAtomicStore, "atomicStore", 4);8234 create_builtin_fn(g, BuiltinFnIdAtomicStore, "atomicStore", 4);
8315 create_builtin_fn(g, BuiltinFnIdErrSetCast, "errSetCast", 2);8235 create_builtin_fn(g, BuiltinFnIdErrSetCast, "errSetCast", 2);
8316 create_builtin_fn(g, BuiltinFnIdToBytes, "sliceToBytes", 1);
8317 create_builtin_fn(g, BuiltinFnIdFromBytes, "bytesToSlice", 2);
8318 create_builtin_fn(g, BuiltinFnIdThis, "This", 0);8236 create_builtin_fn(g, BuiltinFnIdThis, "This", 0);
8319 create_builtin_fn(g, BuiltinFnIdHasDecl, "hasDecl", 2);8237 create_builtin_fn(g, BuiltinFnIdHasDecl, "hasDecl", 2);
8320 create_builtin_fn(g, BuiltinFnIdUnionInit, "unionInit", 3);8238 create_builtin_fn(g, BuiltinFnIdUnionInit, "unionInit", 3);
...@@ -8361,9 +8279,11 @@ static bool detect_dynamic_link(CodeGen *g) {...@@ -8361,9 +8279,11 @@ static bool detect_dynamic_link(CodeGen *g) {
8361 return true;8279 return true;
8362 if (g->zig_target->os == OsFreestanding)8280 if (g->zig_target->os == OsFreestanding)
8363 return false;8281 return false;
8364 if (target_requires_pic(g->zig_target, g->libc_link_lib != nullptr))8282 if (target_os_requires_libc(g->zig_target->os))
8365 return true;8283 return true;
8366 // If there are no dynamic libraries then we can disable PIC8284 if (g->libc_link_lib != nullptr && target_is_glibc(g->zig_target))
8285 return true;
8286 // If there are no dynamic libraries then we can disable dynamic linking.
8367 for (size_t i = 0; i < g->link_libs_list.length; i += 1) {8287 for (size_t i = 0; i < g->link_libs_list.length; i += 1) {
8368 LinkLib *link_lib = g->link_libs_list.at(i);8288 LinkLib *link_lib = g->link_libs_list.at(i);
8369 if (target_is_libc_lib_name(g->zig_target, buf_ptr(link_lib->name)))8289 if (target_is_libc_lib_name(g->zig_target, buf_ptr(link_lib->name)))
...@@ -8498,25 +8418,9 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -8498,25 +8418,9 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
8498 for (uint32_t arch_i = 0; arch_i < field_count; arch_i += 1) {8418 for (uint32_t arch_i = 0; arch_i < field_count; arch_i += 1) {
8499 ZigLLVM_ArchType arch = target_arch_enum(arch_i);8419 ZigLLVM_ArchType arch = target_arch_enum(arch_i);
8500 const char *arch_name = target_arch_name(arch);8420 const char *arch_name = target_arch_name(arch);
8501 SubArchList sub_arch_list = target_subarch_list(arch);8421 if (arch == g->zig_target->arch) {
8502 if (sub_arch_list == SubArchListNone) {8422 g->target_arch_index = arch_i;
8503 if (arch == g->zig_target->arch) {8423 cur_arch = arch_name;
8504 g->target_arch_index = arch_i;
8505 cur_arch = buf_ptr(buf_sprintf("Arch.%s", arch_name));
8506 }
8507 } else {
8508 const char *sub_arch_list_name = target_subarch_list_name(sub_arch_list);
8509 if (arch == g->zig_target->arch) {
8510 size_t sub_count = target_subarch_count(sub_arch_list);
8511 for (size_t sub_i = 0; sub_i < sub_count; sub_i += 1) {
8512 ZigLLVM_SubArchType sub = target_subarch_enum(sub_arch_list, sub_i);
8513 if (sub == g->zig_target->sub_arch) {
8514 g->target_sub_arch_index = sub_i;
8515 cur_arch = buf_ptr(buf_sprintf("Arch{ .%s = Arch.%s.%s }",
8516 arch_name, sub_arch_list_name, target_subarch_name(sub)));
8517 }
8518 }
8519 }
8520 }8424 }
8521 }8425 }
8522 }8426 }
...@@ -8610,22 +8514,19 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {...@@ -8610,22 +8514,19 @@ Buf *codegen_generate_builtin_source(CodeGen *g) {
8610 break;8514 break;
8611 }8515 }
8612 buf_appendf(contents, "pub const output_mode = OutputMode.%s;\n", out_type);8516 buf_appendf(contents, "pub const output_mode = OutputMode.%s;\n", out_type);
8613 const char *link_type = g->is_dynamic ? "Dynamic" : "Static";8517 const char *link_type = g->have_dynamic_link ? "Dynamic" : "Static";
8614 buf_appendf(contents, "pub const link_mode = LinkMode.%s;\n", link_type);8518 buf_appendf(contents, "pub const link_mode = LinkMode.%s;\n", link_type);
8615 buf_appendf(contents, "pub const is_test = %s;\n", bool_to_str(g->is_test_build));8519 buf_appendf(contents, "pub const is_test = %s;\n", bool_to_str(g->is_test_build));
8616 buf_appendf(contents, "pub const single_threaded = %s;\n", bool_to_str(g->is_single_threaded));8520 buf_appendf(contents, "pub const single_threaded = %s;\n", bool_to_str(g->is_single_threaded));
8617 buf_appendf(contents, "pub const os = Os.%s;\n", cur_os);8521 buf_appendf(contents, "pub const os = Os.%s;\n", cur_os);
8618 buf_appendf(contents, "pub const arch = %s;\n", cur_arch);8522 buf_appendf(contents, "pub const arch = Arch.%s;\n", cur_arch);
8619 buf_appendf(contents, "pub const abi = Abi.%s;\n", cur_abi);8523 buf_appendf(contents, "pub const abi = Abi.%s;\n", cur_abi);
8620 {8524 {
8621 buf_append_str(contents, "pub const cpu_features: CpuFeatures = ");8525 buf_append_str(contents, "pub const cpu: Cpu = ");
8622 if (g->zig_target->cpu_features != nullptr) {8526 if (g->zig_target->builtin_str != nullptr) {
8623 const char *ptr;8527 buf_append_str(contents, g->zig_target->builtin_str);
8624 size_t len;
8625 stage2_cpu_features_get_builtin_str(g->zig_target->cpu_features, &ptr, &len);
8626 buf_append_mem(contents, ptr, len);
8627 } else {8528 } else {
8628 buf_append_str(contents, "arch.getBaselineCpuFeatures();\n");8529 buf_append_str(contents, "Target.Cpu.baseline(arch);\n");
8629 }8530 }
8630 }8531 }
8631 if (g->libc_link_lib != nullptr && g->zig_target->glibc_version != nullptr) {8532 if (g->libc_link_lib != nullptr && g->zig_target->glibc_version != nullptr) {
...@@ -8717,22 +8618,18 @@ static Error define_builtin_compile_vars(CodeGen *g) {...@@ -8717,22 +8618,18 @@ static Error define_builtin_compile_vars(CodeGen *g) {
8717 cache_int(&cache_hash, g->build_mode);8618 cache_int(&cache_hash, g->build_mode);
8718 cache_bool(&cache_hash, g->strip_debug_symbols);8619 cache_bool(&cache_hash, g->strip_debug_symbols);
8719 cache_int(&cache_hash, g->out_type);8620 cache_int(&cache_hash, g->out_type);
8720 cache_bool(&cache_hash, g->is_dynamic);8621 cache_bool(&cache_hash, detect_dynamic_link(g));
8721 cache_bool(&cache_hash, g->is_test_build);8622 cache_bool(&cache_hash, g->is_test_build);
8722 cache_bool(&cache_hash, g->is_single_threaded);8623 cache_bool(&cache_hash, g->is_single_threaded);
8723 cache_bool(&cache_hash, g->test_is_evented);8624 cache_bool(&cache_hash, g->test_is_evented);
8724 cache_int(&cache_hash, g->code_model);8625 cache_int(&cache_hash, g->code_model);
8725 cache_int(&cache_hash, g->zig_target->is_native);8626 cache_int(&cache_hash, g->zig_target->is_native);
8726 cache_int(&cache_hash, g->zig_target->arch);8627 cache_int(&cache_hash, g->zig_target->arch);
8727 cache_int(&cache_hash, g->zig_target->sub_arch);
8728 cache_int(&cache_hash, g->zig_target->vendor);8628 cache_int(&cache_hash, g->zig_target->vendor);
8729 cache_int(&cache_hash, g->zig_target->os);8629 cache_int(&cache_hash, g->zig_target->os);
8730 cache_int(&cache_hash, g->zig_target->abi);8630 cache_int(&cache_hash, g->zig_target->abi);
8731 if (g->zig_target->cpu_features != nullptr) {8631 if (g->zig_target->cache_hash != nullptr) {
8732 const char *ptr;8632 cache_str(&cache_hash, g->zig_target->cache_hash);
8733 size_t len;
8734 stage2_cpu_features_get_cache_hash(g->zig_target->cpu_features, &ptr, &len);
8735 cache_str(&cache_hash, ptr);
8736 }8633 }
8737 if (g->zig_target->glibc_version != nullptr) {8634 if (g->zig_target->glibc_version != nullptr) {
8738 cache_int(&cache_hash, g->zig_target->glibc_version->major);8635 cache_int(&cache_hash, g->zig_target->glibc_version->major);
...@@ -8867,9 +8764,11 @@ static void init(CodeGen *g) {...@@ -8867,9 +8764,11 @@ static void init(CodeGen *g) {
8867 }8764 }
88688765
8869 // Override CPU and features if defined by user.8766 // Override CPU and features if defined by user.
8870 if (g->zig_target->cpu_features != nullptr) {8767 if (g->zig_target->llvm_cpu_name != nullptr) {
8871 target_specific_cpu_args = stage2_cpu_features_get_llvm_cpu(g->zig_target->cpu_features);8768 target_specific_cpu_args = g->zig_target->llvm_cpu_name;
8872 target_specific_features = stage2_cpu_features_get_llvm_features(g->zig_target->cpu_features);8769 }
8770 if (g->zig_target->llvm_cpu_features != nullptr) {
8771 target_specific_features = g->zig_target->llvm_cpu_features;
8873 }8772 }
8874 if (g->verbose_llvm_cpu_features) {8773 if (g->verbose_llvm_cpu_features) {
8875 fprintf(stderr, "name=%s triple=%s\n", buf_ptr(g->root_out_name), buf_ptr(&g->llvm_triple_str));8774 fprintf(stderr, "name=%s triple=%s\n", buf_ptr(g->root_out_name), buf_ptr(&g->llvm_triple_str));
...@@ -8943,6 +8842,8 @@ static void init(CodeGen *g) {...@@ -8943,6 +8842,8 @@ static void init(CodeGen *g) {
8943}8842}
89448843
8945static void detect_dynamic_linker(CodeGen *g) {8844static void detect_dynamic_linker(CodeGen *g) {
8845 Error err;
8846
8946 if (g->dynamic_linker_path != nullptr)8847 if (g->dynamic_linker_path != nullptr)
8947 return;8848 return;
8948 if (!g->have_dynamic_link)8849 if (!g->have_dynamic_link)
...@@ -8950,42 +8851,16 @@ static void detect_dynamic_linker(CodeGen *g) {...@@ -8950,42 +8851,16 @@ static void detect_dynamic_linker(CodeGen *g) {
8950 if (g->out_type == OutTypeObj || (g->out_type == OutTypeLib && !g->is_dynamic))8851 if (g->out_type == OutTypeObj || (g->out_type == OutTypeLib && !g->is_dynamic))
8951 return;8852 return;
89528853
8953 const char *standard_ld_path = target_dynamic_linker(g->zig_target);8854 char *dynamic_linker_ptr;
8954 if (standard_ld_path == nullptr)8855 size_t dynamic_linker_len;
8955 return;8856 if ((err = stage2_detect_dynamic_linker(g->zig_target, &dynamic_linker_ptr, &dynamic_linker_len))) {
89568857 if (err == ErrorTargetHasNoDynamicLinker) return;
8957 if (g->zig_target->is_native) {8858 fprintf(stderr, "Unable to detect dynamic linker: %s\n", err_str(err));
8958 // target_dynamic_linker is usually correct. However on some systems, such as NixOS8859 exit(1);
8959 // it will be incorrect. See if we can do better by looking at what zig's own
8960 // dynamic linker path is.
8961 g->dynamic_linker_path = get_self_dynamic_linker_path();
8962 if (g->dynamic_linker_path != nullptr)
8963 return;
8964
8965 // If Zig is statically linked, such as via distributed binary static builds, the above
8966 // trick won't work. What are we left with? Try to run the system C compiler and get
8967 // it to tell us the dynamic linker path
8968#if defined(ZIG_OS_LINUX)
8969 {
8970 Error err;
8971 Buf *result = buf_alloc();
8972 for (size_t i = 0; possible_ld_names[i] != NULL; i += 1) {
8973 const char *lib_name = possible_ld_names[i];
8974 if ((err = zig_libc_cc_print_file_name(lib_name, result, false, true))) {
8975 if (err != ErrorCCompilerCannotFindFile && err != ErrorNoCCompilerInstalled) {
8976 fprintf(stderr, "Unable to detect native dynamic linker: %s\n", err_str(err));
8977 exit(1);
8978 }
8979 continue;
8980 }
8981 g->dynamic_linker_path = result;
8982 return;
8983 }
8984 }
8985#endif
8986 }8860 }
89878861 g->dynamic_linker_path = buf_create_from_mem(dynamic_linker_ptr, dynamic_linker_len);
8988 g->dynamic_linker_path = buf_create_from_str(standard_ld_path);8862 // Skips heap::c_allocator because the memory is allocated by stage2 library.
8863 free(dynamic_linker_ptr);
8989}8864}
89908865
8991static void detect_libc(CodeGen *g) {8866static void detect_libc(CodeGen *g) {
...@@ -9014,16 +8889,16 @@ static void detect_libc(CodeGen *g) {...@@ -9014,16 +8889,16 @@ static void detect_libc(CodeGen *g) {
9014 buf_ptr(g->zig_lib_dir), target_os_name(g->zig_target->os));8889 buf_ptr(g->zig_lib_dir), target_os_name(g->zig_target->os));
90158890
9016 g->libc_include_dir_len = 4;8891 g->libc_include_dir_len = 4;
9017 g->libc_include_dir_list = heap::c_allocator.allocate<Buf*>(g->libc_include_dir_len);8892 g->libc_include_dir_list = heap::c_allocator.allocate<const char*>(g->libc_include_dir_len);
9018 g->libc_include_dir_list[0] = arch_include_dir;8893 g->libc_include_dir_list[0] = buf_ptr(arch_include_dir);
9019 g->libc_include_dir_list[1] = generic_include_dir;8894 g->libc_include_dir_list[1] = buf_ptr(generic_include_dir);
9020 g->libc_include_dir_list[2] = arch_os_include_dir;8895 g->libc_include_dir_list[2] = buf_ptr(arch_os_include_dir);
9021 g->libc_include_dir_list[3] = generic_os_include_dir;8896 g->libc_include_dir_list[3] = buf_ptr(generic_os_include_dir);
9022 return;8897 return;
9023 }8898 }
90248899
9025 if (g->zig_target->is_native) {8900 if (g->zig_target->is_native) {
9026 g->libc = heap::c_allocator.create<ZigLibCInstallation>();8901 g->libc = heap::c_allocator.create<Stage2LibCInstallation>();
90278902
9028 // search for native_libc.txt in following dirs:8903 // search for native_libc.txt in following dirs:
9029 // - LOCAL_CACHE_DIR8904 // - LOCAL_CACHE_DIR
...@@ -9068,8 +8943,8 @@ static void detect_libc(CodeGen *g) {...@@ -9068,8 +8943,8 @@ static void detect_libc(CodeGen *g) {
9068 if (libc_txt == nullptr)8943 if (libc_txt == nullptr)
9069 libc_txt = &global_libc_txt;8944 libc_txt = &global_libc_txt;
90708945
9071 if ((err = zig_libc_parse(g->libc, libc_txt, g->zig_target, false))) {8946 if ((err = stage2_libc_parse(g->libc, buf_ptr(libc_txt)))) {
9072 if ((err = zig_libc_find_native(g->libc, true))) {8947 if ((err = stage2_libc_find_native(g->libc))) {
9073 fprintf(stderr,8948 fprintf(stderr,
9074 "Unable to link against libc: Unable to find libc installation: %s\n"8949 "Unable to link against libc: Unable to find libc installation: %s\n"
9075 "See `zig libc --help` for more details.\n", err_str(err));8950 "See `zig libc --help` for more details.\n", err_str(err));
...@@ -9089,7 +8964,7 @@ static void detect_libc(CodeGen *g) {...@@ -9089,7 +8964,7 @@ static void detect_libc(CodeGen *g) {
9089 fprintf(stderr, "Unable to open %s: %s\n", buf_ptr(native_libc_tmp), strerror(errno));8964 fprintf(stderr, "Unable to open %s: %s\n", buf_ptr(native_libc_tmp), strerror(errno));
9090 exit(1);8965 exit(1);
9091 }8966 }
9092 zig_libc_render(g->libc, file);8967 stage2_libc_render(g->libc, file);
9093 if (fclose(file) != 0) {8968 if (fclose(file) != 0) {
9094 fprintf(stderr, "Unable to save %s: %s\n", buf_ptr(native_libc_tmp), strerror(errno));8969 fprintf(stderr, "Unable to save %s: %s\n", buf_ptr(native_libc_tmp), strerror(errno));
9095 exit(1);8970 exit(1);
...@@ -9099,27 +8974,28 @@ static void detect_libc(CodeGen *g) {...@@ -9099,27 +8974,28 @@ static void detect_libc(CodeGen *g) {
9099 exit(1);8974 exit(1);
9100 }8975 }
9101 }8976 }
9102 bool want_sys_dir = !buf_eql_buf(&g->libc->include_dir, &g->libc->sys_include_dir);8977 bool want_sys_dir = !mem_eql_mem(g->libc->include_dir, g->libc->include_dir_len,
8978 g->libc->sys_include_dir, g->libc->sys_include_dir_len);
9103 size_t want_um_and_shared_dirs = (g->zig_target->os == OsWindows) ? 2 : 0;8979 size_t want_um_and_shared_dirs = (g->zig_target->os == OsWindows) ? 2 : 0;
9104 size_t dir_count = 1 + want_sys_dir + want_um_and_shared_dirs;8980 size_t dir_count = 1 + want_sys_dir + want_um_and_shared_dirs;
9105 g->libc_include_dir_len = 0;8981 g->libc_include_dir_len = 0;
9106 g->libc_include_dir_list = heap::c_allocator.allocate<Buf*>(dir_count);8982 g->libc_include_dir_list = heap::c_allocator.allocate<const char *>(dir_count);
91078983
9108 g->libc_include_dir_list[g->libc_include_dir_len] = &g->libc->include_dir;8984 g->libc_include_dir_list[g->libc_include_dir_len] = g->libc->include_dir;
9109 g->libc_include_dir_len += 1;8985 g->libc_include_dir_len += 1;
91108986
9111 if (want_sys_dir) {8987 if (want_sys_dir) {
9112 g->libc_include_dir_list[g->libc_include_dir_len] = &g->libc->sys_include_dir;8988 g->libc_include_dir_list[g->libc_include_dir_len] = g->libc->sys_include_dir;
9113 g->libc_include_dir_len += 1;8989 g->libc_include_dir_len += 1;
9114 }8990 }
91158991
9116 if (want_um_and_shared_dirs != 0) {8992 if (want_um_and_shared_dirs != 0) {
9117 g->libc_include_dir_list[g->libc_include_dir_len] = buf_sprintf("%s" OS_SEP ".." OS_SEP "um",8993 g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buf_sprintf(
9118 buf_ptr(&g->libc->include_dir));8994 "%s" OS_SEP ".." OS_SEP "um", g->libc->include_dir));
9119 g->libc_include_dir_len += 1;8995 g->libc_include_dir_len += 1;
91208996
9121 g->libc_include_dir_list[g->libc_include_dir_len] = buf_sprintf("%s" OS_SEP ".." OS_SEP "shared",8997 g->libc_include_dir_list[g->libc_include_dir_len] = buf_ptr(buf_sprintf(
9122 buf_ptr(&g->libc->include_dir));8998 "%s" OS_SEP ".." OS_SEP "shared", g->libc->include_dir));
9123 g->libc_include_dir_len += 1;8999 g->libc_include_dir_len += 1;
9124 }9000 }
9125 assert(g->libc_include_dir_len == dir_count);9001 assert(g->libc_include_dir_len == dir_count);
...@@ -9194,9 +9070,9 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa...@@ -9194,9 +9070,9 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa
9194 args.append(buf_ptr(g->zig_c_headers_dir));9070 args.append(buf_ptr(g->zig_c_headers_dir));
91959071
9196 for (size_t i = 0; i < g->libc_include_dir_len; i += 1) {9072 for (size_t i = 0; i < g->libc_include_dir_len; i += 1) {
9197 Buf *include_dir = g->libc_include_dir_list[i];9073 const char *include_dir = g->libc_include_dir_list[i];
9198 args.append("-isystem");9074 args.append("-isystem");
9199 args.append(buf_ptr(include_dir));9075 args.append(include_dir);
9200 }9076 }
92019077
9202 if (g->zig_target->is_native) {9078 if (g->zig_target->is_native) {
...@@ -9207,19 +9083,17 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa...@@ -9207,19 +9083,17 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa
9207 args.append("-target");9083 args.append("-target");
9208 args.append(buf_ptr(&g->llvm_triple_str));9084 args.append(buf_ptr(&g->llvm_triple_str));
92099085
9210 const char *llvm_cpu = stage2_cpu_features_get_llvm_cpu(g->zig_target->cpu_features);9086 if (g->zig_target->llvm_cpu_name != nullptr) {
9211 if (llvm_cpu != nullptr) {
9212 args.append("-Xclang");9087 args.append("-Xclang");
9213 args.append("-target-cpu");9088 args.append("-target-cpu");
9214 args.append("-Xclang");9089 args.append("-Xclang");
9215 args.append(llvm_cpu);9090 args.append(g->zig_target->llvm_cpu_name);
9216 }9091 }
9217 const char *llvm_target_features = stage2_cpu_features_get_llvm_features(g->zig_target->cpu_features);9092 if (g->zig_target->llvm_cpu_features != nullptr) {
9218 if (llvm_target_features != nullptr) {
9219 args.append("-Xclang");9093 args.append("-Xclang");
9220 args.append("-target-feature");9094 args.append("-target-feature");
9221 args.append("-Xclang");9095 args.append("-Xclang");
9222 args.append(llvm_target_features);9096 args.append(g->zig_target->llvm_cpu_features);
9223 }9097 }
9224 }9098 }
92259099
...@@ -9652,10 +9526,9 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose...@@ -9652,10 +9526,9 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose
9652 cache_buf(cache_hash, compiler_id);9526 cache_buf(cache_hash, compiler_id);
9653 cache_int(cache_hash, g->err_color);9527 cache_int(cache_hash, g->err_color);
9654 cache_buf(cache_hash, g->zig_c_headers_dir);9528 cache_buf(cache_hash, g->zig_c_headers_dir);
9655 cache_list_of_buf(cache_hash, g->libc_include_dir_list, g->libc_include_dir_len);9529 cache_list_of_str(cache_hash, g->libc_include_dir_list, g->libc_include_dir_len);
9656 cache_int(cache_hash, g->zig_target->is_native);9530 cache_int(cache_hash, g->zig_target->is_native);
9657 cache_int(cache_hash, g->zig_target->arch);9531 cache_int(cache_hash, g->zig_target->arch);
9658 cache_int(cache_hash, g->zig_target->sub_arch);
9659 cache_int(cache_hash, g->zig_target->vendor);9532 cache_int(cache_hash, g->zig_target->vendor);
9660 cache_int(cache_hash, g->zig_target->os);9533 cache_int(cache_hash, g->zig_target->os);
9661 cache_int(cache_hash, g->zig_target->abi);9534 cache_int(cache_hash, g->zig_target->abi);
...@@ -10419,15 +10292,11 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {...@@ -10419,15 +10292,11 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
10419 cache_int(ch, g->out_type);10292 cache_int(ch, g->out_type);
10420 cache_bool(ch, g->zig_target->is_native);10293 cache_bool(ch, g->zig_target->is_native);
10421 cache_int(ch, g->zig_target->arch);10294 cache_int(ch, g->zig_target->arch);
10422 cache_int(ch, g->zig_target->sub_arch);
10423 cache_int(ch, g->zig_target->vendor);10295 cache_int(ch, g->zig_target->vendor);
10424 cache_int(ch, g->zig_target->os);10296 cache_int(ch, g->zig_target->os);
10425 cache_int(ch, g->zig_target->abi);10297 cache_int(ch, g->zig_target->abi);
10426 if (g->zig_target->cpu_features != nullptr) {10298 if (g->zig_target->cache_hash != nullptr) {
10427 const char *ptr;10299 cache_str(ch, g->zig_target->cache_hash);
10428 size_t len;
10429 stage2_cpu_features_get_cache_hash(g->zig_target->cpu_features, &ptr, &len);
10430 cache_str(ch, ptr);
10431 }10300 }
10432 if (g->zig_target->glibc_version != nullptr) {10301 if (g->zig_target->glibc_version != nullptr) {
10433 cache_int(ch, g->zig_target->glibc_version->major);10302 cache_int(ch, g->zig_target->glibc_version->major);
...@@ -10457,7 +10326,9 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {...@@ -10457,7 +10326,9 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
10457 cache_bool(ch, g->function_sections);10326 cache_bool(ch, g->function_sections);
10458 cache_bool(ch, g->enable_dump_analysis);10327 cache_bool(ch, g->enable_dump_analysis);
10459 cache_bool(ch, g->enable_doc_generation);10328 cache_bool(ch, g->enable_doc_generation);
10460 cache_bool(ch, g->disable_bin_generation);10329 cache_bool(ch, g->emit_bin);
10330 cache_bool(ch, g->emit_llvm_ir);
10331 cache_bool(ch, g->emit_asm);
10461 cache_buf_opt(ch, g->mmacosx_version_min);10332 cache_buf_opt(ch, g->mmacosx_version_min);
10462 cache_buf_opt(ch, g->mios_version_min);10333 cache_buf_opt(ch, g->mios_version_min);
10463 cache_usize(ch, g->version_major);10334 cache_usize(ch, g->version_major);
...@@ -10468,11 +10339,11 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {...@@ -10468,11 +10339,11 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
10468 cache_list_of_str(ch, g->lib_dirs.items, g->lib_dirs.length);10339 cache_list_of_str(ch, g->lib_dirs.items, g->lib_dirs.length);
10469 cache_list_of_str(ch, g->framework_dirs.items, g->framework_dirs.length);10340 cache_list_of_str(ch, g->framework_dirs.items, g->framework_dirs.length);
10470 if (g->libc) {10341 if (g->libc) {
10471 cache_buf(ch, &g->libc->include_dir);10342 cache_str(ch, g->libc->include_dir);
10472 cache_buf(ch, &g->libc->sys_include_dir);10343 cache_str(ch, g->libc->sys_include_dir);
10473 cache_buf(ch, &g->libc->crt_dir);10344 cache_str(ch, g->libc->crt_dir);
10474 cache_buf(ch, &g->libc->msvc_lib_dir);10345 cache_str(ch, g->libc->msvc_lib_dir);
10475 cache_buf(ch, &g->libc->kernel32_lib_dir);10346 cache_str(ch, g->libc->kernel32_lib_dir);
10476 }10347 }
10477 cache_buf_opt(ch, g->dynamic_linker_path);10348 cache_buf_opt(ch, g->dynamic_linker_path);
10478 cache_buf_opt(ch, g->version_script_path);10349 cache_buf_opt(ch, g->version_script_path);
...@@ -10502,58 +10373,54 @@ static void resolve_out_paths(CodeGen *g) {...@@ -10502,58 +10373,54 @@ static void resolve_out_paths(CodeGen *g) {
10502 assert(g->output_dir != nullptr);10373 assert(g->output_dir != nullptr);
10503 assert(g->root_out_name != nullptr);10374 assert(g->root_out_name != nullptr);
1050410375
10505 Buf *out_basename = buf_create_from_buf(g->root_out_name);10376 if (g->emit_bin) {
10506 Buf *o_basename = buf_create_from_buf(g->root_out_name);10377 Buf *out_basename = buf_create_from_buf(g->root_out_name);
10507 switch (g->emit_file_type) {10378 Buf *o_basename = buf_create_from_buf(g->root_out_name);
10508 case EmitFileTypeBinary: {10379 switch (g->out_type) {
10509 switch (g->out_type) {10380 case OutTypeUnknown:
10510 case OutTypeUnknown:10381 zig_unreachable();
10511 zig_unreachable();10382 case OutTypeObj:
10512 case OutTypeObj:10383 if (g->enable_cache && g->link_objects.length == 1 && !need_llvm_module(g)) {
10513 if (g->enable_cache && g->link_objects.length == 1 && !need_llvm_module(g)) {10384 buf_init_from_buf(&g->bin_file_output_path, g->link_objects.at(0));
10514 buf_init_from_buf(&g->output_file_path, g->link_objects.at(0));10385 return;
10515 return;10386 }
10516 }10387 if (need_llvm_module(g) && g->link_objects.length != 0 && !g->enable_cache &&
10517 if (need_llvm_module(g) && g->link_objects.length != 0 && !g->enable_cache &&10388 buf_eql_buf(o_basename, out_basename))
10518 buf_eql_buf(o_basename, out_basename))10389 {
10519 {10390 // make it not collide with main output object
10520 // make it not collide with main output object10391 buf_append_str(o_basename, ".root");
10521 buf_append_str(o_basename, ".root");10392 }
10522 }10393 buf_append_str(o_basename, target_o_file_ext(g->zig_target));
10523 buf_append_str(o_basename, target_o_file_ext(g->zig_target));10394 buf_append_str(out_basename, target_o_file_ext(g->zig_target));
10524 buf_append_str(out_basename, target_o_file_ext(g->zig_target));10395 break;
10525 break;10396 case OutTypeExe:
10526 case OutTypeExe:10397 buf_append_str(o_basename, target_o_file_ext(g->zig_target));
10527 buf_append_str(o_basename, target_o_file_ext(g->zig_target));10398 buf_append_str(out_basename, target_exe_file_ext(g->zig_target));
10528 buf_append_str(out_basename, target_exe_file_ext(g->zig_target));10399 break;
10529 break;10400 case OutTypeLib:
10530 case OutTypeLib:10401 buf_append_str(o_basename, target_o_file_ext(g->zig_target));
10531 buf_append_str(o_basename, target_o_file_ext(g->zig_target));10402 buf_resize(out_basename, 0);
10532 buf_resize(out_basename, 0);10403 buf_append_str(out_basename, target_lib_file_prefix(g->zig_target));
10533 buf_append_str(out_basename, target_lib_file_prefix(g->zig_target));10404 buf_append_buf(out_basename, g->root_out_name);
10534 buf_append_buf(out_basename, g->root_out_name);10405 buf_append_str(out_basename, target_lib_file_ext(g->zig_target, !g->is_dynamic,
10535 buf_append_str(out_basename, target_lib_file_ext(g->zig_target, !g->is_dynamic,10406 g->version_major, g->version_minor, g->version_patch));
10536 g->version_major, g->version_minor, g->version_patch));10407 break;
10537 break;
10538 }
10539 break;
10540 }
10541 case EmitFileTypeAssembly: {
10542 const char *asm_ext = target_asm_file_ext(g->zig_target);
10543 buf_append_str(o_basename, asm_ext);
10544 buf_append_str(out_basename, asm_ext);
10545 break;
10546 }
10547 case EmitFileTypeLLVMIr: {
10548 const char *llvm_ir_ext = target_llvm_ir_file_ext(g->zig_target);
10549 buf_append_str(o_basename, llvm_ir_ext);
10550 buf_append_str(out_basename, llvm_ir_ext);
10551 break;
10552 }10408 }
10409 os_path_join(g->output_dir, o_basename, &g->o_file_output_path);
10410 os_path_join(g->output_dir, out_basename, &g->bin_file_output_path);
10411 }
10412 if (g->emit_asm) {
10413 Buf *asm_basename = buf_create_from_buf(g->root_out_name);
10414 const char *asm_ext = target_asm_file_ext(g->zig_target);
10415 buf_append_str(asm_basename, asm_ext);
10416 os_path_join(g->output_dir, asm_basename, &g->asm_file_output_path);
10417 }
10418 if (g->emit_llvm_ir) {
10419 Buf *llvm_ir_basename = buf_create_from_buf(g->root_out_name);
10420 const char *llvm_ir_ext = target_llvm_ir_file_ext(g->zig_target);
10421 buf_append_str(llvm_ir_basename, llvm_ir_ext);
10422 os_path_join(g->output_dir, llvm_ir_basename, &g->llvm_ir_file_output_path);
10553 }10423 }
10554
10555 os_path_join(g->output_dir, o_basename, &g->o_file_output_path);
10556 os_path_join(g->output_dir, out_basename, &g->output_file_path);
10557}10424}
1055810425
10559void codegen_build_and_link(CodeGen *g) {10426void codegen_build_and_link(CodeGen *g) {
...@@ -10715,7 +10582,7 @@ void codegen_build_and_link(CodeGen *g) {...@@ -10715,7 +10582,7 @@ void codegen_build_and_link(CodeGen *g) {
10715 // If there is more than one object, we have to link them (with -r).10582 // If there is more than one object, we have to link them (with -r).
10716 // Finally, if we didn't make an object from zig source, and we don't have caching enabled,10583 // Finally, if we didn't make an object from zig source, and we don't have caching enabled,
10717 // then we have an object from C source that we must copy to the output dir which we do with a -r link.10584 // then we have an object from C source that we must copy to the output dir which we do with a -r link.
10718 if (!g->disable_bin_generation && g->emit_file_type == EmitFileTypeBinary &&10585 if (g->emit_bin &&
10719 (g->out_type != OutTypeObj || g->link_objects.length > 1 ||10586 (g->out_type != OutTypeObj || g->link_objects.length > 1 ||
10720 (!need_llvm_module(g) && !g->enable_cache)))10587 (!need_llvm_module(g) && !g->enable_cache)))
10721 {10588 {
...@@ -10751,7 +10618,7 @@ ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const c...@@ -10751,7 +10618,7 @@ ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const c
10751}10618}
1075210619
10753CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType out_type,10620CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType out_type,
10754 ZigLibCInstallation *libc, const char *name, Stage2ProgressNode *parent_progress_node)10621 Stage2LibCInstallation *libc, const char *name, Stage2ProgressNode *parent_progress_node)
10755{10622{
10756 Stage2ProgressNode *child_progress_node = stage2_progress_start(10623 Stage2ProgressNode *child_progress_node = stage2_progress_start(
10757 parent_progress_node ? parent_progress_node : parent_gen->sub_progress_node,10624 parent_progress_node ? parent_progress_node : parent_gen->sub_progress_node,
...@@ -10790,9 +10657,10 @@ CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType o...@@ -10790,9 +10657,10 @@ CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType o
1079010657
10791CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target,10658CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target,
10792 OutType out_type, BuildMode build_mode, Buf *override_lib_dir,10659 OutType out_type, BuildMode build_mode, Buf *override_lib_dir,
10793 ZigLibCInstallation *libc, Buf *cache_dir, bool is_test_build, Stage2ProgressNode *progress_node)10660 Stage2LibCInstallation *libc, Buf *cache_dir, bool is_test_build, Stage2ProgressNode *progress_node)
10794{10661{
10795 CodeGen *g = heap::c_allocator.create<CodeGen>();10662 CodeGen *g = heap::c_allocator.create<CodeGen>();
10663 g->emit_bin = true;
10796 g->pass1_arena = heap::ArenaAllocator::construct(&heap::c_allocator, &heap::c_allocator, "pass1");10664 g->pass1_arena = heap::ArenaAllocator::construct(&heap::c_allocator, &heap::c_allocator, "pass1");
10797 g->main_progress_node = progress_node;10665 g->main_progress_node = progress_node;
1079810666
src/codegen.hpp+3-5
...@@ -11,23 +11,21 @@...@@ -11,23 +11,21 @@
11#include "parser.hpp"11#include "parser.hpp"
12#include "errmsg.hpp"12#include "errmsg.hpp"
13#include "target.hpp"13#include "target.hpp"
14#include "libc_installation.hpp"14#include "stage2.h"
15#include "userland.h"
1615
17#include <stdio.h>16#include <stdio.h>
1817
19CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target,18CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget *target,
20 OutType out_type, BuildMode build_mode, Buf *zig_lib_dir,19 OutType out_type, BuildMode build_mode, Buf *zig_lib_dir,
21 ZigLibCInstallation *libc, Buf *cache_dir, bool is_test_build, Stage2ProgressNode *progress_node);20 Stage2LibCInstallation *libc, Buf *cache_dir, bool is_test_build, Stage2ProgressNode *progress_node);
2221
23CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType out_type,22CodeGen *create_child_codegen(CodeGen *parent_gen, Buf *root_src_path, OutType out_type,
24 ZigLibCInstallation *libc, const char *name, Stage2ProgressNode *progress_node);23 Stage2LibCInstallation *libc, const char *name, Stage2ProgressNode *progress_node);
2524
26void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len);25void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len);
27void codegen_set_llvm_argv(CodeGen *codegen, const char **args, size_t len);26void codegen_set_llvm_argv(CodeGen *codegen, const char **args, size_t len);
28void codegen_set_each_lib_rpath(CodeGen *codegen, bool each_lib_rpath);27void codegen_set_each_lib_rpath(CodeGen *codegen, bool each_lib_rpath);
2928
30void codegen_set_emit_file_type(CodeGen *g, EmitFileType emit_file_type);
31void codegen_set_strip(CodeGen *codegen, bool strip);29void codegen_set_strip(CodeGen *codegen, bool strip);
32void codegen_set_errmsg_color(CodeGen *codegen, ErrColor err_color);30void codegen_set_errmsg_color(CodeGen *codegen, ErrColor err_color);
33void codegen_set_out_name(CodeGen *codegen, Buf *out_name);31void codegen_set_out_name(CodeGen *codegen, Buf *out_name);
src/compiler.cpp-34
...@@ -4,20 +4,6 @@...@@ -4,20 +4,6 @@
44
5#include <stdio.h>5#include <stdio.h>
66
7static Buf saved_dynamic_linker_path = BUF_INIT;
8static bool searched_for_dyn_linker = false;
9
10static void detect_dynamic_linker(Buf *lib_path) {
11#if defined(ZIG_OS_LINUX)
12 for (size_t i = 0; possible_ld_names[i] != NULL; i += 1) {
13 if (buf_ends_with_str(lib_path, possible_ld_names[i])) {
14 buf_init_from_buf(&saved_dynamic_linker_path, lib_path);
15 break;
16 }
17 }
18#endif
19}
20
21Buf *get_self_libc_path(void) {7Buf *get_self_libc_path(void) {
22 static Buf saved_libc_path = BUF_INIT;8 static Buf saved_libc_path = BUF_INIT;
23 static bool searched_for_libc = false;9 static bool searched_for_libc = false;
...@@ -43,25 +29,6 @@ Buf *get_self_libc_path(void) {...@@ -43,25 +29,6 @@ Buf *get_self_libc_path(void) {
43 }29 }
44}30}
4531
46Buf *get_self_dynamic_linker_path(void) {
47 for (;;) {
48 if (saved_dynamic_linker_path.list.length != 0) {
49 return &saved_dynamic_linker_path;
50 }
51 if (searched_for_dyn_linker)
52 return nullptr;
53 ZigList<Buf *> lib_paths = {};
54 Error err;
55 if ((err = os_self_exe_shared_libs(lib_paths)))
56 return nullptr;
57 for (size_t i = 0; i < lib_paths.length; i += 1) {
58 Buf *lib_path = lib_paths.at(i);
59 detect_dynamic_linker(lib_path);
60 }
61 searched_for_dyn_linker = true;
62 }
63}
64
65Error get_compiler_id(Buf **result) {32Error get_compiler_id(Buf **result) {
66 static Buf saved_compiler_id = BUF_INIT;33 static Buf saved_compiler_id = BUF_INIT;
6734
...@@ -98,7 +65,6 @@ Error get_compiler_id(Buf **result) {...@@ -98,7 +65,6 @@ Error get_compiler_id(Buf **result) {
98 return err;65 return err;
99 for (size_t i = 0; i < lib_paths.length; i += 1) {66 for (size_t i = 0; i < lib_paths.length; i += 1) {
100 Buf *lib_path = lib_paths.at(i);67 Buf *lib_path = lib_paths.at(i);
101 detect_dynamic_linker(lib_path);
102 if ((err = cache_add_file(ch, lib_path)))68 if ((err = cache_add_file(ch, lib_path)))
103 return err;69 return err;
104 }70 }
src/compiler.hpp-1
...@@ -12,7 +12,6 @@...@@ -12,7 +12,6 @@
12#include "error.hpp"12#include "error.hpp"
1313
14Error get_compiler_id(Buf **result);14Error get_compiler_id(Buf **result);
15Buf *get_self_dynamic_linker_path(void);
16Buf *get_self_libc_path(void);15Buf *get_self_libc_path(void);
1716
18Buf *get_zig_lib_dir(void);17Buf *get_zig_lib_dir(void);
src/error.cpp+18-1
...@@ -59,11 +59,28 @@ const char *err_str(Error err) {...@@ -59,11 +59,28 @@ const char *err_str(Error err) {
59 case ErrorIsAsync: return "is async";59 case ErrorIsAsync: return "is async";
60 case ErrorImportOutsidePkgPath: return "import of file outside package path";60 case ErrorImportOutsidePkgPath: return "import of file outside package path";
61 case ErrorUnknownCpu: return "unknown CPU";61 case ErrorUnknownCpu: return "unknown CPU";
62 case ErrorUnknownSubArchitecture: return "unknown sub-architecture";
63 case ErrorUnknownCpuFeature: return "unknown CPU feature";62 case ErrorUnknownCpuFeature: return "unknown CPU feature";
64 case ErrorInvalidCpuFeatures: return "invalid CPU features";63 case ErrorInvalidCpuFeatures: return "invalid CPU features";
65 case ErrorInvalidLlvmCpuFeaturesFormat: return "invalid LLVM CPU features format";64 case ErrorInvalidLlvmCpuFeaturesFormat: return "invalid LLVM CPU features format";
66 case ErrorUnknownApplicationBinaryInterface: return "unknown application binary interface";65 case ErrorUnknownApplicationBinaryInterface: return "unknown application binary interface";
66 case ErrorASTUnitFailure: return "compiler bug: clang encountered a compile error, but the libclang API does not expose the error. See https://github.com/ziglang/zig/issues/4455 for more details";
67 case ErrorBadPathName: return "bad path name";
68 case ErrorSymLinkLoop: return "sym link loop";
69 case ErrorProcessFdQuotaExceeded: return "process fd quota exceeded";
70 case ErrorSystemFdQuotaExceeded: return "system fd quota exceeded";
71 case ErrorNoDevice: return "no device";
72 case ErrorDeviceBusy: return "device busy";
73 case ErrorUnableToSpawnCCompiler: return "unable to spawn system C compiler";
74 case ErrorCCompilerExitCode: return "system C compiler exited with failure code";
75 case ErrorCCompilerCrashed: return "system C compiler crashed";
76 case ErrorCCompilerCannotFindHeaders: return "system C compiler cannot find libc headers";
77 case ErrorLibCRuntimeNotFound: return "libc runtime not found";
78 case ErrorLibCStdLibHeaderNotFound: return "libc std lib headers not found";
79 case ErrorLibCKernel32LibNotFound: return "kernel32 library not found";
80 case ErrorUnsupportedArchitecture: return "unsupported architecture";
81 case ErrorWindowsSdkNotFound: return "Windows SDK not found";
82 case ErrorUnknownDynamicLinkerPath: return "unknown dynamic linker path";
83 case ErrorTargetHasNoDynamicLinker: return "target has no dynamic linker";
67 }84 }
68 return "(invalid error)";85 return "(invalid error)";
69}86}
src/error.hpp+1-1
...@@ -8,7 +8,7 @@...@@ -8,7 +8,7 @@
8#ifndef ERROR_HPP8#ifndef ERROR_HPP
9#define ERROR_HPP9#define ERROR_HPP
1010
11#include "userland.h"11#include "stage2.h"
1212
13const char *err_str(Error err);13const char *err_str(Error err);
1414
src/glibc.cpp+2-4
...@@ -116,10 +116,8 @@ Error glibc_load_metadata(ZigGLibCAbi **out_result, Buf *zig_lib_dir, bool verbo...@@ -116,10 +116,8 @@ Error glibc_load_metadata(ZigGLibCAbi **out_result, Buf *zig_lib_dir, bool verbo
116 assert(opt_abi.is_some);116 assert(opt_abi.is_some);
117117
118118
119 err = target_parse_archsub(&target->arch, &target->sub_arch,119 err = target_parse_arch(&target->arch, (char*)opt_arch.value.ptr, opt_arch.value.len);
120 (char*)opt_arch.value.ptr, opt_arch.value.len);120 assert(err == ErrorNone);
121 // there's no sub arch so we might get an error, but the arch is still populated
122 assert(err == ErrorNone || err == ErrorUnknownArchitecture);
123121
124 target->os = OsLinux;122 target->os = OsLinux;
125123
src/ir.cpp+166-666
...@@ -14,6 +14,7 @@...@@ -14,6 +14,7 @@
14#include "range_set.hpp"14#include "range_set.hpp"
15#include "softfloat.hpp"15#include "softfloat.hpp"
16#include "util.hpp"16#include "util.hpp"
17#include "mem_list.hpp"
1718
18#include <errno.h>19#include <errno.h>
1920
...@@ -28,6 +29,9 @@ struct IrBuilderGen {...@@ -28,6 +29,9 @@ struct IrBuilderGen {
28 CodeGen *codegen;29 CodeGen *codegen;
29 IrExecutableGen *exec;30 IrExecutableGen *exec;
30 IrBasicBlockGen *current_basic_block;31 IrBasicBlockGen *current_basic_block;
32
33 // track for immediate post-analysis destruction
34 mem::List<IrInstGenConst *> constants;
31};35};
3236
33struct IrAnalyze {37struct IrAnalyze {
...@@ -383,18 +387,12 @@ static void destroy_instruction_src(IrInstSrc *inst) {...@@ -383,18 +387,12 @@ static void destroy_instruction_src(IrInstSrc *inst) {
383 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFloatCast *>(inst));387 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFloatCast *>(inst));
384 case IrInstSrcIdErrSetCast:388 case IrInstSrcIdErrSetCast:
385 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrSetCast *>(inst));389 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcErrSetCast *>(inst));
386 case IrInstSrcIdFromBytes:
387 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFromBytes *>(inst));
388 case IrInstSrcIdToBytes:
389 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcToBytes *>(inst));
390 case IrInstSrcIdIntToFloat:390 case IrInstSrcIdIntToFloat:
391 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntToFloat *>(inst));391 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntToFloat *>(inst));
392 case IrInstSrcIdFloatToInt:392 case IrInstSrcIdFloatToInt:
393 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFloatToInt *>(inst));393 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcFloatToInt *>(inst));
394 case IrInstSrcIdBoolToInt:394 case IrInstSrcIdBoolToInt:
395 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBoolToInt *>(inst));395 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBoolToInt *>(inst));
396 case IrInstSrcIdIntType:
397 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcIntType *>(inst));
398 case IrInstSrcIdVectorType:396 case IrInstSrcIdVectorType:
399 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcVectorType *>(inst));397 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcVectorType *>(inst));
400 case IrInstSrcIdShuffleVector:398 case IrInstSrcIdShuffleVector:
...@@ -409,12 +407,6 @@ static void destroy_instruction_src(IrInstSrc *inst) {...@@ -409,12 +407,6 @@ static void destroy_instruction_src(IrInstSrc *inst) {
409 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMemcpy *>(inst));407 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMemcpy *>(inst));
410 case IrInstSrcIdSlice:408 case IrInstSrcIdSlice:
411 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSlice *>(inst));409 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSlice *>(inst));
412 case IrInstSrcIdMemberCount:
413 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMemberCount *>(inst));
414 case IrInstSrcIdMemberType:
415 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMemberType *>(inst));
416 case IrInstSrcIdMemberName:
417 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcMemberName *>(inst));
418 case IrInstSrcIdBreakpoint:410 case IrInstSrcIdBreakpoint:
419 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBreakpoint *>(inst));411 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcBreakpoint *>(inst));
420 case IrInstSrcIdReturnAddress:412 case IrInstSrcIdReturnAddress:
...@@ -481,8 +473,6 @@ static void destroy_instruction_src(IrInstSrc *inst) {...@@ -481,8 +473,6 @@ static void destroy_instruction_src(IrInstSrc *inst) {
481 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcType *>(inst));473 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcType *>(inst));
482 case IrInstSrcIdHasField:474 case IrInstSrcIdHasField:
483 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcHasField *>(inst));475 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcHasField *>(inst));
484 case IrInstSrcIdTypeId:
485 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcTypeId *>(inst));
486 case IrInstSrcIdSetEvalBranchQuota:476 case IrInstSrcIdSetEvalBranchQuota:
487 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetEvalBranchQuota *>(inst));477 return heap::c_allocator.destroy(reinterpret_cast<IrInstSrcSetEvalBranchQuota *>(inst));
488 case IrInstSrcIdAlignCast:478 case IrInstSrcIdAlignCast:
...@@ -707,8 +697,6 @@ void destroy_instruction_gen(IrInstGen *inst) {...@@ -707,8 +697,6 @@ void destroy_instruction_gen(IrInstGen *inst) {
707 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAssertZero *>(inst));697 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAssertZero *>(inst));
708 case IrInstGenIdAssertNonNull:698 case IrInstGenIdAssertNonNull:
709 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAssertNonNull *>(inst));699 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAssertNonNull *>(inst));
710 case IrInstGenIdResizeSlice:
711 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenResizeSlice *>(inst));
712 case IrInstGenIdAlloca:700 case IrInstGenIdAlloca:
713 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAlloca *>(inst));701 return heap::c_allocator.destroy(reinterpret_cast<IrInstGenAlloca *>(inst));
714 case IrInstGenIdSuspendBegin:702 case IrInstGenIdSuspendBegin:
...@@ -741,6 +729,10 @@ static void ira_ref(IrAnalyze *ira) {...@@ -741,6 +729,10 @@ static void ira_ref(IrAnalyze *ira) {
741static void ira_deref(IrAnalyze *ira) {729static void ira_deref(IrAnalyze *ira) {
742 if (ira->ref_count > 1) {730 if (ira->ref_count > 1) {
743 ira->ref_count -= 1;731 ira->ref_count -= 1;
732
733 // immediate destruction of dangling IrInstGenConst is not possible
734 // free tracking memory because it will never be used
735 ira->new_irb.constants.deinit(&heap::c_allocator);
744 return;736 return;
745 }737 }
746 assert(ira->ref_count != 0);738 assert(ira->ref_count != 0);
...@@ -758,6 +750,15 @@ static void ira_deref(IrAnalyze *ira) {...@@ -758,6 +750,15 @@ static void ira_deref(IrAnalyze *ira) {
758 heap::c_allocator.destroy(ira->old_irb.exec);750 heap::c_allocator.destroy(ira->old_irb.exec);
759 ira->src_implicit_return_type_list.deinit();751 ira->src_implicit_return_type_list.deinit();
760 ira->resume_stack.deinit();752 ira->resume_stack.deinit();
753
754 // destroy dangling IrInstGenConst
755 for (size_t i = 0; i < ira->new_irb.constants.length; i += 1) {
756 auto constant = ira->new_irb.constants.items[i];
757 if (constant->base.base.ref_count == 0 && !ir_inst_gen_has_side_effects(&constant->base))
758 destroy_instruction_gen(&constant->base);
759 }
760 ira->new_irb.constants.deinit(&heap::c_allocator);
761
761 heap::c_allocator.destroy(ira);762 heap::c_allocator.destroy(ira);
762}763}
763764
...@@ -1299,10 +1300,6 @@ static constexpr IrInstSrcId ir_inst_id(IrInstSrcBoolToInt *) {...@@ -1299,10 +1300,6 @@ static constexpr IrInstSrcId ir_inst_id(IrInstSrcBoolToInt *) {
1299 return IrInstSrcIdBoolToInt;1300 return IrInstSrcIdBoolToInt;
1300}1301}
13011302
1302static constexpr IrInstSrcId ir_inst_id(IrInstSrcIntType *) {
1303 return IrInstSrcIdIntType;
1304}
1305
1306static constexpr IrInstSrcId ir_inst_id(IrInstSrcVectorType *) {1303static constexpr IrInstSrcId ir_inst_id(IrInstSrcVectorType *) {
1307 return IrInstSrcIdVectorType;1304 return IrInstSrcIdVectorType;
1308}1305}
...@@ -1331,18 +1328,6 @@ static constexpr IrInstSrcId ir_inst_id(IrInstSrcSlice *) {...@@ -1331,18 +1328,6 @@ static constexpr IrInstSrcId ir_inst_id(IrInstSrcSlice *) {
1331 return IrInstSrcIdSlice;1328 return IrInstSrcIdSlice;
1332}1329}
13331330
1334static constexpr IrInstSrcId ir_inst_id(IrInstSrcMemberCount *) {
1335 return IrInstSrcIdMemberCount;
1336}
1337
1338static constexpr IrInstSrcId ir_inst_id(IrInstSrcMemberType *) {
1339 return IrInstSrcIdMemberType;
1340}
1341
1342static constexpr IrInstSrcId ir_inst_id(IrInstSrcMemberName *) {
1343 return IrInstSrcIdMemberName;
1344}
1345
1346static constexpr IrInstSrcId ir_inst_id(IrInstSrcBreakpoint *) {1331static constexpr IrInstSrcId ir_inst_id(IrInstSrcBreakpoint *) {
1347 return IrInstSrcIdBreakpoint;1332 return IrInstSrcIdBreakpoint;
1348}1333}
...@@ -1487,10 +1472,6 @@ static constexpr IrInstSrcId ir_inst_id(IrInstSrcHasField *) {...@@ -1487,10 +1472,6 @@ static constexpr IrInstSrcId ir_inst_id(IrInstSrcHasField *) {
1487 return IrInstSrcIdHasField;1472 return IrInstSrcIdHasField;
1488}1473}
14891474
1490static constexpr IrInstSrcId ir_inst_id(IrInstSrcTypeId *) {
1491 return IrInstSrcIdTypeId;
1492}
1493
1494static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetEvalBranchQuota *) {1475static constexpr IrInstSrcId ir_inst_id(IrInstSrcSetEvalBranchQuota *) {
1495 return IrInstSrcIdSetEvalBranchQuota;1476 return IrInstSrcIdSetEvalBranchQuota;
1496}1477}
...@@ -1563,14 +1544,6 @@ static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrSetCast *) {...@@ -1563,14 +1544,6 @@ static constexpr IrInstSrcId ir_inst_id(IrInstSrcErrSetCast *) {
1563 return IrInstSrcIdErrSetCast;1544 return IrInstSrcIdErrSetCast;
1564}1545}
15651546
1566static constexpr IrInstSrcId ir_inst_id(IrInstSrcToBytes *) {
1567 return IrInstSrcIdToBytes;
1568}
1569
1570static constexpr IrInstSrcId ir_inst_id(IrInstSrcFromBytes *) {
1571 return IrInstSrcIdFromBytes;
1572}
1573
1574static constexpr IrInstSrcId ir_inst_id(IrInstSrcCheckRuntimeScope *) {1547static constexpr IrInstSrcId ir_inst_id(IrInstSrcCheckRuntimeScope *) {
1575 return IrInstSrcIdCheckRuntimeScope;1548 return IrInstSrcIdCheckRuntimeScope;
1576}1549}
...@@ -1700,10 +1673,6 @@ static constexpr IrInstGenId ir_inst_id(IrInstGenCast *) {...@@ -1700,10 +1673,6 @@ static constexpr IrInstGenId ir_inst_id(IrInstGenCast *) {
1700 return IrInstGenIdCast;1673 return IrInstGenIdCast;
1701}1674}
17021675
1703static constexpr IrInstGenId ir_inst_id(IrInstGenResizeSlice *) {
1704 return IrInstGenIdResizeSlice;
1705}
1706
1707static constexpr IrInstGenId ir_inst_id(IrInstGenUnreachable *) {1676static constexpr IrInstGenId ir_inst_id(IrInstGenUnreachable *) {
1708 return IrInstGenIdUnreachable;1677 return IrInstGenIdUnreachable;
1709}1678}
...@@ -2759,21 +2728,6 @@ static IrInstGen *ir_build_var_decl_gen(IrAnalyze *ira, IrInst *source_instructi...@@ -2759,21 +2728,6 @@ static IrInstGen *ir_build_var_decl_gen(IrAnalyze *ira, IrInst *source_instructi
2759 return &inst->base;2728 return &inst->base;
2760}2729}
27612730
2762static IrInstGen *ir_build_resize_slice(IrAnalyze *ira, IrInst *source_instruction,
2763 IrInstGen *operand, ZigType *ty, IrInstGen *result_loc)
2764{
2765 IrInstGenResizeSlice *instruction = ir_build_inst_gen<IrInstGenResizeSlice>(&ira->new_irb,
2766 source_instruction->scope, source_instruction->source_node);
2767 instruction->base.value->type = ty;
2768 instruction->operand = operand;
2769 instruction->result_loc = result_loc;
2770
2771 ir_ref_inst_gen(operand, ira->new_irb.current_basic_block);
2772 if (result_loc != nullptr) ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block);
2773
2774 return &instruction->base;
2775}
2776
2777static IrInstSrc *ir_build_export(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,2731static IrInstSrc *ir_build_export(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
2778 IrInstSrc *target, IrInstSrc *options)2732 IrInstSrc *target, IrInstSrc *options)
2779{2733{
...@@ -3540,32 +3494,6 @@ static IrInstSrc *ir_build_err_set_cast(IrBuilderSrc *irb, Scope *scope, AstNode...@@ -3540,32 +3494,6 @@ static IrInstSrc *ir_build_err_set_cast(IrBuilderSrc *irb, Scope *scope, AstNode
3540 return &instruction->base;3494 return &instruction->base;
3541}3495}
35423496
3543static IrInstSrc *ir_build_to_bytes(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *target,
3544 ResultLoc *result_loc)
3545{
3546 IrInstSrcToBytes *instruction = ir_build_instruction<IrInstSrcToBytes>(irb, scope, source_node);
3547 instruction->target = target;
3548 instruction->result_loc = result_loc;
3549
3550 ir_ref_instruction(target, irb->current_basic_block);
3551
3552 return &instruction->base;
3553}
3554
3555static IrInstSrc *ir_build_from_bytes(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
3556 IrInstSrc *dest_child_type, IrInstSrc *target, ResultLoc *result_loc)
3557{
3558 IrInstSrcFromBytes *instruction = ir_build_instruction<IrInstSrcFromBytes>(irb, scope, source_node);
3559 instruction->dest_child_type = dest_child_type;
3560 instruction->target = target;
3561 instruction->result_loc = result_loc;
3562
3563 ir_ref_instruction(dest_child_type, irb->current_basic_block);
3564 ir_ref_instruction(target, irb->current_basic_block);
3565
3566 return &instruction->base;
3567}
3568
3569static IrInstSrc *ir_build_int_to_float(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,3497static IrInstSrc *ir_build_int_to_float(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
3570 IrInstSrc *dest_type, IrInstSrc *target)3498 IrInstSrc *dest_type, IrInstSrc *target)
3571{3499{
...@@ -3601,19 +3529,6 @@ static IrInstSrc *ir_build_bool_to_int(IrBuilderSrc *irb, Scope *scope, AstNode...@@ -3601,19 +3529,6 @@ static IrInstSrc *ir_build_bool_to_int(IrBuilderSrc *irb, Scope *scope, AstNode
3601 return &instruction->base;3529 return &instruction->base;
3602}3530}
36033531
3604static IrInstSrc *ir_build_int_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *is_signed,
3605 IrInstSrc *bit_count)
3606{
3607 IrInstSrcIntType *instruction = ir_build_instruction<IrInstSrcIntType>(irb, scope, source_node);
3608 instruction->is_signed = is_signed;
3609 instruction->bit_count = bit_count;
3610
3611 ir_ref_instruction(is_signed, irb->current_basic_block);
3612 ir_ref_instruction(bit_count, irb->current_basic_block);
3613
3614 return &instruction->base;
3615}
3616
3617static IrInstSrc *ir_build_vector_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *len,3532static IrInstSrc *ir_build_vector_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *len,
3618 IrInstSrc *elem_type)3533 IrInstSrc *elem_type)
3619{3534{
...@@ -3808,41 +3723,6 @@ static IrInstGen *ir_build_slice_gen(IrAnalyze *ira, IrInst *source_instruction,...@@ -3808,41 +3723,6 @@ static IrInstGen *ir_build_slice_gen(IrAnalyze *ira, IrInst *source_instruction,
3808 return &instruction->base;3723 return &instruction->base;
3809}3724}
38103725
3811static IrInstSrc *ir_build_member_count(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *container) {
3812 IrInstSrcMemberCount *instruction = ir_build_instruction<IrInstSrcMemberCount>(irb, scope, source_node);
3813 instruction->container = container;
3814
3815 ir_ref_instruction(container, irb->current_basic_block);
3816
3817 return &instruction->base;
3818}
3819
3820static IrInstSrc *ir_build_member_type(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
3821 IrInstSrc *container_type, IrInstSrc *member_index)
3822{
3823 IrInstSrcMemberType *instruction = ir_build_instruction<IrInstSrcMemberType>(irb, scope, source_node);
3824 instruction->container_type = container_type;
3825 instruction->member_index = member_index;
3826
3827 ir_ref_instruction(container_type, irb->current_basic_block);
3828 ir_ref_instruction(member_index, irb->current_basic_block);
3829
3830 return &instruction->base;
3831}
3832
3833static IrInstSrc *ir_build_member_name(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
3834 IrInstSrc *container_type, IrInstSrc *member_index)
3835{
3836 IrInstSrcMemberName *instruction = ir_build_instruction<IrInstSrcMemberName>(irb, scope, source_node);
3837 instruction->container_type = container_type;
3838 instruction->member_index = member_index;
3839
3840 ir_ref_instruction(container_type, irb->current_basic_block);
3841 ir_ref_instruction(member_index, irb->current_basic_block);
3842
3843 return &instruction->base;
3844}
3845
3846static IrInstSrc *ir_build_breakpoint(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) {3726static IrInstSrc *ir_build_breakpoint(IrBuilderSrc *irb, Scope *scope, AstNode *source_node) {
3847 IrInstSrcBreakpoint *instruction = ir_build_instruction<IrInstSrcBreakpoint>(irb, scope, source_node);3727 IrInstSrcBreakpoint *instruction = ir_build_instruction<IrInstSrcBreakpoint>(irb, scope, source_node);
3848 return &instruction->base;3728 return &instruction->base;
...@@ -4517,15 +4397,6 @@ static IrInstSrc *ir_build_type(IrBuilderSrc *irb, Scope *scope, AstNode *source...@@ -4517,15 +4397,6 @@ static IrInstSrc *ir_build_type(IrBuilderSrc *irb, Scope *scope, AstNode *source
4517 return &instruction->base;4397 return &instruction->base;
4518}4398}
45194399
4520static IrInstSrc *ir_build_type_id(IrBuilderSrc *irb, Scope *scope, AstNode *source_node, IrInstSrc *type_value) {
4521 IrInstSrcTypeId *instruction = ir_build_instruction<IrInstSrcTypeId>(irb, scope, source_node);
4522 instruction->type_value = type_value;
4523
4524 ir_ref_instruction(type_value, irb->current_basic_block);
4525
4526 return &instruction->base;
4527}
4528
4529static IrInstSrc *ir_build_set_eval_branch_quota(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,4400static IrInstSrc *ir_build_set_eval_branch_quota(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4530 IrInstSrc *new_quota)4401 IrInstSrc *new_quota)
4531{4402{
...@@ -4956,11 +4827,12 @@ static IrInstGen *ir_build_suspend_finish_gen(IrAnalyze *ira, IrInst *source_ins...@@ -4956,11 +4827,12 @@ static IrInstGen *ir_build_suspend_finish_gen(IrAnalyze *ira, IrInst *source_ins
4956}4827}
49574828
4958static IrInstSrc *ir_build_await_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,4829static IrInstSrc *ir_build_await_src(IrBuilderSrc *irb, Scope *scope, AstNode *source_node,
4959 IrInstSrc *frame, ResultLoc *result_loc)4830 IrInstSrc *frame, ResultLoc *result_loc, bool is_noasync)
4960{4831{
4961 IrInstSrcAwait *instruction = ir_build_instruction<IrInstSrcAwait>(irb, scope, source_node);4832 IrInstSrcAwait *instruction = ir_build_instruction<IrInstSrcAwait>(irb, scope, source_node);
4962 instruction->frame = frame;4833 instruction->frame = frame;
4963 instruction->result_loc = result_loc;4834 instruction->result_loc = result_loc;
4835 instruction->is_noasync = is_noasync;
49644836
4965 ir_ref_instruction(frame, irb->current_basic_block);4837 ir_ref_instruction(frame, irb->current_basic_block);
49664838
...@@ -4968,13 +4840,14 @@ static IrInstSrc *ir_build_await_src(IrBuilderSrc *irb, Scope *scope, AstNode *s...@@ -4968,13 +4840,14 @@ static IrInstSrc *ir_build_await_src(IrBuilderSrc *irb, Scope *scope, AstNode *s
4968}4840}
49694841
4970static IrInstGenAwait *ir_build_await_gen(IrAnalyze *ira, IrInst *source_instruction,4842static IrInstGenAwait *ir_build_await_gen(IrAnalyze *ira, IrInst *source_instruction,
4971 IrInstGen *frame, ZigType *result_type, IrInstGen *result_loc)4843 IrInstGen *frame, ZigType *result_type, IrInstGen *result_loc, bool is_noasync)
4972{4844{
4973 IrInstGenAwait *instruction = ir_build_inst_gen<IrInstGenAwait>(&ira->new_irb,4845 IrInstGenAwait *instruction = ir_build_inst_gen<IrInstGenAwait>(&ira->new_irb,
4974 source_instruction->scope, source_instruction->source_node);4846 source_instruction->scope, source_instruction->source_node);
4975 instruction->base.value->type = result_type;4847 instruction->base.value->type = result_type;
4976 instruction->frame = frame;4848 instruction->frame = frame;
4977 instruction->result_loc = result_loc;4849 instruction->result_loc = result_loc;
4850 instruction->is_noasync = is_noasync;
49784851
4979 ir_ref_inst_gen(frame, ira->new_irb.current_basic_block);4852 ir_ref_inst_gen(frame, ira->new_irb.current_basic_block);
4980 if (result_loc != nullptr) ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block);4853 if (result_loc != nullptr) ir_ref_inst_gen(result_loc, ira->new_irb.current_basic_block);
...@@ -6595,31 +6468,6 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod...@@ -6595,31 +6468,6 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod
6595 IrInstSrc *result = ir_build_err_set_cast(irb, scope, node, arg0_value, arg1_value);6468 IrInstSrc *result = ir_build_err_set_cast(irb, scope, node, arg0_value, arg1_value);
6596 return ir_lval_wrap(irb, scope, result, lval, result_loc);6469 return ir_lval_wrap(irb, scope, result, lval, result_loc);
6597 }6470 }
6598 case BuiltinFnIdFromBytes:
6599 {
6600 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6601 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6602 if (arg0_value == irb->codegen->invalid_inst_src)
6603 return arg0_value;
6604
6605 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
6606 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
6607 if (arg1_value == irb->codegen->invalid_inst_src)
6608 return arg1_value;
6609
6610 IrInstSrc *result = ir_build_from_bytes(irb, scope, node, arg0_value, arg1_value, result_loc);
6611 return ir_lval_wrap(irb, scope, result, lval, result_loc);
6612 }
6613 case BuiltinFnIdToBytes:
6614 {
6615 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6616 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6617 if (arg0_value == irb->codegen->invalid_inst_src)
6618 return arg0_value;
6619
6620 IrInstSrc *result = ir_build_to_bytes(irb, scope, node, arg0_value, result_loc);
6621 return ir_lval_wrap(irb, scope, result, lval, result_loc);
6622 }
6623 case BuiltinFnIdIntToFloat:6471 case BuiltinFnIdIntToFloat:
6624 {6472 {
6625 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);6473 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
...@@ -6680,21 +6528,6 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod...@@ -6680,21 +6528,6 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod
6680 IrInstSrc *result = ir_build_bool_to_int(irb, scope, node, arg0_value);6528 IrInstSrc *result = ir_build_bool_to_int(irb, scope, node, arg0_value);
6681 return ir_lval_wrap(irb, scope, result, lval, result_loc);6529 return ir_lval_wrap(irb, scope, result, lval, result_loc);
6682 }6530 }
6683 case BuiltinFnIdIntType:
6684 {
6685 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6686 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6687 if (arg0_value == irb->codegen->invalid_inst_src)
6688 return arg0_value;
6689
6690 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
6691 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
6692 if (arg1_value == irb->codegen->invalid_inst_src)
6693 return arg1_value;
6694
6695 IrInstSrc *int_type = ir_build_int_type(irb, scope, node, arg0_value, arg1_value);
6696 return ir_lval_wrap(irb, scope, int_type, lval, result_loc);
6697 }
6698 case BuiltinFnIdVectorType:6531 case BuiltinFnIdVectorType:
6699 {6532 {
6700 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);6533 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
...@@ -6792,48 +6625,6 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod...@@ -6792,48 +6625,6 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod
6792 IrInstSrc *ir_memset = ir_build_memset_src(irb, scope, node, arg0_value, arg1_value, arg2_value);6625 IrInstSrc *ir_memset = ir_build_memset_src(irb, scope, node, arg0_value, arg1_value, arg2_value);
6793 return ir_lval_wrap(irb, scope, ir_memset, lval, result_loc);6626 return ir_lval_wrap(irb, scope, ir_memset, lval, result_loc);
6794 }6627 }
6795 case BuiltinFnIdMemberCount:
6796 {
6797 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6798 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6799 if (arg0_value == irb->codegen->invalid_inst_src)
6800 return arg0_value;
6801
6802 IrInstSrc *member_count = ir_build_member_count(irb, scope, node, arg0_value);
6803 return ir_lval_wrap(irb, scope, member_count, lval, result_loc);
6804 }
6805 case BuiltinFnIdMemberType:
6806 {
6807 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6808 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6809 if (arg0_value == irb->codegen->invalid_inst_src)
6810 return arg0_value;
6811
6812 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
6813 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
6814 if (arg1_value == irb->codegen->invalid_inst_src)
6815 return arg1_value;
6816
6817
6818 IrInstSrc *member_type = ir_build_member_type(irb, scope, node, arg0_value, arg1_value);
6819 return ir_lval_wrap(irb, scope, member_type, lval, result_loc);
6820 }
6821 case BuiltinFnIdMemberName:
6822 {
6823 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
6824 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
6825 if (arg0_value == irb->codegen->invalid_inst_src)
6826 return arg0_value;
6827
6828 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
6829 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
6830 if (arg1_value == irb->codegen->invalid_inst_src)
6831 return arg1_value;
6832
6833
6834 IrInstSrc *member_name = ir_build_member_name(irb, scope, node, arg0_value, arg1_value);
6835 return ir_lval_wrap(irb, scope, member_name, lval, result_loc);
6836 }
6837 case BuiltinFnIdField:6628 case BuiltinFnIdField:
6838 {6629 {
6839 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);6630 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
...@@ -7158,16 +6949,6 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod...@@ -7158,16 +6949,6 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod
7158 }6949 }
7159 case BuiltinFnIdAsyncCall:6950 case BuiltinFnIdAsyncCall:
7160 return ir_gen_async_call(irb, scope, nullptr, node, lval, result_loc);6951 return ir_gen_async_call(irb, scope, nullptr, node, lval, result_loc);
7161 case BuiltinFnIdTypeId:
7162 {
7163 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7164 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
7165 if (arg0_value == irb->codegen->invalid_inst_src)
7166 return arg0_value;
7167
7168 IrInstSrc *type_id = ir_build_type_id(irb, scope, node, arg0_value);
7169 return ir_lval_wrap(irb, scope, type_id, lval, result_loc);
7170 }
7171 case BuiltinFnIdShlExact:6952 case BuiltinFnIdShlExact:
7172 {6953 {
7173 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);6954 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
...@@ -7243,21 +7024,6 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod...@@ -7243,21 +7024,6 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod
7243 IrInstSrc *set_align_stack = ir_build_set_align_stack(irb, scope, node, arg0_value);7024 IrInstSrc *set_align_stack = ir_build_set_align_stack(irb, scope, node, arg0_value);
7244 return ir_lval_wrap(irb, scope, set_align_stack, lval, result_loc);7025 return ir_lval_wrap(irb, scope, set_align_stack, lval, result_loc);
7245 }7026 }
7246 case BuiltinFnIdArgType:
7247 {
7248 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
7249 IrInstSrc *arg0_value = ir_gen_node(irb, arg0_node, scope);
7250 if (arg0_value == irb->codegen->invalid_inst_src)
7251 return arg0_value;
7252
7253 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
7254 IrInstSrc *arg1_value = ir_gen_node(irb, arg1_node, scope);
7255 if (arg1_value == irb->codegen->invalid_inst_src)
7256 return arg1_value;
7257
7258 IrInstSrc *arg_type = ir_build_arg_type(irb, scope, node, arg0_value, arg1_value, false);
7259 return ir_lval_wrap(irb, scope, arg_type, lval, result_loc);
7260 }
7261 case BuiltinFnIdExport:7027 case BuiltinFnIdExport:
7262 {7028 {
7263 // Cast the options parameter to the options type7029 // Cast the options parameter to the options type
...@@ -8073,9 +7839,9 @@ static IrInstSrc *ir_gen_while_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no...@@ -8073,9 +7839,9 @@ static IrInstSrc *ir_gen_while_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no
8073 if (var_symbol) {7839 if (var_symbol) {
8074 IrInstSrc *payload_ptr = ir_build_unwrap_err_payload_src(irb, &spill_scope->base, symbol_node,7840 IrInstSrc *payload_ptr = ir_build_unwrap_err_payload_src(irb, &spill_scope->base, symbol_node,
8075 err_val_ptr, false, false);7841 err_val_ptr, false, false);
8076 IrInstSrc *var_ptr = node->data.while_expr.var_is_ptr ?7842 IrInstSrc *var_value = node->data.while_expr.var_is_ptr ?
8077 ir_build_ref_src(irb, &spill_scope->base, symbol_node, payload_ptr, true, false) : payload_ptr;7843 payload_ptr : ir_build_load_ptr(irb, &spill_scope->base, symbol_node, payload_ptr);
8078 ir_build_var_decl_src(irb, payload_scope, symbol_node, payload_var, nullptr, var_ptr);7844 build_decl_var_and_init(irb, payload_scope, symbol_node, payload_var, var_value, buf_ptr(var_symbol), is_comptime);
8079 }7845 }
80807846
8081 ZigList<IrInstSrc *> incoming_values = {0};7847 ZigList<IrInstSrc *> incoming_values = {0};
...@@ -8123,7 +7889,8 @@ static IrInstSrc *ir_gen_while_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no...@@ -8123,7 +7889,8 @@ static IrInstSrc *ir_gen_while_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no
8123 true, false, false, is_comptime);7889 true, false, false, is_comptime);
8124 Scope *err_scope = err_var->child_scope;7890 Scope *err_scope = err_var->child_scope;
8125 IrInstSrc *err_ptr = ir_build_unwrap_err_code_src(irb, err_scope, err_symbol_node, err_val_ptr);7891 IrInstSrc *err_ptr = ir_build_unwrap_err_code_src(irb, err_scope, err_symbol_node, err_val_ptr);
8126 ir_build_var_decl_src(irb, err_scope, symbol_node, err_var, nullptr, err_ptr);7892 IrInstSrc *err_value = ir_build_load_ptr(irb, err_scope, err_symbol_node, err_ptr);
7893 build_decl_var_and_init(irb, err_scope, err_symbol_node, err_var, err_value, buf_ptr(err_symbol), is_comptime);
81277894
8128 if (peer_parent->peers.length != 0) {7895 if (peer_parent->peers.length != 0) {
8129 peer_parent->peers.last()->next_bb = else_block;7896 peer_parent->peers.last()->next_bb = else_block;
...@@ -8184,9 +7951,9 @@ static IrInstSrc *ir_gen_while_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no...@@ -8184,9 +7951,9 @@ static IrInstSrc *ir_gen_while_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no
81847951
8185 ir_set_cursor_at_end_and_append_block(irb, body_block);7952 ir_set_cursor_at_end_and_append_block(irb, body_block);
8186 IrInstSrc *payload_ptr = ir_build_optional_unwrap_ptr(irb, &spill_scope->base, symbol_node, maybe_val_ptr, false, false);7953 IrInstSrc *payload_ptr = ir_build_optional_unwrap_ptr(irb, &spill_scope->base, symbol_node, maybe_val_ptr, false, false);
8187 IrInstSrc *var_ptr = node->data.while_expr.var_is_ptr ?7954 IrInstSrc *var_value = node->data.while_expr.var_is_ptr ?
8188 ir_build_ref_src(irb, &spill_scope->base, symbol_node, payload_ptr, true, false) : payload_ptr;7955 payload_ptr : ir_build_load_ptr(irb, &spill_scope->base, symbol_node, payload_ptr);
8189 ir_build_var_decl_src(irb, child_scope, symbol_node, payload_var, nullptr, var_ptr);7956 build_decl_var_and_init(irb, child_scope, symbol_node, payload_var, var_value, buf_ptr(var_symbol), is_comptime);
81907957
8191 ZigList<IrInstSrc *> incoming_values = {0};7958 ZigList<IrInstSrc *> incoming_values = {0};
8192 ZigList<IrBasicBlockSrc *> incoming_blocks = {0};7959 ZigList<IrBasicBlockSrc *> incoming_blocks = {0};
...@@ -8425,9 +8192,9 @@ static IrInstSrc *ir_gen_for_expr(IrBuilderSrc *irb, Scope *parent_scope, AstNod...@@ -8425,9 +8192,9 @@ static IrInstSrc *ir_gen_for_expr(IrBuilderSrc *irb, Scope *parent_scope, AstNod
8425 ZigVar *elem_var = ir_create_var(irb, elem_node, parent_scope, elem_var_name, true, false, false, is_comptime);8192 ZigVar *elem_var = ir_create_var(irb, elem_node, parent_scope, elem_var_name, true, false, false, is_comptime);
8426 Scope *child_scope = elem_var->child_scope;8193 Scope *child_scope = elem_var->child_scope;
84278194
8428 IrInstSrc *var_ptr = node->data.for_expr.elem_is_ptr ?8195 IrInstSrc *elem_value = node->data.for_expr.elem_is_ptr ?
8429 ir_build_ref_src(irb, &spill_scope->base, elem_node, elem_ptr, true, false) : elem_ptr;8196 elem_ptr : ir_build_load_ptr(irb, &spill_scope->base, elem_node, elem_ptr);
8430 ir_build_var_decl_src(irb, parent_scope, elem_node, elem_var, nullptr, var_ptr);8197 build_decl_var_and_init(irb, parent_scope, elem_node, elem_var, elem_value, buf_ptr(elem_var_name), is_comptime);
84318198
8432 ZigList<IrInstSrc *> incoming_values = {0};8199 ZigList<IrInstSrc *> incoming_values = {0};
8433 ZigList<IrBasicBlockSrc *> incoming_blocks = {0};8200 ZigList<IrBasicBlockSrc *> incoming_blocks = {0};
...@@ -8847,8 +8614,9 @@ static IrInstSrc *ir_gen_if_optional_expr(IrBuilderSrc *irb, Scope *scope, AstNo...@@ -8847,8 +8614,9 @@ static IrInstSrc *ir_gen_if_optional_expr(IrBuilderSrc *irb, Scope *scope, AstNo
8847 var_symbol, is_const, is_const, is_shadowable, is_comptime);8614 var_symbol, is_const, is_const, is_shadowable, is_comptime);
88488615
8849 IrInstSrc *payload_ptr = ir_build_optional_unwrap_ptr(irb, subexpr_scope, node, maybe_val_ptr, false, false);8616 IrInstSrc *payload_ptr = ir_build_optional_unwrap_ptr(irb, subexpr_scope, node, maybe_val_ptr, false, false);
8850 IrInstSrc *var_ptr = var_is_ptr ? ir_build_ref_src(irb, subexpr_scope, node, payload_ptr, true, false) : payload_ptr;8617 IrInstSrc *var_value = var_is_ptr ?
8851 ir_build_var_decl_src(irb, subexpr_scope, node, var, nullptr, var_ptr);8618 payload_ptr : ir_build_load_ptr(irb, &spill_scope->base, node, payload_ptr);
8619 build_decl_var_and_init(irb, subexpr_scope, node, var, var_value, buf_ptr(var_symbol), is_comptime);
8852 var_scope = var->child_scope;8620 var_scope = var->child_scope;
8853 } else {8621 } else {
8854 var_scope = subexpr_scope;8622 var_scope = subexpr_scope;
...@@ -8929,9 +8697,9 @@ static IrInstSrc *ir_gen_if_err_expr(IrBuilderSrc *irb, Scope *scope, AstNode *n...@@ -8929,9 +8697,9 @@ static IrInstSrc *ir_gen_if_err_expr(IrBuilderSrc *irb, Scope *scope, AstNode *n
8929 var_symbol, var_is_const, var_is_const, is_shadowable, var_is_comptime);8697 var_symbol, var_is_const, var_is_const, is_shadowable, var_is_comptime);
89308698
8931 IrInstSrc *payload_ptr = ir_build_unwrap_err_payload_src(irb, subexpr_scope, node, err_val_ptr, false, false);8699 IrInstSrc *payload_ptr = ir_build_unwrap_err_payload_src(irb, subexpr_scope, node, err_val_ptr, false, false);
8932 IrInstSrc *var_ptr = var_is_ptr ?8700 IrInstSrc *var_value = var_is_ptr ?
8933 ir_build_ref_src(irb, subexpr_scope, node, payload_ptr, true, false) : payload_ptr;8701 payload_ptr : ir_build_load_ptr(irb, subexpr_scope, node, payload_ptr);
8934 ir_build_var_decl_src(irb, subexpr_scope, node, var, nullptr, var_ptr);8702 build_decl_var_and_init(irb, subexpr_scope, node, var, var_value, buf_ptr(var_symbol), var_is_comptime);
8935 var_scope = var->child_scope;8703 var_scope = var->child_scope;
8936 } else {8704 } else {
8937 var_scope = subexpr_scope;8705 var_scope = subexpr_scope;
...@@ -8956,7 +8724,8 @@ static IrInstSrc *ir_gen_if_err_expr(IrBuilderSrc *irb, Scope *scope, AstNode *n...@@ -8956,7 +8724,8 @@ static IrInstSrc *ir_gen_if_err_expr(IrBuilderSrc *irb, Scope *scope, AstNode *n
8956 err_symbol, is_const, is_const, is_shadowable, is_comptime);8724 err_symbol, is_const, is_const, is_shadowable, is_comptime);
89578725
8958 IrInstSrc *err_ptr = ir_build_unwrap_err_code_src(irb, subexpr_scope, node, err_val_ptr);8726 IrInstSrc *err_ptr = ir_build_unwrap_err_code_src(irb, subexpr_scope, node, err_val_ptr);
8959 ir_build_var_decl_src(irb, subexpr_scope, node, var, nullptr, err_ptr);8727 IrInstSrc *err_value = ir_build_load_ptr(irb, subexpr_scope, node, err_ptr);
8728 build_decl_var_and_init(irb, subexpr_scope, node, var, err_value, buf_ptr(err_symbol), is_comptime);
8960 err_var_scope = var->child_scope;8729 err_var_scope = var->child_scope;
8961 } else {8730 } else {
8962 err_var_scope = subexpr_scope;8731 err_var_scope = subexpr_scope;
...@@ -9006,22 +8775,24 @@ static bool ir_gen_switch_prong_expr(IrBuilderSrc *irb, Scope *scope, AstNode *s...@@ -9006,22 +8775,24 @@ static bool ir_gen_switch_prong_expr(IrBuilderSrc *irb, Scope *scope, AstNode *s
9006 ZigVar *var = ir_create_var(irb, var_symbol_node, scope,8775 ZigVar *var = ir_create_var(irb, var_symbol_node, scope,
9007 var_name, is_const, is_const, is_shadowable, var_is_comptime);8776 var_name, is_const, is_const, is_shadowable, var_is_comptime);
9008 child_scope = var->child_scope;8777 child_scope = var->child_scope;
9009 IrInstSrc *var_ptr;8778 IrInstSrc *var_value;
9010 if (out_switch_else_var != nullptr) {8779 if (out_switch_else_var != nullptr) {
9011 IrInstSrcSwitchElseVar *switch_else_var = ir_build_switch_else_var(irb, scope, var_symbol_node,8780 IrInstSrcSwitchElseVar *switch_else_var = ir_build_switch_else_var(irb, scope, var_symbol_node,
9012 target_value_ptr);8781 target_value_ptr);
9013 *out_switch_else_var = switch_else_var;8782 *out_switch_else_var = switch_else_var;
9014 IrInstSrc *payload_ptr = &switch_else_var->base;8783 IrInstSrc *payload_ptr = &switch_else_var->base;
9015 var_ptr = var_is_ptr ? ir_build_ref_src(irb, scope, var_symbol_node, payload_ptr, true, false) : payload_ptr;8784 var_value = var_is_ptr ?
8785 payload_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, payload_ptr);
9016 } else if (prong_values != nullptr) {8786 } else if (prong_values != nullptr) {
9017 IrInstSrc *payload_ptr = ir_build_switch_var(irb, scope, var_symbol_node, target_value_ptr,8787 IrInstSrc *payload_ptr = ir_build_switch_var(irb, scope, var_symbol_node, target_value_ptr,
9018 prong_values, prong_values_len);8788 prong_values, prong_values_len);
9019 var_ptr = var_is_ptr ? ir_build_ref_src(irb, scope, var_symbol_node, payload_ptr, true, false) : payload_ptr;8789 var_value = var_is_ptr ?
8790 payload_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, payload_ptr);
9020 } else {8791 } else {
9021 var_ptr = var_is_ptr ?8792 var_value = var_is_ptr ?
9022 ir_build_ref_src(irb, scope, var_symbol_node, target_value_ptr, true, false) : target_value_ptr;8793 target_value_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, target_value_ptr);
9023 }8794 }
9024 ir_build_var_decl_src(irb, scope, var_symbol_node, var, nullptr, var_ptr);8795 build_decl_var_and_init(irb, scope, var_symbol_node, var, var_value, buf_ptr(var_name), var_is_comptime);
9025 } else {8796 } else {
9026 child_scope = scope;8797 child_scope = scope;
9027 }8798 }
...@@ -9594,7 +9365,8 @@ static IrInstSrc *ir_gen_catch(IrBuilderSrc *irb, Scope *parent_scope, AstNode *...@@ -9594,7 +9365,8 @@ static IrInstSrc *ir_gen_catch(IrBuilderSrc *irb, Scope *parent_scope, AstNode *
9594 is_const, is_const, is_shadowable, is_comptime);9365 is_const, is_const, is_shadowable, is_comptime);
9595 err_scope = var->child_scope;9366 err_scope = var->child_scope;
9596 IrInstSrc *err_ptr = ir_build_unwrap_err_code_src(irb, err_scope, node, err_union_ptr);9367 IrInstSrc *err_ptr = ir_build_unwrap_err_code_src(irb, err_scope, node, err_union_ptr);
9597 ir_build_var_decl_src(irb, err_scope, var_node, var, nullptr, err_ptr);9368 IrInstSrc *err_value = ir_build_load_ptr(irb, err_scope, var_node, err_ptr);
9369 build_decl_var_and_init(irb, err_scope, var_node, var, err_value, buf_ptr(var_name), is_comptime);
9598 } else {9370 } else {
9599 err_scope = subexpr_scope;9371 err_scope = subexpr_scope;
9600 }9372 }
...@@ -9914,6 +9686,8 @@ static IrInstSrc *ir_gen_await_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no...@@ -9914,6 +9686,8 @@ static IrInstSrc *ir_gen_await_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no
9914{9686{
9915 assert(node->type == NodeTypeAwaitExpr);9687 assert(node->type == NodeTypeAwaitExpr);
99169688
9689 bool is_noasync = node->data.await_expr.noasync_token != nullptr;
9690
9917 AstNode *expr_node = node->data.await_expr.expr;9691 AstNode *expr_node = node->data.await_expr.expr;
9918 if (expr_node->type == NodeTypeFnCallExpr && expr_node->data.fn_call_expr.modifier == CallModifierBuiltin) {9692 if (expr_node->type == NodeTypeFnCallExpr && expr_node->data.fn_call_expr.modifier == CallModifierBuiltin) {
9919 AstNode *fn_ref_expr = expr_node->data.fn_call_expr.fn_ref_expr;9693 AstNode *fn_ref_expr = expr_node->data.fn_call_expr.fn_ref_expr;
...@@ -9946,7 +9720,7 @@ static IrInstSrc *ir_gen_await_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no...@@ -9946,7 +9720,7 @@ static IrInstSrc *ir_gen_await_expr(IrBuilderSrc *irb, Scope *scope, AstNode *no
9946 if (target_inst == irb->codegen->invalid_inst_src)9720 if (target_inst == irb->codegen->invalid_inst_src)
9947 return irb->codegen->invalid_inst_src;9721 return irb->codegen->invalid_inst_src;
99489722
9949 IrInstSrc *await_inst = ir_build_await_src(irb, scope, node, target_inst, result_loc);9723 IrInstSrc *await_inst = ir_build_await_src(irb, scope, node, target_inst, result_loc, is_noasync);
9950 return ir_lval_wrap(irb, scope, await_inst, lval, result_loc);9724 return ir_lval_wrap(irb, scope, await_inst, lval, result_loc);
9951}9725}
99529726
...@@ -12703,12 +12477,14 @@ static IrInstGen *ir_const(IrAnalyze *ira, IrInst *inst, ZigType *ty) {...@@ -12703,12 +12477,14 @@ static IrInstGen *ir_const(IrAnalyze *ira, IrInst *inst, ZigType *ty) {
12703 IrInstGen *new_instruction = &const_instruction->base;12477 IrInstGen *new_instruction = &const_instruction->base;
12704 new_instruction->value->type = ty;12478 new_instruction->value->type = ty;
12705 new_instruction->value->special = ConstValSpecialStatic;12479 new_instruction->value->special = ConstValSpecialStatic;
12480 ira->new_irb.constants.append(&heap::c_allocator, const_instruction);
12706 return new_instruction;12481 return new_instruction;
12707}12482}
1270812483
12709static IrInstGen *ir_const_noval(IrAnalyze *ira, IrInst *old_instruction) {12484static IrInstGen *ir_const_noval(IrAnalyze *ira, IrInst *old_instruction) {
12710 IrInstGenConst *const_instruction = ir_create_inst_noval<IrInstGenConst>(&ira->new_irb,12485 IrInstGenConst *const_instruction = ir_create_inst_noval<IrInstGenConst>(&ira->new_irb,
12711 old_instruction->scope, old_instruction->source_node);12486 old_instruction->scope, old_instruction->source_node);
12487 ira->new_irb.constants.append(&heap::c_allocator, const_instruction);
12712 return &const_instruction->base;12488 return &const_instruction->base;
12713}12489}
1271412490
...@@ -20599,12 +20375,12 @@ static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemP...@@ -20599,12 +20375,12 @@ static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemP
20599 if (type_is_invalid(array_ptr->value->type))20375 if (type_is_invalid(array_ptr->value->type))
20600 return ira->codegen->invalid_inst_gen;20376 return ira->codegen->invalid_inst_gen;
2060120377
20602 ZigValue *orig_array_ptr_val = array_ptr->value;
20603
20604 IrInstGen *elem_index = elem_ptr_instruction->elem_index->child;20378 IrInstGen *elem_index = elem_ptr_instruction->elem_index->child;
20605 if (type_is_invalid(elem_index->value->type))20379 if (type_is_invalid(elem_index->value->type))
20606 return ira->codegen->invalid_inst_gen;20380 return ira->codegen->invalid_inst_gen;
2060720381
20382 ZigValue *orig_array_ptr_val = array_ptr->value;
20383
20608 ZigType *ptr_type = orig_array_ptr_val->type;20384 ZigType *ptr_type = orig_array_ptr_val->type;
20609 assert(ptr_type->id == ZigTypeIdPointer);20385 assert(ptr_type->id == ZigTypeIdPointer);
2061020386
...@@ -20614,23 +20390,25 @@ static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemP...@@ -20614,23 +20390,25 @@ static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemP
20614 // We will adjust return_type's alignment before returning it.20390 // We will adjust return_type's alignment before returning it.
20615 ZigType *return_type;20391 ZigType *return_type;
2061620392
20617 if (type_is_invalid(array_type)) {20393 if (type_is_invalid(array_type))
20618 return ira->codegen->invalid_inst_gen;20394 return ira->codegen->invalid_inst_gen;
20619 } else if (array_type->id == ZigTypeIdArray ||20395
20620 (array_type->id == ZigTypeIdPointer &&20396 if (array_type->id == ZigTypeIdPointer &&
20621 array_type->data.pointer.ptr_len == PtrLenSingle &&20397 array_type->data.pointer.ptr_len == PtrLenSingle &&
20622 array_type->data.pointer.child_type->id == ZigTypeIdArray))20398 array_type->data.pointer.child_type->id == ZigTypeIdArray)
20623 {20399 {
20624 if (array_type->id == ZigTypeIdPointer) {20400 IrInstGen *ptr_value = ir_get_deref(ira, &elem_ptr_instruction->base.base,
20625 array_type = array_type->data.pointer.child_type;20401 array_ptr, nullptr);
20626 ptr_type = ptr_type->data.pointer.child_type;20402 if (type_is_invalid(ptr_value->value->type))
20627 if (orig_array_ptr_val->special != ConstValSpecialRuntime) {20403 return ira->codegen->invalid_inst_gen;
20628 orig_array_ptr_val = const_ptr_pointee(ira, ira->codegen, orig_array_ptr_val,20404
20629 elem_ptr_instruction->base.base.source_node);20405 array_type = array_type->data.pointer.child_type;
20630 if (orig_array_ptr_val == nullptr)20406 ptr_type = ptr_type->data.pointer.child_type;
20631 return ira->codegen->invalid_inst_gen;20407
20632 }20408 orig_array_ptr_val = ptr_value->value;
20633 }20409 }
20410
20411 if (array_type->id == ZigTypeIdArray) {
20634 if (array_type->data.array.len == 0) {20412 if (array_type->data.array.len == 0) {
20635 ir_add_error_node(ira, elem_ptr_instruction->base.base.source_node,20413 ir_add_error_node(ira, elem_ptr_instruction->base.base.source_node,
20636 buf_sprintf("index 0 outside array of size 0"));20414 buf_sprintf("index 0 outside array of size 0"));
...@@ -20768,8 +20546,14 @@ static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemP...@@ -20768,8 +20546,14 @@ static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemP
20768 orig_array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr &&20546 orig_array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr &&
20769 (orig_array_ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar || array_type->id == ZigTypeIdArray))20547 (orig_array_ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar || array_type->id == ZigTypeIdArray))
20770 {20548 {
20549 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec,
20550 elem_ptr_instruction->base.base.source_node, orig_array_ptr_val, UndefBad)))
20551 {
20552 return ira->codegen->invalid_inst_gen;
20553 }
20554
20771 ZigValue *array_ptr_val = const_ptr_pointee(ira, ira->codegen, orig_array_ptr_val,20555 ZigValue *array_ptr_val = const_ptr_pointee(ira, ira->codegen, orig_array_ptr_val,
20772 elem_ptr_instruction->base.base.source_node);20556 elem_ptr_instruction->base.base.source_node);
20773 if (array_ptr_val == nullptr)20557 if (array_ptr_val == nullptr)
20774 return ira->codegen->invalid_inst_gen;20558 return ira->codegen->invalid_inst_gen;
2077520559
...@@ -21178,6 +20962,13 @@ static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_ins...@@ -21178,6 +20962,13 @@ static IrInstGen *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInst* source_ins
21178 return ira->codegen->invalid_inst_gen;20962 return ira->codegen->invalid_inst_gen;
21179 if (type_is_invalid(struct_val->type))20963 if (type_is_invalid(struct_val->type))
21180 return ira->codegen->invalid_inst_gen;20964 return ira->codegen->invalid_inst_gen;
20965
20966 // This to allow lazy values to be resolved.
20967 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec,
20968 source_instr->source_node, struct_val, UndefOk)))
20969 {
20970 return ira->codegen->invalid_inst_gen;
20971 }
21181 if (initializing && struct_val->special == ConstValSpecialUndef) {20972 if (initializing && struct_val->special == ConstValSpecialUndef) {
21182 struct_val->data.x_struct.fields = alloc_const_vals_ptrs(ira->codegen, struct_type->data.structure.src_field_count);20973 struct_val->data.x_struct.fields = alloc_const_vals_ptrs(ira->codegen, struct_type->data.structure.src_field_count);
21183 struct_val->special = ConstValSpecialStatic;20974 struct_val->special = ConstValSpecialStatic;
...@@ -23583,7 +23374,7 @@ static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, Zig...@@ -23583,7 +23374,7 @@ static ZigType *ir_type_info_get_type(IrAnalyze *ira, const char *type_name, Zig
23583}23374}
2358423375
23585static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigValue *out_val,23376static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigValue *out_val,
23586 ScopeDecls *decls_scope)23377 ScopeDecls *decls_scope, bool resolve_types)
23587{23378{
23588 Error err;23379 Error err;
23589 ZigType *type_info_declaration_type = ir_type_info_get_type(ira, "Declaration", nullptr);23380 ZigType *type_info_declaration_type = ir_type_info_get_type(ira, "Declaration", nullptr);
...@@ -23594,6 +23385,24 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa...@@ -23594,6 +23385,24 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa
23594 ensure_field_index(type_info_declaration_type, "is_pub", 1);23385 ensure_field_index(type_info_declaration_type, "is_pub", 1);
23595 ensure_field_index(type_info_declaration_type, "data", 2);23386 ensure_field_index(type_info_declaration_type, "data", 2);
2359623387
23388 if (!resolve_types) {
23389 ZigType *ptr_type = get_pointer_to_type_extra(ira->codegen, type_info_declaration_type,
23390 false, false, PtrLenUnknown, 0, 0, 0, false);
23391
23392 out_val->special = ConstValSpecialLazy;
23393 out_val->type = get_slice_type(ira->codegen, ptr_type);
23394
23395 LazyValueTypeInfoDecls *lazy_type_info_decls = heap::c_allocator.create<LazyValueTypeInfoDecls>();
23396 lazy_type_info_decls->ira = ira; ira_ref(ira);
23397 out_val->data.x_lazy = &lazy_type_info_decls->base;
23398 lazy_type_info_decls->base.id = LazyValueIdTypeInfoDecls;
23399
23400 lazy_type_info_decls->source_instr = source_instr;
23401 lazy_type_info_decls->decls_scope = decls_scope;
23402
23403 return ErrorNone;
23404 }
23405
23597 ZigType *type_info_declaration_data_type = ir_type_info_get_type(ira, "Data", type_info_declaration_type);23406 ZigType *type_info_declaration_data_type = ir_type_info_get_type(ira, "Data", type_info_declaration_type);
23598 if ((err = type_resolve(ira->codegen, type_info_declaration_data_type, ResolveStatusSizeKnown)))23407 if ((err = type_resolve(ira->codegen, type_info_declaration_data_type, ResolveStatusSizeKnown)))
23599 return err;23408 return err;
...@@ -23606,14 +23415,13 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa...@@ -23606,14 +23415,13 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa
23606 if ((err = type_resolve(ira->codegen, type_info_fn_decl_inline_type, ResolveStatusSizeKnown)))23415 if ((err = type_resolve(ira->codegen, type_info_fn_decl_inline_type, ResolveStatusSizeKnown)))
23607 return err;23416 return err;
2360823417
23609 // Loop through our declarations once to figure out how many declarations we will generate info for.23418 // The unresolved declarations are collected in a separate queue to avoid
23419 // modifying decl_table while iterating over it
23420 ZigList<Tld*> resolve_decl_queue{};
23421
23610 auto decl_it = decls_scope->decl_table.entry_iterator();23422 auto decl_it = decls_scope->decl_table.entry_iterator();
23611 decltype(decls_scope->decl_table)::Entry *curr_entry = nullptr;23423 decltype(decls_scope->decl_table)::Entry *curr_entry = nullptr;
23612 int declaration_count = 0;
23613
23614 while ((curr_entry = decl_it.next()) != nullptr) {23424 while ((curr_entry = decl_it.next()) != nullptr) {
23615 // If the declaration is unresolved, force it to be resolved again.
23616 resolve_top_level_decl(ira->codegen, curr_entry->value, curr_entry->value->source_node, false);
23617 if (curr_entry->value->resolution == TldResolutionInvalid) {23425 if (curr_entry->value->resolution == TldResolutionInvalid) {
23618 return ErrorSemanticAnalyzeFail;23426 return ErrorSemanticAnalyzeFail;
23619 }23427 }
...@@ -23623,16 +23431,36 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa...@@ -23623,16 +23431,36 @@ static Error ir_make_type_info_decls(IrAnalyze *ira, IrInst* source_instr, ZigVa
23623 return ErrorSemanticAnalyzeFail;23431 return ErrorSemanticAnalyzeFail;
23624 }23432 }
2362523433
23434 // If the declaration is unresolved, force it to be resolved again.
23435 if (curr_entry->value->resolution == TldResolutionUnresolved)
23436 resolve_decl_queue.append(curr_entry->value);
23437 }
23438
23439 for (size_t i = 0; i < resolve_decl_queue.length; i++) {
23440 Tld *decl = resolve_decl_queue.at(i);
23441 resolve_top_level_decl(ira->codegen, decl, decl->source_node, false);
23442 if (decl->resolution == TldResolutionInvalid) {
23443 return ErrorSemanticAnalyzeFail;
23444 }
23445 }
23446
23447 resolve_decl_queue.deinit();
23448
23449 // Loop through our declarations once to figure out how many declarations we will generate info for.
23450 int declaration_count = 0;
23451 decl_it = decls_scope->decl_table.entry_iterator();
23452 while ((curr_entry = decl_it.next()) != nullptr) {
23626 // Skip comptime blocks and test functions.23453 // Skip comptime blocks and test functions.
23627 if (curr_entry->value->id != TldIdCompTime) {23454 if (curr_entry->value->id == TldIdCompTime)
23628 if (curr_entry->value->id == TldIdFn) {23455 continue;
23629 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry;
23630 if (fn_entry->is_test)
23631 continue;
23632 }
2363323456
23634 declaration_count += 1;23457 if (curr_entry->value->id == TldIdFn) {
23458 ZigFn *fn_entry = ((TldFn *)curr_entry->value)->fn_entry;
23459 if (fn_entry->is_test)
23460 continue;
23635 }23461 }
23462
23463 declaration_count += 1;
23636 }23464 }
2363723465
23638 ZigValue *declaration_array = ira->codegen->pass1_arena->create<ZigValue>();23466 ZigValue *declaration_array = ira->codegen->pass1_arena->create<ZigValue>();
...@@ -24146,7 +23974,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy...@@ -24146,7 +23974,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
24146 // decls: []TypeInfo.Declaration23974 // decls: []TypeInfo.Declaration
24147 ensure_field_index(result->type, "decls", 3);23975 ensure_field_index(result->type, "decls", 3);
24148 if ((err = ir_make_type_info_decls(ira, source_instr, fields[3],23976 if ((err = ir_make_type_info_decls(ira, source_instr, fields[3],
24149 type_entry->data.enumeration.decls_scope)))23977 type_entry->data.enumeration.decls_scope, false)))
24150 {23978 {
24151 return err;23979 return err;
24152 }23980 }
...@@ -24318,7 +24146,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy...@@ -24318,7 +24146,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
24318 // decls: []TypeInfo.Declaration24146 // decls: []TypeInfo.Declaration
24319 ensure_field_index(result->type, "decls", 3);24147 ensure_field_index(result->type, "decls", 3);
24320 if ((err = ir_make_type_info_decls(ira, source_instr, fields[3],24148 if ((err = ir_make_type_info_decls(ira, source_instr, fields[3],
24321 type_entry->data.unionation.decls_scope)))24149 type_entry->data.unionation.decls_scope, false)))
24322 {24150 {
24323 return err;24151 return err;
24324 }24152 }
...@@ -24410,7 +24238,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy...@@ -24410,7 +24238,7 @@ static Error ir_make_type_info_value(IrAnalyze *ira, IrInst* source_instr, ZigTy
24410 // decls: []TypeInfo.Declaration24238 // decls: []TypeInfo.Declaration
24411 ensure_field_index(result->type, "decls", 2);24239 ensure_field_index(result->type, "decls", 2);
24412 if ((err = ir_make_type_info_decls(ira, source_instr, fields[2],24240 if ((err = ir_make_type_info_decls(ira, source_instr, fields[2],
24413 type_entry->data.structure.decls_scope)))24241 type_entry->data.structure.decls_scope, false)))
24414 {24242 {
24415 return err;24243 return err;
24416 }24244 }
...@@ -24784,19 +24612,6 @@ static IrInstGen *ir_analyze_instruction_type(IrAnalyze *ira, IrInstSrcType *ins...@@ -24784,19 +24612,6 @@ static IrInstGen *ir_analyze_instruction_type(IrAnalyze *ira, IrInstSrcType *ins
24784 return ir_const_type(ira, &instruction->base.base, type);24612 return ir_const_type(ira, &instruction->base.base, type);
24785}24613}
2478624614
24787static IrInstGen *ir_analyze_instruction_type_id(IrAnalyze *ira, IrInstSrcTypeId *instruction) {
24788 IrInstGen *type_value = instruction->type_value->child;
24789 ZigType *type_entry = ir_resolve_type(ira, type_value);
24790 if (type_is_invalid(type_entry))
24791 return ira->codegen->invalid_inst_gen;
24792
24793 ZigType *result_type = get_builtin_type(ira->codegen, "TypeId");
24794
24795 IrInstGen *result = ir_const(ira, &instruction->base.base, result_type);
24796 bigint_init_unsigned(&result->value->data.x_enum_tag, type_id_index(type_entry));
24797 return result;
24798}
24799
24800static IrInstGen *ir_analyze_instruction_set_eval_branch_quota(IrAnalyze *ira,24615static IrInstGen *ir_analyze_instruction_set_eval_branch_quota(IrAnalyze *ira,
24801 IrInstSrcSetEvalBranchQuota *instruction)24616 IrInstSrcSetEvalBranchQuota *instruction)
24802{24617{
...@@ -25394,171 +25209,6 @@ static IrInstGen *ir_analyze_instruction_err_set_cast(IrAnalyze *ira, IrInstSrcE...@@ -25394,171 +25209,6 @@ static IrInstGen *ir_analyze_instruction_err_set_cast(IrAnalyze *ira, IrInstSrcE
25394 return ir_analyze_err_set_cast(ira, &instruction->base.base, target, dest_type);25209 return ir_analyze_err_set_cast(ira, &instruction->base.base, target, dest_type);
25395}25210}
2539625211
25397static IrInstGen *ir_analyze_instruction_from_bytes(IrAnalyze *ira, IrInstSrcFromBytes *instruction) {
25398 Error err;
25399
25400 ZigType *dest_child_type = ir_resolve_type(ira, instruction->dest_child_type->child);
25401 if (type_is_invalid(dest_child_type))
25402 return ira->codegen->invalid_inst_gen;
25403
25404 IrInstGen *target = instruction->target->child;
25405 if (type_is_invalid(target->value->type))
25406 return ira->codegen->invalid_inst_gen;
25407
25408 bool src_ptr_const;
25409 bool src_ptr_volatile;
25410 uint32_t src_ptr_align;
25411 if (target->value->type->id == ZigTypeIdPointer) {
25412 src_ptr_const = target->value->type->data.pointer.is_const;
25413 src_ptr_volatile = target->value->type->data.pointer.is_volatile;
25414
25415 if ((err = resolve_ptr_align(ira, target->value->type, &src_ptr_align)))
25416 return ira->codegen->invalid_inst_gen;
25417 } else if (is_slice(target->value->type)) {
25418 ZigType *src_ptr_type = target->value->type->data.structure.fields[slice_ptr_index]->type_entry;
25419 src_ptr_const = src_ptr_type->data.pointer.is_const;
25420 src_ptr_volatile = src_ptr_type->data.pointer.is_volatile;
25421
25422 if ((err = resolve_ptr_align(ira, src_ptr_type, &src_ptr_align)))
25423 return ira->codegen->invalid_inst_gen;
25424 } else {
25425 src_ptr_const = true;
25426 src_ptr_volatile = false;
25427
25428 if ((err = type_resolve(ira->codegen, target->value->type, ResolveStatusAlignmentKnown)))
25429 return ira->codegen->invalid_inst_gen;
25430
25431 src_ptr_align = get_abi_alignment(ira->codegen, target->value->type);
25432 }
25433
25434 if (src_ptr_align != 0) {
25435 if ((err = type_resolve(ira->codegen, dest_child_type, ResolveStatusAlignmentKnown)))
25436 return ira->codegen->invalid_inst_gen;
25437 }
25438
25439 ZigType *dest_ptr_type = get_pointer_to_type_extra(ira->codegen, dest_child_type,
25440 src_ptr_const, src_ptr_volatile, PtrLenUnknown,
25441 src_ptr_align, 0, 0, false);
25442 ZigType *dest_slice_type = get_slice_type(ira->codegen, dest_ptr_type);
25443
25444 ZigType *u8_ptr = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8,
25445 src_ptr_const, src_ptr_volatile, PtrLenUnknown,
25446 src_ptr_align, 0, 0, false);
25447 ZigType *u8_slice = get_slice_type(ira->codegen, u8_ptr);
25448
25449 IrInstGen *casted_value = ir_implicit_cast2(ira, &instruction->target->base, target, u8_slice);
25450 if (type_is_invalid(casted_value->value->type))
25451 return ira->codegen->invalid_inst_gen;
25452
25453 bool have_known_len = false;
25454 uint64_t known_len;
25455
25456 if (instr_is_comptime(casted_value)) {
25457 ZigValue *val = ir_resolve_const(ira, casted_value, UndefBad);
25458 if (!val)
25459 return ira->codegen->invalid_inst_gen;
25460
25461 ZigValue *len_val = val->data.x_struct.fields[slice_len_index];
25462 if (value_is_comptime(len_val)) {
25463 known_len = bigint_as_u64(&len_val->data.x_bigint);
25464 have_known_len = true;
25465 }
25466 }
25467
25468 IrInstGen *result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc,
25469 dest_slice_type, nullptr, true, true);
25470 if (result_loc != nullptr && (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable)) {
25471 return result_loc;
25472 }
25473
25474 if (target->value->type->id == ZigTypeIdPointer &&
25475 target->value->type->data.pointer.ptr_len == PtrLenSingle &&
25476 target->value->type->data.pointer.child_type->id == ZigTypeIdArray)
25477 {
25478 known_len = target->value->type->data.pointer.child_type->data.array.len;
25479 have_known_len = true;
25480 } else if (casted_value->value->data.rh_slice.id == RuntimeHintSliceIdLen) {
25481 known_len = casted_value->value->data.rh_slice.len;
25482 have_known_len = true;
25483 }
25484
25485 if (have_known_len) {
25486 if ((err = type_resolve(ira->codegen, dest_child_type, ResolveStatusSizeKnown)))
25487 return ira->codegen->invalid_inst_gen;
25488 uint64_t child_type_size = type_size(ira->codegen, dest_child_type);
25489 uint64_t remainder = known_len % child_type_size;
25490 if (remainder != 0) {
25491 ErrorMsg *msg = ir_add_error(ira, &instruction->base.base,
25492 buf_sprintf("unable to convert [%" ZIG_PRI_u64 "]u8 to %s: size mismatch",
25493 known_len, buf_ptr(&dest_slice_type->name)));
25494 add_error_note(ira->codegen, msg, instruction->dest_child_type->base.source_node,
25495 buf_sprintf("%s has size %" ZIG_PRI_u64 "; remaining bytes: %" ZIG_PRI_u64,
25496 buf_ptr(&dest_child_type->name), child_type_size, remainder));
25497 return ira->codegen->invalid_inst_gen;
25498 }
25499 }
25500
25501 return ir_build_resize_slice(ira, &instruction->base.base, casted_value, dest_slice_type, result_loc);
25502}
25503
25504static IrInstGen *ir_analyze_instruction_to_bytes(IrAnalyze *ira, IrInstSrcToBytes *instruction) {
25505 Error err;
25506
25507 IrInstGen *target = instruction->target->child;
25508 if (type_is_invalid(target->value->type))
25509 return ira->codegen->invalid_inst_gen;
25510
25511 if (!is_slice(target->value->type)) {
25512 ir_add_error(ira, &instruction->target->base,
25513 buf_sprintf("expected slice, found '%s'", buf_ptr(&target->value->type->name)));
25514 return ira->codegen->invalid_inst_gen;
25515 }
25516
25517 ZigType *src_ptr_type = target->value->type->data.structure.fields[slice_ptr_index]->type_entry;
25518
25519 uint32_t alignment;
25520 if ((err = resolve_ptr_align(ira, src_ptr_type, &alignment)))
25521 return ira->codegen->invalid_inst_gen;
25522
25523 ZigType *dest_ptr_type = get_pointer_to_type_extra(ira->codegen, ira->codegen->builtin_types.entry_u8,
25524 src_ptr_type->data.pointer.is_const, src_ptr_type->data.pointer.is_volatile, PtrLenUnknown,
25525 alignment, 0, 0, false);
25526 ZigType *dest_slice_type = get_slice_type(ira->codegen, dest_ptr_type);
25527
25528 if (instr_is_comptime(target)) {
25529 ZigValue *target_val = ir_resolve_const(ira, target, UndefBad);
25530 if (target_val == nullptr)
25531 return ira->codegen->invalid_inst_gen;
25532
25533 IrInstGen *result = ir_const(ira, &instruction->base.base, dest_slice_type);
25534 result->value->data.x_struct.fields = alloc_const_vals_ptrs(ira->codegen, 2);
25535
25536 ZigValue *ptr_val = result->value->data.x_struct.fields[slice_ptr_index];
25537 ZigValue *target_ptr_val = target_val->data.x_struct.fields[slice_ptr_index];
25538 copy_const_val(ira->codegen, ptr_val, target_ptr_val);
25539 ptr_val->type = dest_ptr_type;
25540
25541 ZigValue *len_val = result->value->data.x_struct.fields[slice_len_index];
25542 len_val->special = ConstValSpecialStatic;
25543 len_val->type = ira->codegen->builtin_types.entry_usize;
25544 ZigValue *target_len_val = target_val->data.x_struct.fields[slice_len_index];
25545 ZigType *elem_type = src_ptr_type->data.pointer.child_type;
25546 BigInt elem_size_bigint;
25547 bigint_init_unsigned(&elem_size_bigint, type_size(ira->codegen, elem_type));
25548 bigint_mul(&len_val->data.x_bigint, &target_len_val->data.x_bigint, &elem_size_bigint);
25549
25550 return result;
25551 }
25552
25553 IrInstGen *result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc,
25554 dest_slice_type, nullptr, true, true);
25555 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) {
25556 return result_loc;
25557 }
25558
25559 return ir_build_resize_slice(ira, &instruction->base.base, target, dest_slice_type, result_loc);
25560}
25561
25562static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align) {25212static Error resolve_ptr_align(IrAnalyze *ira, ZigType *ty, uint32_t *result_align) {
25563 Error err;25213 Error err;
2556425214
...@@ -25672,20 +25322,6 @@ static IrInstGen *ir_analyze_instruction_bool_to_int(IrAnalyze *ira, IrInstSrcBo...@@ -25672,20 +25322,6 @@ static IrInstGen *ir_analyze_instruction_bool_to_int(IrAnalyze *ira, IrInstSrcBo
25672 return ir_resolve_cast(ira, &instruction->base.base, target, u1_type, CastOpBoolToInt);25322 return ir_resolve_cast(ira, &instruction->base.base, target, u1_type, CastOpBoolToInt);
25673}25323}
2567425324
25675static IrInstGen *ir_analyze_instruction_int_type(IrAnalyze *ira, IrInstSrcIntType *instruction) {
25676 IrInstGen *is_signed_value = instruction->is_signed->child;
25677 bool is_signed;
25678 if (!ir_resolve_bool(ira, is_signed_value, &is_signed))
25679 return ira->codegen->invalid_inst_gen;
25680
25681 IrInstGen *bit_count_value = instruction->bit_count->child;
25682 uint64_t bit_count;
25683 if (!ir_resolve_unsigned(ira, bit_count_value, ira->codegen->builtin_types.entry_u16, &bit_count))
25684 return ira->codegen->invalid_inst_gen;
25685
25686 return ir_const_type(ira, &instruction->base.base, get_int_type(ira->codegen, is_signed, (uint32_t)bit_count));
25687}
25688
25689static IrInstGen *ir_analyze_instruction_vector_type(IrAnalyze *ira, IrInstSrcVectorType *instruction) {25325static IrInstGen *ir_analyze_instruction_vector_type(IrAnalyze *ira, IrInstSrcVectorType *instruction) {
25690 uint64_t len;25326 uint64_t len;
25691 if (!ir_resolve_unsigned(ira, instruction->len->child, ira->codegen->builtin_types.entry_u32, &len))25327 if (!ir_resolve_unsigned(ira, instruction->len->child, ira->codegen->builtin_types.entry_u32, &len))
...@@ -26582,148 +26218,21 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i...@@ -26582,148 +26218,21 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
2658226218
26583 IrInstGen *result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc,26219 IrInstGen *result_loc = ir_resolve_result(ira, &instruction->base.base, instruction->result_loc,
26584 return_type, nullptr, true, true);26220 return_type, nullptr, true, true);
26585 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) {
26586 return result_loc;
26587 }
26588 return ir_build_slice_gen(ira, &instruction->base.base, return_type,
26589 ptr_ptr, casted_start, end, instruction->safety_check_on, result_loc);
26590}
26591
26592static IrInstGen *ir_analyze_instruction_member_count(IrAnalyze *ira, IrInstSrcMemberCount *instruction) {
26593 Error err;
26594 IrInstGen *container = instruction->container->child;
26595 if (type_is_invalid(container->value->type))
26596 return ira->codegen->invalid_inst_gen;
26597 ZigType *container_type = ir_resolve_type(ira, container);
26598
26599 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown)))
26600 return ira->codegen->invalid_inst_gen;
26601
26602 uint64_t result;
26603 if (type_is_invalid(container_type)) {
26604 return ira->codegen->invalid_inst_gen;
26605 } else if (container_type->id == ZigTypeIdEnum) {
26606 result = container_type->data.enumeration.src_field_count;
26607 } else if (container_type->id == ZigTypeIdStruct) {
26608 result = container_type->data.structure.src_field_count;
26609 } else if (container_type->id == ZigTypeIdUnion) {
26610 result = container_type->data.unionation.src_field_count;
26611 } else if (container_type->id == ZigTypeIdErrorSet) {
26612 if (!resolve_inferred_error_set(ira->codegen, container_type, instruction->base.base.source_node)) {
26613 return ira->codegen->invalid_inst_gen;
26614 }
26615 if (type_is_global_error_set(container_type)) {
26616 ir_add_error(ira, &instruction->base.base, buf_sprintf("global error set member count not available at comptime"));
26617 return ira->codegen->invalid_inst_gen;
26618 }
26619 result = container_type->data.error_set.err_count;
26620 } else {
26621 ir_add_error(ira, &instruction->base.base, buf_sprintf("no value count available for type '%s'", buf_ptr(&container_type->name)));
26622 return ira->codegen->invalid_inst_gen;
26623 }
26624
26625 return ir_const_unsigned(ira, &instruction->base.base, result);
26626}
26627
26628static IrInstGen *ir_analyze_instruction_member_type(IrAnalyze *ira, IrInstSrcMemberType *instruction) {
26629 Error err;
26630 IrInstGen *container_type_value = instruction->container_type->child;
26631 ZigType *container_type = ir_resolve_type(ira, container_type_value);
26632 if (type_is_invalid(container_type))
26633 return ira->codegen->invalid_inst_gen;
26634
26635 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown)))
26636 return ira->codegen->invalid_inst_gen;
26637
26638
26639 uint64_t member_index;
26640 IrInstGen *index_value = instruction->member_index->child;
26641 if (!ir_resolve_usize(ira, index_value, &member_index))
26642 return ira->codegen->invalid_inst_gen;
2664326221
26644 if (container_type->id == ZigTypeIdStruct) {26222 if (result_loc != nullptr) {
26645 if (member_index >= container_type->data.structure.src_field_count) {26223 if (type_is_invalid(result_loc->value->type) || result_loc->value->type->id == ZigTypeIdUnreachable) {
26646 ir_add_error(ira, &index_value->base,26224 return result_loc;
26647 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members",
26648 member_index, buf_ptr(&container_type->name), container_type->data.structure.src_field_count));
26649 return ira->codegen->invalid_inst_gen;
26650 }26225 }
26651 TypeStructField *field = container_type->data.structure.fields[member_index];26226 IrInstGen *dummy_value = ir_const(ira, &instruction->base.base, return_type);
2665226227 dummy_value->value->special = ConstValSpecialRuntime;
26653 return ir_const_type(ira, &instruction->base.base, field->type_entry);26228 IrInstGen *dummy_result = ir_implicit_cast2(ira, &instruction->base.base,
26654 } else if (container_type->id == ZigTypeIdUnion) {26229 dummy_value, result_loc->value->type->data.pointer.child_type);
26655 if (member_index >= container_type->data.unionation.src_field_count) {26230 if (type_is_invalid(dummy_result->value->type))
26656 ir_add_error(ira, &index_value->base,
26657 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members",
26658 member_index, buf_ptr(&container_type->name), container_type->data.unionation.src_field_count));
26659 return ira->codegen->invalid_inst_gen;26231 return ira->codegen->invalid_inst_gen;
26660 }
26661 TypeUnionField *field = &container_type->data.unionation.fields[member_index];
26662
26663 return ir_const_type(ira, &instruction->base.base, field->type_entry);
26664 } else {
26665 ir_add_error(ira, &container_type_value->base,
26666 buf_sprintf("type '%s' does not support @memberType", buf_ptr(&container_type->name)));
26667 return ira->codegen->invalid_inst_gen;
26668 }26232 }
26669}
26670
26671static IrInstGen *ir_analyze_instruction_member_name(IrAnalyze *ira, IrInstSrcMemberName *instruction) {
26672 Error err;
26673 IrInstGen *container_type_value = instruction->container_type->child;
26674 ZigType *container_type = ir_resolve_type(ira, container_type_value);
26675 if (type_is_invalid(container_type))
26676 return ira->codegen->invalid_inst_gen;
2667726233
26678 if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown)))26234 return ir_build_slice_gen(ira, &instruction->base.base, return_type,
26679 return ira->codegen->invalid_inst_gen;26235 ptr_ptr, casted_start, end, instruction->safety_check_on, result_loc);
26680
26681 uint64_t member_index;
26682 IrInstGen *index_value = instruction->member_index->child;
26683 if (!ir_resolve_usize(ira, index_value, &member_index))
26684 return ira->codegen->invalid_inst_gen;
26685
26686 if (container_type->id == ZigTypeIdStruct) {
26687 if (member_index >= container_type->data.structure.src_field_count) {
26688 ir_add_error(ira, &index_value->base,
26689 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members",
26690 member_index, buf_ptr(&container_type->name), container_type->data.structure.src_field_count));
26691 return ira->codegen->invalid_inst_gen;
26692 }
26693 TypeStructField *field = container_type->data.structure.fields[member_index];
26694
26695 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr);
26696 init_const_str_lit(ira->codegen, result->value, field->name);
26697 return result;
26698 } else if (container_type->id == ZigTypeIdEnum) {
26699 if (member_index >= container_type->data.enumeration.src_field_count) {
26700 ir_add_error(ira, &index_value->base,
26701 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members",
26702 member_index, buf_ptr(&container_type->name), container_type->data.enumeration.src_field_count));
26703 return ira->codegen->invalid_inst_gen;
26704 }
26705 TypeEnumField *field = &container_type->data.enumeration.fields[member_index];
26706
26707 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr);
26708 init_const_str_lit(ira->codegen, result->value, field->name);
26709 return result;
26710 } else if (container_type->id == ZigTypeIdUnion) {
26711 if (member_index >= container_type->data.unionation.src_field_count) {
26712 ir_add_error(ira, &index_value->base,
26713 buf_sprintf("member index %" ZIG_PRI_u64 " out of bounds; '%s' has %" PRIu32 " members",
26714 member_index, buf_ptr(&container_type->name), container_type->data.unionation.src_field_count));
26715 return ira->codegen->invalid_inst_gen;
26716 }
26717 TypeUnionField *field = &container_type->data.unionation.fields[member_index];
26718
26719 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr);
26720 init_const_str_lit(ira->codegen, result->value, field->name);
26721 return result;
26722 } else {
26723 ir_add_error(ira, &container_type_value->base,
26724 buf_sprintf("type '%s' does not support @memberName", buf_ptr(&container_type->name)));
26725 return ira->codegen->invalid_inst_gen;
26726 }
26727}26236}
2672826237
26729static IrInstGen *ir_analyze_instruction_has_field(IrAnalyze *ira, IrInstSrcHasField *instruction) {26238static IrInstGen *ir_analyze_instruction_has_field(IrAnalyze *ira, IrInstSrcHasField *instruction) {
...@@ -29466,7 +28975,7 @@ static IrInstGen *ir_analyze_instruction_await(IrAnalyze *ira, IrInstSrcAwait *i...@@ -29466,7 +28975,7 @@ static IrInstGen *ir_analyze_instruction_await(IrAnalyze *ira, IrInstSrcAwait *i
29466 ir_assert(fn_entry != nullptr, &instruction->base.base);28975 ir_assert(fn_entry != nullptr, &instruction->base.base);
2946728976
29468 // If it's not @Frame(func) then it's definitely a suspend point28977 // If it's not @Frame(func) then it's definitely a suspend point
29469 if (target_fn == nullptr) {28978 if (target_fn == nullptr && !instruction->is_noasync) {
29470 if (fn_entry->inferred_async_node == nullptr) {28979 if (fn_entry->inferred_async_node == nullptr) {
29471 fn_entry->inferred_async_node = instruction->base.base.source_node;28980 fn_entry->inferred_async_node = instruction->base.base.source_node;
29472 }28981 }
...@@ -29489,7 +28998,8 @@ static IrInstGen *ir_analyze_instruction_await(IrAnalyze *ira, IrInstSrcAwait *i...@@ -29489,7 +28998,8 @@ static IrInstGen *ir_analyze_instruction_await(IrAnalyze *ira, IrInstSrcAwait *i
29489 result_loc = nullptr;28998 result_loc = nullptr;
29490 }28999 }
2949129000
29492 IrInstGenAwait *result = ir_build_await_gen(ira, &instruction->base.base, frame, result_type, result_loc);29001 IrInstGenAwait *result = ir_build_await_gen(ira, &instruction->base.base, frame, result_type, result_loc,
29002 instruction->is_noasync);
29493 result->target_fn = target_fn;29003 result->target_fn = target_fn;
29494 fn_entry->await_list.append(result);29004 fn_entry->await_list.append(result);
29495 return ir_finish_anal(ira, &result->base);29005 return ir_finish_anal(ira, &result->base);
...@@ -29677,18 +29187,12 @@ static IrInstGen *ir_analyze_instruction_base(IrAnalyze *ira, IrInstSrc *instruc...@@ -29677,18 +29187,12 @@ static IrInstGen *ir_analyze_instruction_base(IrAnalyze *ira, IrInstSrc *instruc
29677 return ir_analyze_instruction_float_cast(ira, (IrInstSrcFloatCast *)instruction);29187 return ir_analyze_instruction_float_cast(ira, (IrInstSrcFloatCast *)instruction);
29678 case IrInstSrcIdErrSetCast:29188 case IrInstSrcIdErrSetCast:
29679 return ir_analyze_instruction_err_set_cast(ira, (IrInstSrcErrSetCast *)instruction);29189 return ir_analyze_instruction_err_set_cast(ira, (IrInstSrcErrSetCast *)instruction);
29680 case IrInstSrcIdFromBytes:
29681 return ir_analyze_instruction_from_bytes(ira, (IrInstSrcFromBytes *)instruction);
29682 case IrInstSrcIdToBytes:
29683 return ir_analyze_instruction_to_bytes(ira, (IrInstSrcToBytes *)instruction);
29684 case IrInstSrcIdIntToFloat:29190 case IrInstSrcIdIntToFloat:
29685 return ir_analyze_instruction_int_to_float(ira, (IrInstSrcIntToFloat *)instruction);29191 return ir_analyze_instruction_int_to_float(ira, (IrInstSrcIntToFloat *)instruction);
29686 case IrInstSrcIdFloatToInt:29192 case IrInstSrcIdFloatToInt:
29687 return ir_analyze_instruction_float_to_int(ira, (IrInstSrcFloatToInt *)instruction);29193 return ir_analyze_instruction_float_to_int(ira, (IrInstSrcFloatToInt *)instruction);
29688 case IrInstSrcIdBoolToInt:29194 case IrInstSrcIdBoolToInt:
29689 return ir_analyze_instruction_bool_to_int(ira, (IrInstSrcBoolToInt *)instruction);29195 return ir_analyze_instruction_bool_to_int(ira, (IrInstSrcBoolToInt *)instruction);
29690 case IrInstSrcIdIntType:
29691 return ir_analyze_instruction_int_type(ira, (IrInstSrcIntType *)instruction);
29692 case IrInstSrcIdVectorType:29196 case IrInstSrcIdVectorType:
29693 return ir_analyze_instruction_vector_type(ira, (IrInstSrcVectorType *)instruction);29197 return ir_analyze_instruction_vector_type(ira, (IrInstSrcVectorType *)instruction);
29694 case IrInstSrcIdShuffleVector:29198 case IrInstSrcIdShuffleVector:
...@@ -29703,12 +29207,6 @@ static IrInstGen *ir_analyze_instruction_base(IrAnalyze *ira, IrInstSrc *instruc...@@ -29703,12 +29207,6 @@ static IrInstGen *ir_analyze_instruction_base(IrAnalyze *ira, IrInstSrc *instruc
29703 return ir_analyze_instruction_memcpy(ira, (IrInstSrcMemcpy *)instruction);29207 return ir_analyze_instruction_memcpy(ira, (IrInstSrcMemcpy *)instruction);
29704 case IrInstSrcIdSlice:29208 case IrInstSrcIdSlice:
29705 return ir_analyze_instruction_slice(ira, (IrInstSrcSlice *)instruction);29209 return ir_analyze_instruction_slice(ira, (IrInstSrcSlice *)instruction);
29706 case IrInstSrcIdMemberCount:
29707 return ir_analyze_instruction_member_count(ira, (IrInstSrcMemberCount *)instruction);
29708 case IrInstSrcIdMemberType:
29709 return ir_analyze_instruction_member_type(ira, (IrInstSrcMemberType *)instruction);
29710 case IrInstSrcIdMemberName:
29711 return ir_analyze_instruction_member_name(ira, (IrInstSrcMemberName *)instruction);
29712 case IrInstSrcIdBreakpoint:29210 case IrInstSrcIdBreakpoint:
29713 return ir_analyze_instruction_breakpoint(ira, (IrInstSrcBreakpoint *)instruction);29211 return ir_analyze_instruction_breakpoint(ira, (IrInstSrcBreakpoint *)instruction);
29714 case IrInstSrcIdReturnAddress:29212 case IrInstSrcIdReturnAddress:
...@@ -29763,8 +29261,6 @@ static IrInstGen *ir_analyze_instruction_base(IrAnalyze *ira, IrInstSrc *instruc...@@ -29763,8 +29261,6 @@ static IrInstGen *ir_analyze_instruction_base(IrAnalyze *ira, IrInstSrc *instruc
29763 return ir_analyze_instruction_type(ira, (IrInstSrcType *)instruction);29261 return ir_analyze_instruction_type(ira, (IrInstSrcType *)instruction);
29764 case IrInstSrcIdHasField:29262 case IrInstSrcIdHasField:
29765 return ir_analyze_instruction_has_field(ira, (IrInstSrcHasField *) instruction);29263 return ir_analyze_instruction_has_field(ira, (IrInstSrcHasField *) instruction);
29766 case IrInstSrcIdTypeId:
29767 return ir_analyze_instruction_type_id(ira, (IrInstSrcTypeId *)instruction);
29768 case IrInstSrcIdSetEvalBranchQuota:29264 case IrInstSrcIdSetEvalBranchQuota:
29769 return ir_analyze_instruction_set_eval_branch_quota(ira, (IrInstSrcSetEvalBranchQuota *)instruction);29265 return ir_analyze_instruction_set_eval_branch_quota(ira, (IrInstSrcSetEvalBranchQuota *)instruction);
29770 case IrInstSrcIdPtrType:29266 case IrInstSrcIdPtrType:
...@@ -30007,7 +29503,6 @@ bool ir_inst_gen_has_side_effects(IrInstGen *instruction) {...@@ -30007,7 +29503,6 @@ bool ir_inst_gen_has_side_effects(IrInstGen *instruction) {
30007 case IrInstGenIdCmpxchg:29503 case IrInstGenIdCmpxchg:
30008 case IrInstGenIdAssertZero:29504 case IrInstGenIdAssertZero:
30009 case IrInstGenIdAssertNonNull:29505 case IrInstGenIdAssertNonNull:
30010 case IrInstGenIdResizeSlice:
30011 case IrInstGenIdPtrOfArrayToSlice:29506 case IrInstGenIdPtrOfArrayToSlice:
30012 case IrInstGenIdSlice:29507 case IrInstGenIdSlice:
30013 case IrInstGenIdOptionalWrap:29508 case IrInstGenIdOptionalWrap:
...@@ -30180,15 +29675,11 @@ bool ir_inst_src_has_side_effects(IrInstSrc *instruction) {...@@ -30180,15 +29675,11 @@ bool ir_inst_src_has_side_effects(IrInstSrc *instruction) {
30180 case IrInstSrcIdRef:29675 case IrInstSrcIdRef:
30181 case IrInstSrcIdEmbedFile:29676 case IrInstSrcIdEmbedFile:
30182 case IrInstSrcIdTruncate:29677 case IrInstSrcIdTruncate:
30183 case IrInstSrcIdIntType:
30184 case IrInstSrcIdVectorType:29678 case IrInstSrcIdVectorType:
30185 case IrInstSrcIdShuffleVector:29679 case IrInstSrcIdShuffleVector:
30186 case IrInstSrcIdSplat:29680 case IrInstSrcIdSplat:
30187 case IrInstSrcIdBoolNot:29681 case IrInstSrcIdBoolNot:
30188 case IrInstSrcIdSlice:29682 case IrInstSrcIdSlice:
30189 case IrInstSrcIdMemberCount:
30190 case IrInstSrcIdMemberType:
30191 case IrInstSrcIdMemberName:
30192 case IrInstSrcIdAlignOf:29683 case IrInstSrcIdAlignOf:
30193 case IrInstSrcIdReturnAddress:29684 case IrInstSrcIdReturnAddress:
30194 case IrInstSrcIdFrameAddress:29685 case IrInstSrcIdFrameAddress:
...@@ -30215,7 +29706,6 @@ bool ir_inst_src_has_side_effects(IrInstSrc *instruction) {...@@ -30215,7 +29706,6 @@ bool ir_inst_src_has_side_effects(IrInstSrc *instruction) {
30215 case IrInstSrcIdTypeInfo:29706 case IrInstSrcIdTypeInfo:
30216 case IrInstSrcIdType:29707 case IrInstSrcIdType:
30217 case IrInstSrcIdHasField:29708 case IrInstSrcIdHasField:
30218 case IrInstSrcIdTypeId:
30219 case IrInstSrcIdAlignCast:29709 case IrInstSrcIdAlignCast:
30220 case IrInstSrcIdImplicitCast:29710 case IrInstSrcIdImplicitCast:
30221 case IrInstSrcIdResolveResult:29711 case IrInstSrcIdResolveResult:
...@@ -30233,8 +29723,6 @@ bool ir_inst_src_has_side_effects(IrInstSrc *instruction) {...@@ -30233,8 +29723,6 @@ bool ir_inst_src_has_side_effects(IrInstSrc *instruction) {
30233 case IrInstSrcIdIntToFloat:29723 case IrInstSrcIdIntToFloat:
30234 case IrInstSrcIdFloatToInt:29724 case IrInstSrcIdFloatToInt:
30235 case IrInstSrcIdBoolToInt:29725 case IrInstSrcIdBoolToInt:
30236 case IrInstSrcIdFromBytes:
30237 case IrInstSrcIdToBytes:
30238 case IrInstSrcIdEnumToInt:29726 case IrInstSrcIdEnumToInt:
30239 case IrInstSrcIdHasDecl:29727 case IrInstSrcIdHasDecl:
30240 case IrInstSrcIdAlloca:29728 case IrInstSrcIdAlloca:
...@@ -30347,6 +29835,18 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {...@@ -30347,6 +29835,18 @@ static Error ir_resolve_lazy_raw(AstNode *source_node, ZigValue *val) {
30347 switch (val->data.x_lazy->id) {29835 switch (val->data.x_lazy->id) {
30348 case LazyValueIdInvalid:29836 case LazyValueIdInvalid:
30349 zig_unreachable();29837 zig_unreachable();
29838 case LazyValueIdTypeInfoDecls: {
29839 LazyValueTypeInfoDecls *type_info_decls = reinterpret_cast<LazyValueTypeInfoDecls *>(val->data.x_lazy);
29840 IrAnalyze *ira = type_info_decls->ira;
29841
29842 if ((err = ir_make_type_info_decls(ira, type_info_decls->source_instr, val, type_info_decls->decls_scope, true)))
29843 {
29844 return err;
29845 };
29846
29847 // We can't free the lazy value here, because multiple other ZigValues might be pointing to it.
29848 return ErrorNone;
29849 }
30350 case LazyValueIdAlignOf: {29850 case LazyValueIdAlignOf: {
30351 LazyValueAlignOf *lazy_align_of = reinterpret_cast<LazyValueAlignOf *>(val->data.x_lazy);29851 LazyValueAlignOf *lazy_align_of = reinterpret_cast<LazyValueAlignOf *>(val->data.x_lazy);
30352 IrAnalyze *ira = lazy_align_of->ira;29852 IrAnalyze *ira = lazy_align_of->ira;
src/ir_print.cpp-102
...@@ -179,8 +179,6 @@ const char* ir_inst_src_type_str(IrInstSrcId id) {...@@ -179,8 +179,6 @@ const char* ir_inst_src_type_str(IrInstSrcId id) {
179 return "SrcFloatToInt";179 return "SrcFloatToInt";
180 case IrInstSrcIdBoolToInt:180 case IrInstSrcIdBoolToInt:
181 return "SrcBoolToInt";181 return "SrcBoolToInt";
182 case IrInstSrcIdIntType:
183 return "SrcIntType";
184 case IrInstSrcIdVectorType:182 case IrInstSrcIdVectorType:
185 return "SrcVectorType";183 return "SrcVectorType";
186 case IrInstSrcIdBoolNot:184 case IrInstSrcIdBoolNot:
...@@ -191,12 +189,6 @@ const char* ir_inst_src_type_str(IrInstSrcId id) {...@@ -191,12 +189,6 @@ const char* ir_inst_src_type_str(IrInstSrcId id) {
191 return "SrcMemcpy";189 return "SrcMemcpy";
192 case IrInstSrcIdSlice:190 case IrInstSrcIdSlice:
193 return "SrcSlice";191 return "SrcSlice";
194 case IrInstSrcIdMemberCount:
195 return "SrcMemberCount";
196 case IrInstSrcIdMemberType:
197 return "SrcMemberType";
198 case IrInstSrcIdMemberName:
199 return "SrcMemberName";
200 case IrInstSrcIdBreakpoint:192 case IrInstSrcIdBreakpoint:
201 return "SrcBreakpoint";193 return "SrcBreakpoint";
202 case IrInstSrcIdReturnAddress:194 case IrInstSrcIdReturnAddress:
...@@ -269,8 +261,6 @@ const char* ir_inst_src_type_str(IrInstSrcId id) {...@@ -269,8 +261,6 @@ const char* ir_inst_src_type_str(IrInstSrcId id) {
269 return "SrcType";261 return "SrcType";
270 case IrInstSrcIdHasField:262 case IrInstSrcIdHasField:
271 return "SrcHasField";263 return "SrcHasField";
272 case IrInstSrcIdTypeId:
273 return "SrcTypeId";
274 case IrInstSrcIdSetEvalBranchQuota:264 case IrInstSrcIdSetEvalBranchQuota:
275 return "SrcSetEvalBranchQuota";265 return "SrcSetEvalBranchQuota";
276 case IrInstSrcIdPtrType:266 case IrInstSrcIdPtrType:
...@@ -307,10 +297,6 @@ const char* ir_inst_src_type_str(IrInstSrcId id) {...@@ -307,10 +297,6 @@ const char* ir_inst_src_type_str(IrInstSrcId id) {
307 return "SrcAddImplicitReturnType";297 return "SrcAddImplicitReturnType";
308 case IrInstSrcIdErrSetCast:298 case IrInstSrcIdErrSetCast:
309 return "SrcErrSetCast";299 return "SrcErrSetCast";
310 case IrInstSrcIdToBytes:
311 return "SrcToBytes";
312 case IrInstSrcIdFromBytes:
313 return "SrcFromBytes";
314 case IrInstSrcIdCheckRuntimeScope:300 case IrInstSrcIdCheckRuntimeScope:
315 return "SrcCheckRuntimeScope";301 return "SrcCheckRuntimeScope";
316 case IrInstSrcIdHasDecl:302 case IrInstSrcIdHasDecl:
...@@ -383,8 +369,6 @@ const char* ir_inst_gen_type_str(IrInstGenId id) {...@@ -383,8 +369,6 @@ const char* ir_inst_gen_type_str(IrInstGenId id) {
383 return "GenReturn";369 return "GenReturn";
384 case IrInstGenIdCast:370 case IrInstGenIdCast:
385 return "GenCast";371 return "GenCast";
386 case IrInstGenIdResizeSlice:
387 return "GenResizeSlice";
388 case IrInstGenIdUnreachable:372 case IrInstGenIdUnreachable:
389 return "GenUnreachable";373 return "GenUnreachable";
390 case IrInstGenIdAsm:374 case IrInstGenIdAsm:
...@@ -590,11 +574,6 @@ static void ir_print_const_value(CodeGen *g, FILE *f, ZigValue *const_val) {...@@ -590,11 +574,6 @@ static void ir_print_const_value(CodeGen *g, FILE *f, ZigValue *const_val) {
590static void ir_print_other_inst_gen(IrPrintGen *irp, IrInstGen *inst) {574static void ir_print_other_inst_gen(IrPrintGen *irp, IrInstGen *inst) {
591 if (inst == nullptr) {575 if (inst == nullptr) {
592 fprintf(irp->f, "(null)");576 fprintf(irp->f, "(null)");
593 return;
594 }
595
596 if (inst->value->special != ConstValSpecialRuntime) {
597 ir_print_const_value(irp->codegen, irp->f, inst->value);
598 } else {577 } else {
599 ir_print_var_gen(irp, inst);578 ir_print_var_gen(irp, inst);
600 }579 }
...@@ -1649,20 +1628,6 @@ static void ir_print_err_set_cast(IrPrintSrc *irp, IrInstSrcErrSetCast *instruct...@@ -1649,20 +1628,6 @@ static void ir_print_err_set_cast(IrPrintSrc *irp, IrInstSrcErrSetCast *instruct
1649 fprintf(irp->f, ")");1628 fprintf(irp->f, ")");
1650}1629}
16511630
1652static void ir_print_from_bytes(IrPrintSrc *irp, IrInstSrcFromBytes *instruction) {
1653 fprintf(irp->f, "@bytesToSlice(");
1654 ir_print_other_inst_src(irp, instruction->dest_child_type);
1655 fprintf(irp->f, ", ");
1656 ir_print_other_inst_src(irp, instruction->target);
1657 fprintf(irp->f, ")");
1658}
1659
1660static void ir_print_to_bytes(IrPrintSrc *irp, IrInstSrcToBytes *instruction) {
1661 fprintf(irp->f, "@sliceToBytes(");
1662 ir_print_other_inst_src(irp, instruction->target);
1663 fprintf(irp->f, ")");
1664}
1665
1666static void ir_print_int_to_float(IrPrintSrc *irp, IrInstSrcIntToFloat *instruction) {1631static void ir_print_int_to_float(IrPrintSrc *irp, IrInstSrcIntToFloat *instruction) {
1667 fprintf(irp->f, "@intToFloat(");1632 fprintf(irp->f, "@intToFloat(");
1668 ir_print_other_inst_src(irp, instruction->dest_type);1633 ir_print_other_inst_src(irp, instruction->dest_type);
...@@ -1685,14 +1650,6 @@ static void ir_print_bool_to_int(IrPrintSrc *irp, IrInstSrcBoolToInt *instructio...@@ -1685,14 +1650,6 @@ static void ir_print_bool_to_int(IrPrintSrc *irp, IrInstSrcBoolToInt *instructio
1685 fprintf(irp->f, ")");1650 fprintf(irp->f, ")");
1686}1651}
16871652
1688static void ir_print_int_type(IrPrintSrc *irp, IrInstSrcIntType *instruction) {
1689 fprintf(irp->f, "@IntType(");
1690 ir_print_other_inst_src(irp, instruction->is_signed);
1691 fprintf(irp->f, ", ");
1692 ir_print_other_inst_src(irp, instruction->bit_count);
1693 fprintf(irp->f, ")");
1694}
1695
1696static void ir_print_vector_type(IrPrintSrc *irp, IrInstSrcVectorType *instruction) {1653static void ir_print_vector_type(IrPrintSrc *irp, IrInstSrcVectorType *instruction) {
1697 fprintf(irp->f, "@Vector(");1654 fprintf(irp->f, "@Vector(");
1698 ir_print_other_inst_src(irp, instruction->len);1655 ir_print_other_inst_src(irp, instruction->len);
...@@ -1809,28 +1766,6 @@ static void ir_print_slice_gen(IrPrintGen *irp, IrInstGenSlice *instruction) {...@@ -1809,28 +1766,6 @@ static void ir_print_slice_gen(IrPrintGen *irp, IrInstGenSlice *instruction) {
1809 ir_print_other_inst_gen(irp, instruction->result_loc);1766 ir_print_other_inst_gen(irp, instruction->result_loc);
1810}1767}
18111768
1812static void ir_print_member_count(IrPrintSrc *irp, IrInstSrcMemberCount *instruction) {
1813 fprintf(irp->f, "@memberCount(");
1814 ir_print_other_inst_src(irp, instruction->container);
1815 fprintf(irp->f, ")");
1816}
1817
1818static void ir_print_member_type(IrPrintSrc *irp, IrInstSrcMemberType *instruction) {
1819 fprintf(irp->f, "@memberType(");
1820 ir_print_other_inst_src(irp, instruction->container_type);
1821 fprintf(irp->f, ", ");
1822 ir_print_other_inst_src(irp, instruction->member_index);
1823 fprintf(irp->f, ")");
1824}
1825
1826static void ir_print_member_name(IrPrintSrc *irp, IrInstSrcMemberName *instruction) {
1827 fprintf(irp->f, "@memberName(");
1828 ir_print_other_inst_src(irp, instruction->container_type);
1829 fprintf(irp->f, ", ");
1830 ir_print_other_inst_src(irp, instruction->member_index);
1831 fprintf(irp->f, ")");
1832}
1833
1834static void ir_print_breakpoint(IrPrintSrc *irp, IrInstSrcBreakpoint *instruction) {1769static void ir_print_breakpoint(IrPrintSrc *irp, IrInstSrcBreakpoint *instruction) {
1835 fprintf(irp->f, "@breakpoint()");1770 fprintf(irp->f, "@breakpoint()");
1836}1771}
...@@ -2147,13 +2082,6 @@ static void ir_print_assert_non_null(IrPrintGen *irp, IrInstGenAssertNonNull *in...@@ -2147,13 +2082,6 @@ static void ir_print_assert_non_null(IrPrintGen *irp, IrInstGenAssertNonNull *in
2147 fprintf(irp->f, ")");2082 fprintf(irp->f, ")");
2148}2083}
21492084
2150static void ir_print_resize_slice(IrPrintGen *irp, IrInstGenResizeSlice *instruction) {
2151 fprintf(irp->f, "@resizeSlice(");
2152 ir_print_other_inst_gen(irp, instruction->operand);
2153 fprintf(irp->f, ")result=");
2154 ir_print_other_inst_gen(irp, instruction->result_loc);
2155}
2156
2157static void ir_print_alloca_src(IrPrintSrc *irp, IrInstSrcAlloca *instruction) {2085static void ir_print_alloca_src(IrPrintSrc *irp, IrInstSrcAlloca *instruction) {
2158 fprintf(irp->f, "Alloca(align=");2086 fprintf(irp->f, "Alloca(align=");
2159 ir_print_other_inst_src(irp, instruction->align);2087 ir_print_other_inst_src(irp, instruction->align);
...@@ -2311,12 +2239,6 @@ static void ir_print_has_field(IrPrintSrc *irp, IrInstSrcHasField *instruction)...@@ -2311,12 +2239,6 @@ static void ir_print_has_field(IrPrintSrc *irp, IrInstSrcHasField *instruction)
2311 fprintf(irp->f, ")");2239 fprintf(irp->f, ")");
2312}2240}
23132241
2314static void ir_print_type_id(IrPrintSrc *irp, IrInstSrcTypeId *instruction) {
2315 fprintf(irp->f, "@typeId(");
2316 ir_print_other_inst_src(irp, instruction->type_value);
2317 fprintf(irp->f, ")");
2318}
2319
2320static void ir_print_set_eval_branch_quota(IrPrintSrc *irp, IrInstSrcSetEvalBranchQuota *instruction) {2242static void ir_print_set_eval_branch_quota(IrPrintSrc *irp, IrInstSrcSetEvalBranchQuota *instruction) {
2321 fprintf(irp->f, "@setEvalBranchQuota(");2243 fprintf(irp->f, "@setEvalBranchQuota(");
2322 ir_print_other_inst_src(irp, instruction->new_quota);2244 ir_print_other_inst_src(irp, instruction->new_quota);
...@@ -2798,12 +2720,6 @@ static void ir_print_inst_src(IrPrintSrc *irp, IrInstSrc *instruction, bool trai...@@ -2798,12 +2720,6 @@ static void ir_print_inst_src(IrPrintSrc *irp, IrInstSrc *instruction, bool trai
2798 case IrInstSrcIdErrSetCast:2720 case IrInstSrcIdErrSetCast:
2799 ir_print_err_set_cast(irp, (IrInstSrcErrSetCast *)instruction);2721 ir_print_err_set_cast(irp, (IrInstSrcErrSetCast *)instruction);
2800 break;2722 break;
2801 case IrInstSrcIdFromBytes:
2802 ir_print_from_bytes(irp, (IrInstSrcFromBytes *)instruction);
2803 break;
2804 case IrInstSrcIdToBytes:
2805 ir_print_to_bytes(irp, (IrInstSrcToBytes *)instruction);
2806 break;
2807 case IrInstSrcIdIntToFloat:2723 case IrInstSrcIdIntToFloat:
2808 ir_print_int_to_float(irp, (IrInstSrcIntToFloat *)instruction);2724 ir_print_int_to_float(irp, (IrInstSrcIntToFloat *)instruction);
2809 break;2725 break;
...@@ -2813,9 +2729,6 @@ static void ir_print_inst_src(IrPrintSrc *irp, IrInstSrc *instruction, bool trai...@@ -2813,9 +2729,6 @@ static void ir_print_inst_src(IrPrintSrc *irp, IrInstSrc *instruction, bool trai
2813 case IrInstSrcIdBoolToInt:2729 case IrInstSrcIdBoolToInt:
2814 ir_print_bool_to_int(irp, (IrInstSrcBoolToInt *)instruction);2730 ir_print_bool_to_int(irp, (IrInstSrcBoolToInt *)instruction);
2815 break;2731 break;
2816 case IrInstSrcIdIntType:
2817 ir_print_int_type(irp, (IrInstSrcIntType *)instruction);
2818 break;
2819 case IrInstSrcIdVectorType:2732 case IrInstSrcIdVectorType:
2820 ir_print_vector_type(irp, (IrInstSrcVectorType *)instruction);2733 ir_print_vector_type(irp, (IrInstSrcVectorType *)instruction);
2821 break;2734 break;
...@@ -2837,15 +2750,6 @@ static void ir_print_inst_src(IrPrintSrc *irp, IrInstSrc *instruction, bool trai...@@ -2837,15 +2750,6 @@ static void ir_print_inst_src(IrPrintSrc *irp, IrInstSrc *instruction, bool trai
2837 case IrInstSrcIdSlice:2750 case IrInstSrcIdSlice:
2838 ir_print_slice_src(irp, (IrInstSrcSlice *)instruction);2751 ir_print_slice_src(irp, (IrInstSrcSlice *)instruction);
2839 break;2752 break;
2840 case IrInstSrcIdMemberCount:
2841 ir_print_member_count(irp, (IrInstSrcMemberCount *)instruction);
2842 break;
2843 case IrInstSrcIdMemberType:
2844 ir_print_member_type(irp, (IrInstSrcMemberType *)instruction);
2845 break;
2846 case IrInstSrcIdMemberName:
2847 ir_print_member_name(irp, (IrInstSrcMemberName *)instruction);
2848 break;
2849 case IrInstSrcIdBreakpoint:2753 case IrInstSrcIdBreakpoint:
2850 ir_print_breakpoint(irp, (IrInstSrcBreakpoint *)instruction);2754 ir_print_breakpoint(irp, (IrInstSrcBreakpoint *)instruction);
2851 break;2755 break;
...@@ -2945,9 +2849,6 @@ static void ir_print_inst_src(IrPrintSrc *irp, IrInstSrc *instruction, bool trai...@@ -2945,9 +2849,6 @@ static void ir_print_inst_src(IrPrintSrc *irp, IrInstSrc *instruction, bool trai
2945 case IrInstSrcIdHasField:2849 case IrInstSrcIdHasField:
2946 ir_print_has_field(irp, (IrInstSrcHasField *)instruction);2850 ir_print_has_field(irp, (IrInstSrcHasField *)instruction);
2947 break;2851 break;
2948 case IrInstSrcIdTypeId:
2949 ir_print_type_id(irp, (IrInstSrcTypeId *)instruction);
2950 break;
2951 case IrInstSrcIdSetEvalBranchQuota:2852 case IrInstSrcIdSetEvalBranchQuota:
2952 ir_print_set_eval_branch_quota(irp, (IrInstSrcSetEvalBranchQuota *)instruction);2853 ir_print_set_eval_branch_quota(irp, (IrInstSrcSetEvalBranchQuota *)instruction);
2953 break;2854 break;
...@@ -3278,9 +3179,6 @@ static void ir_print_inst_gen(IrPrintGen *irp, IrInstGen *instruction, bool trai...@@ -3278,9 +3179,6 @@ static void ir_print_inst_gen(IrPrintGen *irp, IrInstGen *instruction, bool trai
3278 case IrInstGenIdAssertNonNull:3179 case IrInstGenIdAssertNonNull:
3279 ir_print_assert_non_null(irp, (IrInstGenAssertNonNull *)instruction);3180 ir_print_assert_non_null(irp, (IrInstGenAssertNonNull *)instruction);
3280 break;3181 break;
3281 case IrInstGenIdResizeSlice:
3282 ir_print_resize_slice(irp, (IrInstGenResizeSlice *)instruction);
3283 break;
3284 case IrInstGenIdAlloca:3182 case IrInstGenIdAlloca:
3285 ir_print_alloca_gen(irp, (IrInstGenAlloca *)instruction);3183 ir_print_alloca_gen(irp, (IrInstGenAlloca *)instruction);
3286 break;3184 break;
src/libc_installation.cpp deleted-498
...@@ -1,498 +0,0 @@
1/*
2 * Copyright (c) 2019 Andrew Kelley
3 *
4 * This file is part of zig, which is MIT licensed.
5 * See http://opensource.org/licenses/MIT
6 */
7
8#include "libc_installation.hpp"
9#include "os.hpp"
10#include "windows_sdk.h"
11#include "target.hpp"
12
13static const char *zig_libc_keys[] = {
14 "include_dir",
15 "sys_include_dir",
16 "crt_dir",
17 "static_crt_dir",
18 "msvc_lib_dir",
19 "kernel32_lib_dir",
20};
21
22static const size_t zig_libc_keys_len = array_length(zig_libc_keys);
23
24static bool zig_libc_match_key(Slice<uint8_t> name, Slice<uint8_t> value, bool *found_keys,
25 size_t index, Buf *field_ptr)
26{
27 if (!memEql(name, str(zig_libc_keys[index]))) return false;
28 buf_init_from_mem(field_ptr, (const char*)value.ptr, value.len);
29 found_keys[index] = true;
30 return true;
31}
32
33static void zig_libc_init_empty(ZigLibCInstallation *libc) {
34 *libc = {};
35 buf_init_from_str(&libc->include_dir, "");
36 buf_init_from_str(&libc->sys_include_dir, "");
37 buf_init_from_str(&libc->crt_dir, "");
38 buf_init_from_str(&libc->static_crt_dir, "");
39 buf_init_from_str(&libc->msvc_lib_dir, "");
40 buf_init_from_str(&libc->kernel32_lib_dir, "");
41}
42
43Error zig_libc_parse(ZigLibCInstallation *libc, Buf *libc_file, const ZigTarget *target, bool verbose) {
44 Error err;
45 zig_libc_init_empty(libc);
46
47 bool found_keys[array_length(zig_libc_keys)] = {};
48
49 Buf *contents = buf_alloc();
50 if ((err = os_fetch_file_path(libc_file, contents))) {
51 if (err != ErrorFileNotFound && verbose) {
52 fprintf(stderr, "Unable to read '%s': %s\n", buf_ptr(libc_file), err_str(err));
53 }
54 return err;
55 }
56
57 SplitIterator it = memSplit(buf_to_slice(contents), str("\n"));
58 for (;;) {
59 Optional<Slice<uint8_t>> opt_line = SplitIterator_next(&it);
60 if (!opt_line.is_some)
61 break;
62
63 if (opt_line.value.len == 0 || opt_line.value.ptr[0] == '#')
64 continue;
65
66 SplitIterator line_it = memSplit(opt_line.value, str("="));
67 Slice<uint8_t> name;
68 if (!SplitIterator_next(&line_it).unwrap(&name)) {
69 if (verbose) {
70 fprintf(stderr, "missing equal sign after field name\n");
71 }
72 return ErrorSemanticAnalyzeFail;
73 }
74 Slice<uint8_t> value = SplitIterator_rest(&line_it);
75 bool match = false;
76 match = match || zig_libc_match_key(name, value, found_keys, 0, &libc->include_dir);
77 match = match || zig_libc_match_key(name, value, found_keys, 1, &libc->sys_include_dir);
78 match = match || zig_libc_match_key(name, value, found_keys, 2, &libc->crt_dir);
79 match = match || zig_libc_match_key(name, value, found_keys, 3, &libc->static_crt_dir);
80 match = match || zig_libc_match_key(name, value, found_keys, 4, &libc->msvc_lib_dir);
81 match = match || zig_libc_match_key(name, value, found_keys, 5, &libc->kernel32_lib_dir);
82 }
83
84 for (size_t i = 0; i < zig_libc_keys_len; i += 1) {
85 if (!found_keys[i]) {
86 if (verbose) {
87 fprintf(stderr, "missing field: %s\n", zig_libc_keys[i]);
88 }
89 return ErrorSemanticAnalyzeFail;
90 }
91 }
92
93 if (buf_len(&libc->include_dir) == 0) {
94 if (verbose) {
95 fprintf(stderr, "include_dir may not be empty\n");
96 }
97 return ErrorSemanticAnalyzeFail;
98 }
99
100 if (buf_len(&libc->sys_include_dir) == 0) {
101 if (verbose) {
102 fprintf(stderr, "sys_include_dir may not be empty\n");
103 }
104 return ErrorSemanticAnalyzeFail;
105 }
106
107 if (buf_len(&libc->crt_dir) == 0) {
108 if (!target_os_is_darwin(target->os)) {
109 if (verbose) {
110 fprintf(stderr, "crt_dir may not be empty for %s\n", target_os_name(target->os));
111 }
112 return ErrorSemanticAnalyzeFail;
113 }
114 }
115
116 if (buf_len(&libc->static_crt_dir) == 0) {
117 if (target->os == OsWindows && target_abi_is_gnu(target->abi)) {
118 if (verbose) {
119 fprintf(stderr, "static_crt_dir may not be empty for %s\n", target_os_name(target->os));
120 }
121 return ErrorSemanticAnalyzeFail;
122 }
123 }
124
125 if (buf_len(&libc->msvc_lib_dir) == 0) {
126 if (target->os == OsWindows && !target_abi_is_gnu(target->abi)) {
127 if (verbose) {
128 fprintf(stderr, "msvc_lib_dir may not be empty for %s\n", target_os_name(target->os));
129 }
130 return ErrorSemanticAnalyzeFail;
131 }
132 }
133
134 if (buf_len(&libc->kernel32_lib_dir) == 0) {
135 if (target->os == OsWindows && !target_abi_is_gnu(target->abi)) {
136 if (verbose) {
137 fprintf(stderr, "kernel32_lib_dir may not be empty for %s\n", target_os_name(target->os));
138 }
139 return ErrorSemanticAnalyzeFail;
140 }
141 }
142
143 return ErrorNone;
144}
145
146#if defined(ZIG_OS_WINDOWS)
147#define CC_EXE "cc.exe"
148#else
149#define CC_EXE "cc"
150#endif
151
152static Error zig_libc_find_native_include_dir_posix(ZigLibCInstallation *self, bool verbose) {
153 const char *cc_exe = getenv("CC");
154 cc_exe = (cc_exe == nullptr) ? CC_EXE : cc_exe;
155 ZigList<const char *> args = {};
156 args.append(cc_exe);
157 args.append("-E");
158 args.append("-Wp,-v");
159 args.append("-xc");
160 #if defined(ZIG_OS_WINDOWS)
161 args.append("nul");
162 #else
163 args.append("/dev/null");
164 #endif
165
166 Termination term;
167 Buf *out_stderr = buf_alloc();
168 Buf *out_stdout = buf_alloc();
169 Error err;
170 if ((err = os_exec_process(args, &term, out_stderr, out_stdout))) {
171 if (verbose) {
172 fprintf(stderr, "unable to determine libc include path: executing '%s': %s\n", cc_exe, err_str(err));
173 }
174 return err;
175 }
176 if (term.how != TerminationIdClean || term.code != 0) {
177 if (verbose) {
178 fprintf(stderr, "unable to determine libc include path: executing '%s' failed\n", cc_exe);
179 }
180 return ErrorCCompileErrors;
181 }
182 char *prev_newline = buf_ptr(out_stderr);
183 ZigList<const char *> search_paths = {};
184 for (;;) {
185 char *newline = strchr(prev_newline, '\n');
186 if (newline == nullptr) {
187 break;
188 }
189
190 #if defined(ZIG_OS_WINDOWS)
191 *(newline - 1) = 0;
192 #endif
193 *newline = 0;
194
195 if (prev_newline[0] == ' ') {
196 search_paths.append(prev_newline);
197 }
198 prev_newline = newline + 1;
199 }
200 if (search_paths.length == 0) {
201 if (verbose) {
202 fprintf(stderr, "unable to determine libc include path: '%s' cannot find libc headers\n", cc_exe);
203 }
204 return ErrorCCompileErrors;
205 }
206 for (size_t i = 0; i < search_paths.length; i += 1) {
207 // search in reverse order
208 const char *search_path = search_paths.items[search_paths.length - i - 1];
209 // cut off spaces
210 while (*search_path == ' ') {
211 search_path += 1;
212 }
213
214 #if defined(ZIG_OS_WINDOWS)
215 if (buf_len(&self->include_dir) == 0) {
216 Buf *stdlib_path = buf_sprintf("%s\\stdlib.h", search_path);
217 bool exists;
218 if ((err = os_file_exists(stdlib_path, &exists))) {
219 exists = false;
220 }
221 if (exists) {
222 buf_init_from_str(&self->include_dir, search_path);
223 }
224 }
225 if (buf_len(&self->sys_include_dir) == 0) {
226 Buf *stdlib_path = buf_sprintf("%s\\sys\\types.h", search_path);
227 bool exists;
228 if ((err = os_file_exists(stdlib_path, &exists))) {
229 exists = false;
230 }
231 if (exists) {
232 buf_init_from_str(&self->sys_include_dir, search_path);
233 }
234 }
235 #else
236 if (buf_len(&self->include_dir) == 0) {
237 Buf *stdlib_path = buf_sprintf("%s/stdlib.h", search_path);
238 bool exists;
239 if ((err = os_file_exists(stdlib_path, &exists))) {
240 exists = false;
241 }
242 if (exists) {
243 buf_init_from_str(&self->include_dir, search_path);
244 }
245 }
246 if (buf_len(&self->sys_include_dir) == 0) {
247 Buf *stdlib_path = buf_sprintf("%s/sys/errno.h", search_path);
248 bool exists;
249 if ((err = os_file_exists(stdlib_path, &exists))) {
250 exists = false;
251 }
252 if (exists) {
253 buf_init_from_str(&self->sys_include_dir, search_path);
254 }
255 }
256 #endif
257
258 if (buf_len(&self->include_dir) != 0 && buf_len(&self->sys_include_dir) != 0) {
259 return ErrorNone;
260 }
261 }
262 if (verbose) {
263 if (buf_len(&self->include_dir) == 0) {
264 fprintf(stderr, "unable to determine libc include path: stdlib.h not found in '%s' search paths\n", cc_exe);
265 }
266 if (buf_len(&self->sys_include_dir) == 0) {
267 #if defined(ZIG_OS_WINDOWS)
268 fprintf(stderr, "unable to determine libc include path: sys/types.h not found in '%s' search paths\n", cc_exe);
269 #else
270 fprintf(stderr, "unable to determine libc include path: sys/errno.h not found in '%s' search paths\n", cc_exe);
271 #endif
272 }
273 }
274 return ErrorFileNotFound;
275}
276
277Error zig_libc_cc_print_file_name(const char *o_file, Buf *out, bool want_dirname, bool verbose) {
278 const char *cc_exe = getenv("CC");
279 cc_exe = (cc_exe == nullptr) ? CC_EXE : cc_exe;
280 ZigList<const char *> args = {};
281 args.append(cc_exe);
282 args.append(buf_ptr(buf_sprintf("-print-file-name=%s", o_file)));
283 Termination term;
284 Buf *out_stderr = buf_alloc();
285 Buf *out_stdout = buf_alloc();
286 Error err;
287 if ((err = os_exec_process(args, &term, out_stderr, out_stdout))) {
288 if (err == ErrorFileNotFound)
289 return ErrorNoCCompilerInstalled;
290 if (verbose) {
291 fprintf(stderr, "unable to determine libc library path: executing '%s': %s\n", cc_exe, err_str(err));
292 }
293 return err;
294 }
295 if (term.how != TerminationIdClean || term.code != 0) {
296 if (verbose) {
297 fprintf(stderr, "unable to determine libc library path: executing '%s' failed\n", cc_exe);
298 }
299 return ErrorCCompileErrors;
300 }
301 #if defined(ZIG_OS_WINDOWS)
302 if (buf_ends_with_str(out_stdout, "\r\n")) {
303 buf_resize(out_stdout, buf_len(out_stdout) - 2);
304 }
305 #else
306 if (buf_ends_with_str(out_stdout, "\n")) {
307 buf_resize(out_stdout, buf_len(out_stdout) - 1);
308 }
309 #endif
310 if (buf_len(out_stdout) == 0 || buf_eql_str(out_stdout, o_file)) {
311 return ErrorCCompilerCannotFindFile;
312 }
313 if (want_dirname) {
314 os_path_dirname(out_stdout, out);
315 } else {
316 buf_init_from_buf(out, out_stdout);
317 }
318 return ErrorNone;
319}
320
321#undef CC_EXE
322
323#if defined(ZIG_OS_WINDOWS) || defined(ZIG_OS_LINUX) || defined(ZIG_OS_DRAGONFLY)
324static Error zig_libc_find_native_crt_dir_posix(ZigLibCInstallation *self, bool verbose) {
325 return zig_libc_cc_print_file_name("crt1.o", &self->crt_dir, true, verbose);
326}
327#endif
328
329#if defined(ZIG_OS_WINDOWS)
330static Error zig_libc_find_native_static_crt_dir_posix(ZigLibCInstallation *self, bool verbose) {
331 return zig_libc_cc_print_file_name("crtbegin.o", &self->static_crt_dir, true, verbose);
332}
333
334static Error zig_libc_find_native_include_dir_windows(ZigLibCInstallation *self, ZigWindowsSDK *sdk, bool verbose) {
335 Error err;
336 if ((err = os_get_win32_ucrt_include_path(sdk, &self->include_dir))) {
337 if (verbose) {
338 fprintf(stderr, "Unable to determine libc include path: %s\n", err_str(err));
339 }
340 return err;
341 }
342 return ErrorNone;
343}
344
345static Error zig_libc_find_native_crt_dir_windows(ZigLibCInstallation *self, ZigWindowsSDK *sdk, ZigTarget *target,
346 bool verbose)
347{
348 Error err;
349 if ((err = os_get_win32_ucrt_lib_path(sdk, &self->crt_dir, target->arch))) {
350 if (verbose) {
351 fprintf(stderr, "Unable to determine ucrt path: %s\n", err_str(err));
352 }
353 return err;
354 }
355 return ErrorNone;
356}
357
358static Error zig_libc_find_kernel32_lib_dir(ZigLibCInstallation *self, ZigWindowsSDK *sdk, ZigTarget *target,
359 bool verbose)
360{
361 Error err;
362 if ((err = os_get_win32_kern32_path(sdk, &self->kernel32_lib_dir, target->arch))) {
363 if (verbose) {
364 fprintf(stderr, "Unable to determine kernel32 path: %s\n", err_str(err));
365 }
366 return err;
367 }
368 return ErrorNone;
369}
370
371static Error zig_libc_find_native_msvc_lib_dir(ZigLibCInstallation *self, ZigWindowsSDK *sdk, bool verbose) {
372 if (sdk->msvc_lib_dir_ptr == nullptr) {
373 if (verbose) {
374 fprintf(stderr, "Unable to determine vcruntime.lib path\n");
375 }
376 return ErrorFileNotFound;
377 }
378 buf_init_from_mem(&self->msvc_lib_dir, sdk->msvc_lib_dir_ptr, sdk->msvc_lib_dir_len);
379 return ErrorNone;
380}
381
382static Error zig_libc_find_native_msvc_include_dir(ZigLibCInstallation *self, ZigWindowsSDK *sdk, bool verbose) {
383 Error err;
384 if (sdk->msvc_lib_dir_ptr == nullptr) {
385 if (verbose) {
386 fprintf(stderr, "Unable to determine vcruntime.h path\n");
387 }
388 return ErrorFileNotFound;
389 }
390 Buf search_path = BUF_INIT;
391 buf_init_from_mem(&search_path, sdk->msvc_lib_dir_ptr, sdk->msvc_lib_dir_len);
392 buf_append_str(&search_path, "..\\..\\include");
393
394 Buf *vcruntime_path = buf_sprintf("%s\\vcruntime.h", buf_ptr(&search_path));
395 bool exists;
396 if ((err = os_file_exists(vcruntime_path, &exists))) {
397 exists = false;
398 }
399 if (exists) {
400 self->sys_include_dir = search_path;
401 return ErrorNone;
402 }
403
404 if (verbose) {
405 fprintf(stderr, "Unable to determine vcruntime.h path\n");
406 }
407 return ErrorFileNotFound;
408}
409#endif
410
411void zig_libc_render(ZigLibCInstallation *self, FILE *file) {
412 fprintf(file,
413 "# The directory that contains `stdlib.h`.\n"
414 "# On POSIX-like systems, include directories be found with: `cc -E -Wp,-v -xc /dev/null`\n"
415 "include_dir=%s\n"
416 "\n"
417 "# The system-specific include directory. May be the same as `include_dir`.\n"
418 "# On Windows it's the directory that includes `vcruntime.h`.\n"
419 "# On POSIX it's the directory that includes `sys/errno.h`.\n"
420 "sys_include_dir=%s\n"
421 "\n"
422 "# The directory that contains `crt1.o` or `crt2.o`.\n"
423 "# On POSIX, can be found with `cc -print-file-name=crt1.o`.\n"
424 "# Not needed when targeting MacOS.\n"
425 "crt_dir=%s\n"
426 "\n"
427 "# The directory that contains `crtbegin.o`.\n"
428 "# On POSIX, can be found with `cc -print-file-name=crtbegin.o`.\n"
429 "# Not needed when targeting MacOS.\n"
430 "static_crt_dir=%s\n"
431 "\n"
432 "# The directory that contains `vcruntime.lib`.\n"
433 "# Only needed when targeting MSVC on Windows.\n"
434 "msvc_lib_dir=%s\n"
435 "\n"
436 "# The directory that contains `kernel32.lib`.\n"
437 "# Only needed when targeting MSVC on Windows.\n"
438 "kernel32_lib_dir=%s\n"
439 "\n",
440 buf_ptr(&self->include_dir),
441 buf_ptr(&self->sys_include_dir),
442 buf_ptr(&self->crt_dir),
443 buf_ptr(&self->static_crt_dir),
444 buf_ptr(&self->msvc_lib_dir),
445 buf_ptr(&self->kernel32_lib_dir)
446 );
447}
448
449Error zig_libc_find_native(ZigLibCInstallation *self, bool verbose) {
450 Error err;
451 zig_libc_init_empty(self);
452#if defined(ZIG_OS_WINDOWS)
453 ZigTarget native_target;
454 get_native_target(&native_target);
455 if (target_abi_is_gnu(native_target.abi)) {
456 if ((err = zig_libc_find_native_include_dir_posix(self, verbose)))
457 return err;
458 if ((err = zig_libc_find_native_crt_dir_posix(self, verbose)))
459 return err;
460 if ((err = zig_libc_find_native_static_crt_dir_posix(self, verbose)))
461 return err;
462 return ErrorNone;
463 } else {
464 ZigWindowsSDK *sdk;
465 switch (zig_find_windows_sdk(&sdk)) {
466 case ZigFindWindowsSdkErrorNone:
467 if ((err = zig_libc_find_native_msvc_include_dir(self, sdk, verbose)))
468 return err;
469 if ((err = zig_libc_find_native_msvc_lib_dir(self, sdk, verbose)))
470 return err;
471 if ((err = zig_libc_find_kernel32_lib_dir(self, sdk, &native_target, verbose)))
472 return err;
473 if ((err = zig_libc_find_native_include_dir_windows(self, sdk, verbose)))
474 return err;
475 if ((err = zig_libc_find_native_crt_dir_windows(self, sdk, &native_target, verbose)))
476 return err;
477 return ErrorNone;
478 case ZigFindWindowsSdkErrorOutOfMemory:
479 return ErrorNoMem;
480 case ZigFindWindowsSdkErrorNotFound:
481 return ErrorFileNotFound;
482 case ZigFindWindowsSdkErrorPathTooLong:
483 return ErrorPathTooLong;
484 }
485 }
486 zig_unreachable();
487#else
488 if ((err = zig_libc_find_native_include_dir_posix(self, verbose)))
489 return err;
490#if defined(ZIG_OS_FREEBSD) || defined(ZIG_OS_NETBSD)
491 buf_init_from_str(&self->crt_dir, "/usr/lib");
492#elif defined(ZIG_OS_LINUX) || defined(ZIG_OS_DRAGONFLY)
493 if ((err = zig_libc_find_native_crt_dir_posix(self, verbose)))
494 return err;
495#endif
496 return ErrorNone;
497#endif
498}
src/libc_installation.hpp deleted-35
...@@ -1,35 +0,0 @@
1/*
2 * Copyright (c) 2019 Andrew Kelley
3 *
4 * This file is part of zig, which is MIT licensed.
5 * See http://opensource.org/licenses/MIT
6 */
7
8#ifndef ZIG_LIBC_INSTALLATION_HPP
9#define ZIG_LIBC_INSTALLATION_HPP
10
11#include <stdio.h>
12
13#include "buffer.hpp"
14#include "error.hpp"
15#include "target.hpp"
16
17// Must be synchronized with zig_libc_keys
18struct ZigLibCInstallation {
19 Buf include_dir;
20 Buf sys_include_dir;
21 Buf crt_dir;
22 Buf static_crt_dir;
23 Buf msvc_lib_dir;
24 Buf kernel32_lib_dir;
25};
26
27Error ATTRIBUTE_MUST_USE zig_libc_parse(ZigLibCInstallation *libc, Buf *libc_file,
28 const ZigTarget *target, bool verbose);
29void zig_libc_render(ZigLibCInstallation *self, FILE *file);
30
31Error ATTRIBUTE_MUST_USE zig_libc_find_native(ZigLibCInstallation *self, bool verbose);
32
33Error zig_libc_cc_print_file_name(const char *o_file, Buf *out, bool want_dirname, bool verbose);
34
35#endif
src/link.cpp+26-26
...@@ -605,7 +605,7 @@ static const char *build_libc_object(CodeGen *parent_gen, const char *name, CFil...@@ -605,7 +605,7 @@ static const char *build_libc_object(CodeGen *parent_gen, const char *name, CFil
605 c_source_files.append(c_file);605 c_source_files.append(c_file);
606 child_gen->c_source_files = c_source_files;606 child_gen->c_source_files = c_source_files;
607 codegen_build_and_link(child_gen);607 codegen_build_and_link(child_gen);
608 return buf_ptr(&child_gen->output_file_path);608 return buf_ptr(&child_gen->bin_file_output_path);
609}609}
610610
611static const char *path_from_zig_lib(CodeGen *g, const char *dir, const char *subpath) {611static const char *path_from_zig_lib(CodeGen *g, const char *dir, const char *subpath) {
...@@ -682,7 +682,7 @@ static const char *build_libunwind(CodeGen *parent, Stage2ProgressNode *progress...@@ -682,7 +682,7 @@ static const char *build_libunwind(CodeGen *parent, Stage2ProgressNode *progress
682 }682 }
683 child_gen->c_source_files = c_source_files;683 child_gen->c_source_files = c_source_files;
684 codegen_build_and_link(child_gen);684 codegen_build_and_link(child_gen);
685 return buf_ptr(&child_gen->output_file_path);685 return buf_ptr(&child_gen->bin_file_output_path);
686}686}
687687
688static void mingw_add_cc_args(CodeGen *parent, CFile *c_file) {688static void mingw_add_cc_args(CodeGen *parent, CFile *c_file) {
...@@ -1123,7 +1123,7 @@ static const char *build_musl(CodeGen *parent, Stage2ProgressNode *progress_node...@@ -1123,7 +1123,7 @@ static const char *build_musl(CodeGen *parent, Stage2ProgressNode *progress_node
11231123
1124 child_gen->c_source_files = c_source_files;1124 child_gen->c_source_files = c_source_files;
1125 codegen_build_and_link(child_gen);1125 codegen_build_and_link(child_gen);
1126 return buf_ptr(&child_gen->output_file_path);1126 return buf_ptr(&child_gen->bin_file_output_path);
1127}1127}
11281128
1129static void add_msvcrt_os_dep(CodeGen *parent, CodeGen *child_gen, const char *src_path) {1129static void add_msvcrt_os_dep(CodeGen *parent, CodeGen *child_gen, const char *src_path) {
...@@ -1253,7 +1253,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr...@@ -1253,7 +1253,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
1253 child_gen->c_source_files.append(c_file);1253 child_gen->c_source_files.append(c_file);
1254 }1254 }
1255 codegen_build_and_link(child_gen);1255 codegen_build_and_link(child_gen);
1256 return buf_ptr(&child_gen->output_file_path);1256 return buf_ptr(&child_gen->bin_file_output_path);
1257 } else if (strcmp(file, "msvcrt-os.lib") == 0) {1257 } else if (strcmp(file, "msvcrt-os.lib") == 0) {
1258 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "msvcrt-os", progress_node);1258 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "msvcrt-os", progress_node);
12591259
...@@ -1270,7 +1270,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr...@@ -1270,7 +1270,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
1270 }1270 }
1271 }1271 }
1272 codegen_build_and_link(child_gen);1272 codegen_build_and_link(child_gen);
1273 return buf_ptr(&child_gen->output_file_path);1273 return buf_ptr(&child_gen->bin_file_output_path);
1274 } else if (strcmp(file, "mingwex.lib") == 0) {1274 } else if (strcmp(file, "mingwex.lib") == 0) {
1275 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "mingwex", progress_node);1275 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "mingwex", progress_node);
12761276
...@@ -1295,7 +1295,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr...@@ -1295,7 +1295,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
1295 zig_unreachable();1295 zig_unreachable();
1296 }1296 }
1297 codegen_build_and_link(child_gen);1297 codegen_build_and_link(child_gen);
1298 return buf_ptr(&child_gen->output_file_path);1298 return buf_ptr(&child_gen->bin_file_output_path);
1299 } else {1299 } else {
1300 zig_unreachable();1300 zig_unreachable();
1301 }1301 }
...@@ -1365,7 +1365,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr...@@ -1365,7 +1365,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
1365 codegen_add_object(child_gen, buf_create_from_str(start_os));1365 codegen_add_object(child_gen, buf_create_from_str(start_os));
1366 codegen_add_object(child_gen, buf_create_from_str(abi_note_o));1366 codegen_add_object(child_gen, buf_create_from_str(abi_note_o));
1367 codegen_build_and_link(child_gen);1367 codegen_build_and_link(child_gen);
1368 return buf_ptr(&child_gen->output_file_path);1368 return buf_ptr(&child_gen->bin_file_output_path);
1369 } else if (strcmp(file, "libc_nonshared.a") == 0) {1369 } else if (strcmp(file, "libc_nonshared.a") == 0) {
1370 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "c_nonshared", progress_node);1370 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "c_nonshared", progress_node);
1371 {1371 {
...@@ -1445,7 +1445,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr...@@ -1445,7 +1445,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
1445 build_libc_object(parent, deps[i].name, c_file, progress_node)));1445 build_libc_object(parent, deps[i].name, c_file, progress_node)));
1446 }1446 }
1447 codegen_build_and_link(child_gen);1447 codegen_build_and_link(child_gen);
1448 return buf_ptr(&child_gen->output_file_path);1448 return buf_ptr(&child_gen->bin_file_output_path);
1449 } else {1449 } else {
1450 zig_unreachable();1450 zig_unreachable();
1451 }1451 }
...@@ -1483,7 +1483,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr...@@ -1483,7 +1483,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
1483 } else {1483 } else {
1484 assert(parent->libc != nullptr);1484 assert(parent->libc != nullptr);
1485 Buf *out_buf = buf_alloc();1485 Buf *out_buf = buf_alloc();
1486 os_path_join(&parent->libc->crt_dir, buf_create_from_str(file), out_buf);1486 os_path_join(buf_create_from_str(parent->libc->crt_dir), buf_create_from_str(file), out_buf);
1487 return buf_ptr(out_buf);1487 return buf_ptr(out_buf);
1488 }1488 }
1489}1489}
...@@ -1519,7 +1519,7 @@ static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path,...@@ -1519,7 +1519,7 @@ static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path,
1519 child_gen->want_stack_check = WantStackCheckDisabled;1519 child_gen->want_stack_check = WantStackCheckDisabled;
15201520
1521 codegen_build_and_link(child_gen);1521 codegen_build_and_link(child_gen);
1522 return &child_gen->output_file_path;1522 return &child_gen->bin_file_output_path;
1523}1523}
15241524
1525static Buf *build_compiler_rt(CodeGen *parent_gen, OutType child_out_type, Stage2ProgressNode *progress_node) {1525static Buf *build_compiler_rt(CodeGen *parent_gen, OutType child_out_type, Stage2ProgressNode *progress_node) {
...@@ -1681,7 +1681,7 @@ static void construct_linker_job_elf(LinkJob *lj) {...@@ -1681,7 +1681,7 @@ static void construct_linker_job_elf(LinkJob *lj) {
1681 } else if (is_dyn_lib) {1681 } else if (is_dyn_lib) {
1682 lj->args.append("-shared");1682 lj->args.append("-shared");
16831683
1684 assert(buf_len(&g->output_file_path) != 0);1684 assert(buf_len(&g->bin_file_output_path) != 0);
1685 soname = buf_sprintf("lib%s.so.%" ZIG_PRI_usize, buf_ptr(g->root_out_name), g->version_major);1685 soname = buf_sprintf("lib%s.so.%" ZIG_PRI_usize, buf_ptr(g->root_out_name), g->version_major);
1686 }1686 }
16871687
...@@ -1690,7 +1690,7 @@ static void construct_linker_job_elf(LinkJob *lj) {...@@ -1690,7 +1690,7 @@ static void construct_linker_job_elf(LinkJob *lj) {
1690 }1690 }
16911691
1692 lj->args.append("-o");1692 lj->args.append("-o");
1693 lj->args.append(buf_ptr(&g->output_file_path));1693 lj->args.append(buf_ptr(&g->bin_file_output_path));
16941694
1695 if (lj->link_in_crt) {1695 if (lj->link_in_crt) {
1696 const char *crt1o;1696 const char *crt1o;
...@@ -1747,7 +1747,7 @@ static void construct_linker_job_elf(LinkJob *lj) {...@@ -1747,7 +1747,7 @@ static void construct_linker_job_elf(LinkJob *lj) {
1747 if (g->libc_link_lib != nullptr) {1747 if (g->libc_link_lib != nullptr) {
1748 if (g->libc != nullptr) {1748 if (g->libc != nullptr) {
1749 lj->args.append("-L");1749 lj->args.append("-L");
1750 lj->args.append(buf_ptr(&g->libc->crt_dir));1750 lj->args.append(g->libc->crt_dir);
1751 }1751 }
17521752
1753 if (g->have_dynamic_link && (is_dyn_lib || g->out_type == OutTypeExe)) {1753 if (g->have_dynamic_link && (is_dyn_lib || g->out_type == OutTypeExe)) {
...@@ -1872,7 +1872,7 @@ static void construct_linker_job_wasm(LinkJob *lj) {...@@ -1872,7 +1872,7 @@ static void construct_linker_job_wasm(LinkJob *lj) {
1872 }1872 }
1873 lj->args.append("--allow-undefined");1873 lj->args.append("--allow-undefined");
1874 lj->args.append("-o");1874 lj->args.append("-o");
1875 lj->args.append(buf_ptr(&g->output_file_path));1875 lj->args.append(buf_ptr(&g->bin_file_output_path));
18761876
1877 // .o files1877 // .o files
1878 for (size_t i = 0; i < g->link_objects.length; i += 1) {1878 for (size_t i = 0; i < g->link_objects.length; i += 1) {
...@@ -2253,17 +2253,17 @@ static void construct_linker_job_coff(LinkJob *lj) {...@@ -2253,17 +2253,17 @@ static void construct_linker_job_coff(LinkJob *lj) {
2253 lj->args.append("-DLL");2253 lj->args.append("-DLL");
2254 }2254 }
22552255
2256 lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->output_file_path))));2256 lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->bin_file_output_path))));
22572257
2258 if (g->libc_link_lib != nullptr && g->libc != nullptr) {2258 if (g->libc_link_lib != nullptr && g->libc != nullptr) {
2259 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->crt_dir))));2259 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->crt_dir)));
22602260
2261 if (target_abi_is_gnu(g->zig_target->abi)) {2261 if (target_abi_is_gnu(g->zig_target->abi)) {
2262 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->sys_include_dir))));2262 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->sys_include_dir)));
2263 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->include_dir))));2263 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->include_dir)));
2264 } else {2264 } else {
2265 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->msvc_lib_dir))));2265 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->msvc_lib_dir)));
2266 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", buf_ptr(&g->libc->kernel32_lib_dir))));2266 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->kernel32_lib_dir)));
2267 }2267 }
2268 }2268 }
22692269
...@@ -2506,7 +2506,7 @@ static void construct_linker_job_macho(LinkJob *lj) {...@@ -2506,7 +2506,7 @@ static void construct_linker_job_macho(LinkJob *lj) {
2506 //lj->args.append("-install_name");2506 //lj->args.append("-install_name");
2507 //lj->args.append(buf_ptr(dylib_install_name));2507 //lj->args.append(buf_ptr(dylib_install_name));
25082508
2509 assert(buf_len(&g->output_file_path) != 0);2509 assert(buf_len(&g->bin_file_output_path) != 0);
2510 }2510 }
25112511
2512 lj->args.append("-arch");2512 lj->args.append("-arch");
...@@ -2537,14 +2537,14 @@ static void construct_linker_job_macho(LinkJob *lj) {...@@ -2537,14 +2537,14 @@ static void construct_linker_job_macho(LinkJob *lj) {
2537 }2537 }
25382538
2539 lj->args.append("-o");2539 lj->args.append("-o");
2540 lj->args.append(buf_ptr(&g->output_file_path));2540 lj->args.append(buf_ptr(&g->bin_file_output_path));
25412541
2542 for (size_t i = 0; i < g->rpath_list.length; i += 1) {2542 for (size_t i = 0; i < g->rpath_list.length; i += 1) {
2543 Buf *rpath = g->rpath_list.at(i);2543 Buf *rpath = g->rpath_list.at(i);
2544 add_rpath(lj, rpath);2544 add_rpath(lj, rpath);
2545 }2545 }
2546 if (is_dyn_lib) {2546 if (is_dyn_lib) {
2547 add_rpath(lj, &g->output_file_path);2547 add_rpath(lj, &g->bin_file_output_path);
2548 }2548 }
25492549
2550 if (is_dyn_lib) {2550 if (is_dyn_lib) {
...@@ -2664,14 +2664,14 @@ void codegen_link(CodeGen *g) {...@@ -2664,14 +2664,14 @@ void codegen_link(CodeGen *g) {
2664 progress_name, strlen(progress_name), 0));2664 progress_name, strlen(progress_name), 0));
2665 }2665 }
2666 if (g->verbose_link) {2666 if (g->verbose_link) {
2667 fprintf(stderr, "ar rcs %s", buf_ptr(&g->output_file_path));2667 fprintf(stderr, "ar rcs %s", buf_ptr(&g->bin_file_output_path));
2668 for (size_t i = 0; i < file_names.length; i += 1) {2668 for (size_t i = 0; i < file_names.length; i += 1) {
2669 fprintf(stderr, " %s", file_names.at(i));2669 fprintf(stderr, " %s", file_names.at(i));
2670 }2670 }
2671 fprintf(stderr, "\n");2671 fprintf(stderr, "\n");
2672 }2672 }
2673 if (ZigLLVMWriteArchive(buf_ptr(&g->output_file_path), file_names.items, file_names.length, os_type)) {2673 if (ZigLLVMWriteArchive(buf_ptr(&g->bin_file_output_path), file_names.items, file_names.length, os_type)) {
2674 fprintf(stderr, "Unable to write archive '%s'\n", buf_ptr(&g->output_file_path));2674 fprintf(stderr, "Unable to write archive '%s'\n", buf_ptr(&g->bin_file_output_path));
2675 exit(1);2675 exit(1);
2676 }2676 }
2677 return;2677 return;
src/main.cpp+151-88
...@@ -14,8 +14,7 @@...@@ -14,8 +14,7 @@
14#include "heap.hpp"14#include "heap.hpp"
15#include "os.hpp"15#include "os.hpp"
16#include "target.hpp"16#include "target.hpp"
17#include "libc_installation.hpp"17#include "stage2.h"
18#include "userland.h"
19#include "glibc.hpp"18#include "glibc.hpp"
20#include "dump_analysis.hpp"19#include "dump_analysis.hpp"
21#include "mem_profile.hpp"20#include "mem_profile.hpp"
...@@ -63,17 +62,21 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {...@@ -63,17 +62,21 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
63 " -fno-stack-check disable stack probing in safe builds\n"62 " -fno-stack-check disable stack probing in safe builds\n"
64 " -fsanitize-c enable C undefined behavior detection in unsafe builds\n"63 " -fsanitize-c enable C undefined behavior detection in unsafe builds\n"
65 " -fno-sanitize-c disable C undefined behavior detection in safe builds\n"64 " -fno-sanitize-c disable C undefined behavior detection in safe builds\n"
66 " --emit [asm|bin|llvm-ir] emit a specific file format as compilation output\n"65 " --emit [asm|bin|llvm-ir] (deprecated) emit a specific file format as compilation output\n"
67 " -fPIC enable Position Independent Code\n"66 " -fPIC enable Position Independent Code\n"
68 " -fno-PIC disable Position Independent Code\n"67 " -fno-PIC disable Position Independent Code\n"
69 " -ftime-report print timing diagnostics\n"68 " -ftime-report print timing diagnostics\n"
70 " -fstack-report print stack size diagnostics\n"69 " -fstack-report print stack size diagnostics\n"
71#ifdef ZIG_ENABLE_MEM_PROFILE
72 " -fmem-report print memory usage diagnostics\n"70 " -fmem-report print memory usage diagnostics\n"
73#endif
74 " -fdump-analysis write analysis.json file with type information\n"71 " -fdump-analysis write analysis.json file with type information\n"
75 " -femit-docs create a docs/ dir with html documentation\n"72 " -femit-docs create a docs/ dir with html documentation\n"
76 " -fno-emit-bin skip emitting machine code\n"73 " -fno-emit-docs do not produce docs/ dir with html documentation\n"
74 " -femit-bin (default) output machine code\n"
75 " -fno-emit-bin do not output machine code\n"
76 " -femit-asm output .s (assembly code)\n"
77 " -fno-emit-asm (default) do not output .s (assembly code)\n"
78 " -femit-llvm-ir produce a .ll file with LLVM IR\n"
79 " -fno-emit-llvm-ir (default) do not produce a .ll file with LLVM IR\n"
77 " --libc [file] Provide a file which specifies libc paths\n"80 " --libc [file] Provide a file which specifies libc paths\n"
78 " --name [name] override output name\n"81 " --name [name] override output name\n"
79 " --output-dir [dir] override output directory (defaults to cwd)\n"82 " --output-dir [dir] override output directory (defaults to cwd)\n"
...@@ -103,8 +106,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {...@@ -103,8 +106,7 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
103 " --override-lib-dir [arg] override path to Zig lib directory\n"106 " --override-lib-dir [arg] override path to Zig lib directory\n"
104 " -ffunction-sections places each function in a separate section\n"107 " -ffunction-sections places each function in a separate section\n"
105 " -D[macro]=[value] define C [macro] to [value] (1 if [value] omitted)\n"108 " -D[macro]=[value] define C [macro] to [value] (1 if [value] omitted)\n"
106 " -target-cpu [cpu] target one specific CPU by name\n"109 " -mcpu [cpu] specify target CPU and feature set\n"
107 " -target-feature [features] specify the set of CPU features to target\n"
108 " -code-model [default|tiny| set target code model\n"110 " -code-model [default|tiny| set target code model\n"
109 " small|kernel|\n"111 " small|kernel|\n"
110 " medium|large]\n"112 " medium|large]\n"
...@@ -235,6 +237,14 @@ static int zig_error_no_build_file(void) {...@@ -235,6 +237,14 @@ static int zig_error_no_build_file(void) {
235 return EXIT_FAILURE;237 return EXIT_FAILURE;
236}238}
237239
240static bool str_starts_with(const char *s1, const char *s2) {
241 size_t s2_len = strlen(s2);
242 if (strlen(s1) < s2_len) {
243 return false;
244 }
245 return memcmp(s1, s2, s2_len) == 0;
246}
247
238extern "C" int ZigClang_main(int argc, char **argv);248extern "C" int ZigClang_main(int argc, char **argv);
239249
240#ifdef ZIG_ENABLE_MEM_PROFILE250#ifdef ZIG_ENABLE_MEM_PROFILE
...@@ -378,7 +388,6 @@ static int main0(int argc, char **argv) {...@@ -378,7 +388,6 @@ static int main0(int argc, char **argv) {
378 }388 }
379389
380 Cmd cmd = CmdNone;390 Cmd cmd = CmdNone;
381 EmitFileType emit_file_type = EmitFileTypeBinary;
382 const char *in_file = nullptr;391 const char *in_file = nullptr;
383 Buf *output_dir = nullptr;392 Buf *output_dir = nullptr;
384 bool strip = false;393 bool strip = false;
...@@ -426,7 +435,9 @@ static int main0(int argc, char **argv) {...@@ -426,7 +435,9 @@ static int main0(int argc, char **argv) {
426 bool stack_report = false;435 bool stack_report = false;
427 bool enable_dump_analysis = false;436 bool enable_dump_analysis = false;
428 bool enable_doc_generation = false;437 bool enable_doc_generation = false;
429 bool disable_bin_generation = false;438 bool emit_bin = true;
439 bool emit_asm = false;
440 bool emit_llvm_ir = false;
430 const char *cache_dir = nullptr;441 const char *cache_dir = nullptr;
431 CliPkg *cur_pkg = heap::c_allocator.create<CliPkg>();442 CliPkg *cur_pkg = heap::c_allocator.create<CliPkg>();
432 BuildMode build_mode = BuildModeDebug;443 BuildMode build_mode = BuildModeDebug;
...@@ -444,8 +455,7 @@ static int main0(int argc, char **argv) {...@@ -444,8 +455,7 @@ static int main0(int argc, char **argv) {
444 WantStackCheck want_stack_check = WantStackCheckAuto;455 WantStackCheck want_stack_check = WantStackCheckAuto;
445 WantCSanitize want_sanitize_c = WantCSanitizeAuto;456 WantCSanitize want_sanitize_c = WantCSanitizeAuto;
446 bool function_sections = false;457 bool function_sections = false;
447 const char *cpu = nullptr;458 const char *mcpu = nullptr;
448 const char *features = nullptr;
449 CodeModel code_model = CodeModelDefault;459 CodeModel code_model = CodeModelDefault;
450460
451 ZigList<const char *> llvm_argv = {0};461 ZigList<const char *> llvm_argv = {0};
...@@ -554,7 +564,7 @@ static int main0(int argc, char **argv) {...@@ -554,7 +564,7 @@ static int main0(int argc, char **argv) {
554 }564 }
555565
556 Termination term;566 Termination term;
557 args.items[0] = buf_ptr(&g->output_file_path);567 args.items[0] = buf_ptr(&g->bin_file_output_path);
558 os_spawn_process(args, &term);568 os_spawn_process(args, &term);
559 if (term.how != TerminationIdClean || term.code != 0) {569 if (term.how != TerminationIdClean || term.code != 0) {
560 fprintf(stderr, "\nBuild failed. The following command failed:\n");570 fprintf(stderr, "\nBuild failed. The following command failed:\n");
...@@ -633,8 +643,6 @@ static int main0(int argc, char **argv) {...@@ -633,8 +643,6 @@ static int main0(int argc, char **argv) {
633 enable_dump_analysis = true;643 enable_dump_analysis = true;
634 } else if (strcmp(arg, "-femit-docs") == 0) {644 } else if (strcmp(arg, "-femit-docs") == 0) {
635 enable_doc_generation = true;645 enable_doc_generation = true;
636 } else if (strcmp(arg, "-fno-emit-bin") == 0) {
637 disable_bin_generation = true;
638 } else if (strcmp(arg, "--enable-valgrind") == 0) {646 } else if (strcmp(arg, "--enable-valgrind") == 0) {
639 valgrind_support = ValgrindSupportEnabled;647 valgrind_support = ValgrindSupportEnabled;
640 } else if (strcmp(arg, "--disable-valgrind") == 0) {648 } else if (strcmp(arg, "--disable-valgrind") == 0) {
...@@ -703,6 +711,20 @@ static int main0(int argc, char **argv) {...@@ -703,6 +711,20 @@ static int main0(int argc, char **argv) {
703 function_sections = true;711 function_sections = true;
704 } else if (strcmp(arg, "--test-evented-io") == 0) {712 } else if (strcmp(arg, "--test-evented-io") == 0) {
705 test_evented_io = true;713 test_evented_io = true;
714 } else if (strcmp(arg, "-femit-bin") == 0) {
715 emit_bin = true;
716 } else if (strcmp(arg, "-fno-emit-bin") == 0) {
717 emit_bin = false;
718 } else if (strcmp(arg, "-femit-asm") == 0) {
719 emit_asm = true;
720 } else if (strcmp(arg, "-fno-emit-asm") == 0) {
721 emit_asm = false;
722 } else if (strcmp(arg, "-femit-llvm-ir") == 0) {
723 emit_llvm_ir = true;
724 } else if (strcmp(arg, "-fno-emit-llvm-ir") == 0) {
725 emit_llvm_ir = false;
726 } else if (str_starts_with(arg, "-mcpu=")) {
727 mcpu = arg + strlen("-mcpu=");
706 } else if (i + 1 >= argc) {728 } else if (i + 1 >= argc) {
707 fprintf(stderr, "Expected another argument after %s\n", arg);729 fprintf(stderr, "Expected another argument after %s\n", arg);
708 return print_error_usage(arg0);730 return print_error_usage(arg0);
...@@ -734,11 +756,13 @@ static int main0(int argc, char **argv) {...@@ -734,11 +756,13 @@ static int main0(int argc, char **argv) {
734 }756 }
735 } else if (strcmp(arg, "--emit") == 0) {757 } else if (strcmp(arg, "--emit") == 0) {
736 if (strcmp(argv[i], "asm") == 0) {758 if (strcmp(argv[i], "asm") == 0) {
737 emit_file_type = EmitFileTypeAssembly;759 emit_asm = true;
760 emit_bin = false;
738 } else if (strcmp(argv[i], "bin") == 0) {761 } else if (strcmp(argv[i], "bin") == 0) {
739 emit_file_type = EmitFileTypeBinary;762 emit_bin = true;
740 } else if (strcmp(argv[i], "llvm-ir") == 0) {763 } else if (strcmp(argv[i], "llvm-ir") == 0) {
741 emit_file_type = EmitFileTypeLLVMIr;764 emit_llvm_ir = true;
765 emit_bin = false;
742 } else {766 } else {
743 fprintf(stderr, "--emit options are 'asm', 'bin', or 'llvm-ir'\n");767 fprintf(stderr, "--emit options are 'asm', 'bin', or 'llvm-ir'\n");
744 return print_error_usage(arg0);768 return print_error_usage(arg0);
...@@ -877,10 +901,8 @@ static int main0(int argc, char **argv) {...@@ -877,10 +901,8 @@ static int main0(int argc, char **argv) {
877 , argv[i]);901 , argv[i]);
878 return EXIT_FAILURE;902 return EXIT_FAILURE;
879 }903 }
880 } else if (strcmp(arg, "-target-cpu") == 0) {904 } else if (strcmp(arg, "-mcpu") == 0) {
881 cpu = argv[i];905 mcpu = argv[i];
882 } else if (strcmp(arg, "-target-feature") == 0) {
883 features = argv[i];
884 } else {906 } else {
885 fprintf(stderr, "Invalid argument: %s\n", arg);907 fprintf(stderr, "Invalid argument: %s\n", arg);
886 return print_error_usage(arg0);908 return print_error_usage(arg0);
...@@ -956,58 +978,54 @@ static int main0(int argc, char **argv) {...@@ -956,58 +978,54 @@ static int main0(int argc, char **argv) {
956 init_all_targets();978 init_all_targets();
957979
958 ZigTarget target;980 ZigTarget target;
959 if (target_string == nullptr) {981 if ((err = target_parse_triple(&target, target_string, mcpu))) {
960 get_native_target(&target);982 fprintf(stderr, "invalid target: %s\n"
983 "See `%s targets` to display valid targets.\n", err_str(err), arg0);
984 return print_error_usage(arg0);
985 }
986 if (target_is_glibc(&target)) {
987 target.glibc_version = heap::c_allocator.create<ZigGLibCVersion>();
988
961 if (target_glibc != nullptr) {989 if (target_glibc != nullptr) {
962 fprintf(stderr, "-target-glibc provided but no -target parameter\n");990 if ((err = target_parse_glibc_version(target.glibc_version, target_glibc))) {
963 return print_error_usage(arg0);991 fprintf(stderr, "invalid glibc version '%s': %s\n", target_glibc, err_str(err));
964 }
965 } else {
966 if ((err = target_parse_triple(&target, target_string))) {
967 if (err == ErrorUnknownArchitecture && target.arch != ZigLLVM_UnknownArch) {
968 fprintf(stderr, "'%s' requires a sub-architecture. Try one of these:\n",
969 target_arch_name(target.arch));
970 SubArchList sub_arch_list = target_subarch_list(target.arch);
971 size_t subarch_count = target_subarch_count(sub_arch_list);
972 for (size_t sub_i = 0; sub_i < subarch_count; sub_i += 1) {
973 ZigLLVM_SubArchType sub = target_subarch_enum(sub_arch_list, sub_i);
974 fprintf(stderr, " %s%s\n", target_arch_name(target.arch), target_subarch_name(sub));
975 }
976 return print_error_usage(arg0);
977 } else {
978 fprintf(stderr, "invalid target: %s\n", err_str(err));
979 return print_error_usage(arg0);992 return print_error_usage(arg0);
980 }993 }
981 }994 } else {
982 if (target_is_glibc(&target)) {995 target_init_default_glibc_version(&target);
983 target.glibc_version = heap::c_allocator.create<ZigGLibCVersion>();996#if defined(ZIG_OS_LINUX)
984997 if (target.is_native) {
985 if (target_glibc != nullptr) {998 // TODO self-host glibc version detection, and then this logic can go away
986 if ((err = target_parse_glibc_version(target.glibc_version, target_glibc))) {999 if ((err = glibc_detect_native_version(target.glibc_version))) {
987 fprintf(stderr, "invalid glibc version '%s': %s\n", target_glibc, err_str(err));1000 // Fall back to the default version.
988 return print_error_usage(arg0);
989 }1001 }
990 } else {
991 target_init_default_glibc_version(&target);
992 }1002 }
993 } else if (target_glibc != nullptr) {1003#endif
994 fprintf(stderr, "'%s' is not a glibc-compatible target", target_string);
995 return print_error_usage(arg0);
996 }1004 }
1005 } else if (target_glibc != nullptr) {
1006 fprintf(stderr, "'%s' is not a glibc-compatible target", target_string);
1007 return print_error_usage(arg0);
997 }1008 }
9981009
999 Buf zig_triple_buf = BUF_INIT;1010 Buf zig_triple_buf = BUF_INIT;
1000 target_triple_zig(&zig_triple_buf, &target);1011 target_triple_zig(&zig_triple_buf, &target);
10011012
1002 const char *stage2_triple_arg = target.is_native ? nullptr : buf_ptr(&zig_triple_buf);1013 // If both output_dir and enable_cache are provided, and doing build-lib, we
1003 if ((err = stage2_cpu_features_parse(&target.cpu_features, stage2_triple_arg, cpu, features))) {1014 // will just do a file copy at the end. This helps when bootstrapping zig from zig0
1004 fprintf(stderr, "unable to initialize CPU features: %s\n", err_str(err));1015 // because we want to pass something like this:
1005 return main_exit(root_progress_node, EXIT_FAILURE);1016 // zig0 build-lib --cache on --output-dir ${CMAKE_BINARY_DIR}
1006 }1017 // And we don't have access to `zig0 build` because that would require detecting native libc
10071018 // on systems where we are not able to build a libc from source for them.
1019 // But that's the only reason this works, so otherwise we give an error here.
1020 Buf *final_output_dir_step = nullptr;
1008 if (output_dir != nullptr && enable_cache == CacheOptOn) {1021 if (output_dir != nullptr && enable_cache == CacheOptOn) {
1009 fprintf(stderr, "`--output-dir` is incompatible with --cache on.\n");1022 if (cmd == CmdBuild && out_type == OutTypeLib) {
1010 return print_error_usage(arg0);1023 final_output_dir_step = output_dir;
1024 output_dir = nullptr;
1025 } else {
1026 fprintf(stderr, "`--output-dir` is incompatible with --cache on.\n");
1027 return print_error_usage(arg0);
1028 }
1011 }1029 }
10121030
1013 if (target_requires_pic(&target, have_libc) && want_pic == WantPICDisabled) {1031 if (target_requires_pic(&target, have_libc) && want_pic == WantPICDisabled) {
...@@ -1015,8 +1033,8 @@ static int main0(int argc, char **argv) {...@@ -1015,8 +1033,8 @@ static int main0(int argc, char **argv) {
1015 return print_error_usage(arg0);1033 return print_error_usage(arg0);
1016 }1034 }
10171035
1018 if (emit_file_type != EmitFileTypeBinary && in_file == nullptr) {1036 if ((emit_asm || emit_llvm_ir) && in_file == nullptr) {
1019 fprintf(stderr, "A root source file is required when using `--emit asm` or `--emit llvm-ir`\n");1037 fprintf(stderr, "A root source file is required when using `-femit-asm` or `-femit-llvm-ir`\n");
1020 return print_error_usage(arg0);1038 return print_error_usage(arg0);
1021 }1039 }
10221040
...@@ -1028,15 +1046,22 @@ static int main0(int argc, char **argv) {...@@ -1028,15 +1046,22 @@ static int main0(int argc, char **argv) {
1028 switch (cmd) {1046 switch (cmd) {
1029 case CmdLibC: {1047 case CmdLibC: {
1030 if (in_file) {1048 if (in_file) {
1031 ZigLibCInstallation libc;1049 Stage2LibCInstallation libc;
1032 if ((err = zig_libc_parse(&libc, buf_create_from_str(in_file), &target, true)))1050 if ((err = stage2_libc_parse(&libc, in_file))) {
1051 fprintf(stderr, "unable to parse libc file: %s\n", err_str(err));
1033 return main_exit(root_progress_node, EXIT_FAILURE);1052 return main_exit(root_progress_node, EXIT_FAILURE);
1053 }
1034 return main_exit(root_progress_node, EXIT_SUCCESS);1054 return main_exit(root_progress_node, EXIT_SUCCESS);
1035 }1055 }
1036 ZigLibCInstallation libc;1056 Stage2LibCInstallation libc;
1037 if ((err = zig_libc_find_native(&libc, true)))1057 if ((err = stage2_libc_find_native(&libc))) {
1058 fprintf(stderr, "unable to find native libc file: %s\n", err_str(err));
1038 return main_exit(root_progress_node, EXIT_FAILURE);1059 return main_exit(root_progress_node, EXIT_FAILURE);
1039 zig_libc_render(&libc, stdout);1060 }
1061 if ((err = stage2_libc_render(&libc, stdout))) {
1062 fprintf(stderr, "unable to print libc file: %s\n", err_str(err));
1063 return main_exit(root_progress_node, EXIT_FAILURE);
1064 }
1040 return main_exit(root_progress_node, EXIT_SUCCESS);1065 return main_exit(root_progress_node, EXIT_SUCCESS);
1041 }1066 }
1042 case CmdBuiltin: {1067 case CmdBuiltin: {
...@@ -1080,11 +1105,38 @@ static int main0(int argc, char **argv) {...@@ -1080,11 +1105,38 @@ static int main0(int argc, char **argv) {
1080 {1105 {
1081 fprintf(stderr, "Expected source file argument.\n");1106 fprintf(stderr, "Expected source file argument.\n");
1082 return print_error_usage(arg0);1107 return print_error_usage(arg0);
1083 } else if (cmd == CmdRun && emit_file_type != EmitFileTypeBinary) {1108 } else if (cmd == CmdRun && !emit_bin) {
1084 fprintf(stderr, "Cannot run non-executable file.\n");1109 fprintf(stderr, "Cannot run without emitting a binary file.\n");
1085 return print_error_usage(arg0);1110 return print_error_usage(arg0);
1086 }1111 }
10871112
1113 if (target.is_native && link_libs.length != 0) {
1114 Error err;
1115 Stage2NativePaths paths;
1116 if ((err = stage2_detect_native_paths(&paths))) {
1117 fprintf(stderr, "unable to detect native system paths: %s\n", err_str(err));
1118 exit(1);
1119 }
1120 for (size_t i = 0; i < paths.warnings_len; i += 1) {
1121 const char *warning = paths.warnings_ptr[i];
1122 fprintf(stderr, "warning: %s\n", warning);
1123 }
1124 for (size_t i = 0; i < paths.include_dirs_len; i += 1) {
1125 const char *include_dir = paths.include_dirs_ptr[i];
1126 clang_argv.append("-I");
1127 clang_argv.append(include_dir);
1128 }
1129 for (size_t i = 0; i < paths.lib_dirs_len; i += 1) {
1130 const char *lib_dir = paths.lib_dirs_ptr[i];
1131 lib_dirs.append(lib_dir);
1132 }
1133 for (size_t i = 0; i < paths.rpaths_len; i += 1) {
1134 const char *rpath = paths.rpaths_ptr[i];
1135 rpath_list.append(rpath);
1136 }
1137 }
1138
1139
1088 assert(cmd != CmdBuild || out_type != OutTypeUnknown);1140 assert(cmd != CmdBuild || out_type != OutTypeUnknown);
10891141
1090 bool need_name = (cmd == CmdBuild || cmd == CmdTranslateC);1142 bool need_name = (cmd == CmdBuild || cmd == CmdTranslateC);
...@@ -1126,10 +1178,10 @@ static int main0(int argc, char **argv) {...@@ -1126,10 +1178,10 @@ static int main0(int argc, char **argv) {
1126 if (cmd == CmdRun && buf_out_name == nullptr) {1178 if (cmd == CmdRun && buf_out_name == nullptr) {
1127 buf_out_name = buf_create_from_str("run");1179 buf_out_name = buf_create_from_str("run");
1128 }1180 }
1129 ZigLibCInstallation *libc = nullptr;1181 Stage2LibCInstallation *libc = nullptr;
1130 if (libc_txt != nullptr) {1182 if (libc_txt != nullptr) {
1131 libc = heap::c_allocator.create<ZigLibCInstallation>();1183 libc = heap::c_allocator.create<Stage2LibCInstallation>();
1132 if ((err = zig_libc_parse(libc, buf_create_from_str(libc_txt), &target, true))) {1184 if ((err = stage2_libc_parse(libc, libc_txt))) {
1133 fprintf(stderr, "Unable to parse --libc text file: %s\n", err_str(err));1185 fprintf(stderr, "Unable to parse --libc text file: %s\n", err_str(err));
1134 return main_exit(root_progress_node, EXIT_FAILURE);1186 return main_exit(root_progress_node, EXIT_FAILURE);
1135 }1187 }
...@@ -1158,7 +1210,10 @@ static int main0(int argc, char **argv) {...@@ -1158,7 +1210,10 @@ static int main0(int argc, char **argv) {
1158 g->enable_stack_report = stack_report;1210 g->enable_stack_report = stack_report;
1159 g->enable_dump_analysis = enable_dump_analysis;1211 g->enable_dump_analysis = enable_dump_analysis;
1160 g->enable_doc_generation = enable_doc_generation;1212 g->enable_doc_generation = enable_doc_generation;
1161 g->disable_bin_generation = disable_bin_generation;1213 g->emit_bin = emit_bin;
1214 g->emit_asm = emit_asm;
1215 g->emit_llvm_ir = emit_llvm_ir;
1216
1162 codegen_set_out_name(g, buf_out_name);1217 codegen_set_out_name(g, buf_out_name);
1163 codegen_set_lib_version(g, ver_major, ver_minor, ver_patch);1218 codegen_set_lib_version(g, ver_major, ver_minor, ver_patch);
1164 g->want_single_threaded = want_single_threaded;1219 g->want_single_threaded = want_single_threaded;
...@@ -1188,7 +1243,6 @@ static int main0(int argc, char **argv) {...@@ -1188,7 +1243,6 @@ static int main0(int argc, char **argv) {
1188 g->function_sections = function_sections;1243 g->function_sections = function_sections;
1189 g->code_model = code_model;1244 g->code_model = code_model;
11901245
1191
1192 for (size_t i = 0; i < lib_dirs.length; i += 1) {1246 for (size_t i = 0; i < lib_dirs.length; i += 1) {
1193 codegen_add_lib_dir(g, lib_dirs.at(i));1247 codegen_add_lib_dir(g, lib_dirs.at(i));
1194 }1248 }
...@@ -1244,8 +1298,6 @@ static int main0(int argc, char **argv) {...@@ -1244,8 +1298,6 @@ static int main0(int argc, char **argv) {
12441298
12451299
1246 if (cmd == CmdBuild || cmd == CmdRun) {1300 if (cmd == CmdBuild || cmd == CmdRun) {
1247 codegen_set_emit_file_type(g, emit_file_type);
1248
1249 g->enable_cache = get_cache_opt(enable_cache, cmd == CmdRun);1301 g->enable_cache = get_cache_opt(enable_cache, cmd == CmdRun);
1250 codegen_build_and_link(g);1302 codegen_build_and_link(g);
1251 if (root_progress_node != nullptr) {1303 if (root_progress_node != nullptr) {
...@@ -1263,7 +1315,7 @@ static int main0(int argc, char **argv) {...@@ -1263,7 +1315,7 @@ static int main0(int argc, char **argv) {
1263 mem::print_report();1315 mem::print_report();
1264#endif1316#endif
12651317
1266 const char *exec_path = buf_ptr(&g->output_file_path);1318 const char *exec_path = buf_ptr(&g->bin_file_output_path);
1267 ZigList<const char*> args = {0};1319 ZigList<const char*> args = {0};
12681320
1269 args.append(exec_path);1321 args.append(exec_path);
...@@ -1283,10 +1335,23 @@ static int main0(int argc, char **argv) {...@@ -1283,10 +1335,23 @@ static int main0(int argc, char **argv) {
1283 } else if (cmd == CmdBuild) {1335 } else if (cmd == CmdBuild) {
1284 if (g->enable_cache) {1336 if (g->enable_cache) {
1285#if defined(ZIG_OS_WINDOWS)1337#if defined(ZIG_OS_WINDOWS)
1286 buf_replace(&g->output_file_path, '/', '\\');1338 buf_replace(&g->bin_file_output_path, '/', '\\');
1287#endif1339#endif
1288 if (printf("%s\n", buf_ptr(&g->output_file_path)) < 0)1340 if (final_output_dir_step != nullptr) {
1289 return main_exit(root_progress_node, EXIT_FAILURE);1341 Buf *dest_basename = buf_alloc();
1342 os_path_split(&g->bin_file_output_path, nullptr, dest_basename);
1343 Buf *dest_path = buf_alloc();
1344 os_path_join(final_output_dir_step, dest_basename, dest_path);
1345
1346 if ((err = os_update_file(&g->bin_file_output_path, dest_path))) {
1347 fprintf(stderr, "unable to copy %s to %s: %s\n", buf_ptr(&g->bin_file_output_path),
1348 buf_ptr(dest_path), err_str(err));
1349 return main_exit(root_progress_node, EXIT_FAILURE);
1350 }
1351 } else {
1352 if (printf("%s\n", buf_ptr(&g->bin_file_output_path)) < 0)
1353 return main_exit(root_progress_node, EXIT_FAILURE);
1354 }
1290 }1355 }
1291 return main_exit(root_progress_node, EXIT_SUCCESS);1356 return main_exit(root_progress_node, EXIT_SUCCESS);
1292 } else {1357 } else {
...@@ -1299,8 +1364,6 @@ static int main0(int argc, char **argv) {...@@ -1299,8 +1364,6 @@ static int main0(int argc, char **argv) {
1299 codegen_print_timing_report(g, stderr);1364 codegen_print_timing_report(g, stderr);
1300 return main_exit(root_progress_node, EXIT_SUCCESS);1365 return main_exit(root_progress_node, EXIT_SUCCESS);
1301 } else if (cmd == CmdTest) {1366 } else if (cmd == CmdTest) {
1302 codegen_set_emit_file_type(g, emit_file_type);
1303
1304 ZigTarget native;1367 ZigTarget native;
1305 get_native_target(&native);1368 get_native_target(&native);
13061369
...@@ -1319,17 +1382,17 @@ static int main0(int argc, char **argv) {...@@ -1319,17 +1382,17 @@ static int main0(int argc, char **argv) {
1319 zig_print_stack_report(g, stdout);1382 zig_print_stack_report(g, stdout);
1320 }1383 }
13211384
1322 if (g->disable_bin_generation) {1385 if (!g->emit_bin) {
1323 fprintf(stderr, "Semantic analysis complete. No binary produced due to -fno-emit-bin.\n");1386 fprintf(stderr, "Semantic analysis complete. No binary produced due to -fno-emit-bin.\n");
1324 return main_exit(root_progress_node, EXIT_SUCCESS);1387 return main_exit(root_progress_node, EXIT_SUCCESS);
1325 }1388 }
13261389
1327 Buf *test_exe_path_unresolved = &g->output_file_path;1390 Buf *test_exe_path_unresolved = &g->bin_file_output_path;
1328 Buf *test_exe_path = buf_alloc();1391 Buf *test_exe_path = buf_alloc();
1329 *test_exe_path = os_path_resolve(&test_exe_path_unresolved, 1);1392 *test_exe_path = os_path_resolve(&test_exe_path_unresolved, 1);
13301393
1331 if (emit_file_type != EmitFileTypeBinary) {1394 if (!g->emit_bin) {
1332 fprintf(stderr, "Created %s but skipping execution because it is non executable.\n",1395 fprintf(stderr, "Created %s but skipping execution because no binary generated.\n",
1333 buf_ptr(test_exe_path));1396 buf_ptr(test_exe_path));
1334 return main_exit(root_progress_node, EXIT_SUCCESS);1397 return main_exit(root_progress_node, EXIT_SUCCESS);
1335 }1398 }
src/mem_list.hpp+9-6
...@@ -14,11 +14,14 @@ namespace mem {...@@ -14,11 +14,14 @@ namespace mem {
1414
15template<typename T>15template<typename T>
16struct List {16struct List {
17 void deinit(Allocator& allocator) {17 void deinit(Allocator *allocator) {
18 allocator.deallocate<T>(items, capacity);18 allocator->deallocate<T>(items, capacity);
19 items = nullptr;
20 length = 0;
21 capacity = 0;
19 }22 }
2023
21 void append(Allocator& allocator, const T& item) {24 void append(Allocator *allocator, const T& item) {
22 ensure_capacity(allocator, length + 1);25 ensure_capacity(allocator, length + 1);
23 items[length++] = item;26 items[length++] = item;
24 }27 }
...@@ -57,7 +60,7 @@ struct List {...@@ -57,7 +60,7 @@ struct List {
57 return items[length - 1];60 return items[length - 1];
58 }61 }
5962
60 void resize(Allocator& allocator, size_t new_length) {63 void resize(Allocator *allocator, size_t new_length) {
61 assert(new_length != SIZE_MAX);64 assert(new_length != SIZE_MAX);
62 ensure_capacity(allocator, new_length);65 ensure_capacity(allocator, new_length);
63 length = new_length;66 length = new_length;
...@@ -67,7 +70,7 @@ struct List {...@@ -67,7 +70,7 @@ struct List {
67 length = 0;70 length = 0;
68 }71 }
6972
70 void ensure_capacity(Allocator& allocator, size_t new_capacity) {73 void ensure_capacity(Allocator *allocator, size_t new_capacity) {
71 if (capacity >= new_capacity)74 if (capacity >= new_capacity)
72 return;75 return;
7376
...@@ -76,7 +79,7 @@ struct List {...@@ -76,7 +79,7 @@ struct List {
76 better_capacity = better_capacity * 5 / 2 + 8;79 better_capacity = better_capacity * 5 / 2 + 8;
77 } while (better_capacity < new_capacity);80 } while (better_capacity < new_capacity);
7881
79 items = allocator.reallocate_nonzero<T>(items, capacity, better_capacity);82 items = allocator->reallocate_nonzero<T>(items, capacity, better_capacity);
80 capacity = better_capacity;83 capacity = better_capacity;
81 }84 }
8285
src/mem_profile.cpp+2-2
...@@ -92,7 +92,7 @@ void Profile::print_report(FILE *file) {...@@ -92,7 +92,7 @@ void Profile::print_report(FILE *file) {
92 auto entry = it.next();92 auto entry = it.next();
93 if (!entry)93 if (!entry)
94 break;94 break;
95 list.append(heap::bootstrap_allocator, &entry->value);95 list.append(&heap::bootstrap_allocator, &entry->value);
96 }96 }
9797
98 qsort(list.items, list.length, sizeof(const Entry *), entry_compare);98 qsort(list.items, list.length, sizeof(const Entry *), entry_compare);
...@@ -143,7 +143,7 @@ void Profile::print_report(FILE *file) {...@@ -143,7 +143,7 @@ void Profile::print_report(FILE *file) {
143 fprintf(file, "\n Total calls alloc: %zu, dealloc: %zu, remain: %zu\n",143 fprintf(file, "\n Total calls alloc: %zu, dealloc: %zu, remain: %zu\n",
144 total_calls_alloc, total_calls_dealloc, (total_calls_alloc - total_calls_dealloc));144 total_calls_alloc, total_calls_dealloc, (total_calls_alloc - total_calls_dealloc));
145145
146 list.deinit(heap::bootstrap_allocator);146 list.deinit(&heap::bootstrap_allocator);
147}147}
148148
149uint32_t Profile::usage_hash(UsageKey key) {149uint32_t Profile::usage_hash(UsageKey key) {
src/os.cpp+155-162
...@@ -81,11 +81,7 @@ static clock_serv_t macos_monotonic_clock;...@@ -81,11 +81,7 @@ static clock_serv_t macos_monotonic_clock;
81#include <errno.h>81#include <errno.h>
82#include <time.h>82#include <time.h>
8383
84// Apple doesn't provide the environ global variable84#if !defined(environ)
85#if defined(__APPLE__) && !defined(environ)
86#include <crt_externs.h>
87#define environ (*_NSGetEnviron())
88#elif defined(ZIG_OS_FREEBSD) || defined(ZIG_OS_NETBSD) || defined(ZIG_OS_DRAGONFLY)
89extern char **environ;85extern char **environ;
90#endif86#endif
9187
...@@ -826,7 +822,9 @@ static Error os_exec_process_posix(ZigList<const char *> &args,...@@ -826,7 +822,9 @@ static Error os_exec_process_posix(ZigList<const char *> &args,
826 if (errno == ENOENT) {822 if (errno == ENOENT) {
827 report_err = ErrorFileNotFound;823 report_err = ErrorFileNotFound;
828 }824 }
829 write(err_pipe[1], &report_err, sizeof(Error));825 if (write(err_pipe[1], &report_err, sizeof(Error)) == -1) {
826 zig_panic("write failed");
827 }
830 exit(1);828 exit(1);
831 } else {829 } else {
832 // parent830 // parent
...@@ -851,9 +849,13 @@ static Error os_exec_process_posix(ZigList<const char *> &args,...@@ -851,9 +849,13 @@ static Error os_exec_process_posix(ZigList<const char *> &args,
851 if (err2) return err2;849 if (err2) return err2;
852850
853 Error child_err = ErrorNone;851 Error child_err = ErrorNone;
854 write(err_pipe[1], &child_err, sizeof(Error));852 if (write(err_pipe[1], &child_err, sizeof(Error)) == -1) {
853 zig_panic("write failed");
854 }
855 close(err_pipe[1]);855 close(err_pipe[1]);
856 read(err_pipe[0], &child_err, sizeof(Error));856 if (read(err_pipe[0], &child_err, sizeof(Error)) == -1) {
857 zig_panic("write failed");
858 }
857 close(err_pipe[0]);859 close(err_pipe[0]);
858 return child_err;860 return child_err;
859 }861 }
...@@ -1029,6 +1031,124 @@ Error os_write_file(Buf *full_path, Buf *contents) {...@@ -1029,6 +1031,124 @@ Error os_write_file(Buf *full_path, Buf *contents) {
1029 return ErrorNone;1031 return ErrorNone;
1030}1032}
10311033
1034static Error copy_open_files(FILE *src_f, FILE *dest_f) {
1035 static const size_t buf_size = 2048;
1036 char buf[buf_size];
1037 for (;;) {
1038 size_t amt_read = fread(buf, 1, buf_size, src_f);
1039 if (amt_read != buf_size) {
1040 if (ferror(src_f)) {
1041 return ErrorFileSystem;
1042 }
1043 }
1044 size_t amt_written = fwrite(buf, 1, amt_read, dest_f);
1045 if (amt_written != amt_read) {
1046 return ErrorFileSystem;
1047 }
1048 if (feof(src_f)) {
1049 return ErrorNone;
1050 }
1051 }
1052}
1053
1054#if defined(ZIG_OS_WINDOWS)
1055static void windows_filetime_to_os_timestamp(FILETIME *ft, OsTimeStamp *mtime) {
1056 mtime->sec = (((ULONGLONG) ft->dwHighDateTime) << 32) + ft->dwLowDateTime;
1057 mtime->nsec = 0;
1058}
1059static FILETIME windows_os_timestamp_to_filetime(OsTimeStamp mtime) {
1060 FILETIME result;
1061 result.dwHighDateTime = mtime.sec >> 32;
1062 result.dwLowDateTime = mtime.sec;
1063 return result;
1064}
1065#endif
1066
1067static Error set_file_times(OsFile file, OsTimeStamp ts) {
1068#if defined(ZIG_OS_WINDOWS)
1069 FILETIME ft = windows_os_timestamp_to_filetime(ts);
1070 if (SetFileTime(file, nullptr, &ft, &ft) == 0) {
1071 return ErrorUnexpected;
1072 }
1073 return ErrorNone;
1074#else
1075 struct timespec times[2] = {
1076 { ts.sec, ts.nsec },
1077 { ts.sec, ts.nsec },
1078 };
1079 if (futimens(file, times) == -1) {
1080 switch (errno) {
1081 case EBADF:
1082 zig_panic("futimens EBADF");
1083 default:
1084 return ErrorUnexpected;
1085 }
1086 }
1087 return ErrorNone;
1088#endif
1089}
1090
1091Error os_update_file(Buf *src_path, Buf *dst_path) {
1092 Error err;
1093
1094 OsFile src_file;
1095 OsFileAttr src_attr;
1096 if ((err = os_file_open_r(src_path, &src_file, &src_attr))) {
1097 return err;
1098 }
1099
1100 OsFile dst_file;
1101 OsFileAttr dst_attr;
1102 if ((err = os_file_open_w(dst_path, &dst_file, &dst_attr, src_attr.mode))) {
1103 os_file_close(&src_file);
1104 return err;
1105 }
1106
1107 if (src_attr.size == dst_attr.size &&
1108 src_attr.mode == dst_attr.mode &&
1109 src_attr.mtime.sec == dst_attr.mtime.sec &&
1110 src_attr.mtime.nsec == dst_attr.mtime.nsec)
1111 {
1112 os_file_close(&src_file);
1113 os_file_close(&dst_file);
1114 return ErrorNone;
1115 }
1116#if defined(ZIG_OS_WINDOWS)
1117 if (SetEndOfFile(dst_file) == 0) {
1118 return ErrorUnexpected;
1119 }
1120#else
1121 if (ftruncate(dst_file, 0) == -1) {
1122 return ErrorUnexpected;
1123 }
1124#endif
1125#if defined(ZIG_OS_WINDOWS)
1126 FILE *src_libc_file = _fdopen(_open_osfhandle((intptr_t)src_file, _O_RDONLY), "rb");
1127 FILE *dst_libc_file = _fdopen(_open_osfhandle((intptr_t)dst_file, 0), "wb");
1128#else
1129 FILE *src_libc_file = fdopen(src_file, "rb");
1130 FILE *dst_libc_file = fdopen(dst_file, "wb");
1131#endif
1132 assert(src_libc_file);
1133 assert(dst_libc_file);
1134
1135 if ((err = copy_open_files(src_libc_file, dst_libc_file))) {
1136 fclose(src_libc_file);
1137 fclose(dst_libc_file);
1138 return err;
1139 }
1140 if (fflush(src_libc_file) == -1) {
1141 return ErrorUnexpected;
1142 }
1143 if (fflush(dst_libc_file) == -1) {
1144 return ErrorUnexpected;
1145 }
1146 err = set_file_times(dst_file, src_attr.mtime);
1147 fclose(src_libc_file);
1148 fclose(dst_libc_file);
1149 return err;
1150}
1151
1032Error os_copy_file(Buf *src_path, Buf *dest_path) {1152Error os_copy_file(Buf *src_path, Buf *dest_path) {
1033 FILE *src_f = fopen(buf_ptr(src_path), "rb");1153 FILE *src_f = fopen(buf_ptr(src_path), "rb");
1034 if (!src_f) {1154 if (!src_f) {
...@@ -1055,30 +1175,10 @@ Error os_copy_file(Buf *src_path, Buf *dest_path) {...@@ -1055,30 +1175,10 @@ Error os_copy_file(Buf *src_path, Buf *dest_path) {
1055 return ErrorFileSystem;1175 return ErrorFileSystem;
1056 }1176 }
1057 }1177 }
10581178 Error err = copy_open_files(src_f, dest_f);
1059 static const size_t buf_size = 2048;1179 fclose(src_f);
1060 char buf[buf_size];1180 fclose(dest_f);
1061 for (;;) {1181 return err;
1062 size_t amt_read = fread(buf, 1, buf_size, src_f);
1063 if (amt_read != buf_size) {
1064 if (ferror(src_f)) {
1065 fclose(src_f);
1066 fclose(dest_f);
1067 return ErrorFileSystem;
1068 }
1069 }
1070 size_t amt_written = fwrite(buf, 1, amt_read, dest_f);
1071 if (amt_written != amt_read) {
1072 fclose(src_f);
1073 fclose(dest_f);
1074 return ErrorFileSystem;
1075 }
1076 if (feof(src_f)) {
1077 fclose(src_f);
1078 fclose(dest_f);
1079 return ErrorNone;
1080 }
1081 }
1082}1182}
10831183
1084Error os_fetch_file_path(Buf *full_path, Buf *out_contents) {1184Error os_fetch_file_path(Buf *full_path, Buf *out_contents) {
...@@ -1218,13 +1318,6 @@ Error os_rename(Buf *src_path, Buf *dest_path) {...@@ -1218,13 +1318,6 @@ Error os_rename(Buf *src_path, Buf *dest_path) {
1218 return ErrorNone;1318 return ErrorNone;
1219}1319}
12201320
1221#if defined(ZIG_OS_WINDOWS)
1222static void windows_filetime_to_os_timestamp(FILETIME *ft, OsTimeStamp *mtime) {
1223 mtime->sec = (((ULONGLONG) ft->dwHighDateTime) << 32) + ft->dwLowDateTime;
1224 mtime->nsec = 0;
1225}
1226#endif
1227
1228OsTimeStamp os_timestamp_calendar(void) {1321OsTimeStamp os_timestamp_calendar(void) {
1229 OsTimeStamp result;1322 OsTimeStamp result;
1230#if defined(ZIG_OS_WINDOWS)1323#if defined(ZIG_OS_WINDOWS)
...@@ -1551,108 +1644,6 @@ void os_stderr_set_color(TermColor color) {...@@ -1551,108 +1644,6 @@ void os_stderr_set_color(TermColor color) {
1551#endif1644#endif
1552}1645}
15531646
1554Error os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchType platform_type) {
1555#if defined(ZIG_OS_WINDOWS)
1556 buf_resize(output_buf, 0);
1557 buf_appendf(output_buf, "%sLib\\%s\\ucrt\\", sdk->path10_ptr, sdk->version10_ptr);
1558 switch (platform_type) {
1559 case ZigLLVM_x86:
1560 buf_append_str(output_buf, "x86\\");
1561 break;
1562 case ZigLLVM_x86_64:
1563 buf_append_str(output_buf, "x64\\");
1564 break;
1565 case ZigLLVM_arm:
1566 buf_append_str(output_buf, "arm\\");
1567 break;
1568 default:
1569 zig_panic("Attempted to use vcruntime for non-supported platform.");
1570 }
1571 Buf* tmp_buf = buf_alloc();
1572 buf_init_from_buf(tmp_buf, output_buf);
1573 buf_append_str(tmp_buf, "ucrt.lib");
1574 if (GetFileAttributesA(buf_ptr(tmp_buf)) != INVALID_FILE_ATTRIBUTES) {
1575 return ErrorNone;
1576 }
1577 else {
1578 buf_resize(output_buf, 0);
1579 return ErrorFileNotFound;
1580 }
1581#else
1582 return ErrorFileNotFound;
1583#endif
1584}
1585
1586Error os_get_win32_ucrt_include_path(ZigWindowsSDK *sdk, Buf* output_buf) {
1587#if defined(ZIG_OS_WINDOWS)
1588 buf_resize(output_buf, 0);
1589 buf_appendf(output_buf, "%sInclude\\%s\\ucrt", sdk->path10_ptr, sdk->version10_ptr);
1590 if (GetFileAttributesA(buf_ptr(output_buf)) != INVALID_FILE_ATTRIBUTES) {
1591 return ErrorNone;
1592 }
1593 else {
1594 buf_resize(output_buf, 0);
1595 return ErrorFileNotFound;
1596 }
1597#else
1598 return ErrorFileNotFound;
1599#endif
1600}
1601
1602Error os_get_win32_kern32_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchType platform_type) {
1603#if defined(ZIG_OS_WINDOWS)
1604 {
1605 buf_resize(output_buf, 0);
1606 buf_appendf(output_buf, "%sLib\\%s\\um\\", sdk->path10_ptr, sdk->version10_ptr);
1607 switch (platform_type) {
1608 case ZigLLVM_x86:
1609 buf_append_str(output_buf, "x86\\");
1610 break;
1611 case ZigLLVM_x86_64:
1612 buf_append_str(output_buf, "x64\\");
1613 break;
1614 case ZigLLVM_arm:
1615 buf_append_str(output_buf, "arm\\");
1616 break;
1617 default:
1618 zig_panic("Attempted to use vcruntime for non-supported platform.");
1619 }
1620 Buf* tmp_buf = buf_alloc();
1621 buf_init_from_buf(tmp_buf, output_buf);
1622 buf_append_str(tmp_buf, "kernel32.lib");
1623 if (GetFileAttributesA(buf_ptr(tmp_buf)) != INVALID_FILE_ATTRIBUTES) {
1624 return ErrorNone;
1625 }
1626 }
1627 {
1628 buf_resize(output_buf, 0);
1629 buf_appendf(output_buf, "%sLib\\%s\\um\\", sdk->path81_ptr, sdk->version81_ptr);
1630 switch (platform_type) {
1631 case ZigLLVM_x86:
1632 buf_append_str(output_buf, "x86\\");
1633 break;
1634 case ZigLLVM_x86_64:
1635 buf_append_str(output_buf, "x64\\");
1636 break;
1637 case ZigLLVM_arm:
1638 buf_append_str(output_buf, "arm\\");
1639 break;
1640 default:
1641 zig_panic("Attempted to use vcruntime for non-supported platform.");
1642 }
1643 Buf* tmp_buf = buf_alloc();
1644 buf_init_from_buf(tmp_buf, output_buf);
1645 buf_append_str(tmp_buf, "kernel32.lib");
1646 if (GetFileAttributesA(buf_ptr(tmp_buf)) != INVALID_FILE_ATTRIBUTES) {
1647 return ErrorNone;
1648 }
1649 }
1650 return ErrorFileNotFound;
1651#else
1652 return ErrorFileNotFound;
1653#endif
1654}
1655
1656#if defined(ZIG_OS_WINDOWS)1647#if defined(ZIG_OS_WINDOWS)
1657// Ported from std/unicode.zig1648// Ported from std/unicode.zig
1658struct Utf16LeIterator {1649struct Utf16LeIterator {
...@@ -1835,10 +1826,15 @@ Error os_self_exe_shared_libs(ZigList<Buf *> &paths) {...@@ -1835,10 +1826,15 @@ Error os_self_exe_shared_libs(ZigList<Buf *> &paths) {
1835#endif1826#endif
1836}1827}
18371828
1838Error os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr) {1829Error os_file_open_rw(Buf *full_path, OsFile *out_file, OsFileAttr *attr, bool need_write, uint32_t mode) {
1839#if defined(ZIG_OS_WINDOWS)1830#if defined(ZIG_OS_WINDOWS)
1840 // TODO use CreateFileW1831 // TODO use CreateFileW
1841 HANDLE result = CreateFileA(buf_ptr(full_path), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);1832 HANDLE result = CreateFileA(buf_ptr(full_path),
1833 need_write ? (GENERIC_READ|GENERIC_WRITE) : GENERIC_READ,
1834 need_write ? 0 : FILE_SHARE_READ,
1835 nullptr,
1836 need_write ? OPEN_ALWAYS : OPEN_EXISTING,
1837 FILE_ATTRIBUTE_NORMAL, nullptr);
18421838
1843 if (result == INVALID_HANDLE_VALUE) {1839 if (result == INVALID_HANDLE_VALUE) {
1844 DWORD err = GetLastError();1840 DWORD err = GetLastError();
...@@ -1871,12 +1867,15 @@ Error os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr) {...@@ -1871,12 +1867,15 @@ Error os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr) {
1871 }1867 }
1872 windows_filetime_to_os_timestamp(&file_info.ftLastWriteTime, &attr->mtime);1868 windows_filetime_to_os_timestamp(&file_info.ftLastWriteTime, &attr->mtime);
1873 attr->inode = (((uint64_t)file_info.nFileIndexHigh) << 32) | file_info.nFileIndexLow;1869 attr->inode = (((uint64_t)file_info.nFileIndexHigh) << 32) | file_info.nFileIndexLow;
1870 attr->mode = 0;
1871 attr->size = (((uint64_t)file_info.nFileSizeHigh) << 32) | file_info.nFileSizeLow;
1874 }1872 }
18751873
1876 return ErrorNone;1874 return ErrorNone;
1877#else1875#else
1878 for (;;) {1876 for (;;) {
1879 int fd = open(buf_ptr(full_path), O_RDONLY|O_CLOEXEC);1877 int fd = open(buf_ptr(full_path),
1878 need_write ? (O_RDWR|O_CLOEXEC|O_CREAT) : (O_RDONLY|O_CLOEXEC), mode);
1880 if (fd == -1) {1879 if (fd == -1) {
1881 switch (errno) {1880 switch (errno) {
1882 case EINTR:1881 case EINTR:
...@@ -1886,6 +1885,7 @@ Error os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr) {...@@ -1886,6 +1885,7 @@ Error os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr) {
1886 case EFAULT:1885 case EFAULT:
1887 zig_unreachable();1886 zig_unreachable();
1888 case EACCES:1887 case EACCES:
1888 case EPERM:
1889 return ErrorAccess;1889 return ErrorAccess;
1890 case EISDIR:1890 case EISDIR:
1891 return ErrorIsDir;1891 return ErrorIsDir;
...@@ -1915,12 +1915,22 @@ Error os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr) {...@@ -1915,12 +1915,22 @@ Error os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr) {
1915 attr->mtime.sec = statbuf.st_mtim.tv_sec;1915 attr->mtime.sec = statbuf.st_mtim.tv_sec;
1916 attr->mtime.nsec = statbuf.st_mtim.tv_nsec;1916 attr->mtime.nsec = statbuf.st_mtim.tv_nsec;
1917#endif1917#endif
1918 attr->mode = statbuf.st_mode;
1919 attr->size = statbuf.st_size;
1918 }1920 }
1919 return ErrorNone;1921 return ErrorNone;
1920 }1922 }
1921#endif1923#endif
1922}1924}
19231925
1926Error os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr) {
1927 return os_file_open_rw(full_path, out_file, attr, false, 0);
1928}
1929
1930Error os_file_open_w(Buf *full_path, OsFile *out_file, OsFileAttr *attr, uint32_t mode) {
1931 return os_file_open_rw(full_path, out_file, attr, true, mode);
1932}
1933
1924Error os_file_open_lock_rw(Buf *full_path, OsFile *out_file) {1934Error os_file_open_lock_rw(Buf *full_path, OsFile *out_file) {
1925#if defined(ZIG_OS_WINDOWS)1935#if defined(ZIG_OS_WINDOWS)
1926 for (;;) {1936 for (;;) {
...@@ -1966,6 +1976,7 @@ Error os_file_open_lock_rw(Buf *full_path, OsFile *out_file) {...@@ -1966,6 +1976,7 @@ Error os_file_open_lock_rw(Buf *full_path, OsFile *out_file) {
1966 case EFAULT:1976 case EFAULT:
1967 zig_unreachable();1977 zig_unreachable();
1968 case EACCES:1978 case EACCES:
1979 case EPERM:
1969 return ErrorAccess;1980 return ErrorAccess;
1970 case EISDIR:1981 case EISDIR:
1971 return ErrorIsDir;1982 return ErrorIsDir;
...@@ -2114,21 +2125,3 @@ void os_file_close(OsFile *file) {...@@ -2114,21 +2125,3 @@ void os_file_close(OsFile *file) {
2114 *file = -1;2125 *file = -1;
2115#endif2126#endif
2116}2127}
2117
2118#ifdef ZIG_OS_LINUX
2119const char *possible_ld_names[] = {
2120#if defined(ZIG_ARCH_X86_64)
2121 "ld-linux-x86-64.so.2",
2122 "ld-musl-x86_64.so.1",
2123#elif defined(ZIG_ARCH_ARM64)
2124 "ld-linux-aarch64.so.1",
2125 "ld-musl-aarch64.so.1",
2126#elif defined(ZIG_ARCH_ARM)
2127 "ld-linux-armhf.so.3",
2128 "ld-musl-armhf.so.1",
2129 "ld-linux.so.3",
2130 "ld-musl-arm.so.1",
2131#endif
2132 NULL,
2133};
2134#endif
src/os.hpp+6-10
...@@ -43,10 +43,6 @@...@@ -43,10 +43,6 @@
43#define ZIG_ARCH_UNKNOWN43#define ZIG_ARCH_UNKNOWN
44#endif44#endif
4545
46#ifdef ZIG_OS_LINUX
47extern const char *possible_ld_names[];
48#endif
49
50#if defined(ZIG_OS_WINDOWS)46#if defined(ZIG_OS_WINDOWS)
51#define ZIG_PRI_usize "I64u"47#define ZIG_PRI_usize "I64u"
52#define ZIG_PRI_i64 "I64d"48#define ZIG_PRI_i64 "I64d"
...@@ -93,13 +89,15 @@ struct Termination {...@@ -93,13 +89,15 @@ struct Termination {
93#endif89#endif
9490
95struct OsTimeStamp {91struct OsTimeStamp {
96 uint64_t sec;92 int64_t sec;
97 uint64_t nsec;93 int64_t nsec;
98};94};
9995
100struct OsFileAttr {96struct OsFileAttr {
101 OsTimeStamp mtime;97 OsTimeStamp mtime;
98 uint64_t size;
102 uint64_t inode;99 uint64_t inode;
100 uint32_t mode;
103};101};
104102
105int os_init(void);103int os_init(void);
...@@ -121,6 +119,7 @@ Error ATTRIBUTE_MUST_USE os_make_path(Buf *path);...@@ -121,6 +119,7 @@ Error ATTRIBUTE_MUST_USE os_make_path(Buf *path);
121Error ATTRIBUTE_MUST_USE os_make_dir(Buf *path);119Error ATTRIBUTE_MUST_USE os_make_dir(Buf *path);
122120
123Error ATTRIBUTE_MUST_USE os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr);121Error ATTRIBUTE_MUST_USE os_file_open_r(Buf *full_path, OsFile *out_file, OsFileAttr *attr);
122Error ATTRIBUTE_MUST_USE os_file_open_w(Buf *full_path, OsFile *out_file, OsFileAttr *attr, uint32_t mode);
124Error ATTRIBUTE_MUST_USE os_file_open_lock_rw(Buf *full_path, OsFile *out_file);123Error ATTRIBUTE_MUST_USE os_file_open_lock_rw(Buf *full_path, OsFile *out_file);
125Error ATTRIBUTE_MUST_USE os_file_read(OsFile file, void *ptr, size_t *len);124Error ATTRIBUTE_MUST_USE os_file_read(OsFile file, void *ptr, size_t *len);
126Error ATTRIBUTE_MUST_USE os_file_read_all(OsFile file, Buf *contents);125Error ATTRIBUTE_MUST_USE os_file_read_all(OsFile file, Buf *contents);
...@@ -129,6 +128,7 @@ void os_file_close(OsFile *file);...@@ -129,6 +128,7 @@ void os_file_close(OsFile *file);
129128
130Error ATTRIBUTE_MUST_USE os_write_file(Buf *full_path, Buf *contents);129Error ATTRIBUTE_MUST_USE os_write_file(Buf *full_path, Buf *contents);
131Error ATTRIBUTE_MUST_USE os_copy_file(Buf *src_path, Buf *dest_path);130Error ATTRIBUTE_MUST_USE os_copy_file(Buf *src_path, Buf *dest_path);
131Error ATTRIBUTE_MUST_USE os_update_file(Buf *src_path, Buf *dest_path);
132132
133Error ATTRIBUTE_MUST_USE os_fetch_file(FILE *file, Buf *out_contents);133Error ATTRIBUTE_MUST_USE os_fetch_file(FILE *file, Buf *out_contents);
134Error ATTRIBUTE_MUST_USE os_fetch_file_path(Buf *full_path, Buf *out_contents);134Error ATTRIBUTE_MUST_USE os_fetch_file_path(Buf *full_path, Buf *out_contents);
...@@ -152,10 +152,6 @@ Error ATTRIBUTE_MUST_USE os_self_exe_path(Buf *out_path);...@@ -152,10 +152,6 @@ Error ATTRIBUTE_MUST_USE os_self_exe_path(Buf *out_path);
152152
153Error ATTRIBUTE_MUST_USE os_get_app_data_dir(Buf *out_path, const char *appname);153Error ATTRIBUTE_MUST_USE os_get_app_data_dir(Buf *out_path, const char *appname);
154154
155Error ATTRIBUTE_MUST_USE os_get_win32_ucrt_include_path(ZigWindowsSDK *sdk, Buf *output_buf);
156Error ATTRIBUTE_MUST_USE os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf *output_buf, ZigLLVM_ArchType platform_type);
157Error ATTRIBUTE_MUST_USE os_get_win32_kern32_path(ZigWindowsSDK *sdk, Buf *output_buf, ZigLLVM_ArchType platform_type);
158
159Error ATTRIBUTE_MUST_USE os_self_exe_shared_libs(ZigList<Buf *> &paths);155Error ATTRIBUTE_MUST_USE os_self_exe_shared_libs(ZigList<Buf *> &paths);
160156
161#endif157#endif
src/parser.cpp+7
...@@ -689,6 +689,9 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B...@@ -689,6 +689,9 @@ static AstNode *ast_parse_top_level_decl(ParseContext *pc, VisibMod visib_mod, B
689689
690 AstNode *res = fn_proto;690 AstNode *res = fn_proto;
691 if (body != nullptr) {691 if (body != nullptr) {
692 if (fn_proto->data.fn_proto.is_extern) {
693 ast_error(pc, first, "extern functions have no body");
694 }
692 res = ast_create_node_copy_line_info(pc, NodeTypeFnDef, fn_proto);695 res = ast_create_node_copy_line_info(pc, NodeTypeFnDef, fn_proto);
693 res->data.fn_def.fn_proto = fn_proto;696 res->data.fn_def.fn_proto = fn_proto;
694 res->data.fn_def.body = body;697 res->data.fn_def.body = body;
...@@ -2596,10 +2599,14 @@ static AstNode *ast_parse_prefix_op(ParseContext *pc) {...@@ -2596,10 +2599,14 @@ static AstNode *ast_parse_prefix_op(ParseContext *pc) {
2596 return res;2599 return res;
2597 }2600 }
25982601
2602 Token *noasync_token = eat_token_if(pc, TokenIdKeywordNoAsync);
2599 Token *await = eat_token_if(pc, TokenIdKeywordAwait);2603 Token *await = eat_token_if(pc, TokenIdKeywordAwait);
2600 if (await != nullptr) {2604 if (await != nullptr) {
2601 AstNode *res = ast_create_node(pc, NodeTypeAwaitExpr, await);2605 AstNode *res = ast_create_node(pc, NodeTypeAwaitExpr, await);
2606 res->data.await_expr.noasync_token = noasync_token;
2602 return res;2607 return res;
2608 } else if (noasync_token != nullptr) {
2609 put_back_token(pc);
2603 }2610 }
26042611
2605 return nullptr;2612 return nullptr;
src/stage2.cpp created+208
...@@ -0,0 +1,208 @@
1// This file is a shim for zig1. The real implementations of these are in
2// src-self-hosted/stage1.zig
3
4#include "stage2.h"
5#include "util.hpp"
6#include "zig_llvm.h"
7#include "target.hpp"
8#include <stdio.h>
9#include <stdlib.h>
10#include <string.h>
11
12Error stage2_translate_c(struct Stage2Ast **out_ast,
13 struct Stage2ErrorMsg **out_errors_ptr, size_t *out_errors_len,
14 const char **args_begin, const char **args_end, const char *resources_path)
15{
16 const char *msg = "stage0 called stage2_translate_c";
17 stage2_panic(msg, strlen(msg));
18}
19
20void stage2_free_clang_errors(struct Stage2ErrorMsg *ptr, size_t len) {
21 const char *msg = "stage0 called stage2_free_clang_errors";
22 stage2_panic(msg, strlen(msg));
23}
24
25void stage2_zen(const char **ptr, size_t *len) {
26 const char *msg = "stage0 called stage2_zen";
27 stage2_panic(msg, strlen(msg));
28}
29
30void stage2_attach_segfault_handler(void) { }
31
32void stage2_panic(const char *ptr, size_t len) {
33 fwrite(ptr, 1, len, stderr);
34 fprintf(stderr, "\n");
35 fflush(stderr);
36 abort();
37}
38
39void stage2_render_ast(struct Stage2Ast *ast, FILE *output_file) {
40 const char *msg = "stage0 called stage2_render_ast";
41 stage2_panic(msg, strlen(msg));
42}
43
44int stage2_fmt(int argc, char **argv) {
45 const char *msg = "stage0 called stage2_fmt";
46 stage2_panic(msg, strlen(msg));
47}
48
49stage2_DepTokenizer stage2_DepTokenizer_init(const char *input, size_t len) {
50 const char *msg = "stage0 called stage2_DepTokenizer_init";
51 stage2_panic(msg, strlen(msg));
52}
53
54void stage2_DepTokenizer_deinit(stage2_DepTokenizer *self) {
55 const char *msg = "stage0 called stage2_DepTokenizer_deinit";
56 stage2_panic(msg, strlen(msg));
57}
58
59stage2_DepNextResult stage2_DepTokenizer_next(stage2_DepTokenizer *self) {
60 const char *msg = "stage0 called stage2_DepTokenizer_next";
61 stage2_panic(msg, strlen(msg));
62}
63
64
65struct Stage2Progress {
66 int trash;
67};
68
69struct Stage2ProgressNode {
70 int trash;
71};
72
73Stage2Progress *stage2_progress_create(void) {
74 return nullptr;
75}
76
77void stage2_progress_destroy(Stage2Progress *progress) {}
78
79Stage2ProgressNode *stage2_progress_start_root(Stage2Progress *progress,
80 const char *name_ptr, size_t name_len, size_t estimated_total_items)
81{
82 return nullptr;
83}
84Stage2ProgressNode *stage2_progress_start(Stage2ProgressNode *node,
85 const char *name_ptr, size_t name_len, size_t estimated_total_items)
86{
87 return nullptr;
88}
89void stage2_progress_end(Stage2ProgressNode *node) {}
90void stage2_progress_complete_one(Stage2ProgressNode *node) {}
91void stage2_progress_disable_tty(Stage2Progress *progress) {}
92void stage2_progress_update_node(Stage2ProgressNode *node, size_t completed_count, size_t estimated_total_items){}
93
94Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, const char *mcpu) {
95 Error err;
96
97 if (zig_triple == nullptr) {
98 get_native_target(target);
99
100 if (mcpu == nullptr) {
101 target->llvm_cpu_name = ZigLLVMGetHostCPUName();
102 target->llvm_cpu_features = ZigLLVMGetNativeFeatures();
103 target->builtin_str = "Target.Cpu.baseline(arch);\n";
104 target->cache_hash = "native\n\n";
105 } else if (strcmp(mcpu, "baseline") == 0) {
106 target->is_native = false;
107 target->llvm_cpu_name = "";
108 target->llvm_cpu_features = "";
109 target->builtin_str = "Target.Cpu.baseline(arch);\n";
110 target->cache_hash = "baseline\n\n";
111 } else {
112 const char *msg = "stage0 can't handle CPU/features in the target";
113 stage2_panic(msg, strlen(msg));
114 }
115 } else {
116 // first initialize all to zero
117 *target = {};
118
119 SplitIterator it = memSplit(str(zig_triple), str("-"));
120
121 Optional<Slice<uint8_t>> opt_archsub = SplitIterator_next(&it);
122 Optional<Slice<uint8_t>> opt_os = SplitIterator_next(&it);
123 Optional<Slice<uint8_t>> opt_abi = SplitIterator_next(&it);
124
125 if (!opt_archsub.is_some)
126 return ErrorMissingArchitecture;
127
128 if ((err = target_parse_arch(&target->arch, (char*)opt_archsub.value.ptr, opt_archsub.value.len))) {
129 return err;
130 }
131
132 if (!opt_os.is_some)
133 return ErrorMissingOperatingSystem;
134
135 if ((err = target_parse_os(&target->os, (char*)opt_os.value.ptr, opt_os.value.len))) {
136 return err;
137 }
138
139 if (opt_abi.is_some) {
140 if ((err = target_parse_abi(&target->abi, (char*)opt_abi.value.ptr, opt_abi.value.len))) {
141 return err;
142 }
143 } else {
144 target->abi = target_default_abi(target->arch, target->os);
145 }
146
147 if (mcpu != nullptr && strcmp(mcpu, "baseline") != 0) {
148 const char *msg = "stage0 can't handle CPU/features in the target";
149 stage2_panic(msg, strlen(msg));
150 }
151 target->builtin_str = "Target.Cpu.baseline(arch);\n";
152 target->cache_hash = "\n\n";
153 }
154
155 return ErrorNone;
156}
157
158int stage2_cmd_targets(const char *zig_triple) {
159 const char *msg = "stage0 called stage2_cmd_targets";
160 stage2_panic(msg, strlen(msg));
161}
162
163enum Error stage2_libc_parse(struct Stage2LibCInstallation *libc, const char *libc_file) {
164 libc->include_dir = "/dummy/include";
165 libc->include_dir_len = strlen(libc->include_dir);
166 libc->sys_include_dir = "/dummy/sys/include";
167 libc->sys_include_dir_len = strlen(libc->sys_include_dir);
168 libc->crt_dir = "";
169 libc->crt_dir_len = strlen(libc->crt_dir);
170 libc->static_crt_dir = "";
171 libc->static_crt_dir_len = strlen(libc->static_crt_dir);
172 libc->msvc_lib_dir = "";
173 libc->msvc_lib_dir_len = strlen(libc->msvc_lib_dir);
174 libc->kernel32_lib_dir = "";
175 libc->kernel32_lib_dir_len = strlen(libc->kernel32_lib_dir);
176 return ErrorNone;
177}
178
179enum Error stage2_libc_render(struct Stage2LibCInstallation *self, FILE *file) {
180 const char *msg = "stage0 called stage2_libc_render";
181 stage2_panic(msg, strlen(msg));
182}
183
184enum Error stage2_libc_find_native(struct Stage2LibCInstallation *libc) {
185 const char *msg = "stage0 called stage2_libc_find_native";
186 stage2_panic(msg, strlen(msg));
187}
188
189enum Error stage2_detect_dynamic_linker(const struct ZigTarget *target, char **out_ptr, size_t *out_len) {
190 const char *msg = "stage0 called stage2_detect_dynamic_linker";
191 stage2_panic(msg, strlen(msg));
192}
193
194enum Error stage2_detect_native_paths(struct Stage2NativePaths *native_paths) {
195 native_paths->include_dirs_ptr = nullptr;
196 native_paths->include_dirs_len = 0;
197
198 native_paths->lib_dirs_ptr = nullptr;
199 native_paths->lib_dirs_len = 0;
200
201 native_paths->rpaths_ptr = nullptr;
202 native_paths->rpaths_len = 0;
203
204 native_paths->warnings_ptr = nullptr;
205 native_paths->warnings_len = 0;
206
207 return ErrorNone;
208}
src/stage2.h created+319
...@@ -0,0 +1,319 @@
1/*
2 * Copyright (c) 2019 Andrew Kelley
3 *
4 * This file is part of zig, which is MIT licensed.
5 * See http://opensource.org/licenses/MIT
6 */
7
8#ifndef ZIG_STAGE2_H
9#define ZIG_STAGE2_H
10
11#include <stddef.h>
12#include <stdint.h>
13#include <stdio.h>
14
15#include "zig_llvm.h"
16
17#ifdef __cplusplus
18#define ZIG_EXTERN_C extern "C"
19#else
20#define ZIG_EXTERN_C
21#endif
22
23#if defined(_MSC_VER)
24#define ZIG_ATTRIBUTE_NORETURN __declspec(noreturn)
25#else
26#define ZIG_ATTRIBUTE_NORETURN __attribute__((noreturn))
27#endif
28
29// ABI warning: the types and declarations in this file must match both those in
30// stage2.cpp and src-self-hosted/stage2.zig.
31
32// ABI warning
33enum Error {
34 ErrorNone,
35 ErrorNoMem,
36 ErrorInvalidFormat,
37 ErrorSemanticAnalyzeFail,
38 ErrorAccess,
39 ErrorInterrupted,
40 ErrorSystemResources,
41 ErrorFileNotFound,
42 ErrorFileSystem,
43 ErrorFileTooBig,
44 ErrorDivByZero,
45 ErrorOverflow,
46 ErrorPathAlreadyExists,
47 ErrorUnexpected,
48 ErrorExactDivRemainder,
49 ErrorNegativeDenominator,
50 ErrorShiftedOutOneBits,
51 ErrorCCompileErrors,
52 ErrorEndOfFile,
53 ErrorIsDir,
54 ErrorNotDir,
55 ErrorUnsupportedOperatingSystem,
56 ErrorSharingViolation,
57 ErrorPipeBusy,
58 ErrorPrimitiveTypeNotFound,
59 ErrorCacheUnavailable,
60 ErrorPathTooLong,
61 ErrorCCompilerCannotFindFile,
62 ErrorNoCCompilerInstalled,
63 ErrorReadingDepFile,
64 ErrorInvalidDepFile,
65 ErrorMissingArchitecture,
66 ErrorMissingOperatingSystem,
67 ErrorUnknownArchitecture,
68 ErrorUnknownOperatingSystem,
69 ErrorUnknownABI,
70 ErrorInvalidFilename,
71 ErrorDiskQuota,
72 ErrorDiskSpace,
73 ErrorUnexpectedWriteFailure,
74 ErrorUnexpectedSeekFailure,
75 ErrorUnexpectedFileTruncationFailure,
76 ErrorUnimplemented,
77 ErrorOperationAborted,
78 ErrorBrokenPipe,
79 ErrorNoSpaceLeft,
80 ErrorNotLazy,
81 ErrorIsAsync,
82 ErrorImportOutsidePkgPath,
83 ErrorUnknownCpu,
84 ErrorUnknownCpuFeature,
85 ErrorInvalidCpuFeatures,
86 ErrorInvalidLlvmCpuFeaturesFormat,
87 ErrorUnknownApplicationBinaryInterface,
88 ErrorASTUnitFailure,
89 ErrorBadPathName,
90 ErrorSymLinkLoop,
91 ErrorProcessFdQuotaExceeded,
92 ErrorSystemFdQuotaExceeded,
93 ErrorNoDevice,
94 ErrorDeviceBusy,
95 ErrorUnableToSpawnCCompiler,
96 ErrorCCompilerExitCode,
97 ErrorCCompilerCrashed,
98 ErrorCCompilerCannotFindHeaders,
99 ErrorLibCRuntimeNotFound,
100 ErrorLibCStdLibHeaderNotFound,
101 ErrorLibCKernel32LibNotFound,
102 ErrorUnsupportedArchitecture,
103 ErrorWindowsSdkNotFound,
104 ErrorUnknownDynamicLinkerPath,
105 ErrorTargetHasNoDynamicLinker,
106};
107
108// ABI warning
109struct Stage2ErrorMsg {
110 const char *filename_ptr; // can be null
111 size_t filename_len;
112 const char *msg_ptr;
113 size_t msg_len;
114 const char *source; // valid until the ASTUnit is freed. can be null
115 unsigned line; // 0 based
116 unsigned column; // 0 based
117 unsigned offset; // byte offset into source
118};
119
120// ABI warning
121struct Stage2Ast;
122
123// ABI warning
124ZIG_EXTERN_C enum Error stage2_translate_c(struct Stage2Ast **out_ast,
125 struct Stage2ErrorMsg **out_errors_ptr, size_t *out_errors_len,
126 const char **args_begin, const char **args_end, const char *resources_path);
127
128// ABI warning
129ZIG_EXTERN_C void stage2_free_clang_errors(struct Stage2ErrorMsg *ptr, size_t len);
130
131// ABI warning
132ZIG_EXTERN_C void stage2_render_ast(struct Stage2Ast *ast, FILE *output_file);
133
134// ABI warning
135ZIG_EXTERN_C void stage2_zen(const char **ptr, size_t *len);
136
137// ABI warning
138ZIG_EXTERN_C void stage2_attach_segfault_handler(void);
139
140// ABI warning
141ZIG_EXTERN_C ZIG_ATTRIBUTE_NORETURN void stage2_panic(const char *ptr, size_t len);
142
143// ABI warning
144ZIG_EXTERN_C int stage2_fmt(int argc, char **argv);
145
146// ABI warning
147struct stage2_DepTokenizer {
148 void *handle;
149};
150
151// ABI warning
152struct stage2_DepNextResult {
153 enum TypeId {
154 error,
155 null,
156 target,
157 prereq,
158 };
159
160 TypeId type_id;
161
162 // when ent == error --> error text
163 // when ent == null --> undefined
164 // when ent == target --> target pathname
165 // when ent == prereq --> prereq pathname
166 const char *textz;
167};
168
169// ABI warning
170ZIG_EXTERN_C stage2_DepTokenizer stage2_DepTokenizer_init(const char *input, size_t len);
171
172// ABI warning
173ZIG_EXTERN_C void stage2_DepTokenizer_deinit(stage2_DepTokenizer *self);
174
175// ABI warning
176ZIG_EXTERN_C stage2_DepNextResult stage2_DepTokenizer_next(stage2_DepTokenizer *self);
177
178// ABI warning
179struct Stage2Progress;
180// ABI warning
181struct Stage2ProgressNode;
182// ABI warning
183ZIG_EXTERN_C Stage2Progress *stage2_progress_create(void);
184// ABI warning
185ZIG_EXTERN_C void stage2_progress_disable_tty(Stage2Progress *progress);
186// ABI warning
187ZIG_EXTERN_C void stage2_progress_destroy(Stage2Progress *progress);
188// ABI warning
189ZIG_EXTERN_C Stage2ProgressNode *stage2_progress_start_root(Stage2Progress *progress,
190 const char *name_ptr, size_t name_len, size_t estimated_total_items);
191// ABI warning
192ZIG_EXTERN_C Stage2ProgressNode *stage2_progress_start(Stage2ProgressNode *node,
193 const char *name_ptr, size_t name_len, size_t estimated_total_items);
194// ABI warning
195ZIG_EXTERN_C void stage2_progress_end(Stage2ProgressNode *node);
196// ABI warning
197ZIG_EXTERN_C void stage2_progress_complete_one(Stage2ProgressNode *node);
198// ABI warning
199ZIG_EXTERN_C void stage2_progress_update_node(Stage2ProgressNode *node,
200 size_t completed_count, size_t estimated_total_items);
201
202// ABI warning
203ZIG_EXTERN_C int stage2_cmd_targets(const char *zig_triple);
204
205// ABI warning
206struct Stage2LibCInstallation {
207 const char *include_dir;
208 size_t include_dir_len;
209 const char *sys_include_dir;
210 size_t sys_include_dir_len;
211 const char *crt_dir;
212 size_t crt_dir_len;
213 const char *static_crt_dir;
214 size_t static_crt_dir_len;
215 const char *msvc_lib_dir;
216 size_t msvc_lib_dir_len;
217 const char *kernel32_lib_dir;
218 size_t kernel32_lib_dir_len;
219};
220
221// ABI warning
222ZIG_EXTERN_C enum Error stage2_libc_parse(struct Stage2LibCInstallation *libc, const char *libc_file);
223// ABI warning
224ZIG_EXTERN_C enum Error stage2_libc_render(struct Stage2LibCInstallation *self, FILE *file);
225// ABI warning
226ZIG_EXTERN_C enum Error stage2_libc_find_native(struct Stage2LibCInstallation *libc);
227
228// ABI warning
229// Synchronize with target.cpp::os_list
230enum Os {
231 OsFreestanding,
232 OsAnanas,
233 OsCloudABI,
234 OsDragonFly,
235 OsFreeBSD,
236 OsFuchsia,
237 OsIOS,
238 OsKFreeBSD,
239 OsLinux,
240 OsLv2, // PS3
241 OsMacOSX,
242 OsNetBSD,
243 OsOpenBSD,
244 OsSolaris,
245 OsWindows,
246 OsHaiku,
247 OsMinix,
248 OsRTEMS,
249 OsNaCl, // Native Client
250 OsCNK, // BG/P Compute-Node Kernel
251 OsAIX,
252 OsCUDA, // NVIDIA CUDA
253 OsNVCL, // NVIDIA OpenCL
254 OsAMDHSA, // AMD HSA Runtime
255 OsPS4,
256 OsELFIAMCU,
257 OsTvOS, // Apple tvOS
258 OsWatchOS, // Apple watchOS
259 OsMesa3D,
260 OsContiki,
261 OsAMDPAL,
262 OsHermitCore,
263 OsHurd,
264 OsWASI,
265 OsEmscripten,
266 OsUefi,
267 OsOther,
268};
269
270// ABI warning
271struct ZigGLibCVersion {
272 uint32_t major; // always 2
273 uint32_t minor;
274 uint32_t patch;
275};
276
277struct Stage2TargetData;
278
279// ABI warning
280struct ZigTarget {
281 enum ZigLLVM_ArchType arch;
282 enum ZigLLVM_VendorType vendor;
283
284 enum ZigLLVM_EnvironmentType abi;
285 Os os;
286
287 bool is_native;
288
289 struct ZigGLibCVersion *glibc_version; // null means default
290
291 const char *llvm_cpu_name;
292 const char *llvm_cpu_features;
293 const char *builtin_str;
294 const char *cache_hash;
295};
296
297// ABI warning
298ZIG_EXTERN_C enum Error stage2_detect_dynamic_linker(const struct ZigTarget *target,
299 char **out_ptr, size_t *out_len);
300
301// ABI warning
302ZIG_EXTERN_C enum Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, const char *mcpu);
303
304
305// ABI warning
306struct Stage2NativePaths {
307 const char **include_dirs_ptr;
308 size_t include_dirs_len;
309 const char **lib_dirs_ptr;
310 size_t lib_dirs_len;
311 const char **rpaths_ptr;
312 size_t rpaths_len;
313 const char **warnings_ptr;
314 size_t warnings_len;
315};
316// ABI warning
317ZIG_EXTERN_C enum Error stage2_detect_native_paths(struct Stage2NativePaths *native_paths);
318
319#endif
src/target.cpp+9-533
...@@ -15,65 +15,6 @@...@@ -15,65 +15,6 @@
1515
16#include <stdio.h>16#include <stdio.h>
1717
18static const SubArchList subarch_list_list[] = {
19 SubArchListNone,
20 SubArchListArm32,
21 SubArchListArm64,
22 SubArchListKalimba,
23 SubArchListMips,
24 SubArchListPPC,
25};
26
27static const ZigLLVM_SubArchType subarch_list_arm32[] = {
28 ZigLLVM_ARMSubArch_v8_5a,
29 ZigLLVM_ARMSubArch_v8_4a,
30 ZigLLVM_ARMSubArch_v8_3a,
31 ZigLLVM_ARMSubArch_v8_2a,
32 ZigLLVM_ARMSubArch_v8_1a,
33 ZigLLVM_ARMSubArch_v8,
34 ZigLLVM_ARMSubArch_v8r,
35 ZigLLVM_ARMSubArch_v8m_baseline,
36 ZigLLVM_ARMSubArch_v8m_mainline,
37 ZigLLVM_ARMSubArch_v8_1m_mainline,
38 ZigLLVM_ARMSubArch_v7,
39 ZigLLVM_ARMSubArch_v7em,
40 ZigLLVM_ARMSubArch_v7m,
41 ZigLLVM_ARMSubArch_v7s,
42 ZigLLVM_ARMSubArch_v7k,
43 ZigLLVM_ARMSubArch_v7ve,
44 ZigLLVM_ARMSubArch_v6,
45 ZigLLVM_ARMSubArch_v6m,
46 ZigLLVM_ARMSubArch_v6k,
47 ZigLLVM_ARMSubArch_v6t2,
48 ZigLLVM_ARMSubArch_v5,
49 ZigLLVM_ARMSubArch_v5te,
50 ZigLLVM_ARMSubArch_v4t,
51
52};
53
54static const ZigLLVM_SubArchType subarch_list_arm64[] = {
55 ZigLLVM_ARMSubArch_v8_5a,
56 ZigLLVM_ARMSubArch_v8_4a,
57 ZigLLVM_ARMSubArch_v8_3a,
58 ZigLLVM_ARMSubArch_v8_2a,
59 ZigLLVM_ARMSubArch_v8_1a,
60 ZigLLVM_ARMSubArch_v8,
61};
62
63static const ZigLLVM_SubArchType subarch_list_kalimba[] = {
64 ZigLLVM_KalimbaSubArch_v5,
65 ZigLLVM_KalimbaSubArch_v4,
66 ZigLLVM_KalimbaSubArch_v3,
67};
68
69static const ZigLLVM_SubArchType subarch_list_mips[] = {
70 ZigLLVM_MipsSubArch_r6,
71};
72
73static const ZigLLVM_SubArchType subarch_list_ppc[] = {
74 ZigLLVM_PPCSubArch_spe,
75};
76
77static const ZigLLVM_ArchType arch_list[] = {18static const ZigLLVM_ArchType arch_list[] = {
78 ZigLLVM_arm, // ARM (little endian): arm, armv.*, xscale19 ZigLLVM_arm, // ARM (little endian): arm, armv.*, xscale
79 ZigLLVM_armeb, // ARM (big endian): armeb20 ZigLLVM_armeb, // ARM (big endian): armeb
...@@ -513,7 +454,6 @@ void get_native_target(ZigTarget *target) {...@@ -513,7 +454,6 @@ void get_native_target(ZigTarget *target) {
513 ZigLLVM_ObjectFormatType oformat; // ignored; based on arch/os454 ZigLLVM_ObjectFormatType oformat; // ignored; based on arch/os
514 ZigLLVMGetNativeTarget(455 ZigLLVMGetNativeTarget(
515 &target->arch,456 &target->arch,
516 &target->sub_arch,
517 &target->vendor,457 &target->vendor,
518 &os_type,458 &os_type,
519 &target->abi,459 &target->abi,
...@@ -526,12 +466,6 @@ void get_native_target(ZigTarget *target) {...@@ -526,12 +466,6 @@ void get_native_target(ZigTarget *target) {
526 if (target_is_glibc(target)) {466 if (target_is_glibc(target)) {
527 target->glibc_version = heap::c_allocator.create<ZigGLibCVersion>();467 target->glibc_version = heap::c_allocator.create<ZigGLibCVersion>();
528 target_init_default_glibc_version(target);468 target_init_default_glibc_version(target);
529#ifdef ZIG_OS_LINUX
530 Error err;
531 if ((err = glibc_detect_native_version(target->glibc_version))) {
532 // Fall back to the default version.
533 }
534#endif
535 }469 }
536}470}
537471
...@@ -539,233 +473,18 @@ void target_init_default_glibc_version(ZigTarget *target) {...@@ -539,233 +473,18 @@ void target_init_default_glibc_version(ZigTarget *target) {
539 *target->glibc_version = {2, 17, 0};473 *target->glibc_version = {2, 17, 0};
540}474}
541475
542Error target_parse_archsub(ZigLLVM_ArchType *out_arch, ZigLLVM_SubArchType *out_sub,476Error target_parse_arch(ZigLLVM_ArchType *out_arch, const char *arch_ptr, size_t arch_len) {
543 const char *archsub_ptr, size_t archsub_len)
544{
545 *out_arch = ZigLLVM_UnknownArch;477 *out_arch = ZigLLVM_UnknownArch;
546 *out_sub = ZigLLVM_NoSubArch;
547 for (size_t arch_i = 0; arch_i < array_length(arch_list); arch_i += 1) {478 for (size_t arch_i = 0; arch_i < array_length(arch_list); arch_i += 1) {
548 ZigLLVM_ArchType arch = arch_list[arch_i];479 ZigLLVM_ArchType arch = arch_list[arch_i];
549 SubArchList sub_arch_list = target_subarch_list(arch);480 if (mem_eql_str(arch_ptr, arch_len, target_arch_name(arch))) {
550 size_t subarch_count = target_subarch_count(sub_arch_list);
551 if (mem_eql_str(archsub_ptr, archsub_len, target_arch_name(arch))) {
552 *out_arch = arch;481 *out_arch = arch;
553 if (subarch_count == 0) {482 return ErrorNone;
554 return ErrorNone;
555 }
556 }
557 for (size_t sub_i = 0; sub_i < subarch_count; sub_i += 1) {
558 ZigLLVM_SubArchType sub = target_subarch_enum(sub_arch_list, sub_i);
559 char arch_name[64];
560 int n = sprintf(arch_name, "%s%s", target_arch_name(arch), target_subarch_name(sub));
561 if (mem_eql_mem(arch_name, n, archsub_ptr, archsub_len)) {
562 *out_arch = arch;
563 *out_sub = sub;
564 return ErrorNone;
565 }
566 }483 }
567 }484 }
568 return ErrorUnknownArchitecture;485 return ErrorUnknownArchitecture;
569}486}
570487
571SubArchList target_subarch_list(ZigLLVM_ArchType arch) {
572 switch (arch) {
573 case ZigLLVM_UnknownArch:
574 zig_unreachable();
575 case ZigLLVM_arm:
576 case ZigLLVM_armeb:
577 case ZigLLVM_thumb:
578 case ZigLLVM_thumbeb:
579 return SubArchListArm32;
580
581 case ZigLLVM_aarch64:
582 case ZigLLVM_aarch64_be:
583 case ZigLLVM_aarch64_32:
584 return SubArchListArm64;
585
586 case ZigLLVM_kalimba:
587 return SubArchListKalimba;
588
589 case ZigLLVM_arc:
590 case ZigLLVM_avr:
591 case ZigLLVM_bpfel:
592 case ZigLLVM_bpfeb:
593 case ZigLLVM_hexagon:
594 case ZigLLVM_mips:
595 case ZigLLVM_mipsel:
596 case ZigLLVM_mips64:
597 case ZigLLVM_mips64el:
598 case ZigLLVM_msp430:
599 case ZigLLVM_ppc:
600 case ZigLLVM_ppc64:
601 case ZigLLVM_ppc64le:
602 case ZigLLVM_r600:
603 case ZigLLVM_amdgcn:
604 case ZigLLVM_riscv32:
605 case ZigLLVM_riscv64:
606 case ZigLLVM_sparc:
607 case ZigLLVM_sparcv9:
608 case ZigLLVM_sparcel:
609 case ZigLLVM_systemz:
610 case ZigLLVM_tce:
611 case ZigLLVM_tcele:
612 case ZigLLVM_x86:
613 case ZigLLVM_x86_64:
614 case ZigLLVM_xcore:
615 case ZigLLVM_nvptx:
616 case ZigLLVM_nvptx64:
617 case ZigLLVM_le32:
618 case ZigLLVM_le64:
619 case ZigLLVM_amdil:
620 case ZigLLVM_amdil64:
621 case ZigLLVM_hsail:
622 case ZigLLVM_hsail64:
623 case ZigLLVM_spir:
624 case ZigLLVM_spir64:
625 case ZigLLVM_shave:
626 case ZigLLVM_lanai:
627 case ZigLLVM_wasm32:
628 case ZigLLVM_wasm64:
629 case ZigLLVM_renderscript32:
630 case ZigLLVM_renderscript64:
631 case ZigLLVM_ve:
632 return SubArchListNone;
633 }
634 zig_unreachable();
635}
636
637size_t target_subarch_count(SubArchList sub_arch_list) {
638 switch (sub_arch_list) {
639 case SubArchListNone:
640 return 0;
641 case SubArchListArm32:
642 return array_length(subarch_list_arm32);
643 case SubArchListArm64:
644 return array_length(subarch_list_arm64);
645 case SubArchListKalimba:
646 return array_length(subarch_list_kalimba);
647 case SubArchListMips:
648 return array_length(subarch_list_mips);
649 case SubArchListPPC:
650 return array_length(subarch_list_ppc);
651 }
652 zig_unreachable();
653}
654
655ZigLLVM_SubArchType target_subarch_enum(SubArchList sub_arch_list, size_t i) {
656 switch (sub_arch_list) {
657 case SubArchListNone:
658 zig_unreachable();
659 case SubArchListArm32:
660 assert(i < array_length(subarch_list_arm32));
661 return subarch_list_arm32[i];
662 case SubArchListArm64:
663 assert(i < array_length(subarch_list_arm64));
664 return subarch_list_arm64[i];
665 case SubArchListKalimba:
666 assert(i < array_length(subarch_list_kalimba));
667 return subarch_list_kalimba[i];
668 case SubArchListMips:
669 assert(i < array_length(subarch_list_mips));
670 return subarch_list_mips[i];
671 case SubArchListPPC:
672 assert(i < array_length(subarch_list_ppc));
673 return subarch_list_ppc[i];
674 }
675 zig_unreachable();
676}
677
678const char *target_subarch_name(ZigLLVM_SubArchType subarch) {
679 switch (subarch) {
680 case ZigLLVM_NoSubArch:
681 return "";
682 case ZigLLVM_ARMSubArch_v8_5a:
683 return "v8_5a";
684 case ZigLLVM_ARMSubArch_v8_4a:
685 return "v8_4a";
686 case ZigLLVM_ARMSubArch_v8_3a:
687 return "v8_3a";
688 case ZigLLVM_ARMSubArch_v8_2a:
689 return "v8_2a";
690 case ZigLLVM_ARMSubArch_v8_1a:
691 return "v8_1a";
692 case ZigLLVM_ARMSubArch_v8:
693 return "v8a";
694 case ZigLLVM_ARMSubArch_v8r:
695 return "v8r";
696 case ZigLLVM_ARMSubArch_v8m_baseline:
697 return "v8m_baseline";
698 case ZigLLVM_ARMSubArch_v8m_mainline:
699 return "v8m_mainline";
700 case ZigLLVM_ARMSubArch_v8_1m_mainline:
701 return "v8_1m_mainline";
702 case ZigLLVM_ARMSubArch_v7:
703 return "v7a";
704 case ZigLLVM_ARMSubArch_v7em:
705 return "v7em";
706 case ZigLLVM_ARMSubArch_v7m:
707 return "v7m";
708 case ZigLLVM_ARMSubArch_v7s:
709 return "v7s";
710 case ZigLLVM_ARMSubArch_v7k:
711 return "v7k";
712 case ZigLLVM_ARMSubArch_v7ve:
713 return "v7ve";
714 case ZigLLVM_ARMSubArch_v6:
715 return "v6";
716 case ZigLLVM_ARMSubArch_v6m:
717 return "v6m";
718 case ZigLLVM_ARMSubArch_v6k:
719 return "v6k";
720 case ZigLLVM_ARMSubArch_v6t2:
721 return "v6t2";
722 case ZigLLVM_ARMSubArch_v5:
723 return "v5";
724 case ZigLLVM_ARMSubArch_v5te:
725 return "v5te";
726 case ZigLLVM_ARMSubArch_v4t:
727 return "v4t";
728 case ZigLLVM_KalimbaSubArch_v3:
729 return "v3";
730 case ZigLLVM_KalimbaSubArch_v4:
731 return "v4";
732 case ZigLLVM_KalimbaSubArch_v5:
733 return "v5";
734 case ZigLLVM_MipsSubArch_r6:
735 return "r6";
736 case ZigLLVM_PPCSubArch_spe:
737 return "spe";
738 }
739 zig_unreachable();
740}
741
742size_t target_subarch_list_count(void) {
743 return array_length(subarch_list_list);
744}
745
746SubArchList target_subarch_list_enum(size_t index) {
747 assert(index < array_length(subarch_list_list));
748 return subarch_list_list[index];
749}
750
751const char *target_subarch_list_name(SubArchList sub_arch_list) {
752 switch (sub_arch_list) {
753 case SubArchListNone:
754 return "None";
755 case SubArchListArm32:
756 return "Arm32";
757 case SubArchListArm64:
758 return "Arm64";
759 case SubArchListKalimba:
760 return "Kalimba";
761 case SubArchListMips:
762 return "Mips";
763 case SubArchListPPC:
764 return "PPC";
765 }
766 zig_unreachable();
767}
768
769Error target_parse_os(Os *out_os, const char *os_ptr, size_t os_len) {488Error target_parse_os(Os *out_os, const char *os_ptr, size_t os_len) {
770 for (size_t i = 0; i < array_length(os_list); i += 1) {489 for (size_t i = 0; i < array_length(os_list); i += 1) {
771 Os os = os_list[i];490 Os os = os_list[i];
...@@ -790,42 +509,8 @@ Error target_parse_abi(ZigLLVM_EnvironmentType *out_abi, const char *abi_ptr, si...@@ -790,42 +509,8 @@ Error target_parse_abi(ZigLLVM_EnvironmentType *out_abi, const char *abi_ptr, si
790 return ErrorUnknownABI;509 return ErrorUnknownABI;
791}510}
792511
793Error target_parse_triple(ZigTarget *target, const char *triple) {512Error target_parse_triple(ZigTarget *target, const char *triple, const char *mcpu) {
794 Error err;513 return stage2_target_parse(target, triple, mcpu);
795
796 // first initialize all to zero
797 *target = {};
798
799 SplitIterator it = memSplit(str(triple), str("-"));
800
801 Optional<Slice<uint8_t>> opt_archsub = SplitIterator_next(&it);
802 Optional<Slice<uint8_t>> opt_os = SplitIterator_next(&it);
803 Optional<Slice<uint8_t>> opt_abi = SplitIterator_next(&it);
804
805 if (!opt_archsub.is_some)
806 return ErrorMissingArchitecture;
807
808 if ((err = target_parse_archsub(&target->arch, &target->sub_arch,
809 (char*)opt_archsub.value.ptr, opt_archsub.value.len)))
810 {
811 return err;
812 }
813
814 if (!opt_os.is_some)
815 return ErrorMissingOperatingSystem;
816
817 if ((err = target_parse_os(&target->os, (char*)opt_os.value.ptr, opt_os.value.len))) {
818 return err;
819 }
820
821 if (opt_abi.is_some) {
822 if ((err = target_parse_abi(&target->abi, (char*)opt_abi.value.ptr, opt_abi.value.len))) {
823 return err;
824 }
825 } else {
826 target->abi = target_default_abi(target->arch, target->os);
827 }
828 return ErrorNone;
829}514}
830515
831const char *target_arch_name(ZigLLVM_ArchType arch) {516const char *target_arch_name(ZigLLVM_ArchType arch) {
...@@ -842,18 +527,16 @@ void init_all_targets(void) {...@@ -842,18 +527,16 @@ void init_all_targets(void) {
842527
843void target_triple_zig(Buf *triple, const ZigTarget *target) {528void target_triple_zig(Buf *triple, const ZigTarget *target) {
844 buf_resize(triple, 0);529 buf_resize(triple, 0);
845 buf_appendf(triple, "%s%s-%s-%s",530 buf_appendf(triple, "%s-%s-%s",
846 target_arch_name(target->arch),531 target_arch_name(target->arch),
847 target_subarch_name(target->sub_arch),
848 target_os_name(target->os),532 target_os_name(target->os),
849 target_abi_name(target->abi));533 target_abi_name(target->abi));
850}534}
851535
852void target_triple_llvm(Buf *triple, const ZigTarget *target) {536void target_triple_llvm(Buf *triple, const ZigTarget *target) {
853 buf_resize(triple, 0);537 buf_resize(triple, 0);
854 buf_appendf(triple, "%s%s-%s-%s-%s",538 buf_appendf(triple, "%s-%s-%s-%s",
855 ZigLLVMGetArchTypeName(target->arch),539 ZigLLVMGetArchTypeName(target->arch),
856 ZigLLVMGetSubArchTypeName(target->sub_arch),
857 ZigLLVMGetVendorTypeName(target->vendor),540 ZigLLVMGetVendorTypeName(target->vendor),
858 ZigLLVMGetOSTypeName(get_llvm_os_type(target->os)),541 ZigLLVMGetOSTypeName(get_llvm_os_type(target->os)),
859 ZigLLVMGetEnvironmentTypeName(target->abi));542 ZigLLVMGetEnvironmentTypeName(target->abi));
...@@ -1220,214 +903,10 @@ const char *target_lib_file_ext(const ZigTarget *target, bool is_static,...@@ -1220,214 +903,10 @@ const char *target_lib_file_ext(const ZigTarget *target, bool is_static,
1220 }903 }
1221}904}
1222905
1223enum FloatAbi {
1224 FloatAbiHard,
1225 FloatAbiSoft,
1226 FloatAbiSoftFp,
1227};
1228
1229static FloatAbi get_float_abi(const ZigTarget *target) {
1230 const ZigLLVM_EnvironmentType env = target->abi;
1231 if (env == ZigLLVM_GNUEABIHF ||
1232 env == ZigLLVM_EABIHF ||
1233 env == ZigLLVM_MuslEABIHF)
1234 {
1235 return FloatAbiHard;
1236 } else {
1237 return FloatAbiSoft;
1238 }
1239}
1240
1241static bool is_64_bit(ZigLLVM_ArchType arch) {
1242 return target_arch_pointer_bit_width(arch) == 64;
1243}
1244
1245bool target_is_android(const ZigTarget *target) {906bool target_is_android(const ZigTarget *target) {
1246 return target->abi == ZigLLVM_Android;907 return target->abi == ZigLLVM_Android;
1247}908}
1248909
1249const char *target_dynamic_linker(const ZigTarget *target) {
1250 if (target_is_android(target)) {
1251 return is_64_bit(target->arch) ? "/system/bin/linker64" : "/system/bin/linker";
1252 }
1253
1254 if (target_is_musl(target)) {
1255 Buf buf = BUF_INIT;
1256 buf_init_from_str(&buf, "/lib/ld-musl-");
1257 bool is_arm = false;
1258 switch (target->arch) {
1259 case ZigLLVM_arm:
1260 case ZigLLVM_thumb:
1261 buf_append_str(&buf, "arm");
1262 is_arm = true;
1263 break;
1264 case ZigLLVM_armeb:
1265 case ZigLLVM_thumbeb:
1266 buf_append_str(&buf, "armeb");
1267 is_arm = true;
1268 break;
1269 default:
1270 buf_append_str(&buf, target_arch_name(target->arch));
1271 }
1272 if (is_arm && get_float_abi(target) == FloatAbiHard) {
1273 buf_append_str(&buf, "hf");
1274 }
1275 buf_append_str(&buf, ".so.1");
1276 return buf_ptr(&buf);
1277 }
1278
1279 switch (target->os) {
1280 case OsFreeBSD:
1281 return "/libexec/ld-elf.so.1";
1282 case OsNetBSD:
1283 return "/libexec/ld.elf_so";
1284 case OsDragonFly:
1285 return "/libexec/ld-elf.so.2";
1286 case OsLinux: {
1287 const ZigLLVM_EnvironmentType abi = target->abi;
1288 switch (target->arch) {
1289 case ZigLLVM_UnknownArch:
1290 zig_unreachable();
1291 case ZigLLVM_x86:
1292 case ZigLLVM_sparc:
1293 case ZigLLVM_sparcel:
1294 return "/lib/ld-linux.so.2";
1295
1296 case ZigLLVM_aarch64:
1297 return "/lib/ld-linux-aarch64.so.1";
1298
1299 case ZigLLVM_aarch64_be:
1300 return "/lib/ld-linux-aarch64_be.so.1";
1301
1302 case ZigLLVM_aarch64_32:
1303 return "/lib/ld-linux-aarch64_32.so.1";
1304
1305 case ZigLLVM_arm:
1306 case ZigLLVM_thumb:
1307 if (get_float_abi(target) == FloatAbiHard) {
1308 return "/lib/ld-linux-armhf.so.3";
1309 } else {
1310 return "/lib/ld-linux.so.3";
1311 }
1312
1313 case ZigLLVM_armeb:
1314 case ZigLLVM_thumbeb:
1315 if (get_float_abi(target) == FloatAbiHard) {
1316 return "/lib/ld-linux-armhf.so.3";
1317 } else {
1318 return "/lib/ld-linux.so.3";
1319 }
1320
1321 case ZigLLVM_mips:
1322 case ZigLLVM_mipsel:
1323 case ZigLLVM_mips64:
1324 case ZigLLVM_mips64el:
1325 zig_panic("TODO implement target_dynamic_linker for mips");
1326
1327 case ZigLLVM_ppc:
1328 return "/lib/ld.so.1";
1329
1330 case ZigLLVM_ppc64:
1331 return "/lib64/ld64.so.2";
1332
1333 case ZigLLVM_ppc64le:
1334 return "/lib64/ld64.so.2";
1335
1336 case ZigLLVM_systemz:
1337 return "/lib64/ld64.so.1";
1338
1339 case ZigLLVM_sparcv9:
1340 return "/lib64/ld-linux.so.2";
1341
1342 case ZigLLVM_x86_64:
1343 if (abi == ZigLLVM_GNUX32) {
1344 return "/libx32/ld-linux-x32.so.2";
1345 }
1346 if (abi == ZigLLVM_Musl || abi == ZigLLVM_MuslEABI || abi == ZigLLVM_MuslEABIHF) {
1347 return "/lib/ld-musl-x86_64.so.1";
1348 }
1349 return "/lib64/ld-linux-x86-64.so.2";
1350
1351 case ZigLLVM_wasm32:
1352 case ZigLLVM_wasm64:
1353 return nullptr;
1354
1355 case ZigLLVM_riscv32:
1356 return "/lib/ld-linux-riscv32-ilp32.so.1";
1357 case ZigLLVM_riscv64:
1358 return "/lib/ld-linux-riscv64-lp64.so.1";
1359
1360 case ZigLLVM_arc:
1361 case ZigLLVM_avr:
1362 case ZigLLVM_bpfel:
1363 case ZigLLVM_bpfeb:
1364 case ZigLLVM_hexagon:
1365 case ZigLLVM_msp430:
1366 case ZigLLVM_r600:
1367 case ZigLLVM_amdgcn:
1368 case ZigLLVM_tce:
1369 case ZigLLVM_tcele:
1370 case ZigLLVM_xcore:
1371 case ZigLLVM_nvptx:
1372 case ZigLLVM_nvptx64:
1373 case ZigLLVM_le32:
1374 case ZigLLVM_le64:
1375 case ZigLLVM_amdil:
1376 case ZigLLVM_amdil64:
1377 case ZigLLVM_hsail:
1378 case ZigLLVM_hsail64:
1379 case ZigLLVM_spir:
1380 case ZigLLVM_spir64:
1381 case ZigLLVM_kalimba:
1382 case ZigLLVM_shave:
1383 case ZigLLVM_lanai:
1384 case ZigLLVM_renderscript32:
1385 case ZigLLVM_renderscript64:
1386 case ZigLLVM_ve:
1387 zig_panic("TODO implement target_dynamic_linker for this arch");
1388 }
1389 zig_unreachable();
1390 }
1391 case OsFreestanding:
1392 case OsIOS:
1393 case OsTvOS:
1394 case OsWatchOS:
1395 case OsMacOSX:
1396 case OsUefi:
1397 case OsWindows:
1398 case OsEmscripten:
1399 case OsOther:
1400 return nullptr;
1401
1402 case OsAnanas:
1403 case OsCloudABI:
1404 case OsFuchsia:
1405 case OsKFreeBSD:
1406 case OsLv2:
1407 case OsOpenBSD:
1408 case OsSolaris:
1409 case OsHaiku:
1410 case OsMinix:
1411 case OsRTEMS:
1412 case OsNaCl:
1413 case OsCNK:
1414 case OsAIX:
1415 case OsCUDA:
1416 case OsNVCL:
1417 case OsAMDHSA:
1418 case OsPS4:
1419 case OsELFIAMCU:
1420 case OsMesa3D:
1421 case OsContiki:
1422 case OsAMDPAL:
1423 case OsHermitCore:
1424 case OsHurd:
1425 case OsWASI:
1426 zig_panic("TODO implement target_dynamic_linker for this OS");
1427 }
1428 zig_unreachable();
1429}
1430
1431bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target) {910bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target) {
1432 assert(host_target != nullptr);911 assert(host_target != nullptr);
1433912
...@@ -1436,10 +915,8 @@ bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target...@@ -1436,10 +915,8 @@ bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target
1436 return true;915 return true;
1437 }916 }
1438917
1439 if (guest_target->os == host_target->os && guest_target->arch == host_target->arch &&918 if (guest_target->os == host_target->os && guest_target->arch == host_target->arch) {
1440 guest_target->sub_arch == host_target->sub_arch)919 // OS and arch match
1441 {
1442 // OS, arch, and sub-arch match
1443 return true;920 return true;
1444 }921 }
1445922
...@@ -1861,7 +1338,6 @@ void target_libc_enum(size_t index, ZigTarget *out_target) {...@@ -1861,7 +1338,6 @@ void target_libc_enum(size_t index, ZigTarget *out_target) {
1861 out_target->arch = libcs_available[index].arch;1338 out_target->arch = libcs_available[index].arch;
1862 out_target->os = libcs_available[index].os;1339 out_target->os = libcs_available[index].os;
1863 out_target->abi = libcs_available[index].abi;1340 out_target->abi = libcs_available[index].abi;
1864 out_target->sub_arch = ZigLLVM_NoSubArch;
1865 out_target->vendor = ZigLLVM_UnknownVendor;1341 out_target->vendor = ZigLLVM_UnknownVendor;
1866 out_target->is_native = false;1342 out_target->is_native = false;
1867}1343}
src/target.hpp+3-83
...@@ -8,61 +8,10 @@...@@ -8,61 +8,10 @@
8#ifndef ZIG_TARGET_HPP8#ifndef ZIG_TARGET_HPP
9#define ZIG_TARGET_HPP9#define ZIG_TARGET_HPP
1010
11#include <zig_llvm.h>11#include "stage2.h"
1212
13struct Buf;13struct Buf;
1414
15// Synchronize with target.cpp::os_list
16enum Os {
17 OsFreestanding,
18 OsAnanas,
19 OsCloudABI,
20 OsDragonFly,
21 OsFreeBSD,
22 OsFuchsia,
23 OsIOS,
24 OsKFreeBSD,
25 OsLinux,
26 OsLv2, // PS3
27 OsMacOSX,
28 OsNetBSD,
29 OsOpenBSD,
30 OsSolaris,
31 OsWindows,
32 OsHaiku,
33 OsMinix,
34 OsRTEMS,
35 OsNaCl, // Native Client
36 OsCNK, // BG/P Compute-Node Kernel
37 OsAIX,
38 OsCUDA, // NVIDIA CUDA
39 OsNVCL, // NVIDIA OpenCL
40 OsAMDHSA, // AMD HSA Runtime
41 OsPS4,
42 OsELFIAMCU,
43 OsTvOS, // Apple tvOS
44 OsWatchOS, // Apple watchOS
45 OsMesa3D,
46 OsContiki,
47 OsAMDPAL,
48 OsHermitCore,
49 OsHurd,
50 OsWASI,
51 OsEmscripten,
52 OsUefi,
53 OsOther,
54};
55
56// Synchronize with target.cpp::subarch_list_list
57enum SubArchList {
58 SubArchListNone,
59 SubArchListArm32,
60 SubArchListArm64,
61 SubArchListKalimba,
62 SubArchListMips,
63 SubArchListPPC,
64};
65
66enum TargetSubsystem {15enum TargetSubsystem {
67 TargetSubsystemConsole,16 TargetSubsystemConsole,
68 TargetSubsystemWindows,17 TargetSubsystemWindows,
...@@ -79,23 +28,6 @@ enum TargetSubsystem {...@@ -79,23 +28,6 @@ enum TargetSubsystem {
79 TargetSubsystemAuto28 TargetSubsystemAuto
80};29};
8130
82struct ZigGLibCVersion {
83 uint32_t major; // always 2
84 uint32_t minor;
85 uint32_t patch;
86};
87
88struct ZigTarget {
89 ZigLLVM_ArchType arch;
90 ZigLLVM_SubArchType sub_arch;
91 ZigLLVM_VendorType vendor;
92 Os os;
93 ZigLLVM_EnvironmentType abi;
94 ZigGLibCVersion *glibc_version; // null means default
95 Stage2CpuFeatures *cpu_features;
96 bool is_native;
97};
98
99enum CIntType {31enum CIntType {
100 CIntTypeShort,32 CIntTypeShort,
101 CIntTypeUShort,33 CIntTypeUShort,
...@@ -109,9 +41,8 @@ enum CIntType {...@@ -109,9 +41,8 @@ enum CIntType {
109 CIntTypeCount,41 CIntTypeCount,
110};42};
11143
112Error target_parse_triple(ZigTarget *target, const char *triple);44Error target_parse_triple(ZigTarget *target, const char *triple, const char *mcpu);
113Error target_parse_archsub(ZigLLVM_ArchType *arch, ZigLLVM_SubArchType *sub,45Error target_parse_arch(ZigLLVM_ArchType *arch, const char *arch_ptr, size_t arch_len);
114 const char *archsub_ptr, size_t archsub_len);
115Error target_parse_os(Os *os, const char *os_ptr, size_t os_len);46Error target_parse_os(Os *os, const char *os_ptr, size_t os_len);
116Error target_parse_abi(ZigLLVM_EnvironmentType *abi, const char *abi_ptr, size_t abi_len);47Error target_parse_abi(ZigLLVM_EnvironmentType *abi, const char *abi_ptr, size_t abi_len);
11748
...@@ -122,15 +53,6 @@ size_t target_arch_count(void);...@@ -122,15 +53,6 @@ size_t target_arch_count(void);
122ZigLLVM_ArchType target_arch_enum(size_t index);53ZigLLVM_ArchType target_arch_enum(size_t index);
123const char *target_arch_name(ZigLLVM_ArchType arch);54const char *target_arch_name(ZigLLVM_ArchType arch);
12455
125SubArchList target_subarch_list(ZigLLVM_ArchType arch);
126size_t target_subarch_count(SubArchList sub_arch_list);
127ZigLLVM_SubArchType target_subarch_enum(SubArchList subarch_list, size_t index);
128const char *target_subarch_name(ZigLLVM_SubArchType subarch);
129
130size_t target_subarch_list_count(void);
131SubArchList target_subarch_list_enum(size_t index);
132const char *target_subarch_list_name(SubArchList sub_arch_list);
133
134const char *arch_stack_pointer_register_name(ZigLLVM_ArchType arch);56const char *arch_stack_pointer_register_name(ZigLLVM_ArchType arch);
13557
136size_t target_vendor_count(void);58size_t target_vendor_count(void);
...@@ -169,8 +91,6 @@ const char *target_lib_file_prefix(const ZigTarget *target);...@@ -169,8 +91,6 @@ const char *target_lib_file_prefix(const ZigTarget *target);
169const char *target_lib_file_ext(const ZigTarget *target, bool is_static,91const char *target_lib_file_ext(const ZigTarget *target, bool is_static,
170 size_t version_major, size_t version_minor, size_t version_patch);92 size_t version_major, size_t version_minor, size_t version_patch);
17193
172const char *target_dynamic_linker(const ZigTarget *target);
173
174bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target);94bool target_can_exec(const ZigTarget *host_target, const ZigTarget *guest_target);
175ZigLLVM_OSType get_llvm_os_type(Os os_type);95ZigLLVM_OSType get_llvm_os_type(Os os_type);
17696
src/userland.cpp deleted-146
...@@ -1,146 +0,0 @@
1// This file is a shim for zig1. The real implementations of these are in
2// src-self-hosted/stage1.zig
3
4#include "userland.h"
5#include "util.hpp"
6#include "zig_llvm.h"
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10
11Error stage2_translate_c(struct Stage2Ast **out_ast,
12 struct Stage2ErrorMsg **out_errors_ptr, size_t *out_errors_len,
13 const char **args_begin, const char **args_end, const char *resources_path)
14{
15 const char *msg = "stage0 called stage2_translate_c";
16 stage2_panic(msg, strlen(msg));
17}
18
19void stage2_free_clang_errors(struct Stage2ErrorMsg *ptr, size_t len) {
20 const char *msg = "stage0 called stage2_free_clang_errors";
21 stage2_panic(msg, strlen(msg));
22}
23
24void stage2_zen(const char **ptr, size_t *len) {
25 const char *msg = "stage0 called stage2_zen";
26 stage2_panic(msg, strlen(msg));
27}
28
29void stage2_attach_segfault_handler(void) { }
30
31void stage2_panic(const char *ptr, size_t len) {
32 fwrite(ptr, 1, len, stderr);
33 fprintf(stderr, "\n");
34 fflush(stderr);
35 abort();
36}
37
38void stage2_render_ast(struct Stage2Ast *ast, FILE *output_file) {
39 const char *msg = "stage0 called stage2_render_ast";
40 stage2_panic(msg, strlen(msg));
41}
42
43int stage2_fmt(int argc, char **argv) {
44 const char *msg = "stage0 called stage2_fmt";
45 stage2_panic(msg, strlen(msg));
46}
47
48stage2_DepTokenizer stage2_DepTokenizer_init(const char *input, size_t len) {
49 const char *msg = "stage0 called stage2_DepTokenizer_init";
50 stage2_panic(msg, strlen(msg));
51}
52
53void stage2_DepTokenizer_deinit(stage2_DepTokenizer *self) {
54 const char *msg = "stage0 called stage2_DepTokenizer_deinit";
55 stage2_panic(msg, strlen(msg));
56}
57
58stage2_DepNextResult stage2_DepTokenizer_next(stage2_DepTokenizer *self) {
59 const char *msg = "stage0 called stage2_DepTokenizer_next";
60 stage2_panic(msg, strlen(msg));
61}
62
63
64struct Stage2Progress {
65 int trash;
66};
67
68struct Stage2ProgressNode {
69 int trash;
70};
71
72Stage2Progress *stage2_progress_create(void) {
73 return nullptr;
74}
75
76void stage2_progress_destroy(Stage2Progress *progress) {}
77
78Stage2ProgressNode *stage2_progress_start_root(Stage2Progress *progress,
79 const char *name_ptr, size_t name_len, size_t estimated_total_items)
80{
81 return nullptr;
82}
83Stage2ProgressNode *stage2_progress_start(Stage2ProgressNode *node,
84 const char *name_ptr, size_t name_len, size_t estimated_total_items)
85{
86 return nullptr;
87}
88void stage2_progress_end(Stage2ProgressNode *node) {}
89void stage2_progress_complete_one(Stage2ProgressNode *node) {}
90void stage2_progress_disable_tty(Stage2Progress *progress) {}
91void stage2_progress_update_node(Stage2ProgressNode *node, size_t completed_count, size_t estimated_total_items){}
92
93struct Stage2CpuFeatures {
94 const char *llvm_cpu_name;
95 const char *llvm_cpu_features;
96 const char *builtin_str;
97 const char *cache_hash;
98};
99
100Error stage2_cpu_features_parse(struct Stage2CpuFeatures **out, const char *zig_triple,
101 const char *cpu_name, const char *cpu_features)
102{
103 if (zig_triple == nullptr) {
104 Stage2CpuFeatures *result = heap::c_allocator.create<Stage2CpuFeatures>();
105 result->llvm_cpu_name = ZigLLVMGetHostCPUName();
106 result->llvm_cpu_features = ZigLLVMGetNativeFeatures();
107 result->builtin_str = "arch.getBaselineCpuFeatures();\n";
108 result->cache_hash = "native\n\n";
109 *out = result;
110 return ErrorNone;
111 }
112 if (cpu_name == nullptr && cpu_features == nullptr) {
113 Stage2CpuFeatures *result = heap::c_allocator.create<Stage2CpuFeatures>();
114 result->builtin_str = "arch.getBaselineCpuFeatures();\n";
115 result->cache_hash = "\n\n";
116 *out = result;
117 return ErrorNone;
118 }
119
120 const char *msg = "stage0 called stage2_cpu_features_parse with non-null cpu name or features";
121 stage2_panic(msg, strlen(msg));
122}
123
124void stage2_cpu_features_get_cache_hash(const Stage2CpuFeatures *cpu_features,
125 const char **ptr, size_t *len)
126{
127 *ptr = cpu_features->cache_hash;
128 *len = strlen(cpu_features->cache_hash);
129}
130const char *stage2_cpu_features_get_llvm_cpu(const Stage2CpuFeatures *cpu_features) {
131 return cpu_features->llvm_cpu_name;
132}
133const char *stage2_cpu_features_get_llvm_features(const Stage2CpuFeatures *cpu_features) {
134 return cpu_features->llvm_cpu_features;
135}
136void stage2_cpu_features_get_builtin_str(const Stage2CpuFeatures *cpu_features,
137 const char **ptr, size_t *len)
138{
139 *ptr = cpu_features->builtin_str;
140 *len = strlen(cpu_features->builtin_str);
141}
142
143int stage2_cmd_targets(const char *zig_triple) {
144 const char *msg = "stage0 called stage2_cmd_targets";
145 stage2_panic(msg, strlen(msg));
146}
src/userland.h deleted-208
...@@ -1,208 +0,0 @@
1/*
2 * Copyright (c) 2019 Andrew Kelley
3 *
4 * This file is part of zig, which is MIT licensed.
5 * See http://opensource.org/licenses/MIT
6 */
7
8#ifndef ZIG_USERLAND_H
9#define ZIG_USERLAND_H
10
11#include <stddef.h>
12#include <stdint.h>
13#include <stdio.h>
14
15#ifdef __cplusplus
16#define ZIG_EXTERN_C extern "C"
17#else
18#define ZIG_EXTERN_C
19#endif
20
21#if defined(_MSC_VER)
22#define ZIG_ATTRIBUTE_NORETURN __declspec(noreturn)
23#else
24#define ZIG_ATTRIBUTE_NORETURN __attribute__((noreturn))
25#endif
26
27// ABI warning: the types and declarations in this file must match both those in
28// userland.cpp and src-self-hosted/stage1.zig.
29
30// ABI warning
31enum Error {
32 ErrorNone,
33 ErrorNoMem,
34 ErrorInvalidFormat,
35 ErrorSemanticAnalyzeFail,
36 ErrorAccess,
37 ErrorInterrupted,
38 ErrorSystemResources,
39 ErrorFileNotFound,
40 ErrorFileSystem,
41 ErrorFileTooBig,
42 ErrorDivByZero,
43 ErrorOverflow,
44 ErrorPathAlreadyExists,
45 ErrorUnexpected,
46 ErrorExactDivRemainder,
47 ErrorNegativeDenominator,
48 ErrorShiftedOutOneBits,
49 ErrorCCompileErrors,
50 ErrorEndOfFile,
51 ErrorIsDir,
52 ErrorNotDir,
53 ErrorUnsupportedOperatingSystem,
54 ErrorSharingViolation,
55 ErrorPipeBusy,
56 ErrorPrimitiveTypeNotFound,
57 ErrorCacheUnavailable,
58 ErrorPathTooLong,
59 ErrorCCompilerCannotFindFile,
60 ErrorNoCCompilerInstalled,
61 ErrorReadingDepFile,
62 ErrorInvalidDepFile,
63 ErrorMissingArchitecture,
64 ErrorMissingOperatingSystem,
65 ErrorUnknownArchitecture,
66 ErrorUnknownOperatingSystem,
67 ErrorUnknownABI,
68 ErrorInvalidFilename,
69 ErrorDiskQuota,
70 ErrorDiskSpace,
71 ErrorUnexpectedWriteFailure,
72 ErrorUnexpectedSeekFailure,
73 ErrorUnexpectedFileTruncationFailure,
74 ErrorUnimplemented,
75 ErrorOperationAborted,
76 ErrorBrokenPipe,
77 ErrorNoSpaceLeft,
78 ErrorNotLazy,
79 ErrorIsAsync,
80 ErrorImportOutsidePkgPath,
81 ErrorUnknownCpu,
82 ErrorUnknownSubArchitecture,
83 ErrorUnknownCpuFeature,
84 ErrorInvalidCpuFeatures,
85 ErrorInvalidLlvmCpuFeaturesFormat,
86 ErrorUnknownApplicationBinaryInterface,
87};
88
89// ABI warning
90struct Stage2ErrorMsg {
91 const char *filename_ptr; // can be null
92 size_t filename_len;
93 const char *msg_ptr;
94 size_t msg_len;
95 const char *source; // valid until the ASTUnit is freed. can be null
96 unsigned line; // 0 based
97 unsigned column; // 0 based
98 unsigned offset; // byte offset into source
99};
100
101// ABI warning
102struct Stage2Ast;
103
104// ABI warning
105ZIG_EXTERN_C enum Error stage2_translate_c(struct Stage2Ast **out_ast,
106 struct Stage2ErrorMsg **out_errors_ptr, size_t *out_errors_len,
107 const char **args_begin, const char **args_end, const char *resources_path);
108
109// ABI warning
110ZIG_EXTERN_C void stage2_free_clang_errors(struct Stage2ErrorMsg *ptr, size_t len);
111
112// ABI warning
113ZIG_EXTERN_C void stage2_render_ast(struct Stage2Ast *ast, FILE *output_file);
114
115// ABI warning
116ZIG_EXTERN_C void stage2_zen(const char **ptr, size_t *len);
117
118// ABI warning
119ZIG_EXTERN_C void stage2_attach_segfault_handler(void);
120
121// ABI warning
122ZIG_EXTERN_C ZIG_ATTRIBUTE_NORETURN void stage2_panic(const char *ptr, size_t len);
123
124// ABI warning
125ZIG_EXTERN_C int stage2_fmt(int argc, char **argv);
126
127// ABI warning
128struct stage2_DepTokenizer {
129 void *handle;
130};
131
132// ABI warning
133struct stage2_DepNextResult {
134 enum TypeId {
135 error,
136 null,
137 target,
138 prereq,
139 };
140
141 TypeId type_id;
142
143 // when ent == error --> error text
144 // when ent == null --> undefined
145 // when ent == target --> target pathname
146 // when ent == prereq --> prereq pathname
147 const char *textz;
148};
149
150// ABI warning
151ZIG_EXTERN_C stage2_DepTokenizer stage2_DepTokenizer_init(const char *input, size_t len);
152
153// ABI warning
154ZIG_EXTERN_C void stage2_DepTokenizer_deinit(stage2_DepTokenizer *self);
155
156// ABI warning
157ZIG_EXTERN_C stage2_DepNextResult stage2_DepTokenizer_next(stage2_DepTokenizer *self);
158
159// ABI warning
160struct Stage2Progress;
161// ABI warning
162struct Stage2ProgressNode;
163// ABI warning
164ZIG_EXTERN_C Stage2Progress *stage2_progress_create(void);
165// ABI warning
166ZIG_EXTERN_C void stage2_progress_disable_tty(Stage2Progress *progress);
167// ABI warning
168ZIG_EXTERN_C void stage2_progress_destroy(Stage2Progress *progress);
169// ABI warning
170ZIG_EXTERN_C Stage2ProgressNode *stage2_progress_start_root(Stage2Progress *progress,
171 const char *name_ptr, size_t name_len, size_t estimated_total_items);
172// ABI warning
173ZIG_EXTERN_C Stage2ProgressNode *stage2_progress_start(Stage2ProgressNode *node,
174 const char *name_ptr, size_t name_len, size_t estimated_total_items);
175// ABI warning
176ZIG_EXTERN_C void stage2_progress_end(Stage2ProgressNode *node);
177// ABI warning
178ZIG_EXTERN_C void stage2_progress_complete_one(Stage2ProgressNode *node);
179// ABI warning
180ZIG_EXTERN_C void stage2_progress_update_node(Stage2ProgressNode *node,
181 size_t completed_count, size_t estimated_total_items);
182
183// ABI warning
184struct Stage2CpuFeatures;
185
186// ABI warning
187ZIG_EXTERN_C Error stage2_cpu_features_parse(struct Stage2CpuFeatures **result,
188 const char *zig_triple, const char *cpu_name, const char *cpu_features);
189
190// ABI warning
191ZIG_EXTERN_C const char *stage2_cpu_features_get_llvm_cpu(const struct Stage2CpuFeatures *cpu_features);
192
193// ABI warning
194ZIG_EXTERN_C const char *stage2_cpu_features_get_llvm_features(const struct Stage2CpuFeatures *cpu_features);
195
196// ABI warning
197ZIG_EXTERN_C void stage2_cpu_features_get_builtin_str(const struct Stage2CpuFeatures *cpu_features,
198 const char **ptr, size_t *len);
199
200// ABI warning
201ZIG_EXTERN_C void stage2_cpu_features_get_cache_hash(const struct Stage2CpuFeatures *cpu_features,
202 const char **ptr, size_t *len);
203
204// ABI warning
205ZIG_EXTERN_C int stage2_cmd_targets(const char *zig_triple);
206
207
208#endif
src/util.cpp+1-1
...@@ -6,7 +6,7 @@...@@ -6,7 +6,7 @@
6 */6 */
77
8#include "util.hpp"8#include "util.hpp"
9#include "userland.h"9#include "stage2.h"
1010
11#include <stdio.h>11#include <stdio.h>
12#include <stdarg.h>12#include <stdarg.h>
src/windows_sdk.h+4
...@@ -16,6 +16,7 @@...@@ -16,6 +16,7 @@
1616
17#include <stddef.h>17#include <stddef.h>
1818
19// ABI warning - src-self-hosted/windows_sdk.zig
19struct ZigWindowsSDK {20struct ZigWindowsSDK {
20 const char *path10_ptr;21 const char *path10_ptr;
21 size_t path10_len;22 size_t path10_len;
...@@ -33,6 +34,7 @@ struct ZigWindowsSDK {...@@ -33,6 +34,7 @@ struct ZigWindowsSDK {
33 size_t msvc_lib_dir_len;34 size_t msvc_lib_dir_len;
34};35};
3536
37// ABI warning - src-self-hosted/windows_sdk.zig
36enum ZigFindWindowsSdkError {38enum ZigFindWindowsSdkError {
37 ZigFindWindowsSdkErrorNone,39 ZigFindWindowsSdkErrorNone,
38 ZigFindWindowsSdkErrorOutOfMemory,40 ZigFindWindowsSdkErrorOutOfMemory,
...@@ -40,8 +42,10 @@ enum ZigFindWindowsSdkError {...@@ -40,8 +42,10 @@ enum ZigFindWindowsSdkError {
40 ZigFindWindowsSdkErrorPathTooLong,42 ZigFindWindowsSdkErrorPathTooLong,
41};43};
4244
45// ABI warning - src-self-hosted/windows_sdk.zig
43ZIG_EXTERN_C enum ZigFindWindowsSdkError zig_find_windows_sdk(struct ZigWindowsSDK **out_sdk);46ZIG_EXTERN_C enum ZigFindWindowsSdkError zig_find_windows_sdk(struct ZigWindowsSDK **out_sdk);
4447
48// ABI warning - src-self-hosted/windows_sdk.zig
45ZIG_EXTERN_C void zig_free_windows_sdk(struct ZigWindowsSDK *sdk);49ZIG_EXTERN_C void zig_free_windows_sdk(struct ZigWindowsSDK *sdk);
4650
47#endif51#endif
src/zig_clang.h+1-1
...@@ -8,7 +8,7 @@...@@ -8,7 +8,7 @@
8#ifndef ZIG_ZIG_CLANG_H8#ifndef ZIG_ZIG_CLANG_H
9#define ZIG_ZIG_CLANG_H9#define ZIG_ZIG_CLANG_H
1010
11#include "userland.h"11#include "stage2.h"
12#include <inttypes.h>12#include <inttypes.h>
13#include <stdbool.h>13#include <stdbool.h>
1414
src/zig_llvm.cpp+60-138
...@@ -162,17 +162,32 @@ unsigned ZigLLVMDataLayoutGetProgramAddressSpace(LLVMTargetDataRef TD) {...@@ -162,17 +162,32 @@ unsigned ZigLLVMDataLayoutGetProgramAddressSpace(LLVMTargetDataRef TD) {
162}162}
163163
164bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,164bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,
165 const char *filename, ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug,165 char **error_message, bool is_debug,
166 bool is_small, bool time_report)166 bool is_small, bool time_report,
167 const char *asm_filename, const char *bin_filename, const char *llvm_ir_filename)
167{168{
168 TimePassesIsEnabled = time_report;169 TimePassesIsEnabled = time_report;
169170
170 std::error_code EC;171 raw_fd_ostream *dest_asm = nullptr;
171 raw_fd_ostream dest(filename, EC, sys::fs::F_None);172 raw_fd_ostream *dest_bin = nullptr;
172 if (EC) {173
173 *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin());174 if (asm_filename) {
174 return true;175 std::error_code EC;
176 dest_asm = new(std::nothrow) raw_fd_ostream(asm_filename, EC, sys::fs::F_None);
177 if (EC) {
178 *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin());
179 return true;
180 }
175 }181 }
182 if (bin_filename) {
183 std::error_code EC;
184 dest_bin = new(std::nothrow) raw_fd_ostream(bin_filename, EC, sys::fs::F_None);
185 if (EC) {
186 *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin());
187 return true;
188 }
189 }
190
176 TargetMachine* target_machine = reinterpret_cast<TargetMachine*>(targ_machine_ref);191 TargetMachine* target_machine = reinterpret_cast<TargetMachine*>(targ_machine_ref);
177 target_machine->setO0WantsFastISel(true);192 target_machine->setO0WantsFastISel(true);
178193
...@@ -223,49 +238,51 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM...@@ -223,49 +238,51 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM
223 }238 }
224 PMBuilder->populateFunctionPassManager(FPM);239 PMBuilder->populateFunctionPassManager(FPM);
225240
226 // Set up the per-module pass manager.241 {
227 legacy::PassManager MPM;242 // Set up the per-module pass manager.
228 MPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis()));243 legacy::PassManager MPM;
229 PMBuilder->populateModulePassManager(MPM);244 MPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis()));
230245 PMBuilder->populateModulePassManager(MPM);
231 // Set output pass.246
232 CodeGenFileType ft;247 // Set output passes.
233 if (output_type != ZigLLVM_EmitLLVMIr) {248 if (dest_bin) {
234 switch (output_type) {249 if (target_machine->addPassesToEmitFile(MPM, *dest_bin, nullptr, CGFT_ObjectFile)) {
235 case ZigLLVM_EmitAssembly:250 *error_message = strdup("TargetMachine can't emit an object file");
236 ft = CGFT_AssemblyFile;251 return true;
237 break;252 }
238 case ZigLLVM_EmitBinary:
239 ft = CGFT_ObjectFile;
240 break;
241 default:
242 abort();
243 }253 }
244254 if (dest_asm) {
245 if (target_machine->addPassesToEmitFile(MPM, dest, nullptr, ft)) {255 if (target_machine->addPassesToEmitFile(MPM, *dest_asm, nullptr, CGFT_AssemblyFile)) {
246 *error_message = strdup("TargetMachine can't emit a file of this type");256 *error_message = strdup("TargetMachine can't emit an assembly file");
247 return true;257 return true;
258 }
248 }259 }
249 }
250260
251 // run per function optimization passes261 // run per function optimization passes
252 FPM.doInitialization();262 FPM.doInitialization();
253 for (Function &F : *module)263 for (Function &F : *module)
254 if (!F.isDeclaration())264 if (!F.isDeclaration())
255 FPM.run(F);265 FPM.run(F);
256 FPM.doFinalization();266 FPM.doFinalization();
257267
258 MPM.run(*module);268 MPM.run(*module);
259269
260 if (output_type == ZigLLVM_EmitLLVMIr) {270 if (llvm_ir_filename) {
261 if (LLVMPrintModuleToFile(module_ref, filename, error_message)) {271 if (LLVMPrintModuleToFile(module_ref, llvm_ir_filename, error_message)) {
262 return true;272 return true;
273 }
274 }
275
276 if (time_report) {
277 TimerGroup::printAll(errs());
263 }278 }
264 }
265279
266 if (time_report) {280 // MPM goes out of scope and writes to the out streams
267 TimerGroup::printAll(errs());
268 }281 }
282
283 delete dest_asm;
284 delete dest_bin;
285
269 return false;286 return false;
270}287}
271288
...@@ -792,7 +809,7 @@ const char *ZigLLVMGetEnvironmentTypeName(ZigLLVM_EnvironmentType env_type) {...@@ -792,7 +809,7 @@ const char *ZigLLVMGetEnvironmentTypeName(ZigLLVM_EnvironmentType env_type) {
792 return (const char*)Triple::getEnvironmentTypeName((Triple::EnvironmentType)env_type).bytes_begin();809 return (const char*)Triple::getEnvironmentTypeName((Triple::EnvironmentType)env_type).bytes_begin();
793}810}
794811
795void ZigLLVMGetNativeTarget(ZigLLVM_ArchType *arch_type, ZigLLVM_SubArchType *sub_arch_type,812void ZigLLVMGetNativeTarget(ZigLLVM_ArchType *arch_type,
796 ZigLLVM_VendorType *vendor_type, ZigLLVM_OSType *os_type, ZigLLVM_EnvironmentType *environ_type,813 ZigLLVM_VendorType *vendor_type, ZigLLVM_OSType *os_type, ZigLLVM_EnvironmentType *environ_type,
797 ZigLLVM_ObjectFormatType *oformat)814 ZigLLVM_ObjectFormatType *oformat)
798{815{
...@@ -800,7 +817,6 @@ void ZigLLVMGetNativeTarget(ZigLLVM_ArchType *arch_type, ZigLLVM_SubArchType *su...@@ -800,7 +817,6 @@ void ZigLLVMGetNativeTarget(ZigLLVM_ArchType *arch_type, ZigLLVM_SubArchType *su
800 Triple triple(Triple::normalize(native_triple));817 Triple triple(Triple::normalize(native_triple));
801818
802 *arch_type = (ZigLLVM_ArchType)triple.getArch();819 *arch_type = (ZigLLVM_ArchType)triple.getArch();
803 *sub_arch_type = (ZigLLVM_SubArchType)triple.getSubArch();
804 *vendor_type = (ZigLLVM_VendorType)triple.getVendor();820 *vendor_type = (ZigLLVM_VendorType)triple.getVendor();
805 *os_type = (ZigLLVM_OSType)triple.getOS();821 *os_type = (ZigLLVM_OSType)triple.getOS();
806 *environ_type = (ZigLLVM_EnvironmentType)triple.getEnvironment();822 *environ_type = (ZigLLVM_EnvironmentType)triple.getEnvironment();
...@@ -809,70 +825,6 @@ void ZigLLVMGetNativeTarget(ZigLLVM_ArchType *arch_type, ZigLLVM_SubArchType *su...@@ -809,70 +825,6 @@ void ZigLLVMGetNativeTarget(ZigLLVM_ArchType *arch_type, ZigLLVM_SubArchType *su
809 free(native_triple);825 free(native_triple);
810}826}
811827
812const char *ZigLLVMGetSubArchTypeName(ZigLLVM_SubArchType sub_arch) {
813 switch (sub_arch) {
814 case ZigLLVM_NoSubArch:
815 return "";
816 case ZigLLVM_ARMSubArch_v8_5a:
817 return "v8.5a";
818 case ZigLLVM_ARMSubArch_v8_4a:
819 return "v8.4a";
820 case ZigLLVM_ARMSubArch_v8_3a:
821 return "v8.3a";
822 case ZigLLVM_ARMSubArch_v8_2a:
823 return "v8.2a";
824 case ZigLLVM_ARMSubArch_v8_1a:
825 return "v8.1a";
826 case ZigLLVM_ARMSubArch_v8:
827 return "v8a";
828 case ZigLLVM_ARMSubArch_v8r:
829 return "v8r";
830 case ZigLLVM_ARMSubArch_v8m_baseline:
831 return "v8m.base";
832 case ZigLLVM_ARMSubArch_v8m_mainline:
833 return "v8m.main";
834 case ZigLLVM_ARMSubArch_v8_1m_mainline:
835 return "v8.1m.main";
836 case ZigLLVM_ARMSubArch_v7:
837 return "v7a";
838 case ZigLLVM_ARMSubArch_v7em:
839 return "v7em";
840 case ZigLLVM_ARMSubArch_v7m:
841 return "v7m";
842 case ZigLLVM_ARMSubArch_v7s:
843 return "v7s";
844 case ZigLLVM_ARMSubArch_v7k:
845 return "v7k";
846 case ZigLLVM_ARMSubArch_v7ve:
847 return "v7ve";
848 case ZigLLVM_ARMSubArch_v6:
849 return "v6";
850 case ZigLLVM_ARMSubArch_v6m:
851 return "v6m";
852 case ZigLLVM_ARMSubArch_v6k:
853 return "v6k";
854 case ZigLLVM_ARMSubArch_v6t2:
855 return "v6t2";
856 case ZigLLVM_ARMSubArch_v5:
857 return "v5";
858 case ZigLLVM_ARMSubArch_v5te:
859 return "v5te";
860 case ZigLLVM_ARMSubArch_v4t:
861 return "v4t";
862 case ZigLLVM_KalimbaSubArch_v3:
863 return "v3";
864 case ZigLLVM_KalimbaSubArch_v4:
865 return "v4";
866 case ZigLLVM_KalimbaSubArch_v5:
867 return "v5";
868 case ZigLLVM_MipsSubArch_r6:
869 return "r6";
870 case ZigLLVM_PPCSubArch_spe:
871 return "spe";
872 }
873 abort();
874}
875
876void ZigLLVMAddModuleDebugInfoFlag(LLVMModuleRef module) {828void ZigLLVMAddModuleDebugInfoFlag(LLVMModuleRef module) {
877 unwrap(module)->addModuleFlag(Module::Warning, "Debug Info Version", DEBUG_METADATA_VERSION);829 unwrap(module)->addModuleFlag(Module::Warning, "Debug Info Version", DEBUG_METADATA_VERSION);
878 unwrap(module)->addModuleFlag(Module::Warning, "Dwarf Version", 4);830 unwrap(module)->addModuleFlag(Module::Warning, "Dwarf Version", 4);
...@@ -1210,36 +1162,6 @@ static_assert((Triple::ArchType)ZigLLVM_renderscript64 == Triple::renderscript64...@@ -1210,36 +1162,6 @@ static_assert((Triple::ArchType)ZigLLVM_renderscript64 == Triple::renderscript64
1210static_assert((Triple::ArchType)ZigLLVM_ve == Triple::ve, "");1162static_assert((Triple::ArchType)ZigLLVM_ve == Triple::ve, "");
1211static_assert((Triple::ArchType)ZigLLVM_LastArchType == Triple::LastArchType, "");1163static_assert((Triple::ArchType)ZigLLVM_LastArchType == Triple::LastArchType, "");
12121164
1213static_assert((Triple::SubArchType)ZigLLVM_NoSubArch == Triple::NoSubArch, "");
1214static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8_4a == Triple::ARMSubArch_v8_4a, "");
1215static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8_3a == Triple::ARMSubArch_v8_3a, "");
1216static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8_2a == Triple::ARMSubArch_v8_2a, "");
1217static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8_1a == Triple::ARMSubArch_v8_1a, "");
1218static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8 == Triple::ARMSubArch_v8, "");
1219static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8r == Triple::ARMSubArch_v8r, "");
1220static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8m_baseline == Triple::ARMSubArch_v8m_baseline, "");
1221static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8m_mainline == Triple::ARMSubArch_v8m_mainline, "");
1222static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8_1m_mainline == Triple::ARMSubArch_v8_1m_mainline, "");
1223static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v7 == Triple::ARMSubArch_v7, "");
1224static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v7em == Triple::ARMSubArch_v7em, "");
1225static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v7m == Triple::ARMSubArch_v7m, "");
1226static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v7s == Triple::ARMSubArch_v7s, "");
1227static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v7k == Triple::ARMSubArch_v7k, "");
1228static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v7ve == Triple::ARMSubArch_v7ve, "");
1229static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v6 == Triple::ARMSubArch_v6, "");
1230static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v6m == Triple::ARMSubArch_v6m, "");
1231static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v6k == Triple::ARMSubArch_v6k, "");
1232static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v6t2 == Triple::ARMSubArch_v6t2, "");
1233static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v5 == Triple::ARMSubArch_v5, "");
1234static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v5te == Triple::ARMSubArch_v5te, "");
1235static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v4t == Triple::ARMSubArch_v4t, "");
1236static_assert((Triple::SubArchType)ZigLLVM_KalimbaSubArch_v3 == Triple::KalimbaSubArch_v3, "");
1237static_assert((Triple::SubArchType)ZigLLVM_KalimbaSubArch_v4 == Triple::KalimbaSubArch_v4, "");
1238static_assert((Triple::SubArchType)ZigLLVM_KalimbaSubArch_v5 == Triple::KalimbaSubArch_v5, "");
1239static_assert((Triple::SubArchType)ZigLLVM_KalimbaSubArch_v5 == Triple::KalimbaSubArch_v5, "");
1240static_assert((Triple::SubArchType)ZigLLVM_MipsSubArch_r6 == Triple::MipsSubArch_r6, "");
1241static_assert((Triple::SubArchType)ZigLLVM_PPCSubArch_spe == Triple::PPCSubArch_spe, "");
1242
1243static_assert((Triple::VendorType)ZigLLVM_UnknownVendor == Triple::UnknownVendor, "");1165static_assert((Triple::VendorType)ZigLLVM_UnknownVendor == Triple::UnknownVendor, "");
1244static_assert((Triple::VendorType)ZigLLVM_Apple == Triple::Apple, "");1166static_assert((Triple::VendorType)ZigLLVM_Apple == Triple::Apple, "");
1245static_assert((Triple::VendorType)ZigLLVM_PC == Triple::PC, "");1167static_assert((Triple::VendorType)ZigLLVM_PC == Triple::PC, "");
src/zig_llvm.h+4-49
...@@ -46,17 +46,10 @@ ZIG_EXTERN_C void ZigLLVMInitializeLowerIntrinsicsPass(LLVMPassRegistryRef R);...@@ -46,17 +46,10 @@ ZIG_EXTERN_C void ZigLLVMInitializeLowerIntrinsicsPass(LLVMPassRegistryRef R);
46ZIG_EXTERN_C char *ZigLLVMGetHostCPUName(void);46ZIG_EXTERN_C char *ZigLLVMGetHostCPUName(void);
47ZIG_EXTERN_C char *ZigLLVMGetNativeFeatures(void);47ZIG_EXTERN_C char *ZigLLVMGetNativeFeatures(void);
4848
49// We use a custom enum here since LLVM does not expose LLVMIr as an emit
50// output through the same mechanism as assembly/binary.
51enum ZigLLVM_EmitOutputType {
52 ZigLLVM_EmitAssembly,
53 ZigLLVM_EmitBinary,
54 ZigLLVM_EmitLLVMIr,
55};
56
57ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,49ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,
58 const char *filename, enum ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug,50 char **error_message, bool is_debug,
59 bool is_small, bool time_report);51 bool is_small, bool time_report,
52 const char *asm_filename, const char *bin_filename, const char *llvm_ir_filename);
6053
61ZIG_EXTERN_C LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Triple,54ZIG_EXTERN_C LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Triple,
62 const char *CPU, const char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc,55 const char *CPU, const char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc,
...@@ -332,43 +325,6 @@ enum ZigLLVM_ArchType {...@@ -332,43 +325,6 @@ enum ZigLLVM_ArchType {
332 ZigLLVM_LastArchType = ZigLLVM_ve325 ZigLLVM_LastArchType = ZigLLVM_ve
333};326};
334327
335// synchronize with lists in target.cpp
336enum ZigLLVM_SubArchType {
337 ZigLLVM_NoSubArch,
338
339 ZigLLVM_ARMSubArch_v8_5a,
340 ZigLLVM_ARMSubArch_v8_4a,
341 ZigLLVM_ARMSubArch_v8_3a,
342 ZigLLVM_ARMSubArch_v8_2a,
343 ZigLLVM_ARMSubArch_v8_1a,
344 ZigLLVM_ARMSubArch_v8,
345 ZigLLVM_ARMSubArch_v8r,
346 ZigLLVM_ARMSubArch_v8m_baseline,
347 ZigLLVM_ARMSubArch_v8m_mainline,
348 ZigLLVM_ARMSubArch_v8_1m_mainline,
349 ZigLLVM_ARMSubArch_v7,
350 ZigLLVM_ARMSubArch_v7em,
351 ZigLLVM_ARMSubArch_v7m,
352 ZigLLVM_ARMSubArch_v7s,
353 ZigLLVM_ARMSubArch_v7k,
354 ZigLLVM_ARMSubArch_v7ve,
355 ZigLLVM_ARMSubArch_v6,
356 ZigLLVM_ARMSubArch_v6m,
357 ZigLLVM_ARMSubArch_v6k,
358 ZigLLVM_ARMSubArch_v6t2,
359 ZigLLVM_ARMSubArch_v5,
360 ZigLLVM_ARMSubArch_v5te,
361 ZigLLVM_ARMSubArch_v4t,
362
363 ZigLLVM_KalimbaSubArch_v3,
364 ZigLLVM_KalimbaSubArch_v4,
365 ZigLLVM_KalimbaSubArch_v5,
366
367 ZigLLVM_MipsSubArch_r6,
368
369 ZigLLVM_PPCSubArch_spe,
370};
371
372enum ZigLLVM_VendorType {328enum ZigLLVM_VendorType {
373 ZigLLVM_UnknownVendor,329 ZigLLVM_UnknownVendor,
374330
...@@ -526,7 +482,6 @@ LLVMValueRef ZigLLVMBuildAtomicRMW(LLVMBuilderRef B, enum ZigLLVM_AtomicRMWBinOp...@@ -526,7 +482,6 @@ LLVMValueRef ZigLLVMBuildAtomicRMW(LLVMBuilderRef B, enum ZigLLVM_AtomicRMWBinOp
526#define ZigLLVM_DIFlags_AllCallsDescribed (1U << 29)482#define ZigLLVM_DIFlags_AllCallsDescribed (1U << 29)
527483
528ZIG_EXTERN_C const char *ZigLLVMGetArchTypeName(enum ZigLLVM_ArchType arch);484ZIG_EXTERN_C const char *ZigLLVMGetArchTypeName(enum ZigLLVM_ArchType arch);
529ZIG_EXTERN_C const char *ZigLLVMGetSubArchTypeName(enum ZigLLVM_SubArchType sub_arch);
530ZIG_EXTERN_C const char *ZigLLVMGetVendorTypeName(enum ZigLLVM_VendorType vendor);485ZIG_EXTERN_C const char *ZigLLVMGetVendorTypeName(enum ZigLLVM_VendorType vendor);
531ZIG_EXTERN_C const char *ZigLLVMGetOSTypeName(enum ZigLLVM_OSType os);486ZIG_EXTERN_C const char *ZigLLVMGetOSTypeName(enum ZigLLVM_OSType os);
532ZIG_EXTERN_C const char *ZigLLVMGetEnvironmentTypeName(enum ZigLLVM_EnvironmentType abi);487ZIG_EXTERN_C const char *ZigLLVMGetEnvironmentTypeName(enum ZigLLVM_EnvironmentType abi);
...@@ -541,7 +496,7 @@ ZIG_EXTERN_C bool ZigLLVMWriteArchive(const char *archive_name, const char **fil...@@ -541,7 +496,7 @@ ZIG_EXTERN_C bool ZigLLVMWriteArchive(const char *archive_name, const char **fil
541bool ZigLLVMWriteImportLibrary(const char *def_path, const enum ZigLLVM_ArchType arch,496bool ZigLLVMWriteImportLibrary(const char *def_path, const enum ZigLLVM_ArchType arch,
542 const char *output_lib_path, const bool kill_at);497 const char *output_lib_path, const bool kill_at);
543498
544ZIG_EXTERN_C void ZigLLVMGetNativeTarget(enum ZigLLVM_ArchType *arch_type, enum ZigLLVM_SubArchType *sub_arch_type,499ZIG_EXTERN_C void ZigLLVMGetNativeTarget(enum ZigLLVM_ArchType *arch_type,
545 enum ZigLLVM_VendorType *vendor_type, enum ZigLLVM_OSType *os_type, enum ZigLLVM_EnvironmentType *environ_type,500 enum ZigLLVM_VendorType *vendor_type, enum ZigLLVM_OSType *os_type, enum ZigLLVM_EnvironmentType *environ_type,
546 enum ZigLLVM_ObjectFormatType *oformat);501 enum ZigLLVM_ObjectFormatType *oformat);
547502
test/compile_errors.zig+37-142
...@@ -3,6 +3,35 @@ const builtin = @import("builtin");...@@ -3,6 +3,35 @@ const builtin = @import("builtin");
3const Target = @import("std").Target;3const Target = @import("std").Target;
44
5pub fn addCases(cases: *tests.CompileErrorContext) void {5pub fn addCases(cases: *tests.CompileErrorContext) void {
6 cases.addTest("slice to pointer conversion mismatch",
7 \\pub fn bytesAsSlice(bytes: var) [*]align(1) const u16 {
8 \\ return @ptrCast([*]align(1) const u16, bytes.ptr)[0..1];
9 \\}
10 \\test "bytesAsSlice" {
11 \\ const bytes = [_]u8{ 0xDE, 0xAD, 0xBE, 0xEF };
12 \\ const slice = bytesAsSlice(bytes[0..]);
13 \\}
14 , &[_][]const u8{
15 "tmp.zig:2:54: error: expected type '[*]align(1) const u16', found '[]align(1) const u16'",
16 });
17
18 cases.addTest("access invalid @typeInfo decl",
19 \\const A = B;
20 \\test "Crash" {
21 \\ _ = @typeInfo(@This()).Struct.decls[0];
22 \\}
23 , &[_][]const u8{
24 "tmp.zig:1:11: error: use of undeclared identifier 'B'",
25 });
26
27 cases.addTest("reject extern function definitions with body",
28 \\extern "c" fn definitelyNotInLibC(a: i32, b: i32) i32 {
29 \\ return a + b;
30 \\}
31 , &[_][]const u8{
32 "tmp.zig:1:1: error: extern functions have no body",
33 });
34
6 cases.addTest("duplicate field in anonymous struct literal",35 cases.addTest("duplicate field in anonymous struct literal",
7 \\export fn entry() void {36 \\export fn entry() void {
8 \\ const anon = .{37 \\ const anon = .{
...@@ -30,10 +59,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -30,10 +59,11 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
30 "tmp.zig:5:22: error: expected type 'fn([*c]u8, ...) callconv(.C) void', found 'fn([*:0]u8, ...) callconv(.C) void'",59 "tmp.zig:5:22: error: expected type 'fn([*c]u8, ...) callconv(.C) void', found 'fn([*:0]u8, ...) callconv(.C) void'",
31 });60 });
3261
33 cases.addTest("dependency loop in top-level decl with @TypeInfo",62 cases.addTest("dependency loop in top-level decl with @TypeInfo when accessing the decls",
34 \\export const foo = @typeInfo(@This());63 \\export const foo = @typeInfo(@This()).Struct.decls;
35 , &[_][]const u8{64 , &[_][]const u8{
36 "tmp.zig:1:20: error: dependency loop detected",65 "tmp.zig:1:20: error: dependency loop detected",
66 "tmp.zig:1:45: note: referenced here",
37 });67 });
3868
39 cases.add("function call assigned to incorrect type",69 cases.add("function call assigned to incorrect type",
...@@ -332,8 +362,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -332,8 +362,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
332 });362 });
333 tc.target = Target{363 tc.target = Target{
334 .Cross = .{364 .Cross = .{
335 .arch = .wasm32,365 .cpu = Target.Cpu.baseline(.wasm32),
336 .cpu_features = Target.Arch.wasm32.getBaselineCpuFeatures(),
337 .os = .wasi,366 .os = .wasi,
338 .abi = .none,367 .abi = .none,
339 },368 },
...@@ -734,8 +763,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -734,8 +763,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
734 });763 });
735 tc.target = Target{764 tc.target = Target{
736 .Cross = .{765 .Cross = .{
737 .arch = .x86_64,766 .cpu = Target.Cpu.baseline(.x86_64),
738 .cpu_features = Target.Arch.x86_64.getBaselineCpuFeatures(),
739 .os = .linux,767 .os = .linux,
740 .abi = .gnu,768 .abi = .gnu,
741 },769 },
...@@ -1346,24 +1374,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1346,24 +1374,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1346 "tmp.zig:8:28: note: referenced here",1374 "tmp.zig:8:28: note: referenced here",
1347 });1375 });
13481376
1349 cases.add("@typeInfo causing depend on itself compile error",
1350 \\const start = struct {
1351 \\ fn crash() bug() {
1352 \\ return bug;
1353 \\ }
1354 \\};
1355 \\fn bug() void {
1356 \\ _ = @typeInfo(start).Struct;
1357 \\}
1358 \\export fn entry() void {
1359 \\ var boom = start.crash();
1360 \\}
1361 , &[_][]const u8{
1362 "tmp.zig:7:9: error: dependency loop detected",
1363 "tmp.zig:2:19: note: referenced here",
1364 "tmp.zig:10:21: note: referenced here",
1365 });
1366
1367 cases.add("enum field value references enum",1377 cases.add("enum field value references enum",
1368 \\pub const Foo = extern enum {1378 \\pub const Foo = extern enum {
1369 \\ A = Foo.B,1379 \\ A = Foo.B,
...@@ -1647,7 +1657,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1647,7 +1657,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
1647 \\ var ptr: [*c]u8 = (1 << 64) + 1;1657 \\ var ptr: [*c]u8 = (1 << 64) + 1;
1648 \\}1658 \\}
1649 \\export fn b() void {1659 \\export fn b() void {
1650 \\ var x: @IntType(false, 65) = 0x1234;1660 \\ var x: u65 = 0x1234;
1651 \\ var ptr: [*c]u8 = x;1661 \\ var ptr: [*c]u8 = x;
1652 \\}1662 \\}
1653 , &[_][]const u8{1663 , &[_][]const u8{
...@@ -1886,13 +1896,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -1886,13 +1896,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
18861896
1887 cases.add("exceeded maximum bit width of integer",1897 cases.add("exceeded maximum bit width of integer",
1888 \\export fn entry1() void {1898 \\export fn entry1() void {
1889 \\ const T = @IntType(false, 65536);1899 \\ const T = u65536;
1890 \\}1900 \\}
1891 \\export fn entry2() void {1901 \\export fn entry2() void {
1892 \\ var x: i65536 = 1;1902 \\ var x: i65536 = 1;
1893 \\}1903 \\}
1894 , &[_][]const u8{1904 , &[_][]const u8{
1895 "tmp.zig:2:31: error: integer value 65536 cannot be coerced to type 'u16'",
1896 "tmp.zig:5:12: error: primitive integer type 'i65536' exceeds maximum bit width of 65535",1905 "tmp.zig:5:12: error: primitive integer type 'i65536' exceeds maximum bit width of 65535",
1897 });1906 });
18981907
...@@ -2932,14 +2941,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -2932,14 +2941,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
2932 "tmp.zig:11:13: error: error.B not a member of error set 'Set2'",2941 "tmp.zig:11:13: error: error.B not a member of error set 'Set2'",
2933 });2942 });
29342943
2935 cases.add("@memberCount of error",
2936 \\comptime {
2937 \\ _ = @memberCount(anyerror);
2938 \\}
2939 , &[_][]const u8{
2940 "tmp.zig:2:9: error: global error set member count not available at comptime",
2941 });
2942
2943 cases.add("duplicate error value in error set",2944 cases.add("duplicate error value in error set",
2944 \\const Foo = error {2945 \\const Foo = error {
2945 \\ Bar,2946 \\ Bar,
...@@ -4735,16 +4736,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -4735,16 +4736,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
4735 "tmp.zig:1:15: error: comptime parameter not allowed in function with calling convention 'C'",4736 "tmp.zig:1:15: error: comptime parameter not allowed in function with calling convention 'C'",
4736 });4737 });
47374738
4738 cases.add("convert fixed size array to slice with invalid size",
4739 \\export fn f() void {
4740 \\ var array: [5]u8 = undefined;
4741 \\ var foo = @bytesToSlice(u32, &array)[0];
4742 \\}
4743 , &[_][]const u8{
4744 "tmp.zig:3:15: error: unable to convert [5]u8 to []align(1) u32: size mismatch",
4745 "tmp.zig:3:29: note: u32 has size 4; remaining bytes: 1",
4746 });
4747
4748 cases.add("non-pure function returns type",4739 cases.add("non-pure function returns type",
4749 \\var a: u32 = 0;4740 \\var a: u32 = 0;
4750 \\pub fn List(comptime T: type) type {4741 \\pub fn List(comptime T: type) type {
...@@ -5606,7 +5597,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5606,7 +5597,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5606 });5597 });
56075598
5608 cases.add("globally shadowing a primitive type",5599 cases.add("globally shadowing a primitive type",
5609 \\const u16 = @intType(false, 8);5600 \\const u16 = u8;
5610 \\export fn entry() void {5601 \\export fn entry() void {
5611 \\ const a: u16 = 300;5602 \\ const a: u16 = 300;
5612 \\}5603 \\}
...@@ -5947,93 +5938,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -5947,93 +5938,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
5947 "tmp.zig:2:1: error: invalid character: '\\t'",5938 "tmp.zig:2:1: error: invalid character: '\\t'",
5948 });5939 });
59495940
5950 cases.add("@ArgType given non function parameter",
5951 \\comptime {
5952 \\ _ = @ArgType(i32, 3);
5953 \\}
5954 , &[_][]const u8{
5955 "tmp.zig:2:18: error: expected function, found 'i32'",
5956 });
5957
5958 cases.add("@ArgType arg index out of bounds",
5959 \\comptime {
5960 \\ _ = @ArgType(@TypeOf(add), 2);
5961 \\}
5962 \\fn add(a: i32, b: i32) i32 { return a + b; }
5963 , &[_][]const u8{
5964 "tmp.zig:2:32: error: arg index 2 out of bounds; 'fn(i32, i32) i32' has 2 arguments",
5965 });
5966
5967 cases.add("@memberType on unsupported type",
5968 \\comptime {
5969 \\ _ = @memberType(i32, 0);
5970 \\}
5971 , &[_][]const u8{
5972 "tmp.zig:2:21: error: type 'i32' does not support @memberType",
5973 });
5974
5975 cases.add("@memberType on enum",
5976 \\comptime {
5977 \\ _ = @memberType(Foo, 0);
5978 \\}
5979 \\const Foo = enum {A,};
5980 , &[_][]const u8{
5981 "tmp.zig:2:21: error: type 'Foo' does not support @memberType",
5982 });
5983
5984 cases.add("@memberType struct out of bounds",
5985 \\comptime {
5986 \\ _ = @memberType(Foo, 0);
5987 \\}
5988 \\const Foo = struct {};
5989 , &[_][]const u8{
5990 "tmp.zig:2:26: error: member index 0 out of bounds; 'Foo' has 0 members",
5991 });
5992
5993 cases.add("@memberType union out of bounds",
5994 \\comptime {
5995 \\ _ = @memberType(Foo, 1);
5996 \\}
5997 \\const Foo = union {A: void,};
5998 , &[_][]const u8{
5999 "tmp.zig:2:26: error: member index 1 out of bounds; 'Foo' has 1 members",
6000 });
6001
6002 cases.add("@memberName on unsupported type",
6003 \\comptime {
6004 \\ _ = @memberName(i32, 0);
6005 \\}
6006 , &[_][]const u8{
6007 "tmp.zig:2:21: error: type 'i32' does not support @memberName",
6008 });
6009
6010 cases.add("@memberName struct out of bounds",
6011 \\comptime {
6012 \\ _ = @memberName(Foo, 0);
6013 \\}
6014 \\const Foo = struct {};
6015 , &[_][]const u8{
6016 "tmp.zig:2:26: error: member index 0 out of bounds; 'Foo' has 0 members",
6017 });
6018
6019 cases.add("@memberName enum out of bounds",
6020 \\comptime {
6021 \\ _ = @memberName(Foo, 1);
6022 \\}
6023 \\const Foo = enum {A,};
6024 , &[_][]const u8{
6025 "tmp.zig:2:26: error: member index 1 out of bounds; 'Foo' has 1 members",
6026 });
6027
6028 cases.add("@memberName union out of bounds",
6029 \\comptime {
6030 \\ _ = @memberName(Foo, 1);
6031 \\}
6032 \\const Foo = union {A:i32,};
6033 , &[_][]const u8{
6034 "tmp.zig:2:26: error: member index 1 out of bounds; 'Foo' has 1 members",
6035 });
6036
6037 cases.add("calling var args extern function, passing array instead of pointer",5941 cases.add("calling var args extern function, passing array instead of pointer",
6038 \\export fn entry() void {5942 \\export fn entry() void {
6039 \\ foo("hello".*,);5943 \\ foo("hello".*,);
...@@ -6457,15 +6361,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -6457,15 +6361,6 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
6457 "tmp.zig:3:25: error: ReturnType has not been resolved because 'fn(var) var' is generic",6361 "tmp.zig:3:25: error: ReturnType has not been resolved because 'fn(var) var' is generic",
6458 });6362 });
64596363
6460 cases.add("getting @ArgType of generic function",
6461 \\fn generic(a: var) void {}
6462 \\comptime {
6463 \\ _ = @ArgType(@TypeOf(generic), 0);
6464 \\}
6465 , &[_][]const u8{
6466 "tmp.zig:3:36: error: @ArgType could not resolve the type of arg 0 because 'fn(var) var' is generic",
6467 });
6468
6469 cases.add("unsupported modifier at start of asm output constraint",6364 cases.add("unsupported modifier at start of asm output constraint",
6470 \\export fn foo() void {6365 \\export fn foo() void {
6471 \\ var bar: u32 = 3;6366 \\ var bar: u32 = 3;
test/runtime_safety.zig+9-7
...@@ -553,15 +553,16 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -553,15 +553,16 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
553 );553 );
554554
555 cases.addRuntimeSafety("cast []u8 to bigger slice of wrong size",555 cases.addRuntimeSafety("cast []u8 to bigger slice of wrong size",
556 \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {556 \\const std = @import("std");
557 \\ @import("std").os.exit(126);557 \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
558 \\ std.os.exit(126);
558 \\}559 \\}
559 \\pub fn main() !void {560 \\pub fn main() !void {
560 \\ const x = widenSlice(&[_]u8{1, 2, 3, 4, 5});561 \\ const x = widenSlice(&[_]u8{1, 2, 3, 4, 5});
561 \\ if (x.len == 0) return error.Whatever;562 \\ if (x.len == 0) return error.Whatever;
562 \\}563 \\}
563 \\fn widenSlice(slice: []align(1) const u8) []align(1) const i32 {564 \\fn widenSlice(slice: []align(1) const u8) []align(1) const i32 {
564 \\ return @bytesToSlice(i32, slice);565 \\ return std.mem.bytesAsSlice(i32, slice);
565 \\}566 \\}
566 );567 );
567568
...@@ -656,17 +657,18 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {...@@ -656,17 +657,18 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
656 );657 );
657658
658 cases.addRuntimeSafety("@alignCast misaligned",659 cases.addRuntimeSafety("@alignCast misaligned",
659 \\pub fn panic(message: []const u8, stack_trace: ?*@import("builtin").StackTrace) noreturn {660 \\const std = @import("std");
660 \\ @import("std").os.exit(126);661 \\pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace) noreturn {
662 \\ std.os.exit(126);
661 \\}663 \\}
662 \\pub fn main() !void {664 \\pub fn main() !void {
663 \\ var array align(4) = [_]u32{0x11111111, 0x11111111};665 \\ var array align(4) = [_]u32{0x11111111, 0x11111111};
664 \\ const bytes = @sliceToBytes(array[0..]);666 \\ const bytes = std.mem.sliceAsBytes(array[0..]);
665 \\ if (foo(bytes) != 0x11111111) return error.Wrong;667 \\ if (foo(bytes) != 0x11111111) return error.Wrong;
666 \\}668 \\}
667 \\fn foo(bytes: []u8) u32 {669 \\fn foo(bytes: []u8) u32 {
668 \\ const slice4 = bytes[1..5];670 \\ const slice4 = bytes[1..5];
669 \\ const int_slice = @bytesToSlice(u32, @alignCast(4, slice4));671 \\ const int_slice = std.mem.bytesAsSlice(u32, @alignCast(4, slice4));
670 \\ return int_slice[0];672 \\ return int_slice[0];
671 \\}673 \\}
672 );674 );
test/stage1/behavior.zig+1-1
...@@ -38,6 +38,7 @@ comptime {...@@ -38,6 +38,7 @@ comptime {
38 _ = @import("behavior/bugs/3112.zig");38 _ = @import("behavior/bugs/3112.zig");
39 _ = @import("behavior/bugs/3367.zig");39 _ = @import("behavior/bugs/3367.zig");
40 _ = @import("behavior/bugs/3384.zig");40 _ = @import("behavior/bugs/3384.zig");
41 _ = @import("behavior/bugs/3586.zig");
41 _ = @import("behavior/bugs/3742.zig");42 _ = @import("behavior/bugs/3742.zig");
42 _ = @import("behavior/bugs/394.zig");43 _ = @import("behavior/bugs/394.zig");
43 _ = @import("behavior/bugs/421.zig");44 _ = @import("behavior/bugs/421.zig");
...@@ -91,7 +92,6 @@ comptime {...@@ -91,7 +92,6 @@ comptime {
91 _ = @import("behavior/shuffle.zig");92 _ = @import("behavior/shuffle.zig");
92 _ = @import("behavior/sizeof_and_typeof.zig");93 _ = @import("behavior/sizeof_and_typeof.zig");
93 _ = @import("behavior/slice.zig");94 _ = @import("behavior/slice.zig");
94 _ = @import("behavior/slicetobytes.zig");
95 _ = @import("behavior/struct.zig");95 _ = @import("behavior/struct.zig");
96 _ = @import("behavior/struct_contains_null_ptr_itself.zig");96 _ = @import("behavior/struct_contains_null_ptr_itself.zig");
97 _ = @import("behavior/struct_contains_slice_of_itself.zig");97 _ = @import("behavior/struct_contains_slice_of_itself.zig");
test/stage1/behavior/align.zig-14
...@@ -81,20 +81,6 @@ fn testBytesAlign(b: u8) void {...@@ -81,20 +81,6 @@ fn testBytesAlign(b: u8) void {
81 expect(ptr.* == 0x33333333);81 expect(ptr.* == 0x33333333);
82}82}
8383
84test "specifying alignment allows slice cast" {
85 testBytesAlignSlice(0x33);
86}
87fn testBytesAlignSlice(b: u8) void {
88 var bytes align(4) = [_]u8{
89 b,
90 b,
91 b,
92 b,
93 };
94 const slice: []u32 = @bytesToSlice(u32, bytes[0..]);
95 expect(slice[0] == 0x33333333);
96}
97
98test "@alignCast pointers" {84test "@alignCast pointers" {
99 var x: u32 align(4) = 1;85 var x: u32 align(4) = 1;
100 expectsOnly1(&x);86 expectsOnly1(&x);
test/stage1/behavior/async_fn.zig+52-2
...@@ -334,7 +334,7 @@ test "async fn with inferred error set" {...@@ -334,7 +334,7 @@ test "async fn with inferred error set" {
334 var frame: [1]@Frame(middle) = undefined;334 var frame: [1]@Frame(middle) = undefined;
335 var fn_ptr = middle;335 var fn_ptr = middle;
336 var result: @TypeOf(fn_ptr).ReturnType.ErrorSet!void = undefined;336 var result: @TypeOf(fn_ptr).ReturnType.ErrorSet!void = undefined;
337 _ = @asyncCall(@sliceToBytes(frame[0..]), &result, fn_ptr);337 _ = @asyncCall(std.mem.sliceAsBytes(frame[0..]), &result, fn_ptr);
338 resume global_frame;338 resume global_frame;
339 std.testing.expectError(error.Fail, result);339 std.testing.expectError(error.Fail, result);
340 }340 }
...@@ -954,7 +954,7 @@ test "@asyncCall with comptime-known function, but not awaited directly" {...@@ -954,7 +954,7 @@ test "@asyncCall with comptime-known function, but not awaited directly" {
954 fn doTheTest() void {954 fn doTheTest() void {
955 var frame: [1]@Frame(middle) = undefined;955 var frame: [1]@Frame(middle) = undefined;
956 var result: @TypeOf(middle).ReturnType.ErrorSet!void = undefined;956 var result: @TypeOf(middle).ReturnType.ErrorSet!void = undefined;
957 _ = @asyncCall(@sliceToBytes(frame[0..]), &result, middle);957 _ = @asyncCall(std.mem.sliceAsBytes(frame[0..]), &result, middle);
958 resume global_frame;958 resume global_frame;
959 std.testing.expectError(error.Fail, result);959 std.testing.expectError(error.Fail, result);
960 }960 }
...@@ -1481,3 +1481,53 @@ test "handle defer interfering with return value spill" {...@@ -1481,3 +1481,53 @@ test "handle defer interfering with return value spill" {
1481 };1481 };
1482 S.doTheTest();1482 S.doTheTest();
1483}1483}
1484
1485test "take address of temporary async frame" {
1486 const S = struct {
1487 var global_frame: anyframe = undefined;
1488 var finished = false;
1489
1490 fn doTheTest() void {
1491 _ = async asyncDoTheTest();
1492 resume global_frame;
1493 expect(finished);
1494 }
1495
1496 fn asyncDoTheTest() void {
1497 expect(finishIt(&async foo(10)) == 1245);
1498 finished = true;
1499 }
1500
1501 fn foo(arg: i32) i32 {
1502 global_frame = @frame();
1503 suspend;
1504 return arg + 1234;
1505 }
1506
1507 fn finishIt(frame: anyframe->i32) i32 {
1508 return (await frame) + 1;
1509 }
1510 };
1511 S.doTheTest();
1512}
1513
1514test "noasync await" {
1515 const S = struct {
1516 var finished = false;
1517
1518 fn doTheTest() void {
1519 var frame = async foo(false);
1520 expect(noasync await frame == 42);
1521 finished = true;
1522 }
1523
1524 fn foo(want_suspend: bool) i32 {
1525 if (want_suspend) {
1526 suspend;
1527 }
1528 return 42;
1529 }
1530 };
1531 S.doTheTest();
1532 expect(S.finished);
1533}
test/stage1/behavior/bit_shifting.zig+2-2
...@@ -2,9 +2,9 @@ const std = @import("std");...@@ -2,9 +2,9 @@ const std = @import("std");
2const expect = std.testing.expect;2const expect = std.testing.expect;
33
4fn ShardedTable(comptime Key: type, comptime mask_bit_count: comptime_int, comptime V: type) type {4fn ShardedTable(comptime Key: type, comptime mask_bit_count: comptime_int, comptime V: type) type {
5 expect(Key == @IntType(false, Key.bit_count));5 expect(Key == std.meta.IntType(false, Key.bit_count));
6 expect(Key.bit_count >= mask_bit_count);6 expect(Key.bit_count >= mask_bit_count);
7 const ShardKey = @IntType(false, mask_bit_count);7 const ShardKey = std.meta.IntType(false, mask_bit_count);
8 const shift_amount = Key.bit_count - ShardKey.bit_count;8 const shift_amount = Key.bit_count - ShardKey.bit_count;
9 return struct {9 return struct {
10 const Self = @This();10 const Self = @This();
test/stage1/behavior/bugs/1851.zig+1-1
...@@ -13,7 +13,7 @@ test "allocation and looping over 3-byte integer" {...@@ -13,7 +13,7 @@ test "allocation and looping over 3-byte integer" {
13 x[0] = 0xFFFFFF;13 x[0] = 0xFFFFFF;
14 x[1] = 0xFFFFFF;14 x[1] = 0xFFFFFF;
1515
16 const bytes = @sliceToBytes(x);16 const bytes = std.mem.sliceAsBytes(x);
17 expect(@TypeOf(bytes) == []align(4) u8);17 expect(@TypeOf(bytes) == []align(4) u8);
18 expect(bytes.len == 8);18 expect(bytes.len == 8);
1919
test/stage1/behavior/bugs/3586.zig created+11
...@@ -0,0 +1,11 @@
1const NoteParams = struct {};
2
3const Container = struct {
4 params: ?NoteParams,
5};
6
7test "fixed" {
8 var ctr = Container{
9 .params = NoteParams{},
10 };
11}
test/stage1/behavior/bugs/3742.zig+1-1
...@@ -17,7 +17,7 @@ pub const GET = struct {...@@ -17,7 +17,7 @@ pub const GET = struct {
17};17};
1818
19pub fn isCommand(comptime T: type) bool {19pub fn isCommand(comptime T: type) bool {
20 const tid = @typeId(T);20 const tid = @typeInfo(T);
21 return (tid == .Struct or tid == .Enum or tid == .Union) and21 return (tid == .Struct or tid == .Enum or tid == .Union) and
22 @hasDecl(T, "Redis") and @hasDecl(T.Redis, "Command");22 @hasDecl(T, "Redis") and @hasDecl(T.Redis, "Command");
23}23}
test/stage1/behavior/cast.zig-20
...@@ -300,20 +300,6 @@ fn cast128Float(x: u128) f128 {...@@ -300,20 +300,6 @@ fn cast128Float(x: u128) f128 {
300 return @bitCast(f128, x);300 return @bitCast(f128, x);
301}301}
302302
303test "const slice widen cast" {
304 const bytes align(4) = [_]u8{
305 0x12,
306 0x12,
307 0x12,
308 0x12,
309 };
310
311 const u32_value = @bytesToSlice(u32, bytes[0..])[0];
312 expect(u32_value == 0x12121212);
313
314 expect(@bitCast(u32, bytes) == 0x12121212);
315}
316
317test "single-item pointer of array to slice and to unknown length pointer" {303test "single-item pointer of array to slice and to unknown length pointer" {
318 testCastPtrOfArrayToSliceAndPtr();304 testCastPtrOfArrayToSliceAndPtr();
319 comptime testCastPtrOfArrayToSliceAndPtr();305 comptime testCastPtrOfArrayToSliceAndPtr();
...@@ -388,12 +374,6 @@ test "comptime_int @intToFloat" {...@@ -388,12 +374,6 @@ test "comptime_int @intToFloat" {
388 }374 }
389}375}
390376
391test "@bytesToSlice keeps pointer alignment" {
392 var bytes = [_]u8{ 0x01, 0x02, 0x03, 0x04 };
393 const numbers = @bytesToSlice(u32, bytes[0..]);
394 comptime expect(@TypeOf(numbers) == []align(@alignOf(@TypeOf(bytes))) u32);
395}
396
397test "@intCast i32 to u7" {377test "@intCast i32 to u7" {
398 var x: u128 = maxInt(u128);378 var x: u128 = maxInt(u128);
399 var y: i32 = 120;379 var y: i32 = 120;
test/stage1/behavior/enum.zig+2-2
...@@ -96,8 +96,8 @@ test "enum type" {...@@ -96,8 +96,8 @@ test "enum type" {
96 const bar = Bar.B;96 const bar = Bar.B;
9797
98 expect(bar == Bar.B);98 expect(bar == Bar.B);
99 expect(@memberCount(Foo) == 3);99 expect(@typeInfo(Foo).Union.fields.len == 3);
100 expect(@memberCount(Bar) == 4);100 expect(@typeInfo(Bar).Enum.fields.len == 4);
101 expect(@sizeOf(Foo) == @sizeOf(FooNoVoid));101 expect(@sizeOf(Foo) == @sizeOf(FooNoVoid));
102 expect(@sizeOf(Bar) == 1);102 expect(@sizeOf(Bar) == 1);
103}103}
test/stage1/behavior/error.zig+3-4
...@@ -3,7 +3,6 @@ const expect = std.testing.expect;...@@ -3,7 +3,6 @@ const expect = std.testing.expect;
3const expectError = std.testing.expectError;3const expectError = std.testing.expectError;
4const expectEqual = std.testing.expectEqual;4const expectEqual = std.testing.expectEqual;
5const mem = std.mem;5const mem = std.mem;
6const builtin = @import("builtin");
76
8pub fn foo() anyerror!i32 {7pub fn foo() anyerror!i32 {
9 const x = try bar();8 const x = try bar();
...@@ -84,8 +83,8 @@ test "error union type " {...@@ -84,8 +83,8 @@ test "error union type " {
84fn testErrorUnionType() void {83fn testErrorUnionType() void {
85 const x: anyerror!i32 = 1234;84 const x: anyerror!i32 = 1234;
86 if (x) |value| expect(value == 1234) else |_| unreachable;85 if (x) |value| expect(value == 1234) else |_| unreachable;
87 expect(@typeId(@TypeOf(x)) == builtin.TypeId.ErrorUnion);86 expect(@typeInfo(@TypeOf(x)) == .ErrorUnion);
88 expect(@typeId(@TypeOf(x).ErrorSet) == builtin.TypeId.ErrorSet);87 expect(@typeInfo(@TypeOf(x).ErrorSet) == .ErrorSet);
89 expect(@TypeOf(x).ErrorSet == anyerror);88 expect(@TypeOf(x).ErrorSet == anyerror);
90}89}
9190
...@@ -100,7 +99,7 @@ const MyErrSet = error{...@@ -100,7 +99,7 @@ const MyErrSet = error{
100};99};
101100
102fn testErrorSetType() void {101fn testErrorSetType() void {
103 expect(@memberCount(MyErrSet) == 2);102 expect(@typeInfo(MyErrSet).ErrorSet.?.len == 2);
104103
105 const a: MyErrSet!i32 = 5678;104 const a: MyErrSet!i32 = 5678;
106 const b: MyErrSet!i32 = MyErrSet.OutOfMemory;105 const b: MyErrSet!i32 = MyErrSet.OutOfMemory;
test/stage1/behavior/eval.zig+2-12
...@@ -654,8 +654,8 @@ test "call method with comptime pass-by-non-copying-value self parameter" {...@@ -654,8 +654,8 @@ test "call method with comptime pass-by-non-copying-value self parameter" {
654 expect(b == 2);654 expect(b == 2);
655}655}
656656
657test "@tagName of @typeId" {657test "@tagName of @typeInfo" {
658 const str = @tagName(@typeId(u8));658 const str = @tagName(@typeInfo(u8));
659 expect(std.mem.eql(u8, str, "Int"));659 expect(std.mem.eql(u8, str, "Int"));
660}660}
661661
...@@ -711,16 +711,6 @@ test "bit shift a u1" {...@@ -711,16 +711,6 @@ test "bit shift a u1" {
711 expect(y == 1);711 expect(y == 1);
712}712}
713713
714test "@bytesToslice on a packed struct" {
715 const F = packed struct {
716 a: u8,
717 };
718
719 var b = [1]u8{9};
720 var f = @bytesToSlice(F, &b);
721 expect(f[0].a == 9);
722}
723
724test "comptime pointer cast array and then slice" {714test "comptime pointer cast array and then slice" {
725 const array = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8 };715 const array = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8 };
726716
test/stage1/behavior/for.zig+28
...@@ -1,5 +1,6 @@...@@ -1,5 +1,6 @@
1const std = @import("std");1const std = @import("std");
2const expect = std.testing.expect;2const expect = std.testing.expect;
3const expectEqual = std.testing.expectEqual;
3const mem = std.mem;4const mem = std.mem;
45
5test "continue in for loop" {6test "continue in for loop" {
...@@ -142,3 +143,30 @@ test "for with null and T peer types and inferred result location type" {...@@ -142,3 +143,30 @@ test "for with null and T peer types and inferred result location type" {
142 S.doTheTest(&[_]u8{ 1, 2 });143 S.doTheTest(&[_]u8{ 1, 2 });
143 comptime S.doTheTest(&[_]u8{ 1, 2 });144 comptime S.doTheTest(&[_]u8{ 1, 2 });
144}145}
146
147test "for copies its payload" {
148 const S = struct {
149 fn doTheTest() void {
150 var x = [_]usize{ 1, 2, 3 };
151 for (x) |value, i| {
152 // Modify the original array
153 x[i] += 99;
154 expectEqual(value, i + 1);
155 }
156 }
157 };
158 S.doTheTest();
159 comptime S.doTheTest();
160}
161
162test "for on slice with allowzero ptr" {
163 const S = struct {
164 fn doTheTest(slice: []u8) void {
165 var ptr = @ptrCast([*]allowzero u8, slice.ptr)[0..slice.len];
166 for (ptr) |x, i| expect(x == i + 1);
167 for (ptr) |*x, i| expect(x.* == i + 1);
168 }
169 };
170 S.doTheTest(&[_]u8{ 1, 2, 3, 4 });
171 comptime S.doTheTest(&[_]u8{ 1, 2, 3, 4 });
172}
test/stage1/behavior/if.zig+18-1
...@@ -1,4 +1,6 @@...@@ -1,4 +1,6 @@
1const expect = @import("std").testing.expect;1const std = @import("std");
2const expect = std.testing.expect;
3const expectEqual = std.testing.expectEqual;
24
3test "if statements" {5test "if statements" {
4 shouldBeEqual(1, 1);6 shouldBeEqual(1, 1);
...@@ -90,3 +92,18 @@ test "if prongs cast to expected type instead of peer type resolution" {...@@ -90,3 +92,18 @@ test "if prongs cast to expected type instead of peer type resolution" {
90 S.doTheTest(false);92 S.doTheTest(false);
91 comptime S.doTheTest(false);93 comptime S.doTheTest(false);
92}94}
95
96test "while copies its payload" {
97 const S = struct {
98 fn doTheTest() void {
99 var tmp: ?i32 = 10;
100 if (tmp) |value| {
101 // Modify the original variable
102 tmp = null;
103 expectEqual(@as(i32, 10), value);
104 } else unreachable;
105 }
106 };
107 S.doTheTest();
108 comptime S.doTheTest();
109}
test/stage1/behavior/math.zig+1-1
...@@ -266,7 +266,7 @@ fn testBinaryNot(x: u16) void {...@@ -266,7 +266,7 @@ fn testBinaryNot(x: u16) void {
266}266}
267267
268test "small int addition" {268test "small int addition" {
269 var x: @IntType(false, 2) = 0;269 var x: u2 = 0;
270 expect(x == 0);270 expect(x == 0);
271271
272 x += 1;272 x += 1;
test/stage1/behavior/misc.zig-85
...@@ -3,7 +3,6 @@ const expect = std.testing.expect;...@@ -3,7 +3,6 @@ const expect = std.testing.expect;
3const expectEqualSlices = std.testing.expectEqualSlices;3const expectEqualSlices = std.testing.expectEqualSlices;
4const mem = std.mem;4const mem = std.mem;
5const builtin = @import("builtin");5const builtin = @import("builtin");
6const maxInt = std.math.maxInt;
76
8// normal comment7// normal comment
98
...@@ -25,35 +24,6 @@ test "call disabled extern fn" {...@@ -25,35 +24,6 @@ test "call disabled extern fn" {
25 disabledExternFn();24 disabledExternFn();
26}25}
2726
28test "@IntType builtin" {
29 expect(@IntType(true, 8) == i8);
30 expect(@IntType(true, 16) == i16);
31 expect(@IntType(true, 32) == i32);
32 expect(@IntType(true, 64) == i64);
33
34 expect(@IntType(false, 8) == u8);
35 expect(@IntType(false, 16) == u16);
36 expect(@IntType(false, 32) == u32);
37 expect(@IntType(false, 64) == u64);
38
39 expect(i8.bit_count == 8);
40 expect(i16.bit_count == 16);
41 expect(i32.bit_count == 32);
42 expect(i64.bit_count == 64);
43
44 expect(i8.is_signed);
45 expect(i16.is_signed);
46 expect(i32.is_signed);
47 expect(i64.is_signed);
48 expect(isize.is_signed);
49
50 expect(!u8.is_signed);
51 expect(!u16.is_signed);
52 expect(!u32.is_signed);
53 expect(!u64.is_signed);
54 expect(!usize.is_signed);
55}
56
57test "floating point primitive bit counts" {27test "floating point primitive bit counts" {
58 expect(f16.bit_count == 16);28 expect(f16.bit_count == 16);
59 expect(f32.bit_count == 32);29 expect(f32.bit_count == 32);
...@@ -377,26 +347,6 @@ test "string concatenation" {...@@ -377,26 +347,6 @@ test "string concatenation" {
377 expect(b[len] == 0);347 expect(b[len] == 0);
378}348}
379349
380test "cast slice to u8 slice" {
381 expect(@sizeOf(i32) == 4);
382 var big_thing_array = [_]i32{ 1, 2, 3, 4 };
383 const big_thing_slice: []i32 = big_thing_array[0..];
384 const bytes = @sliceToBytes(big_thing_slice);
385 expect(bytes.len == 4 * 4);
386 bytes[4] = 0;
387 bytes[5] = 0;
388 bytes[6] = 0;
389 bytes[7] = 0;
390 expect(big_thing_slice[1] == 0);
391 const big_thing_again = @bytesToSlice(i32, bytes);
392 expect(big_thing_again[2] == 3);
393 big_thing_again[2] = -1;
394 expect(bytes[8] == maxInt(u8));
395 expect(bytes[9] == maxInt(u8));
396 expect(bytes[10] == maxInt(u8));
397 expect(bytes[11] == maxInt(u8));
398}
399
400test "pointer to void return type" {350test "pointer to void return type" {
401 testPointerToVoidReturnType() catch unreachable;351 testPointerToVoidReturnType() catch unreachable;
402}352}
...@@ -428,7 +378,6 @@ fn testArray2DConstDoublePtr(ptr: *const f32) void {...@@ -428,7 +378,6 @@ fn testArray2DConstDoublePtr(ptr: *const f32) void {
428 expect(ptr2[1] == 2.0);378 expect(ptr2[1] == 2.0);
429}379}
430380
431const Tid = builtin.TypeId;
432const AStruct = struct {381const AStruct = struct {
433 x: i32,382 x: i32,
434};383};
...@@ -445,40 +394,6 @@ const AUnion = union {...@@ -445,40 +394,6 @@ const AUnion = union {
445 Two: void,394 Two: void,
446};395};
447396
448test "@typeId" {
449 comptime {
450 expect(@typeId(type) == Tid.Type);
451 expect(@typeId(void) == Tid.Void);
452 expect(@typeId(bool) == Tid.Bool);
453 expect(@typeId(noreturn) == Tid.NoReturn);
454 expect(@typeId(i8) == Tid.Int);
455 expect(@typeId(u8) == Tid.Int);
456 expect(@typeId(i64) == Tid.Int);
457 expect(@typeId(u64) == Tid.Int);
458 expect(@typeId(f32) == Tid.Float);
459 expect(@typeId(f64) == Tid.Float);
460 expect(@typeId(*f32) == Tid.Pointer);
461 expect(@typeId([2]u8) == Tid.Array);
462 expect(@typeId(AStruct) == Tid.Struct);
463 expect(@typeId(@TypeOf(1)) == Tid.ComptimeInt);
464 expect(@typeId(@TypeOf(1.0)) == Tid.ComptimeFloat);
465 expect(@typeId(@TypeOf(undefined)) == Tid.Undefined);
466 expect(@typeId(@TypeOf(null)) == Tid.Null);
467 expect(@typeId(?i32) == Tid.Optional);
468 expect(@typeId(anyerror!i32) == Tid.ErrorUnion);
469 expect(@typeId(anyerror) == Tid.ErrorSet);
470 expect(@typeId(AnEnum) == Tid.Enum);
471 expect(@typeId(@TypeOf(AUnionEnum.One)) == Tid.Enum);
472 expect(@typeId(AUnionEnum) == Tid.Union);
473 expect(@typeId(AUnion) == Tid.Union);
474 expect(@typeId(fn () void) == Tid.Fn);
475 expect(@typeId(@TypeOf(builtin)) == Tid.Type);
476 // TODO bound fn
477 // TODO arg tuple
478 // TODO opaque
479 }
480}
481
482test "@typeName" {397test "@typeName" {
483 const Struct = struct {};398 const Struct = struct {};
484 const Union = union {399 const Union = union {
test/stage1/behavior/reflection.zig+3-33
...@@ -16,9 +16,9 @@ test "reflection: function return type, var args, and param types" {...@@ -16,9 +16,9 @@ test "reflection: function return type, var args, and param types" {
16 expect(@TypeOf(dummy).ReturnType == i32);16 expect(@TypeOf(dummy).ReturnType == i32);
17 expect(!@TypeOf(dummy).is_var_args);17 expect(!@TypeOf(dummy).is_var_args);
18 expect(@TypeOf(dummy).arg_count == 3);18 expect(@TypeOf(dummy).arg_count == 3);
19 expect(@ArgType(@TypeOf(dummy), 0) == bool);19 expect(@typeInfo(@TypeOf(dummy)).Fn.args[0].arg_type.? == bool);
20 expect(@ArgType(@TypeOf(dummy), 1) == i32);20 expect(@typeInfo(@TypeOf(dummy)).Fn.args[1].arg_type.? == i32);
21 expect(@ArgType(@TypeOf(dummy), 2) == f32);21 expect(@typeInfo(@TypeOf(dummy)).Fn.args[2].arg_type.? == f32);
22 }22 }
23}23}
2424
...@@ -26,36 +26,6 @@ fn dummy(a: bool, b: i32, c: f32) i32 {...@@ -26,36 +26,6 @@ fn dummy(a: bool, b: i32, c: f32) i32 {
26 return 1234;26 return 1234;
27}27}
2828
29test "reflection: struct member types and names" {
30 comptime {
31 expect(@memberCount(Foo) == 3);
32
33 expect(@memberType(Foo, 0) == i32);
34 expect(@memberType(Foo, 1) == bool);
35 expect(@memberType(Foo, 2) == void);
36
37 expect(mem.eql(u8, @memberName(Foo, 0), "one"));
38 expect(mem.eql(u8, @memberName(Foo, 1), "two"));
39 expect(mem.eql(u8, @memberName(Foo, 2), "three"));
40 }
41}
42
43test "reflection: enum member types and names" {
44 comptime {
45 expect(@memberCount(Bar) == 4);
46
47 expect(@memberType(Bar, 0) == void);
48 expect(@memberType(Bar, 1) == i32);
49 expect(@memberType(Bar, 2) == bool);
50 expect(@memberType(Bar, 3) == f64);
51
52 expect(mem.eql(u8, @memberName(Bar, 0), "One"));
53 expect(mem.eql(u8, @memberName(Bar, 1), "Two"));
54 expect(mem.eql(u8, @memberName(Bar, 2), "Three"));
55 expect(mem.eql(u8, @memberName(Bar, 3), "Four"));
56 }
57}
58
59test "reflection: @field" {29test "reflection: @field" {
60 var f = Foo{30 var f = Foo{
61 .one = 42,31 .one = 42,
test/stage1/behavior/slicetobytes.zig deleted-29
...@@ -1,29 +0,0 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const expect = std.testing.expect;
4
5test "@sliceToBytes packed struct at runtime and comptime" {
6 const Foo = packed struct {
7 a: u4,
8 b: u4,
9 };
10 const S = struct {
11 fn doTheTest() void {
12 var foo: Foo = undefined;
13 var slice = @sliceToBytes(@as(*[1]Foo, &foo)[0..1]);
14 slice[0] = 0x13;
15 switch (builtin.endian) {
16 builtin.Endian.Big => {
17 expect(foo.a == 0x1);
18 expect(foo.b == 0x3);
19 },
20 builtin.Endian.Little => {
21 expect(foo.a == 0x3);
22 expect(foo.b == 0x1);
23 },
24 }
25 }
26 };
27 S.doTheTest();
28 comptime S.doTheTest();
29}
test/stage1/behavior/struct.zig+2-2
...@@ -315,7 +315,7 @@ test "packed array 24bits" {...@@ -315,7 +315,7 @@ test "packed array 24bits" {
315315
316 var bytes = [_]u8{0} ** (@sizeOf(FooArray24Bits) + 1);316 var bytes = [_]u8{0} ** (@sizeOf(FooArray24Bits) + 1);
317 bytes[bytes.len - 1] = 0xaa;317 bytes[bytes.len - 1] = 0xaa;
318 const ptr = &@bytesToSlice(FooArray24Bits, bytes[0 .. bytes.len - 1])[0];318 const ptr = &std.mem.bytesAsSlice(FooArray24Bits, bytes[0 .. bytes.len - 1])[0];
319 expect(ptr.a == 0);319 expect(ptr.a == 0);
320 expect(ptr.b[0].field == 0);320 expect(ptr.b[0].field == 0);
321 expect(ptr.b[1].field == 0);321 expect(ptr.b[1].field == 0);
...@@ -364,7 +364,7 @@ test "aligned array of packed struct" {...@@ -364,7 +364,7 @@ test "aligned array of packed struct" {
364 }364 }
365365
366 var bytes = [_]u8{0xbb} ** @sizeOf(FooArrayOfAligned);366 var bytes = [_]u8{0xbb} ** @sizeOf(FooArrayOfAligned);
367 const ptr = &@bytesToSlice(FooArrayOfAligned, bytes[0..bytes.len])[0];367 const ptr = &std.mem.bytesAsSlice(FooArrayOfAligned, bytes[0..])[0];
368368
369 expect(ptr.a[0].a == 0xbb);369 expect(ptr.a[0].a == 0xbb);
370 expect(ptr.a[0].b == 0xbb);370 expect(ptr.a[0].b == 0xbb);
test/stage1/behavior/switch.zig+22
...@@ -1,6 +1,7 @@...@@ -1,6 +1,7 @@
1const std = @import("std");1const std = @import("std");
2const expect = std.testing.expect;2const expect = std.testing.expect;
3const expectError = std.testing.expectError;3const expectError = std.testing.expectError;
4const expectEqual = std.testing.expectEqual;
45
5test "switch with numbers" {6test "switch with numbers" {
6 testSwitchWithNumbers(13);7 testSwitchWithNumbers(13);
...@@ -493,3 +494,24 @@ test "switch on error set with single else" {...@@ -493,3 +494,24 @@ test "switch on error set with single else" {
493 S.doTheTest();494 S.doTheTest();
494 comptime S.doTheTest();495 comptime S.doTheTest();
495}496}
497
498test "while copies its payload" {
499 const S = struct {
500 fn doTheTest() void {
501 var tmp: union(enum) {
502 A: u8,
503 B: u32,
504 } = .{ .A = 42 };
505 switch (tmp) {
506 .A => |value| {
507 // Modify the original union
508 tmp = .{ .B = 0x10101010 };
509 expectEqual(@as(u8, 42), value);
510 },
511 else => unreachable,
512 }
513 }
514 };
515 S.doTheTest();
516 comptime S.doTheTest();
517}
test/stage1/behavior/type_info.zig+11
...@@ -375,3 +375,14 @@ test "sentinel of opaque pointer type" {...@@ -375,3 +375,14 @@ test "sentinel of opaque pointer type" {
375 const c_void_info = @typeInfo(*c_void);375 const c_void_info = @typeInfo(*c_void);
376 expect(c_void_info.Pointer.sentinel == null);376 expect(c_void_info.Pointer.sentinel == null);
377}377}
378
379test "@typeInfo does not force declarations into existence" {
380 const S = struct {
381 x: i32,
382
383 fn doNotReferenceMe() void {
384 @compileError("test failed");
385 }
386 };
387 comptime expect(@typeInfo(S).Struct.fields.len == 1);
388}
test/stage1/behavior/union.zig+1-1
...@@ -531,7 +531,7 @@ var glbl: Foo1 = undefined;...@@ -531,7 +531,7 @@ var glbl: Foo1 = undefined;
531531
532test "global union with single field is correctly initialized" {532test "global union with single field is correctly initialized" {
533 glbl = Foo1{533 glbl = Foo1{
534 .f = @memberType(Foo1, 0){ .x = 123 },534 .f = @typeInfo(Foo1).Union.fields[0].field_type{ .x = 123 },
535 };535 };
536 expect(glbl.f.x == 123);536 expect(glbl.f.x == 123);
537}537}
test/stage1/behavior/while.zig+17-1
...@@ -1,4 +1,5 @@...@@ -1,4 +1,5 @@
1const expect = @import("std").testing.expect;1const std = @import("std");
2const expect = std.testing.expect;
23
3test "while loop" {4test "while loop" {
4 var i: i32 = 0;5 var i: i32 = 0;
...@@ -271,3 +272,18 @@ test "while error 2 break statements and an else" {...@@ -271,3 +272,18 @@ test "while error 2 break statements and an else" {
271 S.entry(true, false);272 S.entry(true, false);
272 comptime S.entry(true, false);273 comptime S.entry(true, false);
273}274}
275
276test "while copies its payload" {
277 const S = struct {
278 fn doTheTest() void {
279 var tmp: ?i32 = 10;
280 while (tmp) |value| {
281 // Modify the original variable
282 tmp = null;
283 expect(value == 10);
284 }
285 }
286 };
287 S.doTheTest();
288 comptime S.doTheTest();
289}
test/standalone/guess_number/main.zig+7-7
...@@ -5,6 +5,7 @@ const fmt = std.fmt;...@@ -5,6 +5,7 @@ const fmt = std.fmt;
55
6pub fn main() !void {6pub fn main() !void {
7 const stdout = &io.getStdOut().outStream().stream;7 const stdout = &io.getStdOut().outStream().stream;
8 const stdin = io.getStdIn();
89
9 try stdout.print("Welcome to the Guess Number Game in Zig.\n", .{});10 try stdout.print("Welcome to the Guess Number Game in Zig.\n", .{});
1011
...@@ -22,13 +23,12 @@ pub fn main() !void {...@@ -22,13 +23,12 @@ pub fn main() !void {
22 try stdout.print("\nGuess a number between 1 and 100: ", .{});23 try stdout.print("\nGuess a number between 1 and 100: ", .{});
23 var line_buf: [20]u8 = undefined;24 var line_buf: [20]u8 = undefined;
2425
25 const line = io.readLineSlice(line_buf[0..]) catch |err| switch (err) {26 const amt = try stdin.read(&line_buf);
26 error.OutOfMemory => {27 if (amt == line_buf.len) {
27 try stdout.print("Input too long.\n", .{});28 try stdout.print("Input too long.\n", .{});
28 continue;29 continue;
29 },30 }
30 else => return err,31 const line = std.mem.trimRight(u8, line_buf[0..amt], "\r\n");
31 };
3232
33 const guess = fmt.parseUnsigned(u8, line, 10) catch {33 const guess = fmt.parseUnsigned(u8, line, 10) catch {
34 try stdout.print("Invalid number.\n", .{});34 try stdout.print("Invalid number.\n", .{});
test/tests.zig+32-57
...@@ -55,20 +55,18 @@ const test_targets = blk: {...@@ -55,20 +55,18 @@ const test_targets = blk: {
55 TestTarget{55 TestTarget{
56 .target = Target{56 .target = Target{
57 .Cross = CrossTarget{57 .Cross = CrossTarget{
58 .cpu = Target.Cpu.baseline(.x86_64),
58 .os = .linux,59 .os = .linux,
59 .arch = .x86_64,
60 .abi = .none,60 .abi = .none,
61 .cpu_features = Target.Arch.x86_64.getBaselineCpuFeatures(),
62 },61 },
63 },62 },
64 },63 },
65 TestTarget{64 TestTarget{
66 .target = Target{65 .target = Target{
67 .Cross = CrossTarget{66 .Cross = CrossTarget{
67 .cpu = Target.Cpu.baseline(.x86_64),
68 .os = .linux,68 .os = .linux,
69 .arch = .x86_64,
70 .abi = .gnu,69 .abi = .gnu,
71 .cpu_features = Target.Arch.x86_64.getBaselineCpuFeatures(),
72 },70 },
73 },71 },
74 .link_libc = true,72 .link_libc = true,
...@@ -76,9 +74,8 @@ const test_targets = blk: {...@@ -76,9 +74,8 @@ const test_targets = blk: {
76 TestTarget{74 TestTarget{
77 .target = Target{75 .target = Target{
78 .Cross = CrossTarget{76 .Cross = CrossTarget{
77 .cpu = Target.Cpu.baseline(.x86_64),
79 .os = .linux,78 .os = .linux,
80 .arch = .x86_64,
81 .cpu_features = Target.Arch.x86_64.getBaselineCpuFeatures(),
82 .abi = .musl,79 .abi = .musl,
83 },80 },
84 },81 },
...@@ -88,9 +85,8 @@ const test_targets = blk: {...@@ -88,9 +85,8 @@ const test_targets = blk: {
88 TestTarget{85 TestTarget{
89 .target = Target{86 .target = Target{
90 .Cross = CrossTarget{87 .Cross = CrossTarget{
88 .cpu = Target.Cpu.baseline(.i386),
91 .os = .linux,89 .os = .linux,
92 .arch = .i386,
93 .cpu_features = Target.Arch.i386.getBaselineCpuFeatures(),
94 .abi = .none,90 .abi = .none,
95 },91 },
96 },92 },
...@@ -98,9 +94,8 @@ const test_targets = blk: {...@@ -98,9 +94,8 @@ const test_targets = blk: {
98 TestTarget{94 TestTarget{
99 .target = Target{95 .target = Target{
100 .Cross = CrossTarget{96 .Cross = CrossTarget{
97 .cpu = Target.Cpu.baseline(.i386),
101 .os = .linux,98 .os = .linux,
102 .arch = .i386,
103 .cpu_features = Target.Arch.i386.getBaselineCpuFeatures(),
104 .abi = .musl,99 .abi = .musl,
105 },100 },
106 },101 },
...@@ -110,9 +105,8 @@ const test_targets = blk: {...@@ -110,9 +105,8 @@ const test_targets = blk: {
110 TestTarget{105 TestTarget{
111 .target = Target{106 .target = Target{
112 .Cross = CrossTarget{107 .Cross = CrossTarget{
108 .cpu = Target.Cpu.baseline(.aarch64),
113 .os = .linux,109 .os = .linux,
114 .arch = Target.Arch{ .aarch64 = .v8a },
115 .cpu_features = (Target.Arch{ .aarch64 = .v8a }).getBaselineCpuFeatures(),
116 .abi = .none,110 .abi = .none,
117 },111 },
118 },112 },
...@@ -120,9 +114,8 @@ const test_targets = blk: {...@@ -120,9 +114,8 @@ const test_targets = blk: {
120 TestTarget{114 TestTarget{
121 .target = Target{115 .target = Target{
122 .Cross = CrossTarget{116 .Cross = CrossTarget{
117 .cpu = Target.Cpu.baseline(.aarch64),
123 .os = .linux,118 .os = .linux,
124 .arch = Target.Arch{ .aarch64 = .v8a },
125 .cpu_features = (Target.Arch{ .aarch64 = .v8a }).getBaselineCpuFeatures(),
126 .abi = .musl,119 .abi = .musl,
127 },120 },
128 },121 },
...@@ -131,9 +124,8 @@ const test_targets = blk: {...@@ -131,9 +124,8 @@ const test_targets = blk: {
131 TestTarget{124 TestTarget{
132 .target = Target{125 .target = Target{
133 .Cross = CrossTarget{126 .Cross = CrossTarget{
127 .cpu = Target.Cpu.baseline(.aarch64),
134 .os = .linux,128 .os = .linux,
135 .arch = Target.Arch{ .aarch64 = .v8a },
136 .cpu_features = (Target.Arch{ .aarch64 = .v8a }).getBaselineCpuFeatures(),
137 .abi = .gnu,129 .abi = .gnu,
138 },130 },
139 },131 },
...@@ -141,45 +133,32 @@ const test_targets = blk: {...@@ -141,45 +133,32 @@ const test_targets = blk: {
141 },133 },
142134
143 TestTarget{135 TestTarget{
144 .target = Target{136 .target = Target.parse(.{
145 .Cross = CrossTarget{137 .arch_os_abi = "arm-linux-none",
146 .os = .linux,138 .cpu_features = "generic+v8a",
147 .arch = Target.Arch{ .arm = .v8a },139 }) catch unreachable,
148 .cpu_features = (Target.Arch{ .arm = .v8a }).getBaselineCpuFeatures(),
149 .abi = .none,
150 },
151 },
152 },140 },
153 TestTarget{141 TestTarget{
154 .target = Target{142 .target = Target.parse(.{
155 .Cross = CrossTarget{143 .arch_os_abi = "arm-linux-musleabihf",
156 .os = .linux,144 .cpu_features = "generic+v8a",
157 .arch = Target.Arch{ .arm = .v8a },145 }) catch unreachable,
158 .cpu_features = (Target.Arch{ .arm = .v8a }).getBaselineCpuFeatures(),
159 .abi = .musleabihf,
160 },
161 },
162 .link_libc = true,146 .link_libc = true,
163 },147 },
164 // TODO https://github.com/ziglang/zig/issues/3287148 // TODO https://github.com/ziglang/zig/issues/3287
165 //TestTarget{149 //TestTarget{
166 // .target = Target{150 // .target = Target.parse(.{
167 // .Cross = CrossTarget{151 // .arch_os_abi = "arm-linux-gnueabihf",
168 // .os = .linux,152 // .cpu_features = "generic+v8a",
169 // .arch = Target.Arch{ .arm = .v8a },153 // }) catch unreachable,
170 // .cpu_features = (Target.Arch{ .arm = .v8a }).getBaselineCpuFeatures(),
171 // .abi = .gnueabihf,
172 // },
173 // },
174 // .link_libc = true,154 // .link_libc = true,
175 //},155 //},
176156
177 TestTarget{157 TestTarget{
178 .target = Target{158 .target = Target{
179 .Cross = CrossTarget{159 .Cross = CrossTarget{
160 .cpu = Target.Cpu.baseline(.mipsel),
180 .os = .linux,161 .os = .linux,
181 .arch = .mipsel,
182 .cpu_features = Target.Arch.mipsel.getBaselineCpuFeatures(),
183 .abi = .none,162 .abi = .none,
184 },163 },
185 },164 },
...@@ -187,9 +166,8 @@ const test_targets = blk: {...@@ -187,9 +166,8 @@ const test_targets = blk: {
187 TestTarget{166 TestTarget{
188 .target = Target{167 .target = Target{
189 .Cross = CrossTarget{168 .Cross = CrossTarget{
169 .cpu = Target.Cpu.baseline(.mipsel),
190 .os = .linux,170 .os = .linux,
191 .arch = .mipsel,
192 .cpu_features = Target.Arch.mipsel.getBaselineCpuFeatures(),
193 .abi = .musl,171 .abi = .musl,
194 },172 },
195 },173 },
...@@ -236,9 +214,8 @@ const test_targets = blk: {...@@ -236,9 +214,8 @@ const test_targets = blk: {
236 TestTarget{214 TestTarget{
237 .target = Target{215 .target = Target{
238 .Cross = CrossTarget{216 .Cross = CrossTarget{
217 .cpu = Target.Cpu.baseline(.x86_64),
239 .os = .macosx,218 .os = .macosx,
240 .arch = .x86_64,
241 .cpu_features = Target.Arch.x86_64.getBaselineCpuFeatures(),
242 .abi = .gnu,219 .abi = .gnu,
243 },220 },
244 },221 },
...@@ -249,9 +226,8 @@ const test_targets = blk: {...@@ -249,9 +226,8 @@ const test_targets = blk: {
249 TestTarget{226 TestTarget{
250 .target = Target{227 .target = Target{
251 .Cross = CrossTarget{228 .Cross = CrossTarget{
229 .cpu = Target.Cpu.baseline(.i386),
252 .os = .windows,230 .os = .windows,
253 .arch = .i386,
254 .cpu_features = Target.Arch.i386.getBaselineCpuFeatures(),
255 .abi = .msvc,231 .abi = .msvc,
256 },232 },
257 },233 },
...@@ -260,9 +236,8 @@ const test_targets = blk: {...@@ -260,9 +236,8 @@ const test_targets = blk: {
260 TestTarget{236 TestTarget{
261 .target = Target{237 .target = Target{
262 .Cross = CrossTarget{238 .Cross = CrossTarget{
239 .cpu = Target.Cpu.baseline(.x86_64),
263 .os = .windows,240 .os = .windows,
264 .arch = .x86_64,
265 .cpu_features = Target.Arch.x86_64.getBaselineCpuFeatures(),
266 .abi = .msvc,241 .abi = .msvc,
267 },242 },
268 },243 },
...@@ -271,9 +246,8 @@ const test_targets = blk: {...@@ -271,9 +246,8 @@ const test_targets = blk: {
271 TestTarget{246 TestTarget{
272 .target = Target{247 .target = Target{
273 .Cross = CrossTarget{248 .Cross = CrossTarget{
249 .cpu = Target.Cpu.baseline(.i386),
274 .os = .windows,250 .os = .windows,
275 .arch = .i386,
276 .cpu_features = Target.Arch.i386.getBaselineCpuFeatures(),
277 .abi = .gnu,251 .abi = .gnu,
278 },252 },
279 },253 },
...@@ -283,9 +257,8 @@ const test_targets = blk: {...@@ -283,9 +257,8 @@ const test_targets = blk: {
283 TestTarget{257 TestTarget{
284 .target = Target{258 .target = Target{
285 .Cross = CrossTarget{259 .Cross = CrossTarget{
260 .cpu = Target.Cpu.baseline(.x86_64),
286 .os = .windows,261 .os = .windows,
287 .arch = .x86_64,
288 .cpu_features = Target.Arch.x86_64.getBaselineCpuFeatures(),
289 .abi = .gnu,262 .abi = .gnu,
290 },263 },
291 },264 },
...@@ -513,7 +486,7 @@ pub fn addPkgTests(...@@ -513,7 +486,7 @@ pub fn addPkgTests(
513 const ArchTag = @TagType(builtin.Arch);486 const ArchTag = @TagType(builtin.Arch);
514 if (test_target.disable_native and487 if (test_target.disable_native and
515 test_target.target.getOs() == builtin.os and488 test_target.target.getOs() == builtin.os and
516 @as(ArchTag, test_target.target.getArch()) == @as(ArchTag, builtin.arch))489 test_target.target.getArch() == builtin.arch)
517 {490 {
518 continue;491 continue;
519 }492 }
...@@ -714,8 +687,10 @@ pub const StackTracesContext = struct {...@@ -714,8 +687,10 @@ pub const StackTracesContext = struct {
714 const got: []const u8 = got_result: {687 const got: []const u8 = got_result: {
715 var buf = try Buffer.initSize(b.allocator, 0);688 var buf = try Buffer.initSize(b.allocator, 0);
716 defer buf.deinit();689 defer buf.deinit();
717 var bytes = stderr.toSliceConst();690 const bytes = if (stderr.endsWith("\n"))
718 if (bytes.len != 0 and bytes[bytes.len - 1] == '\n') bytes = bytes[0 .. bytes.len - 1];691 stderr.toSliceConst()[0 .. stderr.len() - 1]
692 else
693 stderr.toSliceConst()[0..stderr.len()];
719 var it = mem.separate(bytes, "\n");694 var it = mem.separate(bytes, "\n");
720 process_lines: while (it.next()) |line| {695 process_lines: while (it.next()) |line| {
721 if (line.len == 0) continue;696 if (line.len == 0) continue;
test/translate_c.zig+20-22
...@@ -3,6 +3,13 @@ const builtin = @import("builtin");...@@ -3,6 +3,13 @@ const builtin = @import("builtin");
3const Target = @import("std").Target;3const Target = @import("std").Target;
44
5pub fn addCases(cases: *tests.TranslateCContext) void {5pub fn addCases(cases: *tests.TranslateCContext) void {
6 cases.add("macro line continuation",
7 \\#define FOO -\
8 \\BAR
9 , &[_][]const u8{
10 \\pub const FOO = -BAR;
11 });
12
6 cases.add("function prototype translated as optional",13 cases.add("function prototype translated as optional",
7 \\typedef void (*fnptr_ty)(void);14 \\typedef void (*fnptr_ty)(void);
8 \\typedef __attribute__((cdecl)) void (*fnptr_attr_ty)(void);15 \\typedef __attribute__((cdecl)) void (*fnptr_attr_ty)(void);
...@@ -1088,10 +1095,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1088,10 +1095,9 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
10881095
1089 cases.addWithTarget("Calling convention", tests.Target{1096 cases.addWithTarget("Calling convention", tests.Target{
1090 .Cross = .{1097 .Cross = .{
1098 .cpu = Target.Cpu.baseline(.i386),
1091 .os = .linux,1099 .os = .linux,
1092 .arch = .i386,
1093 .abi = .none,1100 .abi = .none,
1094 .cpu_features = Target.Arch.i386.getBaselineCpuFeatures(),
1095 },1101 },
1096 },1102 },
1097 \\void __attribute__((fastcall)) foo1(float *a);1103 \\void __attribute__((fastcall)) foo1(float *a);
...@@ -1107,14 +1113,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1107,14 +1113,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1107 \\pub fn foo5(a: [*c]f32) callconv(.Thiscall) void;1113 \\pub fn foo5(a: [*c]f32) callconv(.Thiscall) void;
1108 });1114 });
11091115
1110 cases.addWithTarget("Calling convention", tests.Target{1116 cases.addWithTarget("Calling convention", Target.parse(.{
1111 .Cross = .{1117 .arch_os_abi = "arm-linux-none",
1112 .os = .linux,1118 .cpu_features = "generic+v8_5a",
1113 .arch = .{ .arm = .v8_5a },1119 }) catch unreachable,
1114 .abi = .none,
1115 .cpu_features = (Target.Arch{ .arm = .v8_5a }).getBaselineCpuFeatures(),
1116 },
1117 },
1118 \\void __attribute__((pcs("aapcs"))) foo1(float *a);1120 \\void __attribute__((pcs("aapcs"))) foo1(float *a);
1119 \\void __attribute__((pcs("aapcs-vfp"))) foo2(float *a);1121 \\void __attribute__((pcs("aapcs-vfp"))) foo2(float *a);
1120 , &[_][]const u8{1122 , &[_][]const u8{
...@@ -1122,14 +1124,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1122,14 +1124,10 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1122 \\pub fn foo2(a: [*c]f32) callconv(.AAPCSVFP) void;1124 \\pub fn foo2(a: [*c]f32) callconv(.AAPCSVFP) void;
1123 });1125 });
11241126
1125 cases.addWithTarget("Calling convention", tests.Target{1127 cases.addWithTarget("Calling convention", Target.parse(.{
1126 .Cross = .{1128 .arch_os_abi = "aarch64-linux-none",
1127 .os = .linux,1129 .cpu_features = "generic+v8_5a",
1128 .arch = .{ .aarch64 = .v8_5a },1130 }) catch unreachable,
1129 .abi = .none,
1130 .cpu_features = (Target.Arch{ .aarch64 = .v8_5a }).getBaselineCpuFeatures(),
1131 },
1132 },
1133 \\void __attribute__((aarch64_vector_pcs)) foo1(float *a);1131 \\void __attribute__((aarch64_vector_pcs)) foo1(float *a);
1134 , &[_][]const u8{1132 , &[_][]const u8{
1135 \\pub fn foo1(a: [*c]f32) callconv(.Vectorcall) void;1133 \\pub fn foo1(a: [*c]f32) callconv(.Vectorcall) void;
...@@ -1356,7 +1354,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1356,7 +1354,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1356 cases.add("macro pointer cast",1354 cases.add("macro pointer cast",
1357 \\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE)1355 \\#define NRF_GPIO ((NRF_GPIO_Type *) NRF_GPIO_BASE)
1358 , &[_][]const u8{1356 , &[_][]const u8{
1359 \\pub const NRF_GPIO = if (@typeId(@TypeOf(NRF_GPIO_BASE)) == .Pointer) @ptrCast([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeId(@TypeOf(NRF_GPIO_BASE)) == .Int) @intToPtr([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else @as([*c]NRF_GPIO_Type, NRF_GPIO_BASE);1357 \\pub const NRF_GPIO = if (@typeInfo(@TypeOf(NRF_GPIO_BASE)) == .Pointer) @ptrCast([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else if (@typeInfo(@TypeOf(NRF_GPIO_BASE)) == .Int) @intToPtr([*c]NRF_GPIO_Type, NRF_GPIO_BASE) else @as([*c]NRF_GPIO_Type, NRF_GPIO_BASE);
1360 });1358 });
13611359
1362 cases.add("basic macro function",1360 cases.add("basic macro function",
...@@ -2540,11 +2538,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2540,11 +2538,11 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2540 \\#define FOO(bar) baz((void *)(baz))2538 \\#define FOO(bar) baz((void *)(baz))
2541 \\#define BAR (void*) a2539 \\#define BAR (void*) a
2542 , &[_][]const u8{2540 , &[_][]const u8{
2543 \\pub inline fn FOO(bar: var) @TypeOf(baz(if (@typeId(@TypeOf(baz)) == .Pointer) @ptrCast(*c_void, baz) else if (@typeId(@TypeOf(baz)) == .Int) @intToPtr(*c_void, baz) else @as(*c_void, baz))) {2541 \\pub inline fn FOO(bar: var) @TypeOf(baz(if (@typeInfo(@TypeOf(baz)) == .Pointer) @ptrCast(*c_void, baz) else if (@typeInfo(@TypeOf(baz)) == .Int) @intToPtr(*c_void, baz) else @as(*c_void, baz))) {
2544 \\ return baz(if (@typeId(@TypeOf(baz)) == .Pointer) @ptrCast(*c_void, baz) else if (@typeId(@TypeOf(baz)) == .Int) @intToPtr(*c_void, baz) else @as(*c_void, baz));2542 \\ return baz(if (@typeInfo(@TypeOf(baz)) == .Pointer) @ptrCast(*c_void, baz) else if (@typeInfo(@TypeOf(baz)) == .Int) @intToPtr(*c_void, baz) else @as(*c_void, baz));
2545 \\}2543 \\}
2546 ,2544 ,
2547 \\pub const BAR = if (@typeId(@TypeOf(a)) == .Pointer) @ptrCast(*c_void, a) else if (@typeId(@TypeOf(a)) == .Int) @intToPtr(*c_void, a) else @as(*c_void, a);2545 \\pub const BAR = if (@typeInfo(@TypeOf(a)) == .Pointer) @ptrCast(*c_void, a) else if (@typeInfo(@TypeOf(a)) == .Int) @intToPtr(*c_void, a) else @as(*c_void, a);
2548 });2546 });
25492547
2550 cases.add("macro conditional operator",2548 cases.add("macro conditional operator",