diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0bfcce1bb..faf517e80 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -102,8 +102,8 @@ jobs: run: | wget https://apt.llvm.org/llvm.sh chmod +x llvm.sh - sudo ./llvm.sh 20 - echo "/usr/lib/llvm-20/bin" >> $GITHUB_PATH + sudo ./llvm.sh 22 + echo "/usr/lib/llvm-22/bin" >> $GITHUB_PATH - name: Build Odin run: ./build_odin.sh release - name: Odin version diff --git a/core/fmt/fmt.odin b/core/fmt/fmt.odin index a2e6d2247..385526a6b 100644 --- a/core/fmt/fmt.odin +++ b/core/fmt/fmt.odin @@ -1461,8 +1461,17 @@ fmt_float :: proc(fi: ^Info, v: f64, bit_size: int, verb: rune) { _fmt_float_as(fi, v, bit_size, verb, 'E', 6) case 'h', 'H': - prev_fi := fi^ - defer fi^ = prev_fi + prev_hash := fi.hash + defer fi.hash = prev_hash + prev_zero := fi.zero + defer fi.zero = prev_zero + prev_plus := fi.plus + defer fi.plus = prev_plus + prev_width := fi.width + defer fi.width = prev_width + prev_width_set := fi.width_set + defer fi.width_set = prev_width_set + fi.hash = false fi.zero = true fi.plus = false diff --git a/core/simd/x86/sse2.odin b/core/simd/x86/sse2.odin index 4c231c377..fba995720 100644 --- a/core/simd/x86/sse2.odin +++ b/core/simd/x86/sse2.odin @@ -482,10 +482,15 @@ _mm_packus_epi16 :: #force_inline proc "c" (a, b: __m128i) -> __m128i { _mm_extract_epi16 :: #force_inline proc "c" (a: __m128i, $IMM8: u32) -> i32 { return i32(simd.extract(transmute(u16x8)a, IMM8)) } + +// Copy `a` to `dst`, and insert the 16-bit integer `i` into `dst` at the location specified by `imm8`. +// +// [Intel's documentation](https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_insert_epi16) @(require_results, enable_target_feature="sse2") -_mm_insert_epi16 :: #force_inline proc "c" (a: __m128i, i: i32, $IMM8: u32) -> __m128i { - return i32(simd.replace(transmute(u16x8)a, IMM8, i16(i))) +_mm_insert_epi16 :: #force_inline proc "c" (a: __m128i, i: i32, $IMM8: i32) -> __m128i where 0 <= IMM8, IMM8 < 8 { + return transmute(__m128i)simd.replace(transmute(simd.i16x8)a, uint(IMM8), i16(i)) } + @(require_results, enable_target_feature="sse2") _mm_movemask_epi8 :: #force_inline proc "c" (a: __m128i) -> i32 { return pmovmskb(transmute(i8x16)a) diff --git a/core/sys/windows/user32.odin b/core/sys/windows/user32.odin index 75ed1e91b..5006c0671 100644 --- a/core/sys/windows/user32.odin +++ b/core/sys/windows/user32.odin @@ -205,6 +205,7 @@ foreign user32 { ClipCursor :: proc(lpRect: LPRECT) -> BOOL --- GetCursorPos :: proc(lpPoint: LPPOINT) -> BOOL --- SetCursorPos :: proc(X, Y: INT) -> BOOL --- + GetCursor :: proc() -> HCURSOR --- SetCursor :: proc(hCursor: HCURSOR) -> HCURSOR --- when !intrinsics.is_package_imported("raylib") { ShowCursor :: proc(bShow: BOOL) -> INT --- @@ -229,6 +230,7 @@ foreign user32 { GetThreadDpiAwarenessContext :: proc() -> DPI_AWARENESS_CONTEXT --- GetWindowDpiAwarenessContext :: proc(hwnd: HWND) -> DPI_AWARENESS_CONTEXT --- GetDpiFromDpiAwarenessContext :: proc(value: DPI_AWARENESS_CONTEXT) -> UINT --- + GetDpiForSystem :: proc() -> UINT --- GetDpiForWindow :: proc(hwnd: HWND) -> UINT --- SetProcessDpiAwarenessContext :: proc(value: DPI_AWARENESS_CONTEXT) -> BOOL --- diff --git a/src/build_settings.cpp b/src/build_settings.cpp index d975cc2f4..022f1cd95 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -674,6 +674,8 @@ struct BuildContext { String android_keystore; String android_keystore_alias; String android_keystore_password; + + String windows_sdk_root; }; gb_global BuildContext build_context = {0}; diff --git a/src/linker.cpp b/src/linker.cpp index 88ec88691..004978aea 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -210,13 +210,22 @@ gb_internal i32 linker_stage(LinkerData *gen) { return result; } - bool is_cross_linking = false; bool is_android = false; - - if (build_context.cross_compiling && (build_context.different_os || selected_subtarget != Subtarget_Default)) { + bool is_windows_cross = false; + if (build_context.cross_compiling && build_context.different_os && build_context.metrics.os == TargetOs_windows) { + if (build_context.linker_choice != Linker_lld) { + gb_printf_err("Cannot link for Windows without LLD (%.*s %.*s)\n", + LIT(target_os_names[build_context.metrics.os]), + LIT(target_arch_names[build_context.metrics.arch]) + ); + build_context.keep_object_files = true; + } else { + is_windows_cross = true; + goto try_cross_linking; + } + } else if (build_context.cross_compiling && (build_context.different_os || selected_subtarget != Subtarget_Default)) { switch (selected_subtarget) { case Subtarget_Android: - is_cross_linking = true; is_android = true; goto try_cross_linking; default: @@ -235,7 +244,7 @@ try_cross_linking:; bool is_windows = build_context.metrics.os == TargetOs_windows; #else String section_name = str_lit("ld-link"); - bool is_windows = false; + bool is_windows = is_windows_cross; #endif bool is_osx = build_context.metrics.os == TargetOs_darwin; @@ -247,6 +256,9 @@ try_cross_linking:; case Linker_radlink: break; // the default on Windows #endif case Linker_lld: section_name = str_lit("lld-link"); break; + #if defined(GB_SYSTEM_WINDOWS) + case Linker_radlink: break; + #endif #if defined(GB_SYSTEM_LINUX) || defined(GB_SYSTEM_FREEBSD) || defined(GB_SYSTEM_NETBSD) case Linker_mold: section_name = str_lit("mold-link"); break; #endif @@ -290,6 +302,29 @@ try_cross_linking:; string_set_init(&asm_files, 64); defer (string_set_destroy(&asm_files)); + #if !defined(GB_SYSTEM_WINDOWS) + StringMap libs_normalized = {}; + string_map_init(&libs_normalized); + defer (string_map_destroy(&libs_normalized)); + Array walker_list = {}; + ReadDirectoryError rd_err = read_directory(build_context.windows_sdk_root, &walker_list); + for_array(i, walker_list) { + FileInfo entry = walker_list[i]; + if (entry.is_dir) { + Array walker_children = {}; + ReadDirectoryError child_rd_err = read_directory(entry.fullpath, &walker_children); + for_array(j, walker_children) { + array_add(&walker_list, walker_children[j]); + } + array_free(&walker_children); + continue; + } + String lowered_name = copy_string(permanent_allocator(), entry.name); + string_to_lower(&lowered_name); + string_map_set(&libs_normalized, lowered_name, entry.name); + } + #endif + for (Entity *e : gen->foreign_libraries) { GB_ASSERT(e->kind == Entity_LibraryName); // NOTE(bill): Add these before the linking values @@ -299,13 +334,25 @@ try_cross_linking:; } for_array(i, e->LibraryName.paths) { String lib = string_trim_whitespace(e->LibraryName.paths[i]); - // IMPORTANT NOTE(bill): calling `string_to_lower` here is not an issue because - // we will never uses these strings afterwards - string_to_lower(&lib); if (lib.len == 0) { continue; } + #if defined(GB_SYSTEM_WINDOWS) + // IMPORTANT NOTE(bill): calling `string_to_lower` here is not an issue because + // we will never uses these strings afterwards + string_to_lower(&lib); + #else + if (lib[0] != '/') { + String lowered_name = copy_string(permanent_allocator(), lib); + string_to_lower(&lowered_name); + String *fixed_lib = string_map_get(&libs_normalized, lowered_name); + if (fixed_lib != nullptr) { + lib = *fixed_lib; + } + } + #endif + if (has_asm_extension(lib)) { if (!string_set_update(&asm_files, lib)) { String asm_file = lib; @@ -329,13 +376,27 @@ try_cross_linking:; obj_format = str_lit("win32"); #endif + #if defined(GB_SYSTEM_WINDOWS) + char nasm_path[4096] = {0}; + gb_snprintf( + nasm_path, + gb_count_of(nasm_path) - 1, + "%.*s\\bin\\nasm\\windows\\nasm.exe", + LIT(build_context.ODIN_ROOT) + ); + #else + const char *nasm_path = gb_get_env("ODIN_NASM_PATH", permanent_allocator()); + if (nasm_path == nullptr) { + nasm_path = "nasm"; + } + #endif result = system_exec_command_line_app("nasm", - "\"%.*s\\bin\\nasm\\windows\\nasm.exe\" \"%.*s\" " + "\"%s\" \"%.*s\" " "-f \"%.*s\" " "-o \"%.*s\" " "%.*s " "", - LIT(build_context.ODIN_ROOT), LIT(asm_file), + nasm_path, LIT(asm_file), LIT(obj_format), LIT(obj_file), LIT(build_context.extra_assembler_flags) @@ -382,6 +443,10 @@ try_cross_linking:; } } + if (build_context.windows_sdk_root.len > 0) { + link_settings = gb_string_append_fmt(link_settings, " /winsysroot:%.*s", LIT(build_context.windows_sdk_root)); + } + if (build_context.ODIN_DEBUG) { link_settings = gb_string_append_fmt(link_settings, " /DEBUG"); if (build_context.build_mode != BuildMode_StaticLibrary) { @@ -437,28 +502,43 @@ try_cross_linking:; switch (build_context.linker_choice) { case Linker_lld: - result = system_exec_msvc_linker_app("msvc-lld-link", - "\"%.*s\\bin\\lld-link\" %s %.*s -OUT:\"%.*s\" %s " - "/nologo /incremental:no /opt:ref /subsystem:%.*s " - "%.*s " - "%.*s " - "%s " - "%s " - "", - LIT(build_context.ODIN_ROOT), object_files, LIT(res_path), LIT(output_filename), - link_settings, - LIT(windows_subsystem_names[build_context.ODIN_WINDOWS_SUBSYSTEM]), - LIT(build_context.link_flags), - LIT(build_context.extra_linker_flags), - lib_str, - lld_lto_flags - ); + { + #if defined(GB_SYSTEM_WINDOWS) + char linker_path[4096] = {0}; + gb_snprintf( + linker_path, + gb_count_of(linker_path) - 1, + "%.*s\\bin\\lld-link", + LIT(build_context.ODIN_ROOT) + ); + #else + const char *linker_path = gb_get_env("ODIN_LLD_PATH", permanent_allocator()); + if (linker_path == nullptr) { + linker_path = "lld-link"; + } + #endif + result = system_exec_msvc_linker_app("lld-link", + "\"%s\" %s -OUT:\"%.*s\" %s " + "/nologo /incremental:no /opt:ref /subsystem:%.*s " + "%.*s " + "%.*s " + "%s " + "%s " + "", + linker_path, object_files, LIT(output_filename), + link_settings, + LIT(windows_subsystem_names[build_context.ODIN_WINDOWS_SUBSYSTEM]), + LIT(build_context.link_flags), + LIT(build_context.extra_linker_flags), + lib_str, + lld_lto_flags + ); - if (result) { - return result; + if (result) { + return result; + } + break; } - break; - case Linker_msvc: { String linker_name = str_lit("link.exe"); switch (build_context.build_mode) { diff --git a/src/llvm_backend_stmt.cpp b/src/llvm_backend_stmt.cpp index eb51e6370..e0325fdf2 100644 --- a/src/llvm_backend_stmt.cpp +++ b/src/llvm_backend_stmt.cpp @@ -2913,6 +2913,9 @@ gb_internal void lb_build_if_stmt(lbProcedure *p, Ast *node) { lb_start_block(p, then); lb_build_stmt(p, is->body); + if (p->debug_info != nullptr) { + LLVMSetCurrentDebugLocation2(p->builder, lb_debug_end_location_from_ast(p, is->body)); + } lb_emit_jump(p, done); } else { if (is->else_stmt != nullptr) { @@ -2922,6 +2925,9 @@ gb_internal void lb_build_if_stmt(lbProcedure *p, Ast *node) { lb_open_scope(p, scope_of_node(is->else_stmt)); lb_build_stmt(p, is->else_stmt); lb_close_scope(p, lbDeferExit_Default, nullptr, is->else_stmt); + if (p->debug_info != nullptr) { + LLVMSetCurrentDebugLocation2(p->builder, lb_debug_end_location_from_ast(p, is->else_stmt)); + } } lb_emit_jump(p, done); @@ -2930,6 +2936,9 @@ gb_internal void lb_build_if_stmt(lbProcedure *p, Ast *node) { lb_start_block(p, then); lb_build_stmt(p, is->body); + if (p->debug_info != nullptr) { + LLVMSetCurrentDebugLocation2(p->builder, lb_debug_end_location_from_ast(p, is->body)); + } lb_emit_jump(p, done); @@ -2939,6 +2948,9 @@ gb_internal void lb_build_if_stmt(lbProcedure *p, Ast *node) { lb_open_scope(p, scope_of_node(is->else_stmt)); lb_build_stmt(p, is->else_stmt); lb_close_scope(p, lbDeferExit_Default, nullptr, is->else_stmt); + if (p->debug_info != nullptr) { + LLVMSetCurrentDebugLocation2(p->builder, lb_debug_end_location_from_ast(p, is->else_stmt)); + } lb_emit_jump(p, done); } diff --git a/src/main.cpp b/src/main.cpp index 54e8075ec..d724e9a94 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -544,6 +544,10 @@ enum BuildFlagKind { BuildFlag_AndroidKeystoreAlias, BuildFlag_AndroidKeystorePassword, +#if !defined(GB_SYSTEM_WINDOWS) + BuildFlag_WindowsSDKRoot, +#endif + BuildFlag_COUNT, }; @@ -811,6 +815,10 @@ gb_internal bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_AndroidKeystoreAlias, str_lit("android-keystore-alias"), BuildFlagParam_String, Command_bundle_android); add_flag(&build_flags, BuildFlag_AndroidKeystorePassword, str_lit("android-keystore-password"), BuildFlagParam_String, Command_bundle_android); +#if !defined(GB_SYSTEM_WINDOWS) + add_flag(&build_flags, BuildFlag_WindowsSDKRoot, str_lit("windows-sdk-root"), BuildFlagParam_String, Command_build); +#endif + Array flag_args = {}; @@ -2019,6 +2027,13 @@ gb_internal bool parse_build_flags(Array args) { GB_ASSERT(value.kind == ExactValue_String); build_context.android_keystore_password = value.value_string; break; + + #if !defined(GB_SYSTEM_WINDOWS) + case BuildFlag_WindowsSDKRoot: + GB_ASSERT(value.kind == ExactValue_String); + build_context.windows_sdk_root = value.value_string; + break; + #endif } } @@ -4304,6 +4319,13 @@ int main(int arg_count, char const **arg_ptr) { // return 1; // } +#if !defined(GB_SYSTEM_WINDOWS) + if (build_context.metrics.os == TargetOs_windows && build_context.windows_sdk_root.len == 0) { + gb_printf_err("-windows-sdk-root: must be used to target Windows\n"); + gb_exit(1); + } +#endif + // Warn about Windows i386 thread-local storage limitations if (build_context.metrics.arch == TargetArch_i386 && build_context.metrics.os == TargetOs_windows) { gb_printf_err("Warning: Thread-local storage is disabled on Windows i386.\n"); diff --git a/tests/issues/test_issue_7689/test_issue_7689.odin b/tests/issues/test_issue_7689/test_issue_7689.odin new file mode 100644 index 000000000..091ae9f56 --- /dev/null +++ b/tests/issues/test_issue_7689/test_issue_7689.odin @@ -0,0 +1,27 @@ +package bug_repro + +import "core:fmt" +import "core:os" + +main :: proc() { + x := len(os.args)+1 // runtime value so nothing is folded + + r: int + if x == 1 { + r = 1 + } else { + if x == 2 { + r = 2 + } else { + if x == 3 { + r = 3 + } else { + if x == 4 { + r = 4 + } + } + } + } + + fmt.println(r) +} diff --git a/vendor/box3d/box3d_types.odin b/vendor/box3d/box3d_types.odin index 84b8cb53f..9e1ca9116 100644 --- a/vendor/box3d/box3d_types.odin +++ b/vendor/box3d/box3d_types.odin @@ -104,7 +104,7 @@ OverlapResultFcn :: proc "c" (shapeId: ShapeId, ctx: rawptr) -> bool // @return -1 to filter, 0 to terminate, fraction to clip the ray for closest hit, 1 to continue // @see b3World_CastRay // @ingroup world -CastResultFcn :: proc "c" (shapeId: ShapeId, point: Pos, normal: Vec3, fraction: f32, userMateriald: u64, triangleIndex: c.int, childIndex: c.int, ctx: rawptr) -> f32 +CastResultFcn :: proc "c" (shapeId: ShapeId, point: Pos, normal: Vec3, fraction: f32, userMaterialId: u64, triangleIndex: c.int, childIndex: c.int, ctx: rawptr) -> f32 @(link_prefix="b3", default_calling_convention="c", require_results) foreign lib {