diff --git a/LICENSE b/LICENSE index 4d155def4..919f29937 100644 --- a/LICENSE +++ b/LICENSE @@ -1,26 +1,17 @@ -Copyright (c) 2016-2024 Ginger Bill. All rights reserved. +Copyright (c) 2016-2025 Ginger Bill. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. \ No newline at end of file diff --git a/base/intrinsics/intrinsics.odin b/base/intrinsics/intrinsics.odin index 952f927bd..d34519f63 100644 --- a/base/intrinsics/intrinsics.odin +++ b/base/intrinsics/intrinsics.odin @@ -244,6 +244,11 @@ constant_utf16_cstring :: proc($literal: string) -> [^]u16 --- constant_log2 :: proc($v: $T) -> T where type_is_integer(T) --- +constant_floor :: proc($v: $T) -> T where type_is_integer(T) || type_is_float(T) --- +constant_trunc :: proc($v: $T) -> T where type_is_integer(T) || type_is_float(T) --- +constant_ceil :: proc($v: $T) -> T where type_is_integer(T) || type_is_float(T) --- +constant_round :: proc($v: $T) -> T where type_is_integer(T) || type_is_float(T) --- + // SIMD related simd_add :: proc(a, b: #simd[N]T) -> #simd[N]T --- simd_sub :: proc(a, b: #simd[N]T) -> #simd[N]T --- diff --git a/base/runtime/core.odin b/base/runtime/core.odin index 71e560700..2e70147db 100644 --- a/base/runtime/core.odin +++ b/base/runtime/core.odin @@ -15,7 +15,7 @@ // // IMPORTANT NOTE(bill): `type_info_of` cannot be used within a // #shared_global_scope due to the internals of the compiler. -// This could change at a later date if the all these data structures are +// This could change at a later date if all these data structures are // implemented within the compiler rather than in this "preload" file // #+no-instrumentation diff --git a/base/runtime/core_builtin_soa.odin b/base/runtime/core_builtin_soa.odin index a97eb3bb3..395b3e4f5 100644 --- a/base/runtime/core_builtin_soa.odin +++ b/base/runtime/core_builtin_soa.odin @@ -504,6 +504,121 @@ append_soa :: proc{ } +// `append_nothing_soa` appends an empty value to a dynamic SOA array. It returns `1, nil` if successful, and `0, err` when it was not possible, +// whatever `err` happens to be. +@builtin +append_nothing_soa :: proc(array: ^$T/#soa[dynamic]$E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { + if array == nil { + return 0, nil + } + prev_len := len(array) + resize_soa(array, len(array)+1, loc) or_return + return len(array)-prev_len, nil +} + + +// `inject_at_elem_soa` injects an element in a dynamic SOA array at a specified index and moves the previous elements after that index "across" +@builtin +inject_at_elem_soa :: proc(array: ^$T/#soa[dynamic]$E, #any_int index: int, #no_broadcast arg: E, loc := #caller_location) -> (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error { + when !ODIN_NO_BOUNDS_CHECK { + ensure(index >= 0, "Index must be positive.", loc) + } + if array == nil { + return + } + n := max(len(array), index) + m :: 1 + new_len := n + m + + resize_soa(array, new_len, loc) or_return + + when size_of(E) != 0 { + ti := type_info_base(type_info_of(typeid_of(T))) + si := &ti.variant.(Type_Info_Struct) + + field_count := len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E) + + item_offset := 0 + + arg_copy := arg + arg_ptr := &arg_copy + + for i in 0.. (ok: bool, err: Allocator_Error) #no_bounds_check #optional_allocator_error { + when !ODIN_NO_BOUNDS_CHECK { + ensure(index >= 0, "Index must be positive.", loc) + } + if array == nil { + return + } + if len(args) == 0 { + ok = true + return + } + + n := max(len(array), index) + m := len(args) + new_len := n + m + + resize_soa(array, new_len, loc) or_return + + when size_of(E) != 0 { + ti := type_info_base(type_info_of(typeid_of(T))) + si := &ti.variant.(Type_Info_Struct) + + field_count := len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E) + + item_offset := 0 + + args_ptr := &args[0] + + for i in 0.. Allocator_Error { field_count :: len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E) when field_count != 0 { diff --git a/base/runtime/dynamic_map_internal.odin b/base/runtime/dynamic_map_internal.odin index ff1c358ac..32ef0bdd0 100644 --- a/base/runtime/dynamic_map_internal.odin +++ b/base/runtime/dynamic_map_internal.odin @@ -6,8 +6,6 @@ _ :: intrinsics // High performance, cache-friendly, open-addressed Robin Hood hashing hash map // data structure with various optimizations for Odin. // -// Copyright 2022 (c) Dale Weiler -// // The core of the hash map data structure is the Raw_Map struct which is a // type-erased representation of the map. This type-erased representation is // used in two ways: static and dynamic. When static type information is known, diff --git a/base/runtime/os_specific.odin b/base/runtime/os_specific.odin index 2807eaf90..b6c1288d0 100644 --- a/base/runtime/os_specific.odin +++ b/base/runtime/os_specific.odin @@ -5,3 +5,7 @@ _OS_Errno :: distinct int stderr_write :: proc "contextless" (data: []byte) -> (int, _OS_Errno) { return _stderr_write(data) } + +exit :: proc "contextless" (code: int) -> ! { + _exit(code) +} \ No newline at end of file diff --git a/base/runtime/os_specific_bsd.odin b/base/runtime/os_specific_bsd.odin index 466001ada..de300f1e0 100644 --- a/base/runtime/os_specific_bsd.odin +++ b/base/runtime/os_specific_bsd.odin @@ -24,3 +24,11 @@ _stderr_write :: proc "contextless" (data: []byte) -> (int, _OS_Errno) { } return int(ret), 0 } + +_exit :: proc "contextless" (code: int) -> ! { + @(default_calling_convention="c") + foreign libc { + exit :: proc(status: i32) -> ! --- + } + exit(i32(code)) +} \ No newline at end of file diff --git a/base/runtime/os_specific_darwin.odin b/base/runtime/os_specific_darwin.odin index 907899d7c..37315240f 100644 --- a/base/runtime/os_specific_darwin.odin +++ b/base/runtime/os_specific_darwin.odin @@ -26,3 +26,13 @@ _stderr_write :: proc "contextless" (data: []byte) -> (int, _OS_Errno) { return 0, _OS_Errno(__error()^) } } + +foreign import libc "system:System" + +_exit :: proc "contextless" (code: int) -> ! { + @(default_calling_convention="c") + foreign libc { + exit :: proc(status: i32) -> ! --- + } + exit(i32(code)) +} \ No newline at end of file diff --git a/base/runtime/os_specific_freestanding.odin b/base/runtime/os_specific_freestanding.odin index f975f61b8..b5a5fb146 100644 --- a/base/runtime/os_specific_freestanding.odin +++ b/base/runtime/os_specific_freestanding.odin @@ -6,3 +6,7 @@ package runtime _stderr_write :: proc "contextless" (data: []byte) -> (int, _OS_Errno) { return 0, -1 } + +_exit :: proc "contextless" (code: int) -> ! { + trap() +} \ No newline at end of file diff --git a/base/runtime/os_specific_haiku.odin b/base/runtime/os_specific_haiku.odin index 0d1ec7a03..74ff58cde 100644 --- a/base/runtime/os_specific_haiku.odin +++ b/base/runtime/os_specific_haiku.odin @@ -19,3 +19,9 @@ _stderr_write :: proc "contextless" (data: []byte) -> (int, _OS_Errno) { } return int(ret), 0 } + + + +_exit :: proc "contextless" (code: int) -> ! { + trap() +} \ No newline at end of file diff --git a/base/runtime/os_specific_js.odin b/base/runtime/os_specific_js.odin index f1d12c808..bd88b1871 100644 --- a/base/runtime/os_specific_js.odin +++ b/base/runtime/os_specific_js.odin @@ -11,3 +11,8 @@ _stderr_write :: proc "contextless" (data: []byte) -> (int, _OS_Errno) { write(1, data) return len(data), 0 } + + +_exit :: proc "contextless" (code: int) -> ! { + trap() +} \ No newline at end of file diff --git a/base/runtime/os_specific_linux.odin b/base/runtime/os_specific_linux.odin index d7b7371a7..dfe3c8841 100644 --- a/base/runtime/os_specific_linux.odin +++ b/base/runtime/os_specific_linux.odin @@ -24,3 +24,17 @@ _stderr_write :: proc "contextless" (data: []byte) -> (int, _OS_Errno) { } return ret, 0 } + + +_exit :: proc "contextless" (code: int) -> ! { + SYS_exit_group :: + 231 when ODIN_ARCH == .amd64 else + 248 when ODIN_ARCH == .arm32 else + 94 when ODIN_ARCH == .arm64 else + 252 when ODIN_ARCH == .i386 else + 94 when ODIN_ARCH == .riscv64 else + 0 + + intrinsics.syscall(uintptr(SYS_exit_group), uintptr(i32(code))) + unreachable() +} diff --git a/base/runtime/os_specific_orca.odin b/base/runtime/os_specific_orca.odin index 876d7d44b..491edcfa4 100644 --- a/base/runtime/os_specific_orca.odin +++ b/base/runtime/os_specific_orca.odin @@ -41,3 +41,8 @@ _stderr_write :: proc "contextless" (data: []byte) -> (int, _OS_Errno) { return len(data), 0 } + + +_exit :: proc "contextless" (code: int) -> ! { + trap() +} \ No newline at end of file diff --git a/base/runtime/os_specific_wasi.odin b/base/runtime/os_specific_wasi.odin index aa562050c..194034865 100644 --- a/base/runtime/os_specific_wasi.odin +++ b/base/runtime/os_specific_wasi.odin @@ -23,6 +23,9 @@ foreign wasi { argv: [^]cstring, argv_buf: [^]byte, ) -> u16 --- + + @(private="file") + proc_exit :: proc(rval: u32) -> ! --- } _stderr_write :: proc "contextless" (data: []byte) -> (int, _OS_Errno) { @@ -53,3 +56,8 @@ _wasi_setup_args :: proc() { delete(args_buf) } } + + +_exit :: proc "contextless" (code: int) -> ! { + proc_exit(u32(code)) +} \ No newline at end of file diff --git a/base/runtime/os_specific_windows.odin b/base/runtime/os_specific_windows.odin index b966193ca..c5ca1e4c5 100644 --- a/base/runtime/os_specific_windows.odin +++ b/base/runtime/os_specific_windows.odin @@ -14,6 +14,8 @@ foreign kernel32 { SetHandleInformation :: proc(hObject: rawptr, dwMask: u32, dwFlags: u32) -> b32 --- WriteFile :: proc(hFile: rawptr, lpBuffer: rawptr, nNumberOfBytesToWrite: u32, lpNumberOfBytesWritten: ^u32, lpOverlapped: rawptr) -> b32 --- GetLastError :: proc() -> u32 --- + + ExitProcess :: proc(code: u32) -> ! --- } _stderr_write :: proc "contextless" (data: []byte) -> (n: int, err: _OS_Errno) #no_bounds_check { @@ -49,3 +51,7 @@ _stderr_write :: proc "contextless" (data: []byte) -> (n: int, err: _OS_Errno) # n = int(total_write) return } + +_exit :: proc "contextless" (code: int) -> ! { + ExitProcess(u32(code)) +} \ No newline at end of file diff --git a/build_odin.sh b/build_odin.sh index 0d7e8a26e..b9545a6b5 100755 --- a/build_odin.sh +++ b/build_odin.sh @@ -28,7 +28,8 @@ error() { # Brew advises people not to add llvm to their $PATH, so try and use brew to find it. if [ -z "$LLVM_CONFIG" ] && [ -n "$(command -v brew)" ]; then - if [ -n "$(command -v $(brew --prefix llvm@20)/bin/llvm-config)" ]; then LLVM_CONFIG="$(brew --prefix llvm@20)/bin/llvm-config" + if [ -n "$(command -v $(brew --prefix llvm@21)/bin/llvm-config)" ]; then LLVM_CONFIG="$(brew --prefix llvm@21)/bin/llvm-config" + elif [ -n "$(command -v $(brew --prefix llvm@20)/bin/llvm-config)" ]; then LLVM_CONFIG="$(brew --prefix llvm@20)/bin/llvm-config" elif [ -n "$(command -v $(brew --prefix llvm@19)/bin/llvm-config)" ]; then LLVM_CONFIG="$(brew --prefix llvm@19)/bin/llvm-config" elif [ -n "$(command -v $(brew --prefix llvm@18)/bin/llvm-config)" ]; then LLVM_CONFIG="$(brew --prefix llvm@18)/bin/llvm-config" elif [ -n "$(command -v $(brew --prefix llvm@17)/bin/llvm-config)" ]; then LLVM_CONFIG="$(brew --prefix llvm@17)/bin/llvm-config" @@ -38,23 +39,19 @@ fi if [ -z "$LLVM_CONFIG" ]; then # darwin, linux, openbsd - if [ -n "$(command -v llvm-config-20)" ]; then LLVM_CONFIG="llvm-config-20" + if [ -n "$(command -v llvm-config-21)" ]; then LLVM_CONFIG="llvm-config-21" + elif [ -n "$(command -v llvm-config-20)" ]; then LLVM_CONFIG="llvm-config-20" elif [ -n "$(command -v llvm-config-19)" ]; then LLVM_CONFIG="llvm-config-19" elif [ -n "$(command -v llvm-config-18)" ]; then LLVM_CONFIG="llvm-config-18" elif [ -n "$(command -v llvm-config-17)" ]; then LLVM_CONFIG="llvm-config-17" elif [ -n "$(command -v llvm-config-14)" ]; then LLVM_CONFIG="llvm-config-14" - elif [ -n "$(command -v llvm-config-13)" ]; then LLVM_CONFIG="llvm-config-13" - elif [ -n "$(command -v llvm-config-12)" ]; then LLVM_CONFIG="llvm-config-12" - elif [ -n "$(command -v llvm-config-11)" ]; then LLVM_CONFIG="llvm-config-11" # freebsd + elif [ -n "$(command -v llvm-config21)" ]; then LLVM_CONFIG="llvm-config21" elif [ -n "$(command -v llvm-config20)" ]; then LLVM_CONFIG="llvm-config20" elif [ -n "$(command -v llvm-config19)" ]; then LLVM_CONFIG="llvm-config19" elif [ -n "$(command -v llvm-config18)" ]; then LLVM_CONFIG="llvm-config18" elif [ -n "$(command -v llvm-config17)" ]; then LLVM_CONFIG="llvm-config17" elif [ -n "$(command -v llvm-config14)" ]; then LLVM_CONFIG="llvm-config14" - elif [ -n "$(command -v llvm-config13)" ]; then LLVM_CONFIG="llvm-config13" - elif [ -n "$(command -v llvm-config12)" ]; then LLVM_CONFIG="llvm-config12" - elif [ -n "$(command -v llvm-config11)" ]; then LLVM_CONFIG="llvm-config11" # fallback elif [ -n "$(command -v llvm-config)" ]; then LLVM_CONFIG="llvm-config" else @@ -75,18 +72,12 @@ LLVM_VERSION_MAJOR="$(echo $LLVM_VERSION | awk -F. '{print $1}')" LLVM_VERSION_MINOR="$(echo $LLVM_VERSION | awk -F. '{print $2}')" LLVM_VERSION_PATCH="$(echo $LLVM_VERSION | awk -F. '{print $3}')" -if [ $LLVM_VERSION_MAJOR -lt 11 ] || ([ $LLVM_VERSION_MAJOR -gt 14 ] && [ $LLVM_VERSION_MAJOR -lt 17 ]) || [ $LLVM_VERSION_MAJOR -gt 20 ]; then - error "Invalid LLVM version $LLVM_VERSION: must be 11, 12, 13, 14, 17, 18, 19 or 20" +if [ $LLVM_VERSION_MAJOR -lt 14 ] || ([ $LLVM_VERSION_MAJOR -gt 14 ] && [ $LLVM_VERSION_MAJOR -lt 17 ]) || [ $LLVM_VERSION_MAJOR -gt 21 ]; then + error "Invalid LLVM version $LLVM_VERSION: must be 14, 17, 18, 19, 20, or 21" fi case "$OS_NAME" in Darwin) - if [ "$OS_ARCH" = "arm64" ]; then - if [ $LLVM_VERSION_MAJOR -lt 13 ]; then - error "Invalid LLVM version $LLVM_VERSION: Darwin Arm64 requires LLVM 13, 14, 17, 18, 19 or 20" - fi - fi - darwin_sysroot= if [ $(which xcrun) ]; then darwin_sysroot="--sysroot $(xcrun --sdk macosx --show-sdk-path)" diff --git a/core/c/c.odin b/core/c/c.odin index 8266bf38a..bc847d566 100644 --- a/core/c/c.odin +++ b/core/c/c.odin @@ -49,7 +49,7 @@ int_least64_t :: builtin.i64 uint_least64_t :: builtin.u64 // Same on Windows, Linux, and FreeBSD -when ODIN_ARCH == .i386 || ODIN_ARCH == .amd64 { +when ODIN_ARCH == .i386 { int_fast8_t :: builtin.i8 uint_fast8_t :: builtin.u8 int_fast16_t :: builtin.i32 @@ -58,6 +58,15 @@ when ODIN_ARCH == .i386 || ODIN_ARCH == .amd64 { uint_fast32_t :: builtin.u32 int_fast64_t :: builtin.i64 uint_fast64_t :: builtin.u64 +} else when ODIN_ARCH == .amd64 { + int_fast8_t :: builtin.i8 + uint_fast8_t :: builtin.u8 + int_fast16_t :: long + uint_fast16_t :: ulong + int_fast32_t :: long + uint_fast32_t :: ulong + int_fast64_t :: builtin.i64 + uint_fast64_t :: builtin.u64 } else { int_fast8_t :: builtin.i8 uint_fast8_t :: builtin.u8 diff --git a/core/compress/common.odin b/core/compress/common.odin index 796a60071..39aa1ca72 100644 --- a/core/compress/common.odin +++ b/core/compress/common.odin @@ -3,7 +3,7 @@ package compress /* Copyright 2021 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Jeroen van Rijn: Initial implementation, optimization. diff --git a/core/compress/gzip/doc.odin b/core/compress/gzip/doc.odin index 18f2259cb..c20ebc33a 100644 --- a/core/compress/gzip/doc.odin +++ b/core/compress/gzip/doc.odin @@ -82,7 +82,7 @@ package compress_gzip /* Copyright 2021 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Jeroen van Rijn: Initial implementation. diff --git a/core/compress/gzip/gzip.odin b/core/compress/gzip/gzip.odin index 57ed3c3c5..7dc8120e4 100644 --- a/core/compress/gzip/gzip.odin +++ b/core/compress/gzip/gzip.odin @@ -2,7 +2,7 @@ package compress_gzip /* Copyright 2021 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Jeroen van Rijn: Initial implementation. diff --git a/core/compress/shoco/shoco.odin b/core/compress/shoco/shoco.odin index be079df19..b112ddb04 100644 --- a/core/compress/shoco/shoco.odin +++ b/core/compress/shoco/shoco.odin @@ -3,7 +3,7 @@ package compress_shoco /* Copyright 2022 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Jeroen van Rijn: Initial implementation. diff --git a/core/compress/zlib/doc.odin b/core/compress/zlib/doc.odin index 6923c2a60..8dac17587 100644 --- a/core/compress/zlib/doc.odin +++ b/core/compress/zlib/doc.odin @@ -44,7 +44,7 @@ package compress_zlib /* Copyright 2021 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Jeroen van Rijn: Initial implementation. diff --git a/core/compress/zlib/zlib.odin b/core/compress/zlib/zlib.odin index be8a7d7d3..b9189c1f1 100644 --- a/core/compress/zlib/zlib.odin +++ b/core/compress/zlib/zlib.odin @@ -3,7 +3,7 @@ package compress_zlib /* Copyright 2021 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Jeroen van Rijn: Initial implementation, optimization. diff --git a/core/container/small_array/small_array.odin b/core/container/small_array/small_array.odin index 1d9795db8..a7e046fcf 100644 --- a/core/container/small_array/small_array.odin +++ b/core/container/small_array/small_array.odin @@ -309,7 +309,7 @@ Example: import "core:container/small_array" import "core:fmt" - non_zero_resize :: proc() { + non_zero_resize_example :: proc() { a: small_array.Small_Array(5, int) small_array.push_back(&a, 1) diff --git a/core/crypto/README.md b/core/crypto/README.md index 303b1f625..5065a6d02 100644 --- a/core/crypto/README.md +++ b/core/crypto/README.md @@ -29,4 +29,4 @@ constant-time byte comparison. ## License -This library is made available under the BSD-3 license. \ No newline at end of file +This library is made available under the zlib license. \ No newline at end of file diff --git a/core/crypto/_blake2/blake2.odin b/core/crypto/_blake2/blake2.odin index 89fbe3a7a..487e93b83 100644 --- a/core/crypto/_blake2/blake2.odin +++ b/core/crypto/_blake2/blake2.odin @@ -2,7 +2,7 @@ package _blake2 /* Copyright 2021 zhibog - Made available under the BSD-3 license. + Made available under Odin's license. List of contributors: zhibog, dotbmp: Initial implementation. diff --git a/core/crypto/_sha3/sha3.odin b/core/crypto/_sha3/sha3.odin index 52b3fbda9..02b0b6578 100644 --- a/core/crypto/_sha3/sha3.odin +++ b/core/crypto/_sha3/sha3.odin @@ -2,7 +2,7 @@ package _sha3 /* Copyright 2021 zhibog - Made available under the BSD-3 license. + Made available under Odin's license. List of contributors: zhibog, dotbmp: Initial implementation. diff --git a/core/crypto/blake2b/blake2b.odin b/core/crypto/blake2b/blake2b.odin index c2822cbaf..4590ca40e 100644 --- a/core/crypto/blake2b/blake2b.odin +++ b/core/crypto/blake2b/blake2b.odin @@ -9,7 +9,7 @@ package blake2b /* Copyright 2021 zhibog - Made available under the BSD-3 license. + Made available under Odin's license. List of contributors: zhibog, dotbmp: Initial implementation. diff --git a/core/crypto/blake2s/blake2s.odin b/core/crypto/blake2s/blake2s.odin index c2a07a6dc..37da53360 100644 --- a/core/crypto/blake2s/blake2s.odin +++ b/core/crypto/blake2s/blake2s.odin @@ -9,7 +9,7 @@ package blake2s /* Copyright 2021 zhibog - Made available under the BSD-3 license. + Made available under Odin's license. List of contributors: zhibog, dotbmp: Initial implementation. diff --git a/core/crypto/hash/hash.odin b/core/crypto/hash/hash.odin index 66d9201cd..ecb33b9d0 100644 --- a/core/crypto/hash/hash.odin +++ b/core/crypto/hash/hash.odin @@ -2,7 +2,7 @@ package crypto_hash /* Copyright 2021 zhibog - Made available under the BSD-3 license. + Made available under Odin's license. List of contributors: zhibog, dotbmp: Initial implementation. diff --git a/core/crypto/legacy/keccak/keccak.odin b/core/crypto/legacy/keccak/keccak.odin index 369eee0d9..ec6af2565 100644 --- a/core/crypto/legacy/keccak/keccak.odin +++ b/core/crypto/legacy/keccak/keccak.odin @@ -10,7 +10,7 @@ package keccak /* Copyright 2021 zhibog - Made available under the BSD-3 license. + Made available under Odin's license. List of contributors: zhibog, dotbmp: Initial implementation. diff --git a/core/crypto/legacy/md5/md5.odin b/core/crypto/legacy/md5/md5.odin index 2d58837c3..d9d74d498 100644 --- a/core/crypto/legacy/md5/md5.odin +++ b/core/crypto/legacy/md5/md5.odin @@ -12,7 +12,7 @@ package md5 /* Copyright 2021 zhibog - Made available under the BSD-3 license. + Made available under Odin's license. List of contributors: zhibog, dotbmp: Initial implementation. diff --git a/core/crypto/legacy/sha1/sha1.odin b/core/crypto/legacy/sha1/sha1.odin index ea74997af..35b228f69 100644 --- a/core/crypto/legacy/sha1/sha1.odin +++ b/core/crypto/legacy/sha1/sha1.odin @@ -13,7 +13,7 @@ package sha1 /* Copyright 2021 zhibog - Made available under the BSD-3 license. + Made available under Odin's license. List of contributors: zhibog, dotbmp: Initial implementation. diff --git a/core/crypto/sha2/sha2.odin b/core/crypto/sha2/sha2.odin index 9290650e7..0b34cd6a1 100644 --- a/core/crypto/sha2/sha2.odin +++ b/core/crypto/sha2/sha2.odin @@ -9,7 +9,7 @@ package sha2 /* Copyright 2021 zhibog - Made available under the BSD-3 license. + Made available under Odin's license. List of contributors: zhibog, dotbmp: Initial implementation. diff --git a/core/crypto/sha3/sha3.odin b/core/crypto/sha3/sha3.odin index 738e7be0d..2ca70963a 100644 --- a/core/crypto/sha3/sha3.odin +++ b/core/crypto/sha3/sha3.odin @@ -12,7 +12,7 @@ package sha3 /* Copyright 2021 zhibog - Made available under the BSD-3 license. + Made available under Odin's license. List of contributors: zhibog, dotbmp: Initial implementation. diff --git a/core/crypto/shake/shake.odin b/core/crypto/shake/shake.odin index 6fcf5dd8d..f959aaf5f 100644 --- a/core/crypto/shake/shake.odin +++ b/core/crypto/shake/shake.odin @@ -11,7 +11,7 @@ package shake /* Copyright 2021 zhibog - Made available under the BSD-3 license. + Made available under Odin's license. List of contributors: zhibog, dotbmp: Initial implementation. diff --git a/core/crypto/siphash/siphash.odin b/core/crypto/siphash/siphash.odin index a091dfd4d..5fede4f55 100644 --- a/core/crypto/siphash/siphash.odin +++ b/core/crypto/siphash/siphash.odin @@ -11,7 +11,7 @@ package siphash /* Copyright 2022 zhibog - Made available under the BSD-3 license. + Made available under Odin's license. List of contributors: zhibog: Initial implementation. diff --git a/core/crypto/sm3/sm3.odin b/core/crypto/sm3/sm3.odin index ce62cfe49..186331d92 100644 --- a/core/crypto/sm3/sm3.odin +++ b/core/crypto/sm3/sm3.odin @@ -8,7 +8,7 @@ package sm3 /* Copyright 2021 zhibog - Made available under the BSD-3 license. + Made available under Odin's license. List of contributors: zhibog, dotbmp: Initial implementation. diff --git a/core/encoding/cbor/tags.odin b/core/encoding/cbor/tags.odin index be07b926a..fa456673d 100644 --- a/core/encoding/cbor/tags.odin +++ b/core/encoding/cbor/tags.odin @@ -130,9 +130,9 @@ tag_time_unmarshal :: proc(_: ^Tag_Implementation, d: Decoder, _: Tag_Number, v: case .U8, .U16, .U32, .U64, .Neg_U8, .Neg_U16, .Neg_U32, .Neg_U64: switch &dst in v { case time.Time: - i: i64 - _unmarshal_any_ptr(d, &i, hdr) or_return - dst = time.unix(i64(i), 0) + secs: i64 + _unmarshal_any_ptr(d, &secs, hdr) or_return + dst = time.unix(i64(secs), 0) return case: return _unmarshal_value(d, v, hdr) @@ -152,19 +152,23 @@ tag_time_unmarshal :: proc(_: ^Tag_Implementation, d: Decoder, _: Tag_Number, v: case: maj, add := _header_split(hdr) - if maj == .Other { - i := _decode_tiny_u8(add) or_return - - switch &dst in v { - case time.Time: - dst = time.unix(i64(i), 0) - case: - if _assign_int(v, i) { return } - } + secs: u8 + #partial switch maj { + case .Unsigned: + secs = _decode_tiny_u8(add) or_return + case .Other: + secs = u8(_decode_tiny_simple(add) or_return) + case: + return .Bad_Tag_Value } - // Only numbers and floats are allowed in this tag. - return .Bad_Tag_Value + switch &dst in v { + case time.Time: + dst = time.unix(i64(secs), 0) + return + case: + if _assign_int(v, secs) { return } + } } return _unsupported(v, hdr) diff --git a/core/encoding/entity/entity.odin b/core/encoding/entity/entity.odin index 28ff58170..e112eedf2 100644 --- a/core/encoding/entity/entity.odin +++ b/core/encoding/entity/entity.odin @@ -15,7 +15,7 @@ package encoding_unicode_entity /* Copyright 2021 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Jeroen van Rijn: Initial implementation. diff --git a/core/encoding/uuid/LICENSE b/core/encoding/uuid/LICENSE index e4e21e62d..c7f46ddf6 100644 --- a/core/encoding/uuid/LICENSE +++ b/core/encoding/uuid/LICENSE @@ -1,28 +1,17 @@ -BSD 3-Clause License +Copyright (c) 2024-2025 Feoramund, Ginger Bill. All rights reserved. -Copyright (c) 2024, Feoramund +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. \ No newline at end of file diff --git a/core/encoding/varint/leb128.odin b/core/encoding/varint/leb128.odin index 876a1ba76..86a72f121 100644 --- a/core/encoding/varint/leb128.odin +++ b/core/encoding/varint/leb128.odin @@ -2,7 +2,7 @@ package encoding_varint /* Copyright 2022 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Jeroen van Rijn: Initial implementation. diff --git a/core/encoding/xml/debug_print.odin b/core/encoding/xml/debug_print.odin index acced262a..9c47e79e8 100644 --- a/core/encoding/xml/debug_print.odin +++ b/core/encoding/xml/debug_print.odin @@ -4,7 +4,7 @@ package encoding_xml An XML 1.0 / 1.1 parser Copyright 2021-2022 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under Odin's license. A from-scratch XML implementation, loosely modeled on the [spec](https://www.w3.org/TR/2006/REC-xml11-20060816). diff --git a/core/encoding/xml/helpers.odin b/core/encoding/xml/helpers.odin index a9d4ad493..79f2d72c7 100644 --- a/core/encoding/xml/helpers.odin +++ b/core/encoding/xml/helpers.odin @@ -4,7 +4,7 @@ package encoding_xml An XML 1.0 / 1.1 parser Copyright 2021-2022 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under Odin's license. This file contains helper functions. */ diff --git a/core/encoding/xml/tokenizer.odin b/core/encoding/xml/tokenizer.odin index 3ef9a6388..71fa0bdf5 100644 --- a/core/encoding/xml/tokenizer.odin +++ b/core/encoding/xml/tokenizer.odin @@ -4,7 +4,7 @@ package encoding_xml An XML 1.0 / 1.1 parser Copyright 2021-2022 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under Odin's license. A from-scratch XML implementation, loosely modeled on the [spec](https://www.w3.org/TR/2006/REC-xml11-20060816). diff --git a/core/encoding/xml/xml_reader.odin b/core/encoding/xml/xml_reader.odin index 621c9c2d0..0e773fd8a 100644 --- a/core/encoding/xml/xml_reader.odin +++ b/core/encoding/xml/xml_reader.odin @@ -3,7 +3,7 @@ package encoding_xml An XML 1.0 / 1.1 parser 2021-2022 Jeroen van Rijn . - available under Odin's BSD-3 license. + available under Odin's license. List of contributors: - Jeroen van Rijn: Initial implementation. diff --git a/core/flags/LICENSE b/core/flags/LICENSE index e4e21e62d..c7f46ddf6 100644 --- a/core/flags/LICENSE +++ b/core/flags/LICENSE @@ -1,28 +1,17 @@ -BSD 3-Clause License +Copyright (c) 2024-2025 Feoramund, Ginger Bill. All rights reserved. -Copyright (c) 2024, Feoramund +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. +3. This notice may not be removed or altered from any source distribution. \ No newline at end of file diff --git a/core/fmt/example.odin b/core/fmt/example.odin index 6929e9be7..a700b238e 100644 --- a/core/fmt/example.odin +++ b/core/fmt/example.odin @@ -10,14 +10,14 @@ SomeType :: struct { My_Custom_Base_Type :: distinct u32 main :: proc() { - // Ensure the fmt._user_formatters map is initialized + // Ensure the fmt._user_formatters map is initialized fmt.set_user_formatters(new(map[typeid]fmt.User_Formatter)) // Register custom formatters for my favorite types err := fmt.register_user_formatter(type_info_of(SomeType).id, SomeType_Formatter) - assert(err == .None) + assert(err == .None) err = fmt.register_user_formatter(type_info_of(My_Custom_Base_Type).id, My_Custom_Base_Formatter) - assert(err == .None) + assert(err == .None) // Use the custom formatters. fmt.printfln("SomeType{{42}}: '%v'", SomeType{42}) @@ -53,5 +53,4 @@ My_Custom_Base_Formatter :: proc(fi: ^fmt.Info, arg: any, verb: rune) -> bool { return false } return true -} - +} \ No newline at end of file diff --git a/core/hash/crc.odin b/core/hash/crc.odin index 68b8f5369..1182ba92e 100644 --- a/core/hash/crc.odin +++ b/core/hash/crc.odin @@ -1,10 +1,27 @@ package hash +/* + Compute CRC-16 in the manner of CCITT (ITU-T V.41), using the 0x1021 polynomial. + Generator polynomial: x^16 + x^12 + x^5 + 1 + + Used in the UDF (DVD *.iso) disk format's Volume Descriptor Tag, + and was more historically the ITU-T V.41 CRC-16 used in the XModem protocol, + which uses 0xffff as the initial value. +*/ +@(optimization_mode="favor_size") +crc16_ccitt_0x1021 :: proc "contextless" (data: []u8, seed := u16(0)) -> (result: u16) #no_bounds_check { + result = seed + #no_bounds_check for b in data { + result = result << 8 ~ _ccitt_0x1021_table[(result >> 8) ~ u16(b)] + } + return result +} + @(optimization_mode="favor_size") crc64_ecma_182 :: proc "contextless" (data: []byte, seed := u64(0)) -> (result: u64) #no_bounds_check { result = seed #no_bounds_check for b in data { - result = result<<8 ~ _crc64_table_ecma_182[((result>>56) ~ u64(b)) & 0xff] + result = result << 8 ~ _crc64_table_ecma_182[((result>>56) ~ u64(b)) & 0xff] } return result } @@ -49,9 +66,7 @@ crc64_xz :: proc "contextless" (data: []byte, seed := u64(0)) -> u64 #no_bounds_ return u64(~result) } -/* - Generator polynomial: x^64 + x^4 + x^3 + x + 1 -*/ +// Generator polynomial: x^64 + x^4 + x^3 + x + 1 @(optimization_mode="favor_size") crc64_iso_3306 :: proc "contextless" (data: []byte, seed := u64(0)) -> u64 #no_bounds_check { @@ -75,7 +90,8 @@ crc64_iso_3306_inverse :: proc "contextless" (data: []byte, seed := u64(0)) -> u return ~result } -@private _crc64_table_ecma_182 := [256]u64{ +@(private, rodata) +_crc64_table_ecma_182 := [256]u64{ 0x0000000000000000, 0x42f0e1eba9ea3693, 0x85e1c3d753d46d26, 0xc711223cfa3e5bb5, 0x493366450e42ecdf, 0x0bc387aea7a8da4c, 0xccd2a5925d9681f9, 0x8e224479f47cb76a, 0x9266cc8a1c85d9be, 0xd0962d61b56fef2d, 0x17870f5d4f51b498, 0x5577eeb6e6bb820b, @@ -142,7 +158,8 @@ crc64_iso_3306_inverse :: proc "contextless" (data: []byte, seed := u64(0)) -> u 0x5dedc41a34bbeeb2, 0x1f1d25f19d51d821, 0xd80c07cd676f8394, 0x9afce626ce85b507, } -@private _crc64_table_xz := [8][256]u64le{ +@(private, rodata) +_crc64_table_xz := [8][256]u64le{ { 0x0000000000000000, 0xb32e4cbe03a75f6f, 0xf4843657a840a05b, 0x47aa7ae9abe7ff34, 0x7bd0c384ff8f5e33, 0xc8fe8f3afc28015c, 0x8f54f5d357cffe68, 0x3c7ab96d5468a107, @@ -673,7 +690,8 @@ crc64_iso_3306_inverse :: proc "contextless" (data: []byte, seed := u64(0)) -> u }, } -@private _crc64_table_iso_3306 := [256]u16{ +@(private, rodata) +_crc64_table_iso_3306 := [256]u16{ 0x0000, 0x01b0, 0x0360, 0x02d0, 0x06c0, 0x0770, 0x05a0, 0x0410, 0x0d80, 0x0c30, 0x0ee0, 0x0f50, @@ -739,3 +757,39 @@ crc64_iso_3306_inverse :: proc "contextless" (data: []byte, seed := u64(0)) -> u 0x9480, 0x9530, 0x97e0, 0x9650, 0x9240, 0x93f0, 0x9120, 0x9090, } + +@(private, rodata) +_ccitt_0x1021_table := [256]u16{ + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, + 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, + 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, + 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, + 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, + 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, + 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, + 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, + 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, + 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, + 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, + 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, + 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, + 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, + 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, + 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, + 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, + 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, + 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, + 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, + 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, + 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, + 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0, +} diff --git a/core/hash/xxhash/common.odin b/core/hash/xxhash/common.odin index ce98f21f9..e0f00a3db 100644 --- a/core/hash/xxhash/common.odin +++ b/core/hash/xxhash/common.odin @@ -6,7 +6,7 @@ package xxhash /* Copyright 2021 Jeroen van Rijn . - Made available under Odin's BSD-3 license, based on the original C code. + Made available under Odin's license, based on the original C code. List of contributors: Jeroen van Rijn: Initial implementation. diff --git a/core/hash/xxhash/streaming.odin b/core/hash/xxhash/streaming.odin index 699a089c9..d34206fdb 100644 --- a/core/hash/xxhash/streaming.odin +++ b/core/hash/xxhash/streaming.odin @@ -4,7 +4,7 @@ package xxhash An implementation of Yann Collet's [xxhash Fast Hash Algorithm](https://cyan4973.github.io/xxHash/). Copyright 2021 Jeroen van Rijn . - Made available under Odin's BSD-3 license, based on the original C code. + Made available under Odin's license, based on the original C code. List of contributors: Jeroen van Rijn: Initial implementation. diff --git a/core/hash/xxhash/xxhash_3.odin b/core/hash/xxhash/xxhash_3.odin index 20dd8e596..810b98f1a 100644 --- a/core/hash/xxhash/xxhash_3.odin +++ b/core/hash/xxhash/xxhash_3.odin @@ -4,7 +4,7 @@ package xxhash An implementation of Yann Collet's [xxhash Fast Hash Algorithm](https://cyan4973.github.io/xxHash/). Copyright 2021 Jeroen van Rijn . - Made available under Odin's BSD-3 license, based on the original C code. + Made available under Odin's license, based on the original C code. List of contributors: Jeroen van Rijn: Initial implementation. diff --git a/core/hash/xxhash/xxhash_32.odin b/core/hash/xxhash/xxhash_32.odin index 8e53d564b..7c03c232e 100644 --- a/core/hash/xxhash/xxhash_32.odin +++ b/core/hash/xxhash/xxhash_32.odin @@ -4,7 +4,7 @@ package xxhash An implementation of Yann Collet's [xxhash Fast Hash Algorithm](https://cyan4973.github.io/xxHash/). Copyright 2021 Jeroen van Rijn . - Made available under Odin's BSD-3 license, based on the original C code. + Made available under Odin's license, based on the original C code. List of contributors: Jeroen van Rijn: Initial implementation. diff --git a/core/hash/xxhash/xxhash_64.odin b/core/hash/xxhash/xxhash_64.odin index 16a70bd2e..80818db67 100644 --- a/core/hash/xxhash/xxhash_64.odin +++ b/core/hash/xxhash/xxhash_64.odin @@ -4,7 +4,7 @@ package xxhash An implementation of Yann Collet's [xxhash Fast Hash Algorithm](https://cyan4973.github.io/xxHash/). Copyright 2021 Jeroen van Rijn . - Made available under Odin's BSD-3 license, based on the original C code. + Made available under Odin's license, based on the original C code. List of contributors: Jeroen van Rijn: Initial implementation. diff --git a/core/image/common.odin b/core/image/common.odin index 11212953e..1d51afb1c 100644 --- a/core/image/common.odin +++ b/core/image/common.odin @@ -2,7 +2,7 @@ package image /* Copyright 2021 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Jeroen van Rijn: Initial implementation, optimization. diff --git a/core/image/png/png.odin b/core/image/png/png.odin index 4e67700f2..1a7240bad 100644 --- a/core/image/png/png.odin +++ b/core/image/png/png.odin @@ -3,7 +3,7 @@ package png /* Copyright 2021 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Jeroen van Rijn: Initial implementation. diff --git a/core/image/qoi/qoi.odin b/core/image/qoi/qoi.odin index a2b38a7a6..f633fe9b6 100644 --- a/core/image/qoi/qoi.odin +++ b/core/image/qoi/qoi.odin @@ -5,7 +5,7 @@ package qoi /* Copyright 2022 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Jeroen van Rijn: Initial implementation. diff --git a/core/image/tga/tga.odin b/core/image/tga/tga.odin index ad939e7ff..260720bb4 100644 --- a/core/image/tga/tga.odin +++ b/core/image/tga/tga.odin @@ -3,7 +3,7 @@ package tga /* Copyright 2022 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Jeroen van Rijn: Initial implementation. diff --git a/core/math/big/api.odin b/core/math/big/api.odin index 668afa534..e18a40b30 100644 --- a/core/math/big/api.odin +++ b/core/math/big/api.odin @@ -2,7 +2,7 @@ package math_big /* Copyright 2021 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under Odin's license. This file collects public proc maps and their aliases. */ diff --git a/core/math/big/common.odin b/core/math/big/common.odin index 66a29e715..a1eb4a7fd 100644 --- a/core/math/big/common.odin +++ b/core/math/big/common.odin @@ -2,7 +2,7 @@ package math_big /* Copyright 2021 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under Odin's license. */ import "base:intrinsics" diff --git a/core/math/big/helpers.odin b/core/math/big/helpers.odin index e8dc792c6..b922881b4 100644 --- a/core/math/big/helpers.odin +++ b/core/math/big/helpers.odin @@ -2,7 +2,7 @@ package math_big /* Copyright 2021 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under Odin's license. */ import "base:intrinsics" diff --git a/core/math/big/internal.odin b/core/math/big/internal.odin index 4b76f3b2e..e22ea0ec7 100644 --- a/core/math/big/internal.odin +++ b/core/math/big/internal.odin @@ -2,7 +2,7 @@ package math_big /* Copyright 2021 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under Odin's license. ========================== Low-level routines ========================== diff --git a/core/math/big/logical.odin b/core/math/big/logical.odin index df7744a9a..a600ef823 100644 --- a/core/math/big/logical.odin +++ b/core/math/big/logical.odin @@ -2,7 +2,7 @@ package math_big /* Copyright 2021 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under Odin's license. An arbitrary precision mathematics implementation in Odin. For the theoretical underpinnings, see Knuth's The Art of Computer Programming, Volume 2, section 4.3. diff --git a/core/math/big/prime.odin b/core/math/big/prime.odin index 8efa97174..d7f902fa5 100644 --- a/core/math/big/prime.odin +++ b/core/math/big/prime.odin @@ -2,7 +2,7 @@ package math_big /* Copyright 2021 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under Odin's license. An arbitrary precision mathematics implementation in Odin. For the theoretical underpinnings, see Knuth's The Art of Computer Programming, Volume 2, section 4.3. diff --git a/core/math/big/private.odin b/core/math/big/private.odin index 692b1d088..fb517f0b7 100644 --- a/core/math/big/private.odin +++ b/core/math/big/private.odin @@ -2,7 +2,7 @@ package math_big /* Copyright 2021 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under Odin's license. An arbitrary precision mathematics implementation in Odin. For the theoretical underpinnings, see Knuth's The Art of Computer Programming, Volume 2, section 4.3. diff --git a/core/math/big/public.odin b/core/math/big/public.odin index dfefbc91a..723e2e04a 100644 --- a/core/math/big/public.odin +++ b/core/math/big/public.odin @@ -3,7 +3,7 @@ package math_big /* Copyright 2021 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under Odin's license. An arbitrary precision mathematics implementation in Odin. For the theoretical underpinnings, see Knuth's The Art of Computer Programming, Volume 2, section 4.3. diff --git a/core/math/big/radix.odin b/core/math/big/radix.odin index bc9ae068d..2bbe593a2 100644 --- a/core/math/big/radix.odin +++ b/core/math/big/radix.odin @@ -2,7 +2,7 @@ package math_big /* Copyright 2021 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under Odin's license. An arbitrary precision mathematics implementation in Odin. For the theoretical underpinnings, see Knuth's The Art of Computer Programming, Volume 2, section 4.3. diff --git a/core/math/big/tune.odin b/core/math/big/tune.odin index 1d24a1325..b2dc9829c 100644 --- a/core/math/big/tune.odin +++ b/core/math/big/tune.odin @@ -3,7 +3,7 @@ package math_big /* Copyright 2021 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under Odin's license. A BigInt implementation in Odin. For the theoretical underpinnings, see Knuth's The Art of Computer Programming, Volume 2, section 4.3. diff --git a/core/math/bits/bits.odin b/core/math/bits/bits.odin index effcf4985..1e8d765dd 100644 --- a/core/math/bits/bits.odin +++ b/core/math/bits/bits.odin @@ -3,26 +3,49 @@ package math_bits import "base:intrinsics" +// The minimum value held by a `u8`. The same value as `min(u8)`, except untyped. U8_MIN :: 0 +// The minimum value held by a `u16`. The same value as `min(u16)`, except untyped. U16_MIN :: 0 +// The minimum value held by a `u32`. The same value as `min(u32)`, except untyped. U32_MIN :: 0 +// The minimum value held by a `u64`. The same value as `min(u64)`, except untyped. U64_MIN :: 0 +// The minimum value held by a `uint`. The same value as `min(uint)`, except untyped. +UINT_MIN :: 0 +// The maximum value held by a `u8`. The same value as `max(u8)`, except untyped. U8_MAX :: 1 << 8 - 1 +// The maximum value held by a `u16`. The same value as `max(u16)`, except untyped. U16_MAX :: 1 << 16 - 1 +// The maximum value held by a `u32`. The same value as `max(u32)`, except untyped. U32_MAX :: 1 << 32 - 1 +// The maximum value held by a `u64`. The same value as `max(u64)`, except untyped. U64_MAX :: 1 << 64 - 1 +// The maximum value held by a `uint`. The same value as `max(uint)`, except untyped. +UINT_MAX :: U64_MAX when size_of(uint) == 8 else U32_MAX +// The minimum value held by an `i8`. The same value as `min(i8)`, except untyped. I8_MIN :: - 1 << 7 +// The minimum value held by an `i16`. The same value as `min(i16)`, except untyped. I16_MIN :: - 1 << 15 +// The minimum value held by an `i32`. The same value as `min(i32)`, except untyped. I32_MIN :: - 1 << 31 +// The minimum value held by an `i64`. The same value as `min(i64)`, except untyped. I64_MIN :: - 1 << 63 +// The minimum value held by an `int`. The same value as `min(int)`, except untyped. +INT_MIN :: I64_MIN when size_of(int) == 8 else I32_MIN +// The maximum value held by an `i8`. The same value as `max(i8)`, except untyped. I8_MAX :: 1 << 7 - 1 +// The maximum value held by an `i16`. The same value as `max(i16)`, except untyped. I16_MAX :: 1 << 15 - 1 +// The maximum value held by an `i32`. The same value as `max(i32)`, except untyped. I32_MAX :: 1 << 31 - 1 +// The maximum value held by an `i64`. The same value as `max(i64)`, except untyped. I64_MAX :: 1 << 63 - 1 - +// The maximum value held by an `int`. The same value as `max(int)`, except untyped. +INT_MAX :: I64_MAX when size_of(int) == 8 else I32_MAX count_ones :: intrinsics.count_ones count_zeros :: intrinsics.count_zeros @@ -32,100 +55,440 @@ count_trailing_zeros :: intrinsics.count_trailing_zeros count_leading_zeros :: intrinsics.count_leading_zeros reverse_bits :: intrinsics.reverse_bits byte_swap :: intrinsics.byte_swap +overflowing_add :: intrinsics.overflow_add +overflowing_sub :: intrinsics.overflow_sub +overflowing_mul :: intrinsics.overflow_mul -overflowing_add :: intrinsics.overflow_add -overflowing_sub :: intrinsics.overflow_sub -overflowing_mul :: intrinsics.overflow_mul +/* +Returns the base-2 logarithm of an unsigned integer `x` +Another way to say this is that `log2(x)` is the position of its leading `1` bit. +NOTE: This is ill-defined for `0` as it has no `1` bits, and `log2(0)` will return `max(T)`. + +Inputs: +- x: The unsigned integer + +Returns: +- res: The base-2 logarithm of `x` + +Example: + + import "core:fmt" + import "core:math/bits" + + log2_example :: proc() { + for i in u8(1)..=8 { + fmt.printfln("{0} ({0:4b}): {1}", i, bits.log2(i)) + } + assert(bits.log2( u8(0)) == max(u8)) + assert(bits.log2( u16(0)) == max(u16)) + assert(bits.log2( u32(0)) == max(u32)) + assert(bits.log2( u64(0)) == max(u64)) + assert(bits.log2(u128(0)) == max(u128)) + } + +Output: + + 1 (0001): 0 + 2 (0010): 1 + 3 (0011): 1 + 4 (0100): 2 + 5 (0101): 2 + 6 (0110): 2 + 7 (0111): 2 + 8 (1000): 3 + +*/ @(require_results) -log2 :: proc "contextless" (x: $T) -> T where intrinsics.type_is_integer(T), intrinsics.type_is_unsigned(T) { +log2 :: proc "contextless" (x: $T) -> (res: T) where intrinsics.type_is_integer(T), intrinsics.type_is_unsigned(T) { return (8*size_of(T)-1) - count_leading_zeros(x) } +/* +Returns unsigned integer `x` rotated left by `k` bits + +Can be thought of as a bit shift in which the leading bits are shifted back in on the bottom, rather than dropped. + +This is equivalent to the [[ROL ; https://www.felixcloutier.com/x86/rcl:rcr:rol:ror]] CPU instruction. + +Inputs: +- x: The unsigned integer +- k: Number of bits to rotate left by + +Returns: +- res: `x` rotated left by `k` bits + +Example: + + import "core:fmt" + import "core:math/bits" + + rotate_left8_example :: proc() { + x := u8(13) + for k in 0..<8 { + fmt.printfln("{0:8b}: {1}", bits.rotate_left8(x, k), k) + } + } + +Output: + + 00001101: 0 + 00011010: 1 + 00110100: 2 + 01101000: 3 + 11010000: 4 + 10100001: 5 + 01000011: 6 + 10000110: 7 + +*/ @(require_results) rotate_left8 :: proc "contextless" (x: u8, k: int) -> u8 { n :: 8 s := uint(k) & (n-1) - return x <>(n-s) + return x << s | x >> (n-s) } + +/* +Returns unsigned integer `x` rotated left by `k` bits + +Can be thought of as a bit shift in which the leading bits are shifted back in on the bottom, rather than dropped. + +This is equivalent to the [[ROL ; https://www.felixcloutier.com/x86/rcl:rcr:rol:ror]] CPU instruction. + +Inputs: +- x: The unsigned integer +- k: Number of bits to rotate left by + +Returns: +- res: `x` rotated left by `k` bits +*/ @(require_results) rotate_left16 :: proc "contextless" (x: u16, k: int) -> u16 { n :: 16 s := uint(k) & (n-1) - return x <>(n-s) + return x << s | x >>(n-s) } + +/* +Returns unsigned integer `x` rotated left by `k` bits + +Can be thought of as a bit shift in which the leading bits are shifted back in on the bottom, rather than dropped. + +This is equivalent to the [[ROL ; https://www.felixcloutier.com/x86/rcl:rcr:rol:ror]] CPU instruction. + +Inputs: +- x: The unsigned integer +- k: Number of bits to rotate left by + +Returns: +- res: `x` rotated left by `k` bits +*/ @(require_results) rotate_left32 :: proc "contextless" (x: u32, k: int) -> u32 { n :: 32 s := uint(k) & (n-1) - return x <>(n-s) + return x << s | x >> (n-s) } + +/* +Returns unsigned integer `x` rotated left by `k` bits + +Can be thought of as a bit shift in which the leading bits are shifted back in on the bottom, rather than dropped. + +This is equivalent to the [[ROL ; https://www.felixcloutier.com/x86/rcl:rcr:rol:ror]] CPU instruction. + +Inputs: +- x: The unsigned integer +- k: Number of bits to rotate left by + +Returns: +- res: `x` rotated left by `k` bits +*/ @(require_results) rotate_left64 :: proc "contextless" (x: u64, k: int) -> u64 { n :: 64 s := uint(k) & (n-1) - return x <>(n-s) + return x << s | x >> (n-s) } +/* +Returns unsigned integer `x` rotated left by `k` bits + +Can be thought of as a bit shift in which the leading bits are shifted back in on the bottom, rather than dropped. + +This is equivalent to the [[ROL ; https://www.felixcloutier.com/x86/rcl:rcr:rol:ror]] CPU instruction. + +Inputs: +- x: The unsigned integer +- k: Number of bits to rotate left by + +Returns: +- res: `x` rotated left by `k` bits +*/ @(require_results) rotate_left :: proc "contextless" (x: uint, k: int) -> uint { n :: 8*size_of(uint) s := uint(k) & (n-1) - return x <>(n-s) + return x << s | x >> (n-s) } +/* +Returns unsigned integer `i` + +NOTE: A byte has no endianness, so `from_be_u8` exists to be complementary to `from_be_*`. + +Inputs: +- i: The unsigned integer + +Returns: +- res: `i` +*/ @(require_results) from_be_u8 :: proc "contextless" (i: u8) -> u8 { return i } + +/* +Returns unsigned integer `i`, byte-swapped if we're on a little endian target. + +Inputs: +- i: The unsigned integer + +Returns: +- res: `i`, optionally byte-swapped +*/ @(require_results) from_be_u16 :: proc "contextless" (i: u16) -> u16 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } + +/* +Returns unsigned integer `i`, byte-swapped if we're on a little endian target. + +Inputs: +- i: The unsigned integer + +Returns: +- res: `i`, optionally byte-swapped +*/ @(require_results) from_be_u32 :: proc "contextless" (i: u32) -> u32 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } + +/* +Returns unsigned integer `i`, byte-swapped if we're on a little endian target. + +Inputs: +- i: The unsigned integer + +Returns: +- res: `i`, optionally byte-swapped +*/ @(require_results) from_be_u64 :: proc "contextless" (i: u64) -> u64 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } + +/* +Returns unsigned integer `i`, byte-swapped if we're on a little endian target. + +Inputs: +- i: The unsigned integer + +Returns: +- res: `i`, optionally byte-swapped +*/ @(require_results) from_be_uint :: proc "contextless" (i: uint) -> uint { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } +/* +Returns unsigned integer `i` + +NOTE: A byte has no endianness, so `from_le_u8` exists to be complementary to `from_le_*`. + +Inputs: +- i: The unsigned integer + +Returns: +- res: `i` +*/ @(require_results) from_le_u8 :: proc "contextless" (i: u8) -> u8 { return i } + +/* +Returns unsigned integer `i`, byte-swapped if we're on a big endian target. + +Inputs: +- i: The unsigned integer + +Returns: +- res: `i`, optionally byte-swapped +*/ @(require_results) from_le_u16 :: proc "contextless" (i: u16) -> u16 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } + +/* +Returns unsigned integer `i`, byte-swapped if we're on a big endian target. + +Inputs: +- i: The unsigned integer + +Returns: +- res: `i`, optionally byte-swapped +*/ @(require_results) from_le_u32 :: proc "contextless" (i: u32) -> u32 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } + +/* +Returns unsigned integer `i`, byte-swapped if we're on a big endian target. + +Inputs: +- i: The unsigned integer + +Returns: +- res: `i`, optionally byte-swapped +*/ @(require_results) from_le_u64 :: proc "contextless" (i: u64) -> u64 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } + +/* +Returns unsigned integer `i`, byte-swapped if we're on a big endian target. + +Inputs: +- i: The unsigned integer + +Returns: +- res: `i`, optionally byte-swapped +*/ @(require_results) from_le_uint :: proc "contextless" (i: uint) -> uint { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } +/* +Returns unsigned integer `i` + +NOTE: A byte has no endianness, so `to_be_u8` exists to be complementary to `to_be_*`. + +Inputs: +- i: The unsigned integer + +Returns: +- res: `i` +*/ @(require_results) to_be_u8 :: proc "contextless" (i: u8) -> u8 { return i } @(require_results) + +/* +Returns unsigned integer `i`, byte-swapped if we're on a little endian target. + +Inputs: +- i: The unsigned integer + +Returns: +- res: `i`, optionally byte-swapped +*/ to_be_u16 :: proc "contextless" (i: u16) -> u16 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } + +/* +Returns unsigned integer `i`, byte-swapped if we're on a little endian target. + +Inputs: +- i: The unsigned integer + +Returns: +- res: `i`, optionally byte-swapped +*/ @(require_results) to_be_u32 :: proc "contextless" (i: u32) -> u32 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } + +/* +Returns unsigned integer `i`, byte-swapped if we're on a little endian target. + +Inputs: +- i: The unsigned integer + +Returns: +- res: `i`, optionally byte-swapped +*/ @(require_results) to_be_u64 :: proc "contextless" (i: u64) -> u64 { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } + +/* +Returns unsigned integer `i`, byte-swapped if we're on a little endian target. + +Inputs: +- i: The unsigned integer + +Returns: +- res: `i`, optionally byte-swapped +*/ @(require_results) to_be_uint :: proc "contextless" (i: uint) -> uint { when ODIN_ENDIAN == .Big { return i } else { return byte_swap(i) } } +/* +Returns unsigned integer `i` +NOTE: A byte has no endianness, so `to_le_u8` exists to be complementary to `to_le_*`. + +Inputs: +- i: The unsigned integer + +Returns: +- res: `i` +*/ @(require_results) to_le_u8 :: proc "contextless" (i: u8) -> u8 { return i } + +/* +Returns unsigned integer `i`, byte-swapped if we're on a big endian target. + +Inputs: +- i: The unsigned integer + +Returns: +- res: `i`, optionally byte-swapped +*/ @(require_results) to_le_u16 :: proc "contextless" (i: u16) -> u16 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } + +/* +Returns unsigned integer `i`, byte-swapped if we're on a big endian target. + +Inputs: +- i: The unsigned integer + +Returns: +- res: `i`, optionally byte-swapped +*/ @(require_results) to_le_u32 :: proc "contextless" (i: u32) -> u32 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } + +/* +Returns unsigned integer `i`, byte-swapped if we're on a big endian target. + +Inputs: +- i: The unsigned integer + +Returns: +- res: `i`, optionally byte-swapped +*/ @(require_results) to_le_u64 :: proc "contextless" (i: u64) -> u64 { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } + +/* +Returns unsigned integer `i`, byte-swapped if we're on a big endian target. + +Inputs: +- i: The unsigned integer + +Returns: +- res: `i`, optionally byte-swapped +*/ @(require_results) to_le_uint :: proc "contextless" (i: uint) -> uint { when ODIN_ENDIAN == .Little { return i } else { return byte_swap(i) } } - - +// returns the minimum number of bits required to represent x @(require_results) len_u8 :: proc "contextless" (x: u8) -> int { return int(len_u8_table[x]) } + +// returns the minimum number of bits required to represent x @(require_results) len_u16 :: proc "contextless" (x: u16) -> (n: int) { x := x @@ -135,6 +498,8 @@ len_u16 :: proc "contextless" (x: u16) -> (n: int) { } return n + int(len_u8_table[x]) } + +// returns the minimum number of bits required to represent x @(require_results) len_u32 :: proc "contextless" (x: u32) -> (n: int) { x := x @@ -148,6 +513,8 @@ len_u32 :: proc "contextless" (x: u32) -> (n: int) { } return n + int(len_u8_table[x]) } + +// returns the minimum number of bits required to represent x @(require_results) len_u64 :: proc "contextless" (x: u64) -> (n: int) { x := x @@ -165,6 +532,8 @@ len_u64 :: proc "contextless" (x: u64) -> (n: int) { } return n + int(len_u8_table[x]) } + +// returns the minimum number of bits required to represent x @(require_results) len_uint :: proc "contextless" (x: uint) -> (n: int) { when size_of(uint) == size_of(u64) { @@ -177,23 +546,60 @@ len_uint :: proc "contextless" (x: uint) -> (n: int) { // returns the minimum number of bits required to represent x len :: proc{len_u8, len_u16, len_u32, len_u64, len_uint} +/* +Add with carry +Inputs: +- x: The unsigned integer +- y: Another unsigned integer +- carry: Carry in + +Returns: +- sum: The sum +- carry_out: Carry out +*/ @(require_results) add_u32 :: proc "contextless" (x, y, carry: u32) -> (sum, carry_out: u32) { tmp_carry, tmp_carry2: bool - sum, tmp_carry = intrinsics.overflow_add(x, y) + sum, tmp_carry = intrinsics.overflow_add(x, y) sum, tmp_carry2 = intrinsics.overflow_add(sum, carry) carry_out = u32(tmp_carry | tmp_carry2) return } + +/* +Add with carry + +Inputs: +- x: The unsigned integer +- y: Another unsigned integer +- carry: Carry in + +Returns: +- sum: The sum +- carry_out: Carry out +*/ @(require_results) add_u64 :: proc "contextless" (x, y, carry: u64) -> (sum, carry_out: u64) { tmp_carry, tmp_carry2: bool - sum, tmp_carry = intrinsics.overflow_add(x, y) + sum, tmp_carry = intrinsics.overflow_add(x, y) sum, tmp_carry2 = intrinsics.overflow_add(sum, carry) carry_out = u64(tmp_carry | tmp_carry2) return } + +/* +Add with carry + +Inputs: +- x: The unsigned integer +- y: Another unsigned integer +- carry: Carry in + +Returns: +- sum: The sum +- carry_out: Carry out +*/ @(require_results) add_uint :: proc "contextless" (x, y, carry: uint) -> (sum, carry_out: uint) { when size_of(uint) == size_of(u64) { @@ -204,17 +610,54 @@ add_uint :: proc "contextless" (x, y, carry: uint) -> (sum, carry_out: uint) { } return uint(a), uint(b) } + +/* +Add with carry + +Inputs: +- x: The unsigned integer +- y: Another unsigned integer +- carry: Carry in + +Returns: +- sum: The sum +- carry_out: Carry out +*/ add :: proc{add_u32, add_u64, add_uint} +/* +Subtract with borrow +Inputs: +- x: The unsigned integer +- y: Another unsigned integer +- borrow: Borrow in + +Returns: +- diff: The difference +- borrow_out: Borrow out +*/ @(require_results) sub_u32 :: proc "contextless" (x, y, borrow: u32) -> (diff, borrow_out: u32) { tmp_borrow, tmp_borrow2: bool - diff, tmp_borrow = intrinsics.overflow_sub(x, y) + diff, tmp_borrow = intrinsics.overflow_sub(x, y) diff, tmp_borrow2 = intrinsics.overflow_sub(diff, borrow) borrow_out = u32(tmp_borrow | tmp_borrow2) return } + +/* +Subtract with borrow + +Inputs: +- x: The unsigned integer +- y: Another unsigned integer +- borrow: Borrow in + +Returns: +- diff: The difference +- borrow_out: Borrow out +*/ @(require_results) sub_u64 :: proc "contextless" (x, y, borrow: u64) -> (diff, borrow_out: u64) { tmp_borrow, tmp_borrow2: bool @@ -223,6 +666,19 @@ sub_u64 :: proc "contextless" (x, y, borrow: u64) -> (diff, borrow_out: u64) { borrow_out = u64(tmp_borrow | tmp_borrow2) return } + +/* +Subtract with borrow + +Inputs: +- x: The unsigned integer +- y: Another unsigned integer +- borrow: Borrow in + +Returns: +- diff: The difference +- borrow_out: Borrow out +*/ @(require_results) sub_uint :: proc "contextless" (x, y, borrow: uint) -> (diff, borrow_out: uint) { when size_of(uint) == size_of(u64) { @@ -233,15 +689,50 @@ sub_uint :: proc "contextless" (x, y, borrow: uint) -> (diff, borrow_out: uint) } return uint(a), uint(b) } + +/* +Subtract with borrow + +Inputs: +- x: The unsigned integer +- y: Another unsigned integer +- borrow: Borrow in + +Returns: +- diff: The difference +- borrow_out: Borrow out +*/ sub :: proc{sub_u32, sub_u64, sub_uint} +/* +Multiply two words and return the result in high and low word +Inputs: +- x: The unsigned integer +- y: Another unsigned integer + +Returns: +- hi: The result's high word +- lo: The result's low word +*/ @(require_results) mul_u32 :: proc "contextless" (x, y: u32) -> (hi, lo: u32) { z := u64(x) * u64(y) hi, lo = u32(z>>32), u32(z) return } + +/* +Multiply two words and return the result in high and low word + +Inputs: +- x: The unsigned integer +- y: Another unsigned integer + +Returns: +- hi: The result's high word +- lo: The result's low word +*/ @(require_results) mul_u64 :: proc "contextless" (x, y: u64) -> (hi, lo: u64) { prod_wide := u128(x) * u128(y) @@ -249,6 +740,17 @@ mul_u64 :: proc "contextless" (x, y: u64) -> (hi, lo: u64) { return } +/* +Multiply two words and return the result in high and low word + +Inputs: +- x: The unsigned integer +- y: Another unsigned integer + +Returns: +- hi: The result's high word +- lo: The result's low word +*/ @(require_results) mul_uint :: proc "contextless" (x, y: uint) -> (hi, lo: uint) { when size_of(uint) == size_of(u32) { @@ -260,9 +762,31 @@ mul_uint :: proc "contextless" (x, y: uint) -> (hi, lo: uint) { return uint(a), uint(b) } +/* +Multiply two words and return the result in high and low word + +Inputs: +- x: The unsigned integer +- y: Another unsigned integer + +Returns: +- hi: The result's high word +- lo: The result's low word +*/ mul :: proc{mul_u32, mul_u64, mul_uint} +/* +Divide a 64-bit unsigned integer (in two 32-bit words) by a 32-bit divisor +Inputs: +- hi: High word of 64-bit integer +- lo: Low word of 64-bit integer +- y: Divisor + +Returns: +- quo: 32-bit quotient +- rem: 32-bit remainder +*/ @(require_results) div_u32 :: proc "odin" (hi, lo, y: u32) -> (quo, rem: u32) { assert(y != 0 && y <= hi) @@ -270,6 +794,19 @@ div_u32 :: proc "odin" (hi, lo, y: u32) -> (quo, rem: u32) { quo, rem = u32(z/u64(y)), u32(z%u64(y)) return } + +/* +Divide a 128-bit unsigned integer (in two 64-bit words) by a 64-bit divisor + +Inputs: +- hi: High word of 128-bit integer +- lo: Low word of 128-bit integer +- y: Divisor + +Returns: +- quo: 64-bit quotient +- rem: 64-bit Remainder +*/ @(require_results) div_u64 :: proc "odin" (hi, lo, y: u64) -> (quo, rem: u64) { y := y @@ -316,6 +853,19 @@ div_u64 :: proc "odin" (hi, lo, y: u64) -> (quo, rem: u64) { return q1*two32 + q0, (un21*two32 + un0 - q0*y) >> s } + +/* +Divide an unsigned integer (in two words) by a divisor + +Inputs: +- hi: High word of input +- lo: Low word of input +- y: Divisor + +Returns: +- quo: Quotient +- rem: Remainder +*/ @(require_results) div_uint :: proc "odin" (hi, lo, y: uint) -> (quo, rem: uint) { when size_of(uint) == size_of(u32) { @@ -326,31 +876,150 @@ div_uint :: proc "odin" (hi, lo, y: uint) -> (quo, rem: uint) { } return uint(a), uint(b) } + +/* +Divide an unsigned integer (in two words) by a divisor + +Inputs: +- hi: High word of input +- lo: Low word of input +- y: Divisor + +Returns: +- quo: Quotient +- rem: Remainder +*/ div :: proc{div_u32, div_u64, div_uint} +/* +Checks whether an unsigned number is a power of two +Inputs: +- i: Unsigned number +Returns: +- is_pot: `true` if `i` is a power of two, `false` otherwise +*/ @(require_results) -is_power_of_two_u8 :: proc "contextless" (i: u8) -> bool { return i > 0 && (i & (i-1)) == 0 } -@(require_results) -is_power_of_two_i8 :: proc "contextless" (i: i8) -> bool { return i > 0 && (i & (i-1)) == 0 } -@(require_results) -is_power_of_two_u16 :: proc "contextless" (i: u16) -> bool { return i > 0 && (i & (i-1)) == 0 } -@(require_results) -is_power_of_two_i16 :: proc "contextless" (i: i16) -> bool { return i > 0 && (i & (i-1)) == 0 } -@(require_results) -is_power_of_two_u32 :: proc "contextless" (i: u32) -> bool { return i > 0 && (i & (i-1)) == 0 } -@(require_results) -is_power_of_two_i32 :: proc "contextless" (i: i32) -> bool { return i > 0 && (i & (i-1)) == 0 } -@(require_results) -is_power_of_two_u64 :: proc "contextless" (i: u64) -> bool { return i > 0 && (i & (i-1)) == 0 } -@(require_results) -is_power_of_two_i64 :: proc "contextless" (i: i64) -> bool { return i > 0 && (i & (i-1)) == 0 } -@(require_results) -is_power_of_two_uint :: proc "contextless" (i: uint) -> bool { return i > 0 && (i & (i-1)) == 0 } -@(require_results) -is_power_of_two_int :: proc "contextless" (i: int) -> bool { return i > 0 && (i & (i-1)) == 0 } +is_power_of_two_u8 :: proc "contextless" (i: u8) -> (is_pot: bool) { return i > 0 && (i & (i-1)) == 0 } +/* +Checks whether an unsigned number is a power of two + +Inputs: +- i: Unsigned number + +Returns: +- is_pot: `true` if `i` is a power of two, `false` otherwise +*/ +@(require_results) +is_power_of_two_i8 :: proc "contextless" (i: i8) -> (is_pot: bool) { return i > 0 && (i & (i-1)) == 0 } + +/* +Checks whether an unsigned number is a power of two + +Inputs: +- i: Unsigned number + +Returns: +- is_pot: `true` if `i` is a power of two, `false` otherwise +*/ +@(require_results) +is_power_of_two_u16 :: proc "contextless" (i: u16) -> (is_pot: bool) { return i > 0 && (i & (i-1)) == 0 } + +/* +Checks whether an unsigned number is a power of two + +Inputs: +- i: Unsigned number + +Returns: +- is_pot: `true` if `i` is a power of two, `false` otherwise +*/ +@(require_results) +is_power_of_two_i16 :: proc "contextless" (i: i16) -> (is_pot: bool) { return i > 0 && (i & (i-1)) == 0 } + +/* +Checks whether an unsigned number is a power of two + +Inputs: +- i: Unsigned number + +Returns: +- is_pot: `true` if `i` is a power of two, `false` otherwise +*/ +@(require_results) +is_power_of_two_u32 :: proc "contextless" (i: u32) -> (is_pot: bool) { return i > 0 && (i & (i-1)) == 0 } + +/* +Checks whether an unsigned number is a power of two + +Inputs: +- i: Unsigned number + +Returns: +- is_pot: `true` if `i` is a power of two, `false` otherwise +*/ +@(require_results) +is_power_of_two_i32 :: proc "contextless" (i: i32) -> (is_pot: bool) { return i > 0 && (i & (i-1)) == 0 } + +/* +Checks whether an unsigned number is a power of two + +Inputs: +- i: Unsigned number + +Returns: +- is_pot: `true` if `i` is a power of two, `false` otherwise +*/ +@(require_results) +is_power_of_two_u64 :: proc "contextless" (i: u64) -> (is_pot: bool) { return i > 0 && (i & (i-1)) == 0 } + +/* +Checks whether an unsigned number is a power of two + +Inputs: +- i: Unsigned number + +Returns: +- is_pot: `true` if `i` is a power of two, `false` otherwise +*/ +@(require_results) +is_power_of_two_i64 :: proc "contextless" (i: i64) -> (is_pot: bool) { return i > 0 && (i & (i-1)) == 0 } + +/* +Checks whether an unsigned number is a power of two + +Inputs: +- i: Unsigned number + +Returns: +- is_pot: `true` if `i` is a power of two, `false` otherwise +*/ +@(require_results) +is_power_of_two_uint :: proc "contextless" (i: uint) -> (is_pot: bool) { return i > 0 && (i & (i-1)) == 0 } + +/* +Checks whether an unsigned number is a power of two + +Inputs: +- i: Unsigned number + +Returns: +- is_pot: `true` if `i` is a power of two, `false` otherwise +*/ +@(require_results) +is_power_of_two_int :: proc "contextless" (i: int) -> (is_pot: bool) { return i > 0 && (i & (i-1)) == 0 } + +/* +Checks whether an unsigned number is a power of two + +Inputs: +- i: Unsigned number + +Returns: +- is_pot: `true` if `i` is a power of two, `false` otherwise +*/ is_power_of_two :: proc{ is_power_of_two_u8, is_power_of_two_i8, is_power_of_two_u16, is_power_of_two_i16, @@ -373,20 +1042,101 @@ len_u8_table := [256]u8{ 128..<256 = 8, } +/* +Extracts bits from an unsigned integer -@(require_results) -bitfield_extract_u8 :: proc "contextless" (value: u8, offset, bits: uint) -> u8 { return (value >> offset) & u8(1< u16 { return (value >> offset) & u16(1< u32 { return (value >> offset) & u32(1< u64 { return (value >> offset) & u64(1< u128 { return (value >> offset) & u128(1< uint { return (value >> offset) & uint(1< (res: u8) { return (value >> offset) & u8(1< (res: u16) { return (value >> offset) & u16(1< (res: u32) { return (value >> offset) & u32(1< (res: u64) { return (value >> offset) & u64(1< (res: u128) { return (value >> offset) & u128(1< (res: uint) { return (value >> offset) & uint(1< i8 { v := (u8(value) >> offset) & u8(1< i8 r := (v~m) - m return i8(r) } + +/* +Extracts bits from a signed integer + +Inputs: +- value: Signed integer +- offset: Offset (counting from LSB) at which to extract +- bits: Number of bits to extract + +Returns: +- res: `bits` bits starting at offset `offset` +*/ @(require_results) bitfield_extract_i16 :: proc "contextless" (value: i16, offset, bits: uint) -> i16 { v := (u16(value) >> offset) & u16(1< i r := (v~m) - m return i16(r) } + +/* +Extracts bits from a signed integer + +Inputs: +- value: Signed integer +- offset: Offset (counting from LSB) at which to extract +- bits: Number of bits to extract + +Returns: +- res: `bits` bits starting at offset `offset` +*/ @(require_results) bitfield_extract_i32 :: proc "contextless" (value: i32, offset, bits: uint) -> i32 { v := (u32(value) >> offset) & u32(1< i r := (v~m) - m return i32(r) } + +/* +Extracts bits from a signed integer + +Inputs: +- value: Signed integer +- offset: Offset (counting from LSB) at which to extract +- bits: Number of bits to extract + +Returns: +- res: `bits` bits starting at offset `offset` +*/ @(require_results) bitfield_extract_i64 :: proc "contextless" (value: i64, offset, bits: uint) -> i64 { v := (u64(value) >> offset) & u64(1< i r := (v~m) - m return i64(r) } + +/* +Extracts bits from a signed integer + +Inputs: +- value: Signed integer +- offset: Offset (counting from LSB) at which to extract +- bits: Number of bits to extract + +Returns: +- res: `bits` bits starting at offset `offset` +*/ @(require_results) bitfield_extract_i128 :: proc "contextless" (value: i128, offset, bits: uint) -> i128 { v := (u128(value) >> offset) & u128(1< r := (v~m) - m return i128(r) } + +/* +Extracts bits from a signed integer + +Inputs: +- value: Signed integer +- offset: Offset (counting from LSB) at which to extract +- bits: Number of bits to extract + +Returns: +- res: `bits` bits starting at offset `offset` +*/ @(require_results) bitfield_extract_int :: proc "contextless" (value: int, offset, bits: uint) -> int { v := (uint(value) >> offset) & uint(1< i return int(r) } +/* +Extracts bits from an integer +Inputs: +- value: Integer +- offset: Offset (counting from LSB) at which to extract +- bits: Number of bits to extract + +Returns: +- res: `bits` bits starting at offset `offset` +*/ bitfield_extract :: proc{ bitfield_extract_u8, bitfield_extract_u16, @@ -446,69 +1266,260 @@ bitfield_extract :: proc{ bitfield_extract_int, } +/* +Insert a subset of bits from one integer into another integer +Copies `bits` number of `insert`'s lower bits to `base` at `offset`. + +Inputs: +- base: Original integer to insert bits into +- insert: Integer to copy bits from +- offset: Bit offset in `base` at which to place `insert`'s bits +- bits: Number of bits to copy + +Returns: +- res: `base` with `bits` bits at `offset` replaced with `insert`'s +*/ @(require_results) -bitfield_insert_u8 :: proc "contextless" (base, insert: u8, offset, bits: uint) -> u8 { +bitfield_insert_u8 :: proc "contextless" (base, insert: u8, offset, bits: uint) -> (res: u8) { mask := u8(1< u16 { +bitfield_insert_u16 :: proc "contextless" (base, insert: u16, offset, bits: uint) -> (res: u16) { mask := u16(1< u32 { +bitfield_insert_u32 :: proc "contextless" (base, insert: u32, offset, bits: uint) -> (res: u32) { mask := u32(1< u64 { +bitfield_insert_u64 :: proc "contextless" (base, insert: u64, offset, bits: uint) -> (res: u64) { mask := u64(1< u128 { +bitfield_insert_u128 :: proc "contextless" (base, insert: u128, offset, bits: uint) -> (res: u128) { mask := u128(1< uint { +bitfield_insert_uint :: proc "contextless" (base, insert: uint, offset, bits: uint) -> (res: uint) { mask := uint(1< i8 { +bitfield_insert_i8 :: proc "contextless" (base, insert: i8, offset, bits: uint) -> (res: i8) { mask := i8(1< i16 { +bitfield_insert_i16 :: proc "contextless" (base, insert: i16, offset, bits: uint) -> (res: i16) { mask := i16(1< i32 { +bitfield_insert_i32 :: proc "contextless" (base, insert: i32, offset, bits: uint) -> (res: i32) { mask := i32(1< i64 { +bitfield_insert_i64 :: proc "contextless" (base, insert: i64, offset, bits: uint) -> (res: i64) { mask := i64(1< i128 { +bitfield_insert_i128 :: proc "contextless" (base, insert: i128, offset, bits: uint) -> (res: i128) { mask := i128(1< int { +bitfield_insert_int :: proc "contextless" (base, insert: int, offset, bits: uint) -> (res: int) { mask := int(1< T where intrinsics.type_is_f if p == 0.0 || p == 1.0 { return p } - + if p < 0.5 { return 0.5 * math.pow(2, (20 * p) - 10) } else { @@ -307,224 +306,51 @@ Ease :: enum { } @(require_results) -ease :: proc "contextless" (type: Ease, p: $T) -> T - where intrinsics.type_is_float(T) { +ease :: proc "contextless" (type: Ease, p: $T) -> T where intrinsics.type_is_float(T) { switch type { - case .Linear: return p + case .Linear: return p - case .Quadratic_In: return quadratic_in(p) - case .Quadratic_Out: return quadratic_out(p) - case .Quadratic_In_Out: return quadratic_in_out(p) + case .Quadratic_In: return quadratic_in(p) + case .Quadratic_Out: return quadratic_out(p) + case .Quadratic_In_Out: return quadratic_in_out(p) - case .Cubic_In: return cubic_in(p) - case .Cubic_Out: return cubic_out(p) - case .Cubic_In_Out: return cubic_in_out(p) + case .Cubic_In: return cubic_in(p) + case .Cubic_Out: return cubic_out(p) + case .Cubic_In_Out: return cubic_in_out(p) - case .Quartic_In: return quartic_in(p) - case .Quartic_Out: return quartic_out(p) - case .Quartic_In_Out: return quartic_in_out(p) + case .Quartic_In: return quartic_in(p) + case .Quartic_Out: return quartic_out(p) + case .Quartic_In_Out: return quartic_in_out(p) - case .Quintic_In: return quintic_in(p) - case .Quintic_Out: return quintic_out(p) - case .Quintic_In_Out: return quintic_in_out(p) + case .Quintic_In: return quintic_in(p) + case .Quintic_Out: return quintic_out(p) + case .Quintic_In_Out: return quintic_in_out(p) - case .Sine_In: return sine_in(p) - case .Sine_Out: return sine_out(p) - case .Sine_In_Out: return sine_in_out(p) + case .Sine_In: return sine_in(p) + case .Sine_Out: return sine_out(p) + case .Sine_In_Out: return sine_in_out(p) - case .Circular_In: return circular_in(p) - case .Circular_Out: return circular_out(p) - case .Circular_In_Out: return circular_in_out(p) + case .Circular_In: return circular_in(p) + case .Circular_Out: return circular_out(p) + case .Circular_In_Out: return circular_in_out(p) - case .Exponential_In: return exponential_in(p) - case .Exponential_Out: return exponential_out(p) + case .Exponential_In: return exponential_in(p) + case .Exponential_Out: return exponential_out(p) case .Exponential_In_Out: return exponential_in_out(p) - case .Elastic_In: return elastic_in(p) - case .Elastic_Out: return elastic_out(p) - case .Elastic_In_Out: return elastic_in_out(p) + case .Elastic_In: return elastic_in(p) + case .Elastic_Out: return elastic_out(p) + case .Elastic_In_Out: return elastic_in_out(p) - case .Back_In: return back_in(p) - case .Back_Out: return back_out(p) - case .Back_In_Out: return back_in_out(p) + case .Back_In: return back_in(p) + case .Back_Out: return back_out(p) + case .Back_In_Out: return back_in_out(p) - case .Bounce_In: return bounce_in(p) - case .Bounce_Out: return bounce_out(p) - case .Bounce_In_Out: return bounce_in_out(p) + case .Bounce_In: return bounce_in(p) + case .Bounce_Out: return bounce_out(p) + case .Bounce_In_Out: return bounce_in_out(p) } // in case type was invalid return 0 } -Flux_Map :: struct($T: typeid) { - values: map[^T]Flux_Tween(T), - keys_to_be_deleted: [dynamic]^T, -} - -Flux_Tween :: struct($T: typeid) { - value: ^T, - start: T, - diff: T, - goal: T, - - delay: f64, // in seconds - duration: time.Duration, - - progress: f64, - rate: f64, - type: Ease, - - inited: bool, - - // callbacks, data can be set, will be pushed to callback - data: rawptr, // by default gets set to value input - on_start: proc(flux: ^Flux_Map(T), data: rawptr), - on_update: proc(flux: ^Flux_Map(T), data: rawptr), - on_complete: proc(flux: ^Flux_Map(T), data: rawptr), -} - -// init flux map to a float type and a wanted cap -@(require_results) -flux_init :: proc($T: typeid, value_capacity := 8) -> Flux_Map(T) where intrinsics.type_is_float(T) { - return { - values = make(map[^T]Flux_Tween(T), value_capacity), - keys_to_be_deleted = make([dynamic]^T, 0, value_capacity), - } -} - -// delete map content -flux_destroy :: proc(flux: Flux_Map($T)) where intrinsics.type_is_float(T) { - delete(flux.values) - delete(flux.keys_to_be_deleted) -} - -// clear map content, stops all animations -flux_clear :: proc(flux: ^Flux_Map($T)) where intrinsics.type_is_float(T) { - clear(&flux.values) -} - -// append / overwrite existing tween value to parameters -// rest is initialized in flux_tween_init, inside update -// return value can be used to set callbacks -@(require_results) -flux_to :: proc( - flux: ^Flux_Map($T), - value: ^T, - goal: T, - type: Ease = .Quadratic_Out, - duration: time.Duration = time.Second, - delay: f64 = 0, -) -> (tween: ^Flux_Tween(T)) where intrinsics.type_is_float(T) { - if res, ok := &flux.values[value]; ok { - tween = res - } else { - flux.values[value] = {} - tween = &flux.values[value] - } - - tween^ = { - value = value, - goal = goal, - duration = duration, - delay = delay, - type = type, - data = value, - } - - return -} - -// init internal properties -flux_tween_init :: proc(tween: ^Flux_Tween($T), duration: time.Duration) where intrinsics.type_is_float(T) { - tween.inited = true - tween.start = tween.value^ - tween.diff = tween.goal - tween.value^ - s := time.duration_seconds(duration) - tween.rate = duration > 0 ? 1.0 / s : 0 - tween.progress = duration > 0 ? 0 : 1 -} - -// update all tweens, wait for their delay if one exists -// calls callbacks in all stages, when they're filled -// deletes tween from the map after completion -flux_update :: proc(flux: ^Flux_Map($T), dt: f64) where intrinsics.type_is_float(T) { - clear(&flux.keys_to_be_deleted) - - for key, &tween in flux.values { - delay_remainder := f64(0) - - // Update delay if necessary. - if tween.delay > 0 { - tween.delay -= dt - - if tween.delay < 0 { - // We finished the delay, but in doing so consumed part of this frame's `dt` budget. - // Keep track of it so we can apply it to this tween without affecting others. - delay_remainder = tween.delay - // We're done with this delay. - tween.delay = 0 - } - } - - // We either had no delay, or the delay has been consumed. - if tween.delay <= 0 { - if !tween.inited { - flux_tween_init(&tween, tween.duration) - - if tween.on_start != nil { - tween.on_start(flux, tween.data) - } - } - - // If part of the `dt` budget was consumed this frame, then `delay_remainder` will be - // that remainder, a negative value. Adding it to `dt` applies what's left of the `dt` - // to the tween so it advances properly, instead of too much or little. - tween.progress += tween.rate * (dt + delay_remainder) - x := tween.progress >= 1 ? 1 : ease(tween.type, tween.progress) - tween.value^ = tween.start + tween.diff * T(x) - - if tween.on_update != nil { - tween.on_update(flux, tween.data) - } - - if tween.progress >= 1 { - // append keys to array that will be deleted after the loop - append(&flux.keys_to_be_deleted, key) - - if tween.on_complete != nil { - tween.on_complete(flux, tween.data) - } - } - } - } - - // loop through keys that should be deleted from the map - if len(flux.keys_to_be_deleted) != 0 { - for key in flux.keys_to_be_deleted { - delete_key(&flux.values, key) - } - } -} - -// stop a specific key inside the map -// returns true when it successfully removed the key -@(require_results) -flux_stop :: proc(flux: ^Flux_Map($T), key: ^T) -> bool where intrinsics.type_is_float(T) { - if key in flux.values { - delete_key(&flux.values, key) - return true - } - - return false -} - -// returns the amount of time left for the tween animation, if the key exists in the map -// returns 0 if the tween doesnt exist on the map -@(require_results) -flux_tween_time_left :: proc(flux: Flux_Map($T), key: ^T) -> f64 { - if tween, ok := flux.values[key]; ok { - return ((1 - tween.progress) * tween.rate) + tween.delay - } else { - return 0 - } -} diff --git a/core/math/ease/ease_inverse.odin b/core/math/ease/ease_inverse.odin new file mode 100644 index 000000000..12d6394eb --- /dev/null +++ b/core/math/ease/ease_inverse.odin @@ -0,0 +1,250 @@ +// Inverse easing procedures +// These are the mathematical inverses of the corresponding easing functions, +// allowing you to reverse the transformation: +// if y = ease_fn(x), then x = ease_fn_inverse(y) + some_imprecision +package ease + +@require import "core:math" +import "base:intrinsics" + +// Helper for handling negative bases with fractional exponents +// since math.pow(negative, fraction) returns NaN +@(private) +_signed_pow :: proc "contextless" (x, exp: $T) -> T where intrinsics.type_is_float(T) { + if x >= 0 { + return math.pow(x, exp) + } else { + return -math.pow(-x, exp) + } +} + +@(private) PI_2_INV :: 2 / math.PI + +// Inverse of quadratic_in +// x = sqrt(y) +@(require_results) +quadratic_in_inverse :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return math.sqrt(p) +} + +// Inverse of quadratic_out +// x = 1 - sqrt(1 - y) +@(require_results) +quadratic_out_inverse :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return 1 - math.sqrt(1 - p) +} + +// Inverse of quadratic_in_out +// x = sqrt(y/2) ; [0, 0.5) +// x = 1 - sqrt((1-y)/2) ; [0.5, 1] +@(require_results) +quadratic_in_out_inverse :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + if p < 0.5 { + return math.sqrt(p * 0.5) + } else { + return 1 - math.sqrt((1 - p) * 0.5) + } +} + +// Inverse of cubic_in +// x = y^(1/3) +@(require_results) +cubic_in_inverse :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return math.pow(p, 1.0/3.0) +} + +// Inverse of cubic_out +// x = (y - 1)^(1/3) + 1 +@(require_results) +cubic_out_inverse :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return _signed_pow(p - 1, 1.0/3.0) + 1 +} + +// Inverse of cubic_in_out +// x = (y/4)^(1/3) ; [0, 0.5) +// x = ((y-1)*2)^(1/3)/2 + 1 ; [0.5, 1] +@(require_results) +cubic_in_out_inverse :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + if p < 0.5 { + return math.pow(p * 0.25, 1.0/3.0) + } else { + return _signed_pow((p - 1) * 2, 1.0/3.0) * 0.5 + 1 + } +} + +// Inverse of quartic_in +// x = y^(1/4) +@(require_results) +quartic_in_inverse :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return math.pow(p, 0.25) +} + +// Inverse of quartic_out +// x = 1 - (1 - y)^(1/4) +@(require_results) +quartic_out_inverse :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return 1 - math.pow(1 - p, 0.25) +} + +// Inverse of quartic_in_out +// x = (y/8)^(1/4) ; [0, 0.5) +// x = 1 - ((1-y)/8)^(1/4) ; [0.5, 1] +@(require_results) +quartic_in_out_inverse :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + if p < 0.5 { + return math.pow(p * 0.125, 0.25) + } else { + return 1 - math.pow((1 - p) * 0.125, 0.25) + } +} + +// Inverse of quintic_in +// x = y^(1/5) +@(require_results) +quintic_in_inverse :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return math.pow(p, 0.2) +} + +// Inverse of quintic_out +// x = (y - 1)^(1/5) + 1 +@(require_results) +quintic_out_inverse :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return _signed_pow(p - 1, 0.2) + 1 +} + +// Inverse of quintic_in_out +// x = (y/16)^(1/5) ; [0, 0.5) +// x = ((y-1)*2)^(1/5)/2 + 1 ; [0.5, 1] +@(require_results) +quintic_in_out_inverse :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + if p < 0.5 { + return math.pow(0.0625 * p, 0.2) + } else { + return _signed_pow((p - 1) * 2, 0.2) * 0.5 + 1 + } +} + +// Inverse of sine_in +// x = asin(y - 1) * 2/π + 1 +@(require_results) +sine_in_inverse :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return math.asin(p - 1) * PI_2_INV + 1 +} + +// Inverse of sine_out +// x = asin(y) * 2/π +@(require_results) +sine_out_inverse :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return math.asin(p) * PI_2_INV +} + +// Inverse of sine_in_out +// x = acos(1 - 2y) / π +@(require_results) +sine_in_out_inverse :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return math.acos(1 - 2*p) / math.PI +} + +// Inverse of circular_in +// x = sqrt(2y - y²) +@(require_results) +circular_in_inverse :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return math.sqrt(2*p - p*p) +} + +// Inverse of circular_out +// x = 1 - sqrt(1 - y²) +@(require_results) +circular_out_inverse :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return 1 - math.sqrt(1 - p*p) +} + +// Inverse of circular_in_out +// x = sqrt(1 - (1-2y)²) / 2 ; [0, 0.5) +// x = 1 - sqrt(1 - (2y-1)²) / 2 ; [0.5, 1] +@(require_results) +circular_in_out_inverse :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + if p < 0.5 { + q := 1 - 2*p + return 0.5 * math.sqrt(1 - q*q) + } else { + q := 2*p - 1 + return 1 - 0.5 * math.sqrt(1 - q*q) + } +} + +// Inverse of exponential_in +// x = log₂(y) / 10 + 1 +@(require_results) +exponential_in_inverse :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return p == 0.0 ? 0.0 : 0.1 * math.log2(p) + 1 +} + +// Inverse of exponential_out +// x = -log₂(1 - y) / 10 +@(require_results) +exponential_out_inverse :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + return p == 1.0 ? 1.0 : 0.1 * -math.log2(1 - p) +} + +// Inverse of exponential_in_out +// x = (log₂(2y) + 10) / 20 ; [0, 0.5) +// x = (10 - log₂(2(1-y))) / 20 ; [0.5, 1] +@(require_results) +exponential_in_out_inverse :: proc "contextless" (p: $T) -> T where intrinsics.type_is_float(T) { + if p == 0.0 || p == 1.0 { + return p + } + + if p < 0.5 { + return 0.05 * (math.log2(2*p) + 10) + } else { + return 0.05 * (10 - math.log2(2*(1-p))) + } +} + +// Additional enum variant + +@(require_results) +ease_inverse :: proc "contextless" (type: Ease, p: $T) -> T where intrinsics.type_is_float(T) { + switch type { + case .Linear: return p + + case .Quadratic_In: return quadratic_in_inverse(p) + case .Quadratic_Out: return quadratic_out_inverse(p) + case .Quadratic_In_Out: return quadratic_in_out_inverse(p) + + case .Cubic_In: return cubic_in_inverse(p) + case .Cubic_Out: return cubic_out_inverse(p) + case .Cubic_In_Out: return cubic_in_out_inverse(p) + + case .Quartic_In: return quartic_in_inverse(p) + case .Quartic_Out: return quartic_out_inverse(p) + case .Quartic_In_Out: return quartic_in_out_inverse(p) + + case .Quintic_In: return quintic_in_inverse(p) + case .Quintic_Out: return quintic_out_inverse(p) + case .Quintic_In_Out: return quintic_in_out_inverse(p) + + case .Sine_In: return sine_in_inverse(p) + case .Sine_Out: return sine_out_inverse(p) + case .Sine_In_Out: return sine_in_out_inverse(p) + + case .Circular_In: return circular_in_inverse(p) + case .Circular_Out: return circular_out_inverse(p) + case .Circular_In_Out: return circular_in_out_inverse(p) + + case .Exponential_In: return exponential_in_inverse(p) + case .Exponential_Out: return exponential_out_inverse(p) + case .Exponential_In_Out: return exponential_in_out_inverse(p) + + case .Elastic_In, .Elastic_Out, .Elastic_In_Out, + .Back_In, .Back_Out, .Back_In_Out, + .Bounce_In, .Bounce_Out, .Bounce_In_Out: + // These do not have simple closed-form inverses + return 0 + } + + // In case type was invalid + return 0 +} diff --git a/core/math/ease/flux.odin b/core/math/ease/flux.odin new file mode 100644 index 000000000..137f3dff6 --- /dev/null +++ b/core/math/ease/flux.odin @@ -0,0 +1,177 @@ +// Flux easing used for animations +package ease + +import "core:time" + +Flux_Map :: struct($T: typeid) { + values: map[^T]Flux_Tween(T), + keys_to_be_deleted: [dynamic]^T, +} + +Flux_Tween :: struct($T: typeid) { + value: ^T, + start: T, + diff: T, + goal: T, + + delay: f64, // in seconds + duration: time.Duration, + + progress: f64, + rate: f64, + type: Ease, + + inited: bool, + + // callbacks, data can be set, will be pushed to callback + data: rawptr, // by default gets set to value input + on_start: proc(flux: ^Flux_Map(T), data: rawptr), + on_update: proc(flux: ^Flux_Map(T), data: rawptr), + on_complete: proc(flux: ^Flux_Map(T), data: rawptr), +} + +// init flux map to a float type and a wanted cap +@(require_results) +flux_init :: proc($T: typeid, value_capacity := 8, allocator := context.allocator, loc := #caller_location) -> Flux_Map(T) where intrinsics.type_is_float(T) { + return { + values = make(map[^T]Flux_Tween(T), value_capacity, allocator, loc), + keys_to_be_deleted = make([dynamic]^T, 0, value_capacity, allocator, loc), + } +} + +// delete map content +flux_destroy :: proc(flux: Flux_Map($T), allocator := context.allocator, loc := #caller_location) where intrinsics.type_is_float(T) { + delete(flux.values, allocator, loc) + delete(flux.keys_to_be_deleted, allocator, loc) +} + +// clear map content, stops all animations +flux_clear :: proc(flux: ^Flux_Map($T)) where intrinsics.type_is_float(T) { + clear(&flux.values) +} + +// append / overwrite existing tween value to parameters +// rest is initialized in flux_tween_init, inside update +// return value can be used to set callbacks +@(require_results) +flux_to :: proc( + flux: ^Flux_Map($T), + value: ^T, + goal: T, + type: Ease = .Quadratic_Out, + duration: time.Duration = time.Second, + delay: f64 = 0, +) -> (tween: ^Flux_Tween(T)) where intrinsics.type_is_float(T) { + if res, ok := &flux.values[value]; ok { + tween = res + } else { + flux.values[value] = {} + tween = &flux.values[value] + } + + tween^ = { + value = value, + goal = goal, + duration = duration, + delay = delay, + type = type, + data = value, + } + + return +} + +// init internal properties +flux_tween_init :: proc(tween: ^Flux_Tween($T), duration: time.Duration) where intrinsics.type_is_float(T) { + tween.inited = true + tween.start = tween.value^ + tween.diff = tween.goal - tween.value^ + s := time.duration_seconds(duration) + tween.rate = duration > 0 ? 1.0 / s : 0 + tween.progress = duration > 0 ? 0 : 1 +} + +// update all tweens, wait for their delay if one exists +// calls callbacks in all stages, when they're filled +// deletes tween from the map after completion +flux_update :: proc(flux: ^Flux_Map($T), dt: f64) where intrinsics.type_is_float(T) { + clear(&flux.keys_to_be_deleted) + + for key, &tween in flux.values { + delay_remainder := f64(0) + + // Update delay if necessary. + if tween.delay > 0 { + tween.delay -= dt + + if tween.delay < 0 { + // We finished the delay, but in doing so consumed part of this frame's `dt` budget. + // Keep track of it so we can apply it to this tween without affecting others. + delay_remainder = tween.delay + // We're done with this delay. + tween.delay = 0 + } + } + + // We either had no delay, or the delay has been consumed. + if tween.delay <= 0 { + if !tween.inited { + flux_tween_init(&tween, tween.duration) + + if tween.on_start != nil { + tween.on_start(flux, tween.data) + } + } + + // If part of the `dt` budget was consumed this frame, then `delay_remainder` will be + // that remainder, a negative value. Adding it to `dt` applies what's left of the `dt` + // to the tween so it advances properly, instead of too much or little. + tween.progress += tween.rate * (dt + delay_remainder) + x := tween.progress >= 1 ? 1 : ease(tween.type, tween.progress) + tween.value^ = tween.start + tween.diff * T(x) + + if tween.on_update != nil { + tween.on_update(flux, tween.data) + } + + if tween.progress >= 1 { + // append keys to array that will be deleted after the loop + append(&flux.keys_to_be_deleted, key) + + if tween.on_complete != nil { + tween.on_complete(flux, tween.data) + } + } + } + } + + // loop through keys that should be deleted from the map + if len(flux.keys_to_be_deleted) != 0 { + for key in flux.keys_to_be_deleted { + delete_key(&flux.values, key) + } + } +} + +// stop a specific key inside the map +// returns true when it successfully removed the key +@(require_results) +flux_stop :: proc(flux: ^Flux_Map($T), key: ^T) -> bool where intrinsics.type_is_float(T) { + if key in flux.values { + delete_key(&flux.values, key) + return true + } + + return false +} + +// returns the amount of time left for the tween animation, if the key exists in the map +// returns 0 if the tween doesn't exist on the map +@(require_results) +flux_tween_time_left :: proc(flux: Flux_Map($T), key: ^T) -> f64 { + if tween, ok := flux.values[key]; ok { + return ((1 - tween.progress) * tween.rate) + tween.delay + } else { + return 0 + } +} diff --git a/core/math/linalg/hlsl/linalg_hlsl.odin b/core/math/linalg/hlsl/linalg_hlsl.odin index 5c78bd8b1..8666f6f60 100644 --- a/core/math/linalg/hlsl/linalg_hlsl.odin +++ b/core/math/linalg/hlsl/linalg_hlsl.odin @@ -22,6 +22,7 @@ FLOAT_EPSILON :: 1e-7 DOUBLE_EPSILON :: 1e-15 // Aliases (not distict) of types +half :: f16 float :: f32 double :: f64 int :: builtin.i32 @@ -46,6 +47,30 @@ float4x1 :: matrix[4, 1]float float4x2 :: matrix[4, 2]float float4x3 :: matrix[4, 3]float +// Half Precision (half) Floating Point Types + +half2 :: [2]half +half3 :: [3]half +half4 :: [4]half + +half1x1 :: matrix[1, 1]half +half2x2 :: matrix[2, 2]half +half3x3 :: matrix[3, 3]half +half4x4 :: matrix[4, 4]half + +half1x2 :: matrix[1, 2]half +half1x3 :: matrix[1, 3]half +half1x4 :: matrix[1, 4]half +half2x1 :: matrix[2, 1]half +half2x3 :: matrix[2, 3]half +half2x4 :: matrix[2, 4]half +half3x1 :: matrix[3, 1]half +half3x2 :: matrix[3, 2]half +half3x4 :: matrix[3, 4]half +half4x1 :: matrix[4, 1]half +half4x2 :: matrix[4, 2]half +half4x3 :: matrix[4, 3]half + float2 :: [2]float float3 :: [3]float float4 :: [4]float @@ -106,8 +131,12 @@ int4x2 :: matrix[4, 2]int int4x3 :: matrix[4, 3]int cos :: proc{ + cos_half, cos_float, cos_double, + cos_half2, + cos_half3, + cos_half4, cos_float2, cos_float3, cos_float4, @@ -115,6 +144,9 @@ cos :: proc{ cos_double3, cos_double4, } +@(require_results) cos_half2 :: proc "c" (x: half2) -> half2 { return {cos(x.x), cos(x.y)} } +@(require_results) cos_half3 :: proc "c" (x: half3) -> half3 { return {cos(x.x), cos(x.y), cos(x.z)} } +@(require_results) cos_half4 :: proc "c" (x: half4) -> half4 { return {cos(x.x), cos(x.y), cos(x.z), cos(x.w)} } @(require_results) cos_float2 :: proc "c" (x: float2) -> float2 { return {cos(x.x), cos(x.y)} } @(require_results) cos_float3 :: proc "c" (x: float3) -> float3 { return {cos(x.x), cos(x.y), cos(x.z)} } @(require_results) cos_float4 :: proc "c" (x: float4) -> float4 { return {cos(x.x), cos(x.y), cos(x.z), cos(x.w)} } @@ -123,8 +155,12 @@ cos :: proc{ @(require_results) cos_double4 :: proc "c" (x: double4) -> double4 { return {cos(x.x), cos(x.y), cos(x.z), cos(x.w)} } sin :: proc{ + sin_half, sin_float, sin_double, + sin_half2, + sin_half3, + sin_half4, sin_float2, sin_float3, sin_float4, @@ -132,6 +168,9 @@ sin :: proc{ sin_double3, sin_double4, } +@(require_results) sin_half2 :: proc "c" (x: half2) -> half2 { return {sin(x.x), sin(x.y)} } +@(require_results) sin_half3 :: proc "c" (x: half3) -> half3 { return {sin(x.x), sin(x.y), sin(x.z)} } +@(require_results) sin_half4 :: proc "c" (x: half4) -> half4 { return {sin(x.x), sin(x.y), sin(x.z), sin(x.w)} } @(require_results) sin_float2 :: proc "c" (x: float2) -> float2 { return {sin(x.x), sin(x.y)} } @(require_results) sin_float3 :: proc "c" (x: float3) -> float3 { return {sin(x.x), sin(x.y), sin(x.z)} } @(require_results) sin_float4 :: proc "c" (x: float4) -> float4 { return {sin(x.x), sin(x.y), sin(x.z), sin(x.w)} } @@ -140,8 +179,12 @@ sin :: proc{ @(require_results) sin_double4 :: proc "c" (x: double4) -> double4 { return {sin(x.x), sin(x.y), sin(x.z), sin(x.w)} } tan :: proc{ + tan_half, tan_float, tan_double, + tan_half2, + tan_half3, + tan_half4, tan_float2, tan_float3, tan_float4, @@ -149,6 +192,9 @@ tan :: proc{ tan_double3, tan_double4, } +@(require_results) tan_half2 :: proc "c" (x: half2) -> half2 { return {tan(x.x), tan(x.y)} } +@(require_results) tan_half3 :: proc "c" (x: half3) -> half3 { return {tan(x.x), tan(x.y), tan(x.z)} } +@(require_results) tan_half4 :: proc "c" (x: half4) -> half4 { return {tan(x.x), tan(x.y), tan(x.z), tan(x.w)} } @(require_results) tan_float2 :: proc "c" (x: float2) -> float2 { return {tan(x.x), tan(x.y)} } @(require_results) tan_float3 :: proc "c" (x: float3) -> float3 { return {tan(x.x), tan(x.y), tan(x.z)} } @(require_results) tan_float4 :: proc "c" (x: float4) -> float4 { return {tan(x.x), tan(x.y), tan(x.z), tan(x.w)} } @@ -157,8 +203,12 @@ tan :: proc{ @(require_results) tan_double4 :: proc "c" (x: double4) -> double4 { return {tan(x.x), tan(x.y), tan(x.z), tan(x.w)} } acos :: proc{ + acos_half, acos_float, acos_double, + acos_half2, + acos_half3, + acos_half4, acos_float2, acos_float3, acos_float4, @@ -166,6 +216,9 @@ acos :: proc{ acos_double3, acos_double4, } +@(require_results) acos_half2 :: proc "c" (x: half2) -> half2 { return {acos(x.x), acos(x.y)} } +@(require_results) acos_half3 :: proc "c" (x: half3) -> half3 { return {acos(x.x), acos(x.y), acos(x.z)} } +@(require_results) acos_half4 :: proc "c" (x: half4) -> half4 { return {acos(x.x), acos(x.y), acos(x.z), acos(x.w)} } @(require_results) acos_float2 :: proc "c" (x: float2) -> float2 { return {acos(x.x), acos(x.y)} } @(require_results) acos_float3 :: proc "c" (x: float3) -> float3 { return {acos(x.x), acos(x.y), acos(x.z)} } @(require_results) acos_float4 :: proc "c" (x: float4) -> float4 { return {acos(x.x), acos(x.y), acos(x.z), acos(x.w)} } @@ -174,8 +227,12 @@ acos :: proc{ @(require_results) acos_double4 :: proc "c" (x: double4) -> double4 { return {acos(x.x), acos(x.y), acos(x.z), acos(x.w)} } asin :: proc{ + asin_half, asin_float, asin_double, + asin_half2, + asin_half3, + asin_half4, asin_float2, asin_float3, asin_float4, @@ -183,6 +240,9 @@ asin :: proc{ asin_double3, asin_double4, } +@(require_results) asin_half2 :: proc "c" (x: half2) -> half2 { return {asin(x.x), asin(x.y)} } +@(require_results) asin_half3 :: proc "c" (x: half3) -> half3 { return {asin(x.x), asin(x.y), asin(x.z)} } +@(require_results) asin_half4 :: proc "c" (x: half4) -> half4 { return {asin(x.x), asin(x.y), asin(x.z), asin(x.w)} } @(require_results) asin_float2 :: proc "c" (x: float2) -> float2 { return {asin(x.x), asin(x.y)} } @(require_results) asin_float3 :: proc "c" (x: float3) -> float3 { return {asin(x.x), asin(x.y), asin(x.z)} } @(require_results) asin_float4 :: proc "c" (x: float4) -> float4 { return {asin(x.x), asin(x.y), asin(x.z), asin(x.w)} } @@ -191,8 +251,12 @@ asin :: proc{ @(require_results) asin_double4 :: proc "c" (x: double4) -> double4 { return {asin(x.x), asin(x.y), asin(x.z), asin(x.w)} } atan :: proc{ + atan_half, atan_float, atan_double, + atan_half2, + atan_half3, + atan_half4, atan_float2, atan_float3, atan_float4, @@ -208,6 +272,9 @@ atan :: proc{ atan2_double3, atan2_double4, } +@(require_results) atan_half2 :: proc "c" (x: half2) -> half2 { return {atan(x.x), atan(x.y)} } +@(require_results) atan_half3 :: proc "c" (x: half3) -> half3 { return {atan(x.x), atan(x.y), atan(x.z)} } +@(require_results) atan_half4 :: proc "c" (x: half4) -> half4 { return {atan(x.x), atan(x.y), atan(x.z), atan(x.w)} } @(require_results) atan_float2 :: proc "c" (x: float2) -> float2 { return {atan(x.x), atan(x.y)} } @(require_results) atan_float3 :: proc "c" (x: float3) -> float3 { return {atan(x.x), atan(x.y), atan(x.z)} } @(require_results) atan_float4 :: proc "c" (x: float4) -> float4 { return {atan(x.x), atan(x.y), atan(x.z), atan(x.w)} } @@ -216,8 +283,12 @@ atan :: proc{ @(require_results) atan_double4 :: proc "c" (x: double4) -> double4 { return {atan(x.x), atan(x.y), atan(x.z), atan(x.w)} } atan2 :: proc{ + atan2_half, atan2_float, atan2_double, + atan2_half2, + atan2_half3, + atan2_half4, atan2_float2, atan2_float3, atan2_float4, @@ -225,6 +296,9 @@ atan2 :: proc{ atan2_double3, atan2_double4, } +@(require_results) atan2_half2 :: proc "c" (y, x: half2) -> half2 { return {atan2(y.x, x.x), atan2(y.y, x.y)} } +@(require_results) atan2_half3 :: proc "c" (y, x: half3) -> half3 { return {atan2(y.x, x.x), atan2(y.y, x.y), atan2(y.z, x.z)} } +@(require_results) atan2_half4 :: proc "c" (y, x: half4) -> half4 { return {atan2(y.x, x.x), atan2(y.y, x.y), atan2(y.z, x.z), atan2(y.w, x.w)} } @(require_results) atan2_float2 :: proc "c" (y, x: float2) -> float2 { return {atan2(y.x, x.x), atan2(y.y, x.y)} } @(require_results) atan2_float3 :: proc "c" (y, x: float3) -> float3 { return {atan2(y.x, x.x), atan2(y.y, x.y), atan2(y.z, x.z)} } @(require_results) atan2_float4 :: proc "c" (y, x: float4) -> float4 { return {atan2(y.x, x.x), atan2(y.y, x.y), atan2(y.z, x.z), atan2(y.w, x.w)} } @@ -235,8 +309,12 @@ atan2 :: proc{ cosh :: proc{ + cosh_half, cosh_float, cosh_double, + cosh_half2, + cosh_half3, + cosh_half4, cosh_float2, cosh_float3, cosh_float4, @@ -244,6 +322,9 @@ cosh :: proc{ cosh_double3, cosh_double4, } +@(require_results) cosh_half2 :: proc "c" (x: half2) -> half2 { return {cosh(x.x), cosh(x.y)} } +@(require_results) cosh_half3 :: proc "c" (x: half3) -> half3 { return {cosh(x.x), cosh(x.y), cosh(x.z)} } +@(require_results) cosh_half4 :: proc "c" (x: half4) -> half4 { return {cosh(x.x), cosh(x.y), cosh(x.z), cosh(x.w)} } @(require_results) cosh_float2 :: proc "c" (x: float2) -> float2 { return {cosh(x.x), cosh(x.y)} } @(require_results) cosh_float3 :: proc "c" (x: float3) -> float3 { return {cosh(x.x), cosh(x.y), cosh(x.z)} } @(require_results) cosh_float4 :: proc "c" (x: float4) -> float4 { return {cosh(x.x), cosh(x.y), cosh(x.z), cosh(x.w)} } @@ -253,8 +334,12 @@ cosh :: proc{ sinh :: proc{ + sinh_half, sinh_float, sinh_double, + sinh_half2, + sinh_half3, + sinh_half4, sinh_float2, sinh_float3, sinh_float4, @@ -262,6 +347,9 @@ sinh :: proc{ sinh_double3, sinh_double4, } +@(require_results) sinh_half2 :: proc "c" (x: half2) -> half2 { return {sinh(x.x), sinh(x.y)} } +@(require_results) sinh_half3 :: proc "c" (x: half3) -> half3 { return {sinh(x.x), sinh(x.y), sinh(x.z)} } +@(require_results) sinh_half4 :: proc "c" (x: half4) -> half4 { return {sinh(x.x), sinh(x.y), sinh(x.z), sinh(x.w)} } @(require_results) sinh_float2 :: proc "c" (x: float2) -> float2 { return {sinh(x.x), sinh(x.y)} } @(require_results) sinh_float3 :: proc "c" (x: float3) -> float3 { return {sinh(x.x), sinh(x.y), sinh(x.z)} } @(require_results) sinh_float4 :: proc "c" (x: float4) -> float4 { return {sinh(x.x), sinh(x.y), sinh(x.z), sinh(x.w)} } @@ -270,8 +358,12 @@ sinh :: proc{ @(require_results) sinh_double4 :: proc "c" (x: double4) -> double4 { return {sinh(x.x), sinh(x.y), sinh(x.z), sinh(x.w)} } tanh :: proc{ + tanh_half, tanh_float, tanh_double, + tanh_half2, + tanh_half3, + tanh_half4, tanh_float2, tanh_float3, tanh_float4, @@ -279,6 +371,9 @@ tanh :: proc{ tanh_double3, tanh_double4, } +@(require_results) tanh_half2 :: proc "c" (x: half2) -> half2 { return {tanh(x.x), tanh(x.y)} } +@(require_results) tanh_half3 :: proc "c" (x: half3) -> half3 { return {tanh(x.x), tanh(x.y), tanh(x.z)} } +@(require_results) tanh_half4 :: proc "c" (x: half4) -> half4 { return {tanh(x.x), tanh(x.y), tanh(x.z), tanh(x.w)} } @(require_results) tanh_float2 :: proc "c" (x: float2) -> float2 { return {tanh(x.x), tanh(x.y)} } @(require_results) tanh_float3 :: proc "c" (x: float3) -> float3 { return {tanh(x.x), tanh(x.y), tanh(x.z)} } @(require_results) tanh_float4 :: proc "c" (x: float4) -> float4 { return {tanh(x.x), tanh(x.y), tanh(x.z), tanh(x.w)} } @@ -287,8 +382,12 @@ tanh :: proc{ @(require_results) tanh_double4 :: proc "c" (x: double4) -> double4 { return {tanh(x.x), tanh(x.y), tanh(x.z), tanh(x.w)} } acosh :: proc{ + acosh_half, acosh_float, acosh_double, + acosh_half2, + acosh_half3, + acosh_half4, acosh_float2, acosh_float3, acosh_float4, @@ -296,6 +395,9 @@ acosh :: proc{ acosh_double3, acosh_double4, } +@(require_results) acosh_half2 :: proc "c" (x: half2) -> half2 { return {acosh(x.x), acosh(x.y)} } +@(require_results) acosh_half3 :: proc "c" (x: half3) -> half3 { return {acosh(x.x), acosh(x.y), acosh(x.z)} } +@(require_results) acosh_half4 :: proc "c" (x: half4) -> half4 { return {acosh(x.x), acosh(x.y), acosh(x.z), acosh(x.w)} } @(require_results) acosh_float2 :: proc "c" (x: float2) -> float2 { return {acosh(x.x), acosh(x.y)} } @(require_results) acosh_float3 :: proc "c" (x: float3) -> float3 { return {acosh(x.x), acosh(x.y), acosh(x.z)} } @(require_results) acosh_float4 :: proc "c" (x: float4) -> float4 { return {acosh(x.x), acosh(x.y), acosh(x.z), acosh(x.w)} } @@ -304,8 +406,12 @@ acosh :: proc{ @(require_results) acosh_double4 :: proc "c" (x: double4) -> double4 { return {acosh(x.x), acosh(x.y), acosh(x.z), acosh(x.w)} } asinh :: proc{ + asinh_half, asinh_float, asinh_double, + asinh_half2, + asinh_half3, + asinh_half4, asinh_float2, asinh_float3, asinh_float4, @@ -313,6 +419,9 @@ asinh :: proc{ asinh_double3, asinh_double4, } +@(require_results) asinh_half2 :: proc "c" (x: half2) -> half2 { return {asinh(x.x), asinh(x.y)} } +@(require_results) asinh_half3 :: proc "c" (x: half3) -> half3 { return {asinh(x.x), asinh(x.y), asinh(x.z)} } +@(require_results) asinh_half4 :: proc "c" (x: half4) -> half4 { return {asinh(x.x), asinh(x.y), asinh(x.z), asinh(x.w)} } @(require_results) asinh_float2 :: proc "c" (x: float2) -> float2 { return {asinh(x.x), asinh(x.y)} } @(require_results) asinh_float3 :: proc "c" (x: float3) -> float3 { return {asinh(x.x), asinh(x.y), asinh(x.z)} } @(require_results) asinh_float4 :: proc "c" (x: float4) -> float4 { return {asinh(x.x), asinh(x.y), asinh(x.z), asinh(x.w)} } @@ -321,8 +430,12 @@ asinh :: proc{ @(require_results) asinh_double4 :: proc "c" (x: double4) -> double4 { return {asinh(x.x), asinh(x.y), asinh(x.z), asinh(x.w)} } atanh :: proc{ + atanh_half, atanh_float, atanh_double, + atanh_half2, + atanh_half3, + atanh_half4, atanh_float2, atanh_float3, atanh_float4, @@ -330,6 +443,9 @@ atanh :: proc{ atanh_double3, atanh_double4, } +@(require_results) atanh_half2 :: proc "c" (x: half2) -> half2 { return {atanh(x.x), atanh(x.y)} } +@(require_results) atanh_half3 :: proc "c" (x: half3) -> half3 { return {atanh(x.x), atanh(x.y), atanh(x.z)} } +@(require_results) atanh_half4 :: proc "c" (x: half4) -> half4 { return {atanh(x.x), atanh(x.y), atanh(x.z), atanh(x.w)} } @(require_results) atanh_float2 :: proc "c" (x: float2) -> float2 { return {atanh(x.x), atanh(x.y)} } @(require_results) atanh_float3 :: proc "c" (x: float3) -> float3 { return {atanh(x.x), atanh(x.y), atanh(x.z)} } @(require_results) atanh_float4 :: proc "c" (x: float4) -> float4 { return {atanh(x.x), atanh(x.y), atanh(x.z), atanh(x.w)} } @@ -338,8 +454,12 @@ atanh :: proc{ @(require_results) atanh_double4 :: proc "c" (x: double4) -> double4 { return {atanh(x.x), atanh(x.y), atanh(x.z), atanh(x.w)} } sqrt :: proc{ + sqrt_half, sqrt_float, sqrt_double, + sqrt_half2, + sqrt_half3, + sqrt_half4, sqrt_float2, sqrt_float3, sqrt_float4, @@ -347,6 +467,9 @@ sqrt :: proc{ sqrt_double3, sqrt_double4, } +@(require_results) sqrt_half2 :: proc "c" (x: half2) -> half2 { return {sqrt(x.x), sqrt(x.y)} } +@(require_results) sqrt_half3 :: proc "c" (x: half3) -> half3 { return {sqrt(x.x), sqrt(x.y), sqrt(x.z)} } +@(require_results) sqrt_half4 :: proc "c" (x: half4) -> half4 { return {sqrt(x.x), sqrt(x.y), sqrt(x.z), sqrt(x.w)} } @(require_results) sqrt_float2 :: proc "c" (x: float2) -> float2 { return {sqrt(x.x), sqrt(x.y)} } @(require_results) sqrt_float3 :: proc "c" (x: float3) -> float3 { return {sqrt(x.x), sqrt(x.y), sqrt(x.z)} } @(require_results) sqrt_float4 :: proc "c" (x: float4) -> float4 { return {sqrt(x.x), sqrt(x.y), sqrt(x.z), sqrt(x.w)} } @@ -355,8 +478,12 @@ sqrt :: proc{ @(require_results) sqrt_double4 :: proc "c" (x: double4) -> double4 { return {sqrt(x.x), sqrt(x.y), sqrt(x.z), sqrt(x.w)} } rsqrt :: proc{ + rsqrt_half, rsqrt_float, rsqrt_double, + rsqrt_half2, + rsqrt_half3, + rsqrt_half4, rsqrt_float2, rsqrt_float3, rsqrt_float4, @@ -364,6 +491,9 @@ rsqrt :: proc{ rsqrt_double3, rsqrt_double4, } +@(require_results) rsqrt_half2 :: proc "c" (x: half2) -> half2 { return {rsqrt(x.x), rsqrt(x.y)} } +@(require_results) rsqrt_half3 :: proc "c" (x: half3) -> half3 { return {rsqrt(x.x), rsqrt(x.y), rsqrt(x.z)} } +@(require_results) rsqrt_half4 :: proc "c" (x: half4) -> half4 { return {rsqrt(x.x), rsqrt(x.y), rsqrt(x.z), rsqrt(x.w)} } @(require_results) rsqrt_float2 :: proc "c" (x: float2) -> float2 { return {rsqrt(x.x), rsqrt(x.y)} } @(require_results) rsqrt_float3 :: proc "c" (x: float3) -> float3 { return {rsqrt(x.x), rsqrt(x.y), rsqrt(x.z)} } @(require_results) rsqrt_float4 :: proc "c" (x: float4) -> float4 { return {rsqrt(x.x), rsqrt(x.y), rsqrt(x.z), rsqrt(x.w)} } @@ -372,8 +502,12 @@ rsqrt :: proc{ @(require_results) rsqrt_double4 :: proc "c" (x: double4) -> double4 { return {rsqrt(x.x), rsqrt(x.y), rsqrt(x.z), rsqrt(x.w)} } rcp :: proc{ + rcp_half, rcp_float, rcp_double, + rcp_half2, + rcp_half3, + rcp_half4, rcp_float2, rcp_float3, rcp_float4, @@ -381,6 +515,9 @@ rcp :: proc{ rcp_double3, rcp_double4, } +@(require_results) rcp_half2 :: proc "c" (x: half2) -> half2 { return {rcp(x.x), rcp(x.y)} } +@(require_results) rcp_half3 :: proc "c" (x: half3) -> half3 { return {rcp(x.x), rcp(x.y), rcp(x.z)} } +@(require_results) rcp_half4 :: proc "c" (x: half4) -> half4 { return {rcp(x.x), rcp(x.y), rcp(x.z), rcp(x.w)} } @(require_results) rcp_float2 :: proc "c" (x: float2) -> float2 { return {rcp(x.x), rcp(x.y)} } @(require_results) rcp_float3 :: proc "c" (x: float3) -> float3 { return {rcp(x.x), rcp(x.y), rcp(x.z)} } @(require_results) rcp_float4 :: proc "c" (x: float4) -> float4 { return {rcp(x.x), rcp(x.y), rcp(x.z), rcp(x.w)} } @@ -390,8 +527,12 @@ rcp :: proc{ pow :: proc{ + pow_half, pow_float, pow_double, + pow_half2, + pow_half3, + pow_half4, pow_float2, pow_float3, pow_float4, @@ -399,6 +540,9 @@ pow :: proc{ pow_double3, pow_double4, } +@(require_results) pow_half2 :: proc "c" (x, y: half2) -> half2 { return {pow(x.x, y.x), pow(x.y, y.y)} } +@(require_results) pow_half3 :: proc "c" (x, y: half3) -> half3 { return {pow(x.x, y.x), pow(x.y, y.y), pow(x.z, y.z)} } +@(require_results) pow_half4 :: proc "c" (x, y: half4) -> half4 { return {pow(x.x, y.x), pow(x.y, y.y), pow(x.z, y.z), pow(x.w, y.w)} } @(require_results) pow_float2 :: proc "c" (x, y: float2) -> float2 { return {pow(x.x, y.x), pow(x.y, y.y)} } @(require_results) pow_float3 :: proc "c" (x, y: float3) -> float3 { return {pow(x.x, y.x), pow(x.y, y.y), pow(x.z, y.z)} } @(require_results) pow_float4 :: proc "c" (x, y: float4) -> float4 { return {pow(x.x, y.x), pow(x.y, y.y), pow(x.z, y.z), pow(x.w, y.w)} } @@ -409,8 +553,12 @@ pow :: proc{ exp :: proc{ + exp_half, exp_float, exp_double, + exp_half2, + exp_half3, + exp_half4, exp_float2, exp_float3, exp_float4, @@ -418,6 +566,9 @@ exp :: proc{ exp_double3, exp_double4, } +@(require_results) exp_half2 :: proc "c" (x: half2) -> half2 { return {exp(x.x), exp(x.y)} } +@(require_results) exp_half3 :: proc "c" (x: half3) -> half3 { return {exp(x.x), exp(x.y), exp(x.z)} } +@(require_results) exp_half4 :: proc "c" (x: half4) -> half4 { return {exp(x.x), exp(x.y), exp(x.z), exp(x.w)} } @(require_results) exp_float2 :: proc "c" (x: float2) -> float2 { return {exp(x.x), exp(x.y)} } @(require_results) exp_float3 :: proc "c" (x: float3) -> float3 { return {exp(x.x), exp(x.y), exp(x.z)} } @(require_results) exp_float4 :: proc "c" (x: float4) -> float4 { return {exp(x.x), exp(x.y), exp(x.z), exp(x.w)} } @@ -428,8 +579,12 @@ exp :: proc{ log :: proc{ + log_half, log_float, log_double, + log_half2, + log_half3, + log_half4, log_float2, log_float3, log_float4, @@ -437,6 +592,9 @@ log :: proc{ log_double3, log_double4, } +@(require_results) log_half2 :: proc "c" (x: half2) -> half2 { return {log(x.x), log(x.y)} } +@(require_results) log_half3 :: proc "c" (x: half3) -> half3 { return {log(x.x), log(x.y), log(x.z)} } +@(require_results) log_half4 :: proc "c" (x: half4) -> half4 { return {log(x.x), log(x.y), log(x.z), log(x.w)} } @(require_results) log_float2 :: proc "c" (x: float2) -> float2 { return {log(x.x), log(x.y)} } @(require_results) log_float3 :: proc "c" (x: float3) -> float3 { return {log(x.x), log(x.y), log(x.z)} } @(require_results) log_float4 :: proc "c" (x: float4) -> float4 { return {log(x.x), log(x.y), log(x.z), log(x.w)} } @@ -446,8 +604,12 @@ log :: proc{ log2 :: proc{ + log2_half, log2_float, log2_double, + log2_half2, + log2_half3, + log2_half4, log2_float2, log2_float3, log2_float4, @@ -455,6 +617,9 @@ log2 :: proc{ log2_double3, log2_double4, } +@(require_results) log2_half2 :: proc "c" (x: half2) -> half2 { return {log2(x.x), log2(x.y)} } +@(require_results) log2_half3 :: proc "c" (x: half3) -> half3 { return {log2(x.x), log2(x.y), log2(x.z)} } +@(require_results) log2_half4 :: proc "c" (x: half4) -> half4 { return {log2(x.x), log2(x.y), log2(x.z), log2(x.w)} } @(require_results) log2_float2 :: proc "c" (x: float2) -> float2 { return {log2(x.x), log2(x.y)} } @(require_results) log2_float3 :: proc "c" (x: float3) -> float3 { return {log2(x.x), log2(x.y), log2(x.z)} } @(require_results) log2_float4 :: proc "c" (x: float4) -> float4 { return {log2(x.x), log2(x.y), log2(x.z), log2(x.w)} } @@ -465,8 +630,12 @@ log2 :: proc{ log10 :: proc{ + log10_half, log10_float, log10_double, + log10_half2, + log10_half3, + log10_half4, log10_float2, log10_float3, log10_float4, @@ -474,6 +643,9 @@ log10 :: proc{ log10_double3, log10_double4, } +@(require_results) log10_half2 :: proc "c" (x: half2) -> half2 { return {log10(x.x), log10(x.y)} } +@(require_results) log10_half3 :: proc "c" (x: half3) -> half3 { return {log10(x.x), log10(x.y), log10(x.z)} } +@(require_results) log10_half4 :: proc "c" (x: half4) -> half4 { return {log10(x.x), log10(x.y), log10(x.z), log10(x.w)} } @(require_results) log10_float2 :: proc "c" (x: float2) -> float2 { return {log10(x.x), log10(x.y)} } @(require_results) log10_float3 :: proc "c" (x: float3) -> float3 { return {log10(x.x), log10(x.y), log10(x.z)} } @(require_results) log10_float4 :: proc "c" (x: float4) -> float4 { return {log10(x.x), log10(x.y), log10(x.z), log10(x.w)} } @@ -485,8 +657,12 @@ log10 :: proc{ exp2 :: proc{ + exp2_half, exp2_float, exp2_double, + exp2_half2, + exp2_half3, + exp2_half4, exp2_float2, exp2_float3, exp2_float4, @@ -494,6 +670,9 @@ exp2 :: proc{ exp2_double3, exp2_double4, } +@(require_results) exp2_half2 :: proc "c" (x: half2) -> half2 { return {exp2(x.x), exp2(x.y)} } +@(require_results) exp2_half3 :: proc "c" (x: half3) -> half3 { return {exp2(x.x), exp2(x.y), exp2(x.z)} } +@(require_results) exp2_half4 :: proc "c" (x: half4) -> half4 { return {exp2(x.x), exp2(x.y), exp2(x.z), exp2(x.w)} } @(require_results) exp2_float2 :: proc "c" (x: float2) -> float2 { return {exp2(x.x), exp2(x.y)} } @(require_results) exp2_float3 :: proc "c" (x: float3) -> float3 { return {exp2(x.x), exp2(x.y), exp2(x.z)} } @(require_results) exp2_float4 :: proc "c" (x: float4) -> float4 { return {exp2(x.x), exp2(x.y), exp2(x.z), exp2(x.w)} } @@ -503,10 +682,14 @@ exp2 :: proc{ sign :: proc{ + sign_half, sign_int, sign_uint, sign_float, sign_double, + sign_half2, + sign_half3, + sign_half4, sign_float2, sign_float3, sign_float4, @@ -522,6 +705,9 @@ sign :: proc{ } @(require_results) sign_int :: proc "c" (x: int) -> int { return -1 if x < 0 else +1 if x > 0 else 0 } @(require_results) sign_uint :: proc "c" (x: uint) -> uint { return +1 if x > 0 else 0 } +@(require_results) sign_half2 :: proc "c" (x: half2) -> half2 { return {sign(x.x), sign(x.y)} } +@(require_results) sign_half3 :: proc "c" (x: half3) -> half3 { return {sign(x.x), sign(x.y), sign(x.z)} } +@(require_results) sign_half4 :: proc "c" (x: half4) -> half4 { return {sign(x.x), sign(x.y), sign(x.z), sign(x.w)} } @(require_results) sign_float2 :: proc "c" (x: float2) -> float2 { return {sign(x.x), sign(x.y)} } @(require_results) sign_float3 :: proc "c" (x: float3) -> float3 { return {sign(x.x), sign(x.y), sign(x.z)} } @(require_results) sign_float4 :: proc "c" (x: float4) -> float4 { return {sign(x.x), sign(x.y), sign(x.z), sign(x.w)} } @@ -536,8 +722,12 @@ sign :: proc{ @(require_results) sign_uint4 :: proc "c" (x: uint4) -> uint4 { return {sign(x.x), sign(x.y), sign(x.z), sign(x.w)} } floor :: proc{ + floor_half, floor_float, floor_double, + floor_half2, + floor_half3, + floor_half4, floor_float2, floor_float3, floor_float4, @@ -545,6 +735,9 @@ floor :: proc{ floor_double3, floor_double4, } +@(require_results) floor_half2 :: proc "c" (x: half2) -> half2 { return {floor(x.x), floor(x.y)} } +@(require_results) floor_half3 :: proc "c" (x: half3) -> half3 { return {floor(x.x), floor(x.y), floor(x.z)} } +@(require_results) floor_half4 :: proc "c" (x: half4) -> half4 { return {floor(x.x), floor(x.y), floor(x.z), floor(x.w)} } @(require_results) floor_float2 :: proc "c" (x: float2) -> float2 { return {floor(x.x), floor(x.y)} } @(require_results) floor_float3 :: proc "c" (x: float3) -> float3 { return {floor(x.x), floor(x.y), floor(x.z)} } @(require_results) floor_float4 :: proc "c" (x: float4) -> float4 { return {floor(x.x), floor(x.y), floor(x.z), floor(x.w)} } @@ -553,8 +746,12 @@ floor :: proc{ @(require_results) floor_double4 :: proc "c" (x: double4) -> double4 { return {floor(x.x), floor(x.y), floor(x.z), floor(x.w)} } round :: proc{ + round_half, round_float, round_double, + round_half2, + round_half3, + round_half4, round_float2, round_float3, round_float4, @@ -562,6 +759,9 @@ round :: proc{ round_double3, round_double4, } +@(require_results) round_half2 :: proc "c" (x: half2) -> half2 { return {round(x.x), round(x.y)} } +@(require_results) round_half3 :: proc "c" (x: half3) -> half3 { return {round(x.x), round(x.y), round(x.z)} } +@(require_results) round_half4 :: proc "c" (x: half4) -> half4 { return {round(x.x), round(x.y), round(x.z), round(x.w)} } @(require_results) round_float2 :: proc "c" (x: float2) -> float2 { return {round(x.x), round(x.y)} } @(require_results) round_float3 :: proc "c" (x: float3) -> float3 { return {round(x.x), round(x.y), round(x.z)} } @(require_results) round_float4 :: proc "c" (x: float4) -> float4 { return {round(x.x), round(x.y), round(x.z), round(x.w)} } @@ -571,8 +771,12 @@ round :: proc{ ceil :: proc{ + ceil_half, ceil_float, ceil_double, + ceil_half2, + ceil_half3, + ceil_half4, ceil_float2, ceil_float3, ceil_float4, @@ -580,6 +784,9 @@ ceil :: proc{ ceil_double3, ceil_double4, } +@(require_results) ceil_half2 :: proc "c" (x: half2) -> half2 { return {ceil(x.x), ceil(x.y)} } +@(require_results) ceil_half3 :: proc "c" (x: half3) -> half3 { return {ceil(x.x), ceil(x.y), ceil(x.z)} } +@(require_results) ceil_half4 :: proc "c" (x: half4) -> half4 { return {ceil(x.x), ceil(x.y), ceil(x.z), ceil(x.w)} } @(require_results) ceil_float2 :: proc "c" (x: float2) -> float2 { return {ceil(x.x), ceil(x.y)} } @(require_results) ceil_float3 :: proc "c" (x: float3) -> float3 { return {ceil(x.x), ceil(x.y), ceil(x.z)} } @(require_results) ceil_float4 :: proc "c" (x: float4) -> float4 { return {ceil(x.x), ceil(x.y), ceil(x.z), ceil(x.w)} } @@ -588,6 +795,10 @@ ceil :: proc{ @(require_results) ceil_double4 :: proc "c" (x: double4) -> double4 { return {ceil(x.x), ceil(x.y), ceil(x.z), ceil(x.w)} } +@(require_results) isfinite_half :: proc "c" (x: half) -> bool { return !isinf_half(x) } +@(require_results) isfinite_half2 :: proc "c" (x: half2) -> bool2 { return {isfinite_half(x.x), isfinite_half(x.y)} } +@(require_results) isfinite_half3 :: proc "c" (x: half3) -> bool3 { return {isfinite_half(x.x), isfinite_half(x.y), isfinite_half(x.z)} } +@(require_results) isfinite_half4 :: proc "c" (x: half4) -> bool4 { return {isfinite_half(x.x), isfinite_half(x.y), isfinite_half(x.z), isfinite_half(x.w)} } @(require_results) isfinite_float :: proc "c" (x: float) -> bool { return !isinf_float(x) } @(require_results) isfinite_float2 :: proc "c" (x: float2) -> bool2 { return {isfinite_float(x.x), isfinite_float(x.y)} } @(require_results) isfinite_float3 :: proc "c" (x: float3) -> bool3 { return {isfinite_float(x.x), isfinite_float(x.y), isfinite_float(x.z)} } @@ -599,6 +810,10 @@ ceil :: proc{ // isfinite is the opposite of isinf and returns true if the number is neither positive-infinite or negative-infinite isfinite :: proc{ + isfinite_half, + isfinite_half2, + isfinite_half3, + isfinite_half4, isfinite_float, isfinite_float2, isfinite_float3, @@ -610,6 +825,10 @@ isfinite :: proc{ } +@(require_results) isinf_half :: proc "c" (x: half) -> bool { return x * 0.5 == x } +@(require_results) isinf_half2 :: proc "c" (x: half2) -> bool2 { return {isinf_half(x.x), isinf_half(x.y)} } +@(require_results) isinf_half3 :: proc "c" (x: half3) -> bool3 { return {isinf_half(x.x), isinf_half(x.y), isinf_half(x.z)} } +@(require_results) isinf_half4 :: proc "c" (x: half4) -> bool4 { return {isinf_half(x.x), isinf_half(x.y), isinf_half(x.z), isinf_half(x.w)} } @(require_results) isinf_float :: proc "c" (x: float) -> bool { return x * 0.5 == x } @(require_results) isinf_float2 :: proc "c" (x: float2) -> bool2 { return {isinf_float(x.x), isinf_float(x.y)} } @(require_results) isinf_float3 :: proc "c" (x: float3) -> bool3 { return {isinf_float(x.x), isinf_float(x.y), isinf_float(x.z)} } @@ -621,6 +840,10 @@ isfinite :: proc{ // isinf is the opposite of isfinite and returns true if the number is either positive-infinite or negative-infinite isinf :: proc{ + isinf_half, + isinf_half2, + isinf_half3, + isinf_half4, isinf_float, isinf_float2, isinf_float3, @@ -632,6 +855,9 @@ isinf :: proc{ } +@(require_results) isnan_half2 :: proc "c" (x: half2) -> bool2 { return {isnan_half(x.x), isnan_half(x.y)} } +@(require_results) isnan_half3 :: proc "c" (x: half3) -> bool3 { return {isnan_half(x.x), isnan_half(x.y), isnan_half(x.z)} } +@(require_results) isnan_half4 :: proc "c" (x: half4) -> bool4 { return {isnan_half(x.x), isnan_half(x.y), isnan_half(x.z), isnan_half(x.w)} } @(require_results) isnan_float2 :: proc "c" (x: float2) -> bool2 { return {isnan_float(x.x), isnan_float(x.y)} } @(require_results) isnan_float3 :: proc "c" (x: float3) -> bool3 { return {isnan_float(x.x), isnan_float(x.y), isnan_float(x.z)} } @(require_results) isnan_float4 :: proc "c" (x: float4) -> bool4 { return {isnan_float(x.x), isnan_float(x.y), isnan_float(x.z), isnan_float(x.w)} } @@ -641,6 +867,10 @@ isinf :: proc{ // isnan returns true if the input value is the special case of Not-A-Number isnan :: proc{ + isnan_half, + isnan_half2, + isnan_half3, + isnan_half4, isnan_float, isnan_float2, isnan_float3, @@ -652,8 +882,12 @@ isnan :: proc{ } fmod :: proc{ + fmod_half, fmod_float, fmod_double, + fmod_half2, + fmod_half3, + fmod_half4, fmod_float2, fmod_float3, fmod_float4, @@ -661,6 +895,9 @@ fmod :: proc{ fmod_double3, fmod_double4, } +@(require_results) fmod_half2 :: proc "c" (x, y: half2) -> half2 { return {fmod(x.x, y.x), fmod(x.y, y.y)} } +@(require_results) fmod_half3 :: proc "c" (x, y: half3) -> half3 { return {fmod(x.x, y.x), fmod(x.y, y.y), fmod(x.z, y.z)} } +@(require_results) fmod_half4 :: proc "c" (x, y: half4) -> half4 { return {fmod(x.x, y.x), fmod(x.y, y.y), fmod(x.z, y.z), fmod(x.w, y.w)} } @(require_results) fmod_float2 :: proc "c" (x, y: float2) -> float2 { return {fmod(x.x, y.x), fmod(x.y, y.y)} } @(require_results) fmod_float3 :: proc "c" (x, y: float3) -> float3 { return {fmod(x.x, y.x), fmod(x.y, y.y), fmod(x.z, y.z)} } @(require_results) fmod_float4 :: proc "c" (x, y: float4) -> float4 { return {fmod(x.x, y.x), fmod(x.y, y.y), fmod(x.z, y.z), fmod(x.w, y.w)} } @@ -670,8 +907,12 @@ fmod :: proc{ frac :: proc{ + frac_half, frac_float, frac_double, + frac_half2, + frac_half3, + frac_half4, frac_float2, frac_float3, frac_float4, @@ -679,6 +920,9 @@ frac :: proc{ frac_double3, frac_double4, } +@(require_results) frac_half2 :: proc "c" (x: half2) -> half2 { return {frac(x.x), frac(x.y)} } +@(require_results) frac_half3 :: proc "c" (x: half3) -> half3 { return {frac(x.x), frac(x.y), frac(x.z)} } +@(require_results) frac_half4 :: proc "c" (x: half4) -> half4 { return {frac(x.x), frac(x.y), frac(x.z), frac(x.w)} } @(require_results) frac_float2 :: proc "c" (x: float2) -> float2 { return {frac(x.x), frac(x.y)} } @(require_results) frac_float3 :: proc "c" (x: float3) -> float3 { return {frac(x.x), frac(x.y), frac(x.z)} } @(require_results) frac_float4 :: proc "c" (x: float4) -> float4 { return {frac(x.x), frac(x.y), frac(x.z), frac(x.w)} } @@ -689,8 +933,12 @@ frac :: proc{ radians :: proc{ + radians_half, radians_float, radians_double, + radians_half2, + radians_half3, + radians_half4, radians_float2, radians_float3, radians_float4, @@ -698,8 +946,12 @@ radians :: proc{ radians_double3, radians_double4, } +@(require_results) radians_half :: proc "c" (degrees: half) -> half { return degrees * TAU / 360.0 } @(require_results) radians_float :: proc "c" (degrees: float) -> float { return degrees * TAU / 360.0 } @(require_results) radians_double :: proc "c" (degrees: double) -> double { return degrees * TAU / 360.0 } +@(require_results) radians_half2 :: proc "c" (degrees: half2) -> half2 { return degrees * TAU / 360.0 } +@(require_results) radians_half3 :: proc "c" (degrees: half3) -> half3 { return degrees * TAU / 360.0 } +@(require_results) radians_half4 :: proc "c" (degrees: half4) -> half4 { return degrees * TAU / 360.0 } @(require_results) radians_float2 :: proc "c" (degrees: float2) -> float2 { return degrees * TAU / 360.0 } @(require_results) radians_float3 :: proc "c" (degrees: float3) -> float3 { return degrees * TAU / 360.0 } @(require_results) radians_float4 :: proc "c" (degrees: float4) -> float4 { return degrees * TAU / 360.0 } @@ -709,8 +961,12 @@ radians :: proc{ degrees :: proc{ + degrees_half, degrees_float, degrees_double, + degrees_half2, + degrees_half3, + degrees_half4, degrees_float2, degrees_float3, degrees_float4, @@ -718,8 +974,12 @@ degrees :: proc{ degrees_double3, degrees_double4, } +@(require_results) degrees_half :: proc "c" (radians: half) -> half { return radians * 360.0 / TAU } @(require_results) degrees_float :: proc "c" (radians: float) -> float { return radians * 360.0 / TAU } @(require_results) degrees_double :: proc "c" (radians: double) -> double { return radians * 360.0 / TAU } +@(require_results) degrees_half2 :: proc "c" (radians: half2) -> half2 { return radians * 360.0 / TAU } +@(require_results) degrees_half3 :: proc "c" (radians: half3) -> half3 { return radians * 360.0 / TAU } +@(require_results) degrees_half4 :: proc "c" (radians: half4) -> half4 { return radians * 360.0 / TAU } @(require_results) degrees_float2 :: proc "c" (radians: float2) -> float2 { return radians * 360.0 / TAU } @(require_results) degrees_float3 :: proc "c" (radians: float3) -> float3 { return radians * 360.0 / TAU } @(require_results) degrees_float4 :: proc "c" (radians: float4) -> float4 { return radians * 360.0 / TAU } @@ -728,10 +988,14 @@ degrees :: proc{ @(require_results) degrees_double4 :: proc "c" (radians: double4) -> double4 { return radians * 360.0 / TAU } min :: proc{ + min_half, min_int, min_uint, min_float, min_double, + min_half2, + min_half3, + min_half4, min_float2, min_float3, min_float4, @@ -747,8 +1011,12 @@ min :: proc{ } @(require_results) min_int :: proc "c" (x, y: int) -> int { return builtin.min(x, y) } @(require_results) min_uint :: proc "c" (x, y: uint) -> uint { return builtin.min(x, y) } +@(require_results) min_half :: proc "c" (x, y: half) -> half { return builtin.min(x, y) } @(require_results) min_float :: proc "c" (x, y: float) -> float { return builtin.min(x, y) } @(require_results) min_double :: proc "c" (x, y: double) -> double { return builtin.min(x, y) } +@(require_results) min_half2 :: proc "c" (x, y: half2) -> half2 { return {min(x.x, y.x), min(x.y, y.y)} } +@(require_results) min_half3 :: proc "c" (x, y: half3) -> half3 { return {min(x.x, y.x), min(x.y, y.y), min(x.z, y.z)} } +@(require_results) min_half4 :: proc "c" (x, y: half4) -> half4 { return {min(x.x, y.x), min(x.y, y.y), min(x.z, y.z), min(x.w, y.w)} } @(require_results) min_float2 :: proc "c" (x, y: float2) -> float2 { return {min(x.x, y.x), min(x.y, y.y)} } @(require_results) min_float3 :: proc "c" (x, y: float3) -> float3 { return {min(x.x, y.x), min(x.y, y.y), min(x.z, y.z)} } @(require_results) min_float4 :: proc "c" (x, y: float4) -> float4 { return {min(x.x, y.x), min(x.y, y.y), min(x.z, y.z), min(x.w, y.w)} } @@ -765,9 +1033,13 @@ min :: proc{ max :: proc{ max_int, - max_uint, + max_uint, + max_half, max_float, max_double, + max_half2, + max_half3, + max_half4, max_float2, max_float3, max_float4, @@ -784,7 +1056,11 @@ max :: proc{ @(require_results) max_int :: proc "c" (x, y: int) -> int { return builtin.max(x, y) } @(require_results) max_uint :: proc "c" (x, y: uint) -> uint { return builtin.max(x, y) } @(require_results) max_float :: proc "c" (x, y: float) -> float { return builtin.max(x, y) } +@(require_results) max_half :: proc "c" (x, y: half) -> half { return builtin.max(x, y) } @(require_results) max_double :: proc "c" (x, y: double) -> double { return builtin.max(x, y) } +@(require_results) max_half2 :: proc "c" (x, y: half2) -> half2 { return {max(x.x, y.x), max(x.y, y.y)} } +@(require_results) max_half3 :: proc "c" (x, y: half3) -> half3 { return {max(x.x, y.x), max(x.y, y.y), max(x.z, y.z)} } +@(require_results) max_half4 :: proc "c" (x, y: half4) -> half4 { return {max(x.x, y.x), max(x.y, y.y), max(x.z, y.z), max(x.w, y.w)} } @(require_results) max_float2 :: proc "c" (x, y: float2) -> float2 { return {max(x.x, y.x), max(x.y, y.y)} } @(require_results) max_float3 :: proc "c" (x, y: float3) -> float3 { return {max(x.x, y.x), max(x.y, y.y), max(x.z, y.z)} } @(require_results) max_float4 :: proc "c" (x, y: float4) -> float4 { return {max(x.x, y.x), max(x.y, y.y), max(x.z, y.z), max(x.w, y.w)} } @@ -803,8 +1079,12 @@ max :: proc{ clamp :: proc{ clamp_int, clamp_uint, - clamp_float, + clamp_half, + clamp_float, clamp_double, + clamp_half2, + clamp_half3, + clamp_half4, clamp_float2, clamp_float3, clamp_float4, @@ -820,8 +1100,12 @@ clamp :: proc{ } @(require_results) clamp_int :: proc "c" (x, y, z: int) -> int { return builtin.clamp(x, y, z) } @(require_results) clamp_uint :: proc "c" (x, y, z: uint) -> uint { return builtin.clamp(x, y, z) } +@(require_results) clamp_half :: proc "c" (x, y, z: half) -> half { return builtin.clamp(x, y, z) } @(require_results) clamp_float :: proc "c" (x, y, z: float) -> float { return builtin.clamp(x, y, z) } @(require_results) clamp_double :: proc "c" (x, y, z: double) -> double { return builtin.clamp(x, y, z) } +@(require_results) clamp_half2 :: proc "c" (x, y, z: half2) -> half2 { return {clamp(x.x, y.x, z.x), clamp(x.y, y.y, z.y)} } +@(require_results) clamp_half3 :: proc "c" (x, y, z: half3) -> half3 { return {clamp(x.x, y.x, z.x), clamp(x.y, y.y, z.y), clamp(x.z, y.z, z.z)} } +@(require_results) clamp_half4 :: proc "c" (x, y, z: half4) -> half4 { return {clamp(x.x, y.x, z.x), clamp(x.y, y.y, z.y), clamp(x.z, y.z, z.z), clamp(x.w, y.w, z.w)} } @(require_results) clamp_float2 :: proc "c" (x, y, z: float2) -> float2 { return {clamp(x.x, y.x, z.x), clamp(x.y, y.y, z.y)} } @(require_results) clamp_float3 :: proc "c" (x, y, z: float3) -> float3 { return {clamp(x.x, y.x, z.x), clamp(x.y, y.y, z.y), clamp(x.z, y.z, z.z)} } @(require_results) clamp_float4 :: proc "c" (x, y, z: float4) -> float4 { return {clamp(x.x, y.x, z.x), clamp(x.y, y.y, z.y), clamp(x.z, y.z, z.z), clamp(x.w, y.w, z.w)} } @@ -838,8 +1122,12 @@ clamp :: proc{ saturate :: proc{ saturate_int, saturate_uint, + saturate_half, saturate_float, saturate_double, + saturate_half2, + saturate_half3, + saturate_half4, saturate_float2, saturate_float3, saturate_float4, @@ -855,8 +1143,12 @@ saturate :: proc{ } @(require_results) saturate_int :: proc "c" (v: int) -> int { return builtin.clamp(v, 0, 1) } @(require_results) saturate_uint :: proc "c" (v: uint) -> uint { return builtin.clamp(v, 0, 1) } +@(require_results) saturate_half :: proc "c" (v: half) -> half { return builtin.clamp(v, 0, 1) } @(require_results) saturate_float :: proc "c" (v: float) -> float { return builtin.clamp(v, 0, 1) } @(require_results) saturate_double :: proc "c" (v: double) -> double { return builtin.clamp(v, 0, 1) } +@(require_results) saturate_half2 :: proc "c" (v: half2) -> half2 { return {builtin.clamp(v.x, 0, 1), builtin.clamp(v.y, 0, 1)} } +@(require_results) saturate_half3 :: proc "c" (v: half3) -> half3 { return {builtin.clamp(v.x, 0, 1), builtin.clamp(v.y, 0, 1), builtin.clamp(v.z, 0, 1)} } +@(require_results) saturate_half4 :: proc "c" (v: half4) -> half4 { return {builtin.clamp(v.x, 0, 1), builtin.clamp(v.y, 0, 1), builtin.clamp(v.z, 0, 1), builtin.clamp(v.w, 0, 1)} } @(require_results) saturate_float2 :: proc "c" (v: float2) -> float2 { return {builtin.clamp(v.x, 0, 1), builtin.clamp(v.y, 0, 1)} } @(require_results) saturate_float3 :: proc "c" (v: float3) -> float3 { return {builtin.clamp(v.x, 0, 1), builtin.clamp(v.y, 0, 1), builtin.clamp(v.z, 0, 1)} } @(require_results) saturate_float4 :: proc "c" (v: float4) -> float4 { return {builtin.clamp(v.x, 0, 1), builtin.clamp(v.y, 0, 1), builtin.clamp(v.z, 0, 1), builtin.clamp(v.w, 0, 1)} } @@ -872,8 +1164,12 @@ saturate :: proc{ lerp :: proc{ + lerp_half, lerp_float, lerp_double, + lerp_half2, + lerp_half3, + lerp_half4, lerp_float2, lerp_float3, lerp_float4, @@ -881,8 +1177,12 @@ lerp :: proc{ lerp_double3, lerp_double4, } +@(require_results) lerp_half :: proc "c" (x, y, t: half) -> half { return x*(1-t) + y*t } @(require_results) lerp_float :: proc "c" (x, y, t: float) -> float { return x*(1-t) + y*t } @(require_results) lerp_double :: proc "c" (x, y, t: double) -> double { return x*(1-t) + y*t } +@(require_results) lerp_half2 :: proc "c" (x, y, t: half2) -> half2 { return {lerp(x.x, y.x, t.x), lerp(x.y, y.y, t.y)} } +@(require_results) lerp_half3 :: proc "c" (x, y, t: half3) -> half3 { return {lerp(x.x, y.x, t.x), lerp(x.y, y.y, t.y), lerp(x.z, y.z, t.z)} } +@(require_results) lerp_half4 :: proc "c" (x, y, t: half4) -> half4 { return {lerp(x.x, y.x, t.x), lerp(x.y, y.y, y.y), lerp(x.z, y.z, t.z), lerp(x.w, y.w, t.w)} } @(require_results) lerp_float2 :: proc "c" (x, y, t: float2) -> float2 { return {lerp(x.x, y.x, t.x), lerp(x.y, y.y, t.y)} } @(require_results) lerp_float3 :: proc "c" (x, y, t: float3) -> float3 { return {lerp(x.x, y.x, t.x), lerp(x.y, y.y, t.y), lerp(x.z, y.z, t.z)} } @(require_results) lerp_float4 :: proc "c" (x, y, t: float4) -> float4 { return {lerp(x.x, y.x, t.x), lerp(x.y, y.y, y.y), lerp(x.z, y.z, t.z), lerp(x.w, y.w, t.w)} } @@ -892,8 +1192,12 @@ lerp :: proc{ step :: proc{ + step_half, step_float, step_double, + step_half2, + step_half3, + step_half4, step_float2, step_float3, step_float4, @@ -901,8 +1205,12 @@ step :: proc{ step_double3, step_double4, } +@(require_results) step_half :: proc "c" (edge, x: half) -> half { return 0 if x < edge else 1 } @(require_results) step_float :: proc "c" (edge, x: float) -> float { return 0 if x < edge else 1 } @(require_results) step_double :: proc "c" (edge, x: double) -> double { return 0 if x < edge else 1 } +@(require_results) step_half2 :: proc "c" (edge, x: half2) -> half2 { return {step(edge.x, x.x), step(edge.y, x.y)} } +@(require_results) step_half3 :: proc "c" (edge, x: half3) -> half3 { return {step(edge.x, x.x), step(edge.y, x.y), step(edge.z, x.z)} } +@(require_results) step_half4 :: proc "c" (edge, x: half4) -> half4 { return {step(edge.x, x.x), step(edge.y, x.y), step(edge.z, x.z), step(edge.w, x.w)} } @(require_results) step_float2 :: proc "c" (edge, x: float2) -> float2 { return {step(edge.x, x.x), step(edge.y, x.y)} } @(require_results) step_float3 :: proc "c" (edge, x: float3) -> float3 { return {step(edge.x, x.x), step(edge.y, x.y), step(edge.z, x.z)} } @(require_results) step_float4 :: proc "c" (edge, x: float4) -> float4 { return {step(edge.x, x.x), step(edge.y, x.y), step(edge.z, x.z), step(edge.w, x.w)} } @@ -911,8 +1219,12 @@ step :: proc{ @(require_results) step_double4 :: proc "c" (edge, x: double4) -> double4 { return {step(edge.x, x.x), step(edge.y, x.y), step(edge.z, x.z), step(edge.w, x.w)} } smoothstep :: proc{ + smoothstep_half, smoothstep_float, smoothstep_double, + smoothstep_half2, + smoothstep_half3, + smoothstep_half4, smoothstep_float2, smoothstep_float3, smoothstep_float4, @@ -920,6 +1232,10 @@ smoothstep :: proc{ smoothstep_double3, smoothstep_double4, } +@(require_results) smoothstep_half :: proc "c" (edge0, edge1, x: half) -> half { + y := clamp(((x-edge0) / (edge1 - edge0)), 0, 1) + return y * y * (3 - 2*y) +} @(require_results) smoothstep_float :: proc "c" (edge0, edge1, x: float) -> float { y := clamp(((x-edge0) / (edge1 - edge0)), 0, 1) return y * y * (3 - 2*y) @@ -928,6 +1244,9 @@ smoothstep :: proc{ y := clamp(((x-edge0) / (edge1 - edge0)), 0, 1) return y * y * (3 - 2*y) } +@(require_results) smoothstep_half2 :: proc "c" (edge0, edge1, x: half2) -> half2 { return {smoothstep(edge0.x, edge1.x, x.x), smoothstep(edge0.y, edge1.y, x.y)} } +@(require_results) smoothstep_half3 :: proc "c" (edge0, edge1, x: half3) -> half3 { return {smoothstep(edge0.x, edge1.x, x.x), smoothstep(edge0.y, edge1.y, x.y), smoothstep(edge0.z, edge1.z, x.z)} } +@(require_results) smoothstep_half4 :: proc "c" (edge0, edge1, x: half4) -> half4 { return {smoothstep(edge0.x, edge1.x, x.x), smoothstep(edge0.y, edge1.y, x.y), smoothstep(edge0.z, edge1.z, x.z), smoothstep(edge0.w, edge1.w, x.w)} } @(require_results) smoothstep_float2 :: proc "c" (edge0, edge1, x: float2) -> float2 { return {smoothstep(edge0.x, edge1.x, x.x), smoothstep(edge0.y, edge1.y, x.y)} } @(require_results) smoothstep_float3 :: proc "c" (edge0, edge1, x: float3) -> float3 { return {smoothstep(edge0.x, edge1.x, x.x), smoothstep(edge0.y, edge1.y, x.y), smoothstep(edge0.z, edge1.z, x.z)} } @(require_results) smoothstep_float4 :: proc "c" (edge0, edge1, x: float4) -> float4 { return {smoothstep(edge0.x, edge1.x, x.x), smoothstep(edge0.y, edge1.y, x.y), smoothstep(edge0.z, edge1.z, x.z), smoothstep(edge0.w, edge1.w, x.w)} } @@ -939,8 +1258,12 @@ smoothstep :: proc{ abs :: proc{ abs_int, abs_uint, + abs_half, abs_float, abs_double, + abs_half2, + abs_half3, + abs_half4, abs_float2, abs_float3, abs_float4, @@ -956,8 +1279,12 @@ abs :: proc{ } @(require_results) abs_int :: proc "c" (x: int) -> int { return builtin.abs(x) } @(require_results) abs_uint :: proc "c" (x: uint) -> uint { return x } +@(require_results) abs_half :: proc "c" (x: half) -> half { return builtin.abs(x) } @(require_results) abs_float :: proc "c" (x: float) -> float { return builtin.abs(x) } @(require_results) abs_double :: proc "c" (x: double) -> double { return builtin.abs(x) } +@(require_results) abs_half2 :: proc "c" (x: half2) -> half2 { return {abs(x.x), abs(x.y)} } +@(require_results) abs_half3 :: proc "c" (x: half3) -> half3 { return {abs(x.x), abs(x.y), abs(x.z)} } +@(require_results) abs_half4 :: proc "c" (x: half4) -> half4 { return {abs(x.x), abs(x.y), abs(x.z), abs(x.w)} } @(require_results) abs_float2 :: proc "c" (x: float2) -> float2 { return {abs(x.x), abs(x.y)} } @(require_results) abs_float3 :: proc "c" (x: float3) -> float3 { return {abs(x.x), abs(x.y), abs(x.z)} } @(require_results) abs_float4 :: proc "c" (x: float4) -> float4 { return {abs(x.x), abs(x.y), abs(x.z), abs(x.w)} } @@ -974,8 +1301,12 @@ abs :: proc{ dot :: proc{ dot_int, dot_uint, + dot_half, dot_float, dot_double, + dot_half2, + dot_half3, + dot_half4, dot_float2, dot_float3, dot_float4, @@ -991,8 +1322,12 @@ dot :: proc{ } @(require_results) dot_int :: proc "c" (a, b: int) -> int { return a*b } @(require_results) dot_uint :: proc "c" (a, b: uint) -> uint { return a*b } +@(require_results) dot_half :: proc "c" (a, b: half) -> half { return a*b } @(require_results) dot_float :: proc "c" (a, b: float) -> float { return a*b } @(require_results) dot_double :: proc "c" (a, b: double) -> double { return a*b } +@(require_results) dot_half2 :: proc "c" (a, b: half2) -> half { return a.x*b.x + a.y*b.y } +@(require_results) dot_half3 :: proc "c" (a, b: half3) -> half { return a.x*b.x + a.y*b.y + a.z*b.z } +@(require_results) dot_half4 :: proc "c" (a, b: half4) -> half { return a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w } @(require_results) dot_float2 :: proc "c" (a, b: float2) -> float { return a.x*b.x + a.y*b.y } @(require_results) dot_float3 :: proc "c" (a, b: float3) -> float { return a.x*b.x + a.y*b.y + a.z*b.z } @(require_results) dot_float4 :: proc "c" (a, b: float4) -> float { return a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w } @@ -1007,8 +1342,12 @@ dot :: proc{ @(require_results) dot_uint4 :: proc "c" (a, b: uint4) -> uint { return a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w } length :: proc{ + length_half, length_float, length_double, + length_half2, + length_half3, + length_half4, length_float2, length_float3, length_float4, @@ -1016,8 +1355,12 @@ length :: proc{ length_double3, length_double4, } +@(require_results) length_half :: proc "c" (x: half) -> half { return builtin.abs(x) } @(require_results) length_float :: proc "c" (x: float) -> float { return builtin.abs(x) } @(require_results) length_double :: proc "c" (x: double) -> double { return builtin.abs(x) } +@(require_results) length_half2 :: proc "c" (x: half2) -> half { return sqrt(x.x*x.x + x.y*x.y) } +@(require_results) length_half3 :: proc "c" (x: half3) -> half { return sqrt(x.x*x.x + x.y*x.y + x.z*x.z) } +@(require_results) length_half4 :: proc "c" (x: half4) -> half { return sqrt(x.x*x.x + x.y*x.y + x.z*x.z + x.w*x.w) } @(require_results) length_float2 :: proc "c" (x: float2) -> float { return sqrt(x.x*x.x + x.y*x.y) } @(require_results) length_float3 :: proc "c" (x: float3) -> float { return sqrt(x.x*x.x + x.y*x.y + x.z*x.z) } @(require_results) length_float4 :: proc "c" (x: float4) -> float { return sqrt(x.x*x.x + x.y*x.y + x.z*x.z + x.w*x.w) } @@ -1027,8 +1370,12 @@ length :: proc{ distance :: proc{ + distance_half, distance_float, distance_double, + distance_half2, + distance_half3, + distance_half4, distance_float2, distance_float3, distance_float4, @@ -1036,8 +1383,12 @@ distance :: proc{ distance_double3, distance_double4, } +@(require_results) distance_half :: proc "c" (x, y: half) -> half { return length(y-x) } @(require_results) distance_float :: proc "c" (x, y: float) -> float { return length(y-x) } @(require_results) distance_double :: proc "c" (x, y: double) -> double { return length(y-x) } +@(require_results) distance_half2 :: proc "c" (x, y: half2) -> half { return length(y-x) } +@(require_results) distance_half3 :: proc "c" (x, y: half3) -> half { return length(y-x) } +@(require_results) distance_half4 :: proc "c" (x, y: half4) -> half { return length(y-x) } @(require_results) distance_float2 :: proc "c" (x, y: float2) -> float { return length(y-x) } @(require_results) distance_float3 :: proc "c" (x, y: float3) -> float { return length(y-x) } @(require_results) distance_float4 :: proc "c" (x, y: float4) -> float { return length(y-x) } @@ -1047,11 +1398,18 @@ distance :: proc{ cross :: proc{ + cross_half3, cross_float3, cross_double3, cross_int3, } +@(require_results) cross_half3 :: proc "c" (a, b: half3) -> (c: half3) { + c.x = a.y*b.z - b.y*a.z + c.y = a.z*b.x - b.z*a.x + c.z = a.x*b.y - b.x*a.y + return +} @(require_results) cross_float3 :: proc "c" (a, b: float3) -> (c: float3) { c.x = a.y*b.z - b.y*a.z c.y = a.z*b.x - b.z*a.x @@ -1072,8 +1430,12 @@ cross :: proc{ } normalize :: proc{ + normalize_half, normalize_float, normalize_double, + normalize_half2, + normalize_half3, + normalize_half4, normalize_float2, normalize_float3, normalize_float4, @@ -1081,8 +1443,12 @@ normalize :: proc{ normalize_double3, normalize_double4, } +@(require_results) normalize_half :: proc "c" (x: half) -> half { return 1.0 } @(require_results) normalize_float :: proc "c" (x: float) -> float { return 1.0 } @(require_results) normalize_double :: proc "c" (x: double) -> double { return 1.0 } +@(require_results) normalize_half2 :: proc "c" (x: half2) -> half2 { return x / length(x) } +@(require_results) normalize_half3 :: proc "c" (x: half3) -> half3 { return x / length(x) } +@(require_results) normalize_half4 :: proc "c" (x: half4) -> half4 { return x / length(x) } @(require_results) normalize_float2 :: proc "c" (x: float2) -> float2 { return x / length(x) } @(require_results) normalize_float3 :: proc "c" (x: float3) -> float3 { return x / length(x) } @(require_results) normalize_float4 :: proc "c" (x: float4) -> float4 { return x / length(x) } @@ -1092,8 +1458,12 @@ normalize :: proc{ faceforward :: proc{ + faceforward_half, faceforward_float, faceforward_double, + faceforward_half2, + faceforward_half3, + faceforward_half4, faceforward_float2, faceforward_float3, faceforward_float4, @@ -1101,8 +1471,12 @@ faceforward :: proc{ faceforward_double3, faceforward_double4, } +@(require_results) faceforward_half :: proc "c" (N, I, Nref: half) -> half { return N if dot(I, Nref) < 0 else -N } @(require_results) faceforward_float :: proc "c" (N, I, Nref: float) -> float { return N if dot(I, Nref) < 0 else -N } @(require_results) faceforward_double :: proc "c" (N, I, Nref: double) -> double { return N if dot(I, Nref) < 0 else -N } +@(require_results) faceforward_half2 :: proc "c" (N, I, Nref: half2) -> half2 { return N if dot(I, Nref) < 0 else -N } +@(require_results) faceforward_half3 :: proc "c" (N, I, Nref: half3) -> half3 { return N if dot(I, Nref) < 0 else -N } +@(require_results) faceforward_half4 :: proc "c" (N, I, Nref: half4) -> half4 { return N if dot(I, Nref) < 0 else -N } @(require_results) faceforward_float2 :: proc "c" (N, I, Nref: float2) -> float2 { return N if dot(I, Nref) < 0 else -N } @(require_results) faceforward_float3 :: proc "c" (N, I, Nref: float3) -> float3 { return N if dot(I, Nref) < 0 else -N } @(require_results) faceforward_float4 :: proc "c" (N, I, Nref: float4) -> float4 { return N if dot(I, Nref) < 0 else -N } @@ -1112,8 +1486,12 @@ faceforward :: proc{ reflect :: proc{ + reflect_half, reflect_float, reflect_double, + reflect_half2, + reflect_half3, + reflect_half4, reflect_float2, reflect_float3, reflect_float4, @@ -1121,8 +1499,12 @@ reflect :: proc{ reflect_double3, reflect_double4, } +@(require_results) reflect_half :: proc "c" (I, N: half) -> half { return I - 2*N*dot(N, I) } @(require_results) reflect_float :: proc "c" (I, N: float) -> float { return I - 2*N*dot(N, I) } @(require_results) reflect_double :: proc "c" (I, N: double) -> double { return I - 2*N*dot(N, I) } +@(require_results) reflect_half2 :: proc "c" (I, N: half2) -> half2 { return I - 2*N*dot(N, I) } +@(require_results) reflect_half3 :: proc "c" (I, N: half3) -> half3 { return I - 2*N*dot(N, I) } +@(require_results) reflect_half4 :: proc "c" (I, N: half4) -> half4 { return I - 2*N*dot(N, I) } @(require_results) reflect_float2 :: proc "c" (I, N: float2) -> float2 { return I - 2*N*dot(N, I) } @(require_results) reflect_float3 :: proc "c" (I, N: float3) -> float3 { return I - 2*N*dot(N, I) } @(require_results) reflect_float4 :: proc "c" (I, N: float4) -> float4 { return I - 2*N*dot(N, I) } @@ -1134,8 +1516,12 @@ reflect :: proc{ refract :: proc{ + refract_half, refract_float, refract_double, + refract_half2, + refract_half3, + refract_half4, refract_float2, refract_float3, refract_float4, @@ -1144,6 +1530,13 @@ refract :: proc{ refract_double4, } @(require_results) +refract_half :: proc "c" (i, n, eta: half) -> half { + cosi := dot(-i, n) + cost2 := 1 - eta*eta*(1 - cosi*cosi) + t := eta*i + ((eta*cosi - sqrt(abs(cost2))) * n) + return t * half(int(cost2 > 0)) +} +@(require_results) refract_float :: proc "c" (i, n, eta: float) -> float { cosi := dot(-i, n) cost2 := 1 - eta*eta*(1 - cosi*cosi) @@ -1158,6 +1551,27 @@ refract_double :: proc "c" (i, n, eta: double) -> double { return t * double(int(cost2 > 0)) } @(require_results) +refract_half2 :: proc "c" (i, n, eta: half2) -> half2 { + cosi := dot(-i, n) + cost2 := 1 - eta*eta*(1 - cosi*cosi) + t := eta*i + ((eta*cosi - sqrt(abs(cost2))) * n) + return t * half2{half(int(cost2.x > 0)), half(int(cost2.y > 0))} +} +@(require_results) +refract_half3 :: proc "c" (i, n, eta: half3) -> half3 { + cosi := dot(-i, n) + cost2 := 1 - eta*eta*(1 - cosi*cosi) + t := eta*i + ((eta*cosi - sqrt(abs(cost2))) * n) + return t * half3{half(int(cost2.x > 0)), half(int(cost2.y > 0)), half(int(cost2.z > 0))} +} +@(require_results) +refract_half4 :: proc "c" (i, n, eta: half4) -> half4 { + cosi := dot(-i, n) + cost2 := 1 - eta*eta*(1 - cosi*cosi) + t := eta*i + ((eta*cosi - sqrt(abs(cost2))) * n) + return t * half4{half(int(cost2.x > 0)), half(int(cost2.y > 0)), half(int(cost2.z > 0)), half(int(cost2.w > 0))} +} +@(require_results) refract_float2 :: proc "c" (i, n, eta: float2) -> float2 { cosi := dot(-i, n) cost2 := 1 - eta*eta*(1 - cosi*cosi) @@ -1201,19 +1615,23 @@ refract_double4 :: proc "c" (i, n, eta: double4) -> double4 { } scalarTripleProduct :: proc{ + scalarTripleProduct_half3, scalarTripleProduct_float3, scalarTripleProduct_double3, scalarTripleProduct_int3, } +@(require_results) scalarTripleProduct_half3 :: proc "c" (a, b, c: half3) -> half { return dot(a, cross(b, c)) } @(require_results) scalarTripleProduct_float3 :: proc "c" (a, b, c: float3) -> float { return dot(a, cross(b, c)) } @(require_results) scalarTripleProduct_double3 :: proc "c" (a, b, c: double3) -> double { return dot(a, cross(b, c)) } @(require_results) scalarTripleProduct_int3 :: proc "c" (a, b, c: int3) -> int { return dot(a, cross(b, c)) } vectorTripleProduct :: proc { + vectorTripleProduct_half3, vectorTripleProduct_float3, vectorTripleProduct_double3, vectorTripleProduct_int3, } +@(require_results) vectorTripleProduct_half3 :: proc "c" (a, b, c: half3) -> half3 { return cross(a, cross(b, c)) } @(require_results) vectorTripleProduct_float3 :: proc "c" (a, b, c: float3) -> float3 { return cross(a, cross(b, c)) } @(require_results) vectorTripleProduct_double3 :: proc "c" (a, b, c: double3) -> double3 { return cross(a, cross(b, c)) } @(require_results) vectorTripleProduct_int3 :: proc "c" (a, b, c: int3) -> int3 { return cross(a, cross(b, c)) } @@ -1222,35 +1640,43 @@ vectorTripleProduct :: proc { // Vector Relational Procedures lessThan :: proc{ + lessThan_half, lessThan_float, lessThan_double, lessThan_int, lessThan_uint, + lessThan_half2, lessThan_float2, lessThan_double2, lessThan_int2, lessThan_uint2, + lessThan_half3, lessThan_float3, lessThan_double3, lessThan_int3, lessThan_uint3, + lessThan_half4, lessThan_float4, lessThan_double4, lessThan_int4, lessThan_uint4, } +@(require_results) lessThan_half :: proc "c" (a, b: half) -> bool { return a < b } @(require_results) lessThan_float :: proc "c" (a, b: float) -> bool { return a < b } @(require_results) lessThan_double :: proc "c" (a, b: double) -> bool { return a < b } @(require_results) lessThan_int :: proc "c" (a, b: int) -> bool { return a < b } @(require_results) lessThan_uint :: proc "c" (a, b: uint) -> bool { return a < b } +@(require_results) lessThan_half2 :: proc "c" (a, b: half2) -> bool2 { return {a.x < b.x, a.y < b.y} } @(require_results) lessThan_float2 :: proc "c" (a, b: float2) -> bool2 { return {a.x < b.x, a.y < b.y} } @(require_results) lessThan_double2 :: proc "c" (a, b: double2) -> bool2 { return {a.x < b.x, a.y < b.y} } @(require_results) lessThan_int2 :: proc "c" (a, b: int2) -> bool2 { return {a.x < b.x, a.y < b.y} } @(require_results) lessThan_uint2 :: proc "c" (a, b: uint2) -> bool2 { return {a.x < b.x, a.y < b.y} } +@(require_results) lessThan_half3 :: proc "c" (a, b: half3) -> bool3 { return {a.x < b.x, a.y < b.y, a.z < b.z} } @(require_results) lessThan_float3 :: proc "c" (a, b: float3) -> bool3 { return {a.x < b.x, a.y < b.y, a.z < b.z} } @(require_results) lessThan_double3 :: proc "c" (a, b: double3) -> bool3 { return {a.x < b.x, a.y < b.y, a.z < b.z} } @(require_results) lessThan_int3 :: proc "c" (a, b: int3) -> bool3 { return {a.x < b.x, a.y < b.y, a.z < b.z} } @(require_results) lessThan_uint3 :: proc "c" (a, b: uint3) -> bool3 { return {a.x < b.x, a.y < b.y, a.z < b.z} } +@(require_results) lessThan_half4 :: proc "c" (a, b: half4) -> bool4 { return {a.x < b.x, a.y < b.y, a.z < b.z, a.w < b.w} } @(require_results) lessThan_float4 :: proc "c" (a, b: float4) -> bool4 { return {a.x < b.x, a.y < b.y, a.z < b.z, a.w < b.w} } @(require_results) lessThan_double4 :: proc "c" (a, b: double4) -> bool4 { return {a.x < b.x, a.y < b.y, a.z < b.z, a.w < b.w} } @(require_results) lessThan_int4 :: proc "c" (a, b: int4) -> bool4 { return {a.x < b.x, a.y < b.y, a.z < b.z, a.w < b.w} } @@ -1258,35 +1684,43 @@ lessThan :: proc{ lessThanEqual :: proc{ + lessThanEqual_half, lessThanEqual_float, lessThanEqual_double, lessThanEqual_int, lessThanEqual_uint, + lessThanEqual_half2, lessThanEqual_float2, lessThanEqual_double2, lessThanEqual_int2, lessThanEqual_uint2, + lessThanEqual_half3, lessThanEqual_float3, lessThanEqual_double3, lessThanEqual_int3, lessThanEqual_uint3, + lessThanEqual_half4, lessThanEqual_float4, lessThanEqual_double4, lessThanEqual_int4, lessThanEqual_uint4, } +@(require_results) lessThanEqual_half :: proc "c" (a, b: half) -> bool { return a <= b } @(require_results) lessThanEqual_float :: proc "c" (a, b: float) -> bool { return a <= b } @(require_results) lessThanEqual_double :: proc "c" (a, b: double) -> bool { return a <= b } @(require_results) lessThanEqual_int :: proc "c" (a, b: int) -> bool { return a <= b } @(require_results) lessThanEqual_uint :: proc "c" (a, b: uint) -> bool { return a <= b } +@(require_results) lessThanEqual_half2 :: proc "c" (a, b: half2) -> bool2 { return {a.x <= b.x, a.y <= b.y} } @(require_results) lessThanEqual_float2 :: proc "c" (a, b: float2) -> bool2 { return {a.x <= b.x, a.y <= b.y} } @(require_results) lessThanEqual_double2 :: proc "c" (a, b: double2) -> bool2 { return {a.x <= b.x, a.y <= b.y} } @(require_results) lessThanEqual_int2 :: proc "c" (a, b: int2) -> bool2 { return {a.x <= b.x, a.y <= b.y} } @(require_results) lessThanEqual_uint2 :: proc "c" (a, b: uint2) -> bool2 { return {a.x <= b.x, a.y <= b.y} } +@(require_results) lessThanEqual_half3 :: proc "c" (a, b: half3) -> bool3 { return {a.x <= b.x, a.y <= b.y, a.z <= b.z} } @(require_results) lessThanEqual_float3 :: proc "c" (a, b: float3) -> bool3 { return {a.x <= b.x, a.y <= b.y, a.z <= b.z} } @(require_results) lessThanEqual_double3 :: proc "c" (a, b: double3) -> bool3 { return {a.x <= b.x, a.y <= b.y, a.z <= b.z} } @(require_results) lessThanEqual_int3 :: proc "c" (a, b: int3) -> bool3 { return {a.x <= b.x, a.y <= b.y, a.z <= b.z} } @(require_results) lessThanEqual_uint3 :: proc "c" (a, b: uint3) -> bool3 { return {a.x <= b.x, a.y <= b.y, a.z <= b.z} } +@(require_results) lessThanEqual_half4 :: proc "c" (a, b: half4) -> bool4 { return {a.x <= b.x, a.y <= b.y, a.z <= b.z, a.w <= b.w} } @(require_results) lessThanEqual_float4 :: proc "c" (a, b: float4) -> bool4 { return {a.x <= b.x, a.y <= b.y, a.z <= b.z, a.w <= b.w} } @(require_results) lessThanEqual_double4 :: proc "c" (a, b: double4) -> bool4 { return {a.x <= b.x, a.y <= b.y, a.z <= b.z, a.w <= b.w} } @(require_results) lessThanEqual_int4 :: proc "c" (a, b: int4) -> bool4 { return {a.x <= b.x, a.y <= b.y, a.z <= b.z, a.w <= b.w} } @@ -1294,35 +1728,43 @@ lessThanEqual :: proc{ greaterThan :: proc{ + greaterThan_half, greaterThan_float, greaterThan_double, greaterThan_int, greaterThan_uint, + greaterThan_half2, greaterThan_float2, greaterThan_double2, greaterThan_int2, greaterThan_uint2, + greaterThan_half3, greaterThan_float3, greaterThan_double3, greaterThan_int3, greaterThan_uint3, + greaterThan_half4, greaterThan_float4, greaterThan_double4, greaterThan_int4, greaterThan_uint4, } +@(require_results) greaterThan_half :: proc "c" (a, b: half) -> bool { return a > b } @(require_results) greaterThan_float :: proc "c" (a, b: float) -> bool { return a > b } @(require_results) greaterThan_double :: proc "c" (a, b: double) -> bool { return a > b } @(require_results) greaterThan_int :: proc "c" (a, b: int) -> bool { return a > b } @(require_results) greaterThan_uint :: proc "c" (a, b: uint) -> bool { return a > b } +@(require_results) greaterThan_half2 :: proc "c" (a, b: half2) -> bool2 { return {a.x > b.x, a.y > b.y} } @(require_results) greaterThan_float2 :: proc "c" (a, b: float2) -> bool2 { return {a.x > b.x, a.y > b.y} } @(require_results) greaterThan_double2 :: proc "c" (a, b: double2) -> bool2 { return {a.x > b.x, a.y > b.y} } @(require_results) greaterThan_int2 :: proc "c" (a, b: int2) -> bool2 { return {a.x > b.x, a.y > b.y} } @(require_results) greaterThan_uint2 :: proc "c" (a, b: uint2) -> bool2 { return {a.x > b.x, a.y > b.y} } +@(require_results) greaterThan_half3 :: proc "c" (a, b: half3) -> bool3 { return {a.x > b.x, a.y > b.y, a.z > b.z} } @(require_results) greaterThan_float3 :: proc "c" (a, b: float3) -> bool3 { return {a.x > b.x, a.y > b.y, a.z > b.z} } @(require_results) greaterThan_double3 :: proc "c" (a, b: double3) -> bool3 { return {a.x > b.x, a.y > b.y, a.z > b.z} } @(require_results) greaterThan_int3 :: proc "c" (a, b: int3) -> bool3 { return {a.x > b.x, a.y > b.y, a.z > b.z} } @(require_results) greaterThan_uint3 :: proc "c" (a, b: uint3) -> bool3 { return {a.x > b.x, a.y > b.y, a.z > b.z} } +@(require_results) greaterThan_half4 :: proc "c" (a, b: half4) -> bool4 { return {a.x > b.x, a.y > b.y, a.z > b.z, a.w > b.w} } @(require_results) greaterThan_float4 :: proc "c" (a, b: float4) -> bool4 { return {a.x > b.x, a.y > b.y, a.z > b.z, a.w > b.w} } @(require_results) greaterThan_double4 :: proc "c" (a, b: double4) -> bool4 { return {a.x > b.x, a.y > b.y, a.z > b.z, a.w > b.w} } @(require_results) greaterThan_int4 :: proc "c" (a, b: int4) -> bool4 { return {a.x > b.x, a.y > b.y, a.z > b.z, a.w > b.w} } @@ -1330,35 +1772,43 @@ greaterThan :: proc{ greaterThanEqual :: proc{ + greaterThanEqual_half, greaterThanEqual_float, greaterThanEqual_double, greaterThanEqual_int, greaterThanEqual_uint, + greaterThanEqual_half2, greaterThanEqual_float2, greaterThanEqual_double2, greaterThanEqual_int2, greaterThanEqual_uint2, + greaterThanEqual_half3, greaterThanEqual_float3, greaterThanEqual_double3, greaterThanEqual_int3, greaterThanEqual_uint3, + greaterThanEqual_half4, greaterThanEqual_float4, greaterThanEqual_double4, greaterThanEqual_int4, greaterThanEqual_uint4, } +@(require_results) greaterThanEqual_half :: proc "c" (a, b: half) -> bool { return a >= b } @(require_results) greaterThanEqual_float :: proc "c" (a, b: float) -> bool { return a >= b } @(require_results) greaterThanEqual_double :: proc "c" (a, b: double) -> bool { return a >= b } @(require_results) greaterThanEqual_int :: proc "c" (a, b: int) -> bool { return a >= b } @(require_results) greaterThanEqual_uint :: proc "c" (a, b: uint) -> bool { return a >= b } +@(require_results) greaterThanEqual_half2 :: proc "c" (a, b: half2) -> bool2 { return {a.x >= b.x, a.y >= b.y} } @(require_results) greaterThanEqual_float2 :: proc "c" (a, b: float2) -> bool2 { return {a.x >= b.x, a.y >= b.y} } @(require_results) greaterThanEqual_double2 :: proc "c" (a, b: double2) -> bool2 { return {a.x >= b.x, a.y >= b.y} } @(require_results) greaterThanEqual_int2 :: proc "c" (a, b: int2) -> bool2 { return {a.x >= b.x, a.y >= b.y} } @(require_results) greaterThanEqual_uint2 :: proc "c" (a, b: uint2) -> bool2 { return {a.x >= b.x, a.y >= b.y} } +@(require_results) greaterThanEqual_half3 :: proc "c" (a, b: half3) -> bool3 { return {a.x >= b.x, a.y >= b.y, a.z >= b.z} } @(require_results) greaterThanEqual_float3 :: proc "c" (a, b: float3) -> bool3 { return {a.x >= b.x, a.y >= b.y, a.z >= b.z} } @(require_results) greaterThanEqual_double3 :: proc "c" (a, b: double3) -> bool3 { return {a.x >= b.x, a.y >= b.y, a.z >= b.z} } @(require_results) greaterThanEqual_int3 :: proc "c" (a, b: int3) -> bool3 { return {a.x >= b.x, a.y >= b.y, a.z >= b.z} } @(require_results) greaterThanEqual_uint3 :: proc "c" (a, b: uint3) -> bool3 { return {a.x >= b.x, a.y >= b.y, a.z >= b.z} } +@(require_results) greaterThanEqual_half4 :: proc "c" (a, b: half4) -> bool4 { return {a.x >= b.x, a.y >= b.y, a.z >= b.z, a.w >= b.w} } @(require_results) greaterThanEqual_float4 :: proc "c" (a, b: float4) -> bool4 { return {a.x >= b.x, a.y >= b.y, a.z >= b.z, a.w >= b.w} } @(require_results) greaterThanEqual_double4 :: proc "c" (a, b: double4) -> bool4 { return {a.x >= b.x, a.y >= b.y, a.z >= b.z, a.w >= b.w} } @(require_results) greaterThanEqual_int4 :: proc "c" (a, b: int4) -> bool4 { return {a.x >= b.x, a.y >= b.y, a.z >= b.z, a.w >= b.w} } @@ -1366,70 +1816,86 @@ greaterThanEqual :: proc{ equal :: proc{ + equal_half, equal_float, equal_double, equal_int, equal_uint, + equal_half2, equal_float2, equal_double2, equal_int2, equal_uint2, + equal_half3, equal_float3, equal_double3, equal_int3, equal_uint3, + equal_half4, equal_float4, equal_double4, equal_int4, equal_uint4, } +@(require_results) equal_half :: proc "c" (a, b: half) -> bool { return a == b } @(require_results) equal_float :: proc "c" (a, b: float) -> bool { return a == b } @(require_results) equal_double :: proc "c" (a, b: double) -> bool { return a == b } @(require_results) equal_int :: proc "c" (a, b: int) -> bool { return a == b } @(require_results) equal_uint :: proc "c" (a, b: uint) -> bool { return a == b } +@(require_results) equal_half2 :: proc "c" (a, b: half2) -> bool2 { return {a.x == b.x, a.y == b.y} } @(require_results) equal_float2 :: proc "c" (a, b: float2) -> bool2 { return {a.x == b.x, a.y == b.y} } @(require_results) equal_double2 :: proc "c" (a, b: double2) -> bool2 { return {a.x == b.x, a.y == b.y} } @(require_results) equal_int2 :: proc "c" (a, b: int2) -> bool2 { return {a.x == b.x, a.y == b.y} } @(require_results) equal_uint2 :: proc "c" (a, b: uint2) -> bool2 { return {a.x == b.x, a.y == b.y} } +@(require_results) equal_half3 :: proc "c" (a, b: half3) -> bool3 { return {a.x == b.x, a.y == b.y, a.z == b.z} } @(require_results) equal_float3 :: proc "c" (a, b: float3) -> bool3 { return {a.x == b.x, a.y == b.y, a.z == b.z} } @(require_results) equal_double3 :: proc "c" (a, b: double3) -> bool3 { return {a.x == b.x, a.y == b.y, a.z == b.z} } @(require_results) equal_int3 :: proc "c" (a, b: int3) -> bool3 { return {a.x == b.x, a.y == b.y, a.z == b.z} } @(require_results) equal_uint3 :: proc "c" (a, b: uint3) -> bool3 { return {a.x == b.x, a.y == b.y, a.z == b.z} } +@(require_results) equal_half4 :: proc "c" (a, b: half4) -> bool4 { return {a.x == b.x, a.y == b.y, a.z == b.z, a.w == b.w} } @(require_results) equal_float4 :: proc "c" (a, b: float4) -> bool4 { return {a.x == b.x, a.y == b.y, a.z == b.z, a.w == b.w} } @(require_results) equal_double4 :: proc "c" (a, b: double4) -> bool4 { return {a.x == b.x, a.y == b.y, a.z == b.z, a.w == b.w} } @(require_results) equal_int4 :: proc "c" (a, b: int4) -> bool4 { return {a.x == b.x, a.y == b.y, a.z == b.z, a.w == b.w} } @(require_results) equal_uint4 :: proc "c" (a, b: uint4) -> bool4 { return {a.x == b.x, a.y == b.y, a.z == b.z, a.w == b.w} } notEqual :: proc{ + notEqual_half, notEqual_float, notEqual_double, notEqual_int, notEqual_uint, + notEqual_half2, notEqual_float2, notEqual_double2, notEqual_int2, notEqual_uint2, + notEqual_half3, notEqual_float3, notEqual_double3, notEqual_int3, notEqual_uint3, + notEqual_half4, notEqual_float4, notEqual_double4, notEqual_int4, notEqual_uint4, } +@(require_results) notEqual_half :: proc "c" (a, b: half) -> bool { return a != b } @(require_results) notEqual_float :: proc "c" (a, b: float) -> bool { return a != b } @(require_results) notEqual_double :: proc "c" (a, b: double) -> bool { return a != b } @(require_results) notEqual_int :: proc "c" (a, b: int) -> bool { return a != b } @(require_results) notEqual_uint :: proc "c" (a, b: uint) -> bool { return a != b } +@(require_results) notEqual_half2 :: proc "c" (a, b: half2) -> bool2 { return {a.x != b.x, a.y != b.y} } @(require_results) notEqual_float2 :: proc "c" (a, b: float2) -> bool2 { return {a.x != b.x, a.y != b.y} } @(require_results) notEqual_double2 :: proc "c" (a, b: double2) -> bool2 { return {a.x != b.x, a.y != b.y} } @(require_results) notEqual_int2 :: proc "c" (a, b: int2) -> bool2 { return {a.x != b.x, a.y != b.y} } @(require_results) notEqual_uint2 :: proc "c" (a, b: uint2) -> bool2 { return {a.x != b.x, a.y != b.y} } +@(require_results) notEqual_half3 :: proc "c" (a, b: half3) -> bool3 { return {a.x != b.x, a.y != b.y, a.z != b.z} } @(require_results) notEqual_float3 :: proc "c" (a, b: float3) -> bool3 { return {a.x != b.x, a.y != b.y, a.z != b.z} } @(require_results) notEqual_double3 :: proc "c" (a, b: double3) -> bool3 { return {a.x != b.x, a.y != b.y, a.z != b.z} } @(require_results) notEqual_int3 :: proc "c" (a, b: int3) -> bool3 { return {a.x != b.x, a.y != b.y, a.z != b.z} } @(require_results) notEqual_uint3 :: proc "c" (a, b: uint3) -> bool3 { return {a.x != b.x, a.y != b.y, a.z != b.z} } +@(require_results) notEqual_half4 :: proc "c" (a, b: half4) -> bool4 { return {a.x != b.x, a.y != b.y, a.z != b.z, a.w != b.w} } @(require_results) notEqual_float4 :: proc "c" (a, b: float4) -> bool4 { return {a.x != b.x, a.y != b.y, a.z != b.z, a.w != b.w} } @(require_results) notEqual_double4 :: proc "c" (a, b: double4) -> bool4 { return {a.x != b.x, a.y != b.y, a.z != b.z, a.w != b.w} } @(require_results) notEqual_int4 :: proc "c" (a, b: int4) -> bool4 { return {a.x != b.x, a.y != b.y, a.z != b.z, a.w != b.w} } @@ -1472,6 +1938,10 @@ not :: proc{ +@(require_results) inverse_half1x1 :: proc "c" (m: half1x1) -> half1x1 { return inverse_matrix1x1(m) } +@(require_results) inverse_half2x2 :: proc "c" (m: half2x2) -> half2x2 { return inverse_matrix2x2(m) } +@(require_results) inverse_half3x3 :: proc "c" (m: half3x3) -> half3x3 { return inverse_matrix3x3(m) } +@(require_results) inverse_half4x4 :: proc "c" (m: half4x4) -> half4x4 { return inverse_matrix4x4(m) } @(require_results) inverse_float1x1 :: proc "c" (m: float1x1) -> float1x1 { return inverse_matrix1x1(m) } @(require_results) inverse_float2x2 :: proc "c" (m: float2x2) -> float2x2 { return inverse_matrix2x2(m) } @(require_results) inverse_float3x3 :: proc "c" (m: float3x3) -> float3x3 { return inverse_matrix3x3(m) } @@ -1482,6 +1952,10 @@ not :: proc{ @(require_results) inverse_double4x4 :: proc "c" (m: double4x4) -> double4x4 { return inverse_matrix4x4(m) } inverse :: proc{ + inverse_half1x1, + inverse_half2x2, + inverse_half3x3, + inverse_half4x4, inverse_float1x1, inverse_float2x2, inverse_float3x3, @@ -1807,12 +2281,176 @@ inverse_matrix4x4 :: proc "contextless" (x: $M/matrix[4, 4]$T) -> (y: M) #no_bou +ashalf :: proc{ + ashalf_half, + ashalf_float, + ashalf_double, + ashalf_int, + ashalf_uint, + ashalf_half1x1, + ashalf_half2x2, + ashalf_half3x3, + ashalf_half4x4, + ashalf_half1x2, + ashalf_half1x3, + ashalf_half1x4, + ashalf_half2x1, + ashalf_half2x3, + ashalf_half2x4, + ashalf_half3x1, + ashalf_half3x2, + ashalf_half3x4, + ashalf_half4x1, + ashalf_half4x2, + ashalf_half4x3, + ashalf_half2, + ashalf_half3, + ashalf_half4, + ashalf_float1x1, + ashalf_float2x2, + ashalf_float3x3, + ashalf_float4x4, + ashalf_float1x2, + ashalf_float1x3, + ashalf_float1x4, + ashalf_float2x1, + ashalf_float2x3, + ashalf_float2x4, + ashalf_float3x1, + ashalf_float3x2, + ashalf_float3x4, + ashalf_float4x1, + ashalf_float4x2, + ashalf_float4x3, + ashalf_float2, + ashalf_float3, + ashalf_float4, + ashalf_int2, + ashalf_int3, + ashalf_int4, + ashalf_uint2, + ashalf_uint3, + ashalf_uint4, + ashalf_bool2, + ashalf_bool3, + ashalf_bool4, + ashalf_double1x1, + ashalf_double2x2, + ashalf_double3x3, + ashalf_double4x4, + ashalf_double1x2, + ashalf_double1x3, + ashalf_double1x4, + ashalf_double2x1, + ashalf_double2x3, + ashalf_double2x4, + ashalf_double3x1, + ashalf_double3x2, + ashalf_double3x4, + ashalf_double4x1, + ashalf_double4x2, + ashalf_double4x3, + ashalf_double2, + ashalf_double3, + ashalf_double4, +} +@(require_results) ashalf_half :: proc "c" (v: half) -> half { return half(v) } +@(require_results) ashalf_float :: proc "c" (v: float) -> half { return half(v) } +@(require_results) ashalf_double :: proc "c" (v: double) -> half { return half(v) } +@(require_results) ashalf_int :: proc "c" (v: int) -> half { return half(v) } +@(require_results) ashalf_uint :: proc "c" (v: uint) -> half { return half(v) } +@(require_results) ashalf_half1x1 :: proc "c" (v: half1x1) -> half1x1 { return half1x1(v) } +@(require_results) ashalf_half2x2 :: proc "c" (v: half2x2) -> half2x2 { return half2x2(v) } +@(require_results) ashalf_half3x3 :: proc "c" (v: half3x3) -> half3x3 { return half3x3(v) } +@(require_results) ashalf_half4x4 :: proc "c" (v: half4x4) -> half4x4 { return half4x4(v) } +@(require_results) ashalf_half1x2 :: proc "c" (v: half1x2) -> half1x2 { return half1x2(v) } +@(require_results) ashalf_half1x3 :: proc "c" (v: half1x3) -> half1x3 { return half1x3(v) } +@(require_results) ashalf_half1x4 :: proc "c" (v: half1x4) -> half1x4 { return half1x4(v) } +@(require_results) ashalf_half2x1 :: proc "c" (v: half2x1) -> half2x1 { return half2x1(v) } +@(require_results) ashalf_half2x3 :: proc "c" (v: half2x3) -> half2x3 { return half2x3(v) } +@(require_results) ashalf_half2x4 :: proc "c" (v: half2x4) -> half2x4 { return half2x4(v) } +@(require_results) ashalf_half3x1 :: proc "c" (v: half3x1) -> half3x1 { return half3x1(v) } +@(require_results) ashalf_half3x2 :: proc "c" (v: half3x2) -> half3x2 { return half3x2(v) } +@(require_results) ashalf_half3x4 :: proc "c" (v: half3x4) -> half3x4 { return half3x4(v) } +@(require_results) ashalf_half4x1 :: proc "c" (v: half4x1) -> half4x1 { return half4x1(v) } +@(require_results) ashalf_half4x2 :: proc "c" (v: half4x2) -> half4x2 { return half4x2(v) } +@(require_results) ashalf_half4x3 :: proc "c" (v: half4x3) -> half4x3 { return half4x3(v) } +@(require_results) ashalf_half2 :: proc "c" (v: half2) -> half2 { return half2(v) } +@(require_results) ashalf_half3 :: proc "c" (v: half3) -> half3 { return half3(v) } +@(require_results) ashalf_half4 :: proc "c" (v: half4) -> half4 { return half4(v) } +@(require_results) ashalf_float1x1 :: proc "c" (v: float1x1) -> half1x1 { return half1x1(v) } +@(require_results) ashalf_float2x2 :: proc "c" (v: float2x2) -> half2x2 { return half2x2(v) } +@(require_results) ashalf_float3x3 :: proc "c" (v: float3x3) -> half3x3 { return half3x3(v) } +@(require_results) ashalf_float4x4 :: proc "c" (v: float4x4) -> half4x4 { return half4x4(v) } +@(require_results) ashalf_float1x2 :: proc "c" (v: float1x2) -> half1x2 { return half1x2(v) } +@(require_results) ashalf_float1x3 :: proc "c" (v: float1x3) -> half1x3 { return half1x3(v) } +@(require_results) ashalf_float1x4 :: proc "c" (v: float1x4) -> half1x4 { return half1x4(v) } +@(require_results) ashalf_float2x1 :: proc "c" (v: float2x1) -> half2x1 { return half2x1(v) } +@(require_results) ashalf_float2x3 :: proc "c" (v: float2x3) -> half2x3 { return half2x3(v) } +@(require_results) ashalf_float2x4 :: proc "c" (v: float2x4) -> half2x4 { return half2x4(v) } +@(require_results) ashalf_float3x1 :: proc "c" (v: float3x1) -> half3x1 { return half3x1(v) } +@(require_results) ashalf_float3x2 :: proc "c" (v: float3x2) -> half3x2 { return half3x2(v) } +@(require_results) ashalf_float3x4 :: proc "c" (v: float3x4) -> half3x4 { return half3x4(v) } +@(require_results) ashalf_float4x1 :: proc "c" (v: float4x1) -> half4x1 { return half4x1(v) } +@(require_results) ashalf_float4x2 :: proc "c" (v: float4x2) -> half4x2 { return half4x2(v) } +@(require_results) ashalf_float4x3 :: proc "c" (v: float4x3) -> half4x3 { return half4x3(v) } +@(require_results) ashalf_float2 :: proc "c" (v: float2) -> half2 { return half2{half(v.x), half(v.y)} } +@(require_results) ashalf_float3 :: proc "c" (v: float3) -> half3 { return half3{half(v.x), half(v.y), half(v.z)} } +@(require_results) ashalf_float4 :: proc "c" (v: float4) -> half4 { return half4{half(v.x), half(v.y), half(v.z), half(v.w)} } +@(require_results) ashalf_int2 :: proc "c" (v: int2) -> half2 { return half2{half(v.x), half(v.y)} } +@(require_results) ashalf_int3 :: proc "c" (v: int3) -> half3 { return half3{half(v.x), half(v.y), half(v.z)} } +@(require_results) ashalf_int4 :: proc "c" (v: int4) -> half4 { return half4{half(v.x), half(v.y), half(v.z), half(v.w)} } +@(require_results) ashalf_uint2 :: proc "c" (v: uint2) -> half2 { return half2{half(v.x), half(v.y)} } +@(require_results) ashalf_uint3 :: proc "c" (v: uint3) -> half3 { return half3{half(v.x), half(v.y), half(v.z)} } +@(require_results) ashalf_uint4 :: proc "c" (v: uint4) -> half4 { return half4{half(v.x), half(v.y), half(v.z), half(v.w)} } +@(require_results) ashalf_bool2 :: proc "c" (v: bool2) -> half2 { return half2{half(int(v.x)), half(int(v.y))} } +@(require_results) ashalf_bool3 :: proc "c" (v: bool3) -> half3 { return half3{half(int(v.x)), half(int(v.y)), half(int(v.z))} } +@(require_results) ashalf_bool4 :: proc "c" (v: bool4) -> half4 { return half4{half(int(v.x)), half(int(v.y)), half(int(v.z)), half(int(v.w))} } +@(require_results) ashalf_double1x1 :: proc "c" (v: double1x1) -> half1x1 { return half1x1(v) } +@(require_results) ashalf_double2x2 :: proc "c" (v: double2x2) -> half2x2 { return half2x2(v) } +@(require_results) ashalf_double3x3 :: proc "c" (v: double3x3) -> half3x3 { return half3x3(v) } +@(require_results) ashalf_double4x4 :: proc "c" (v: double4x4) -> half4x4 { return half4x4(v) } +@(require_results) ashalf_double1x2 :: proc "c" (v: double1x2) -> half1x2 { return half1x2(v) } +@(require_results) ashalf_double1x3 :: proc "c" (v: double1x3) -> half1x3 { return half1x3(v) } +@(require_results) ashalf_double1x4 :: proc "c" (v: double1x4) -> half1x4 { return half1x4(v) } +@(require_results) ashalf_double2x1 :: proc "c" (v: double2x1) -> half2x1 { return half2x1(v) } +@(require_results) ashalf_double2x3 :: proc "c" (v: double2x3) -> half2x3 { return half2x3(v) } +@(require_results) ashalf_double2x4 :: proc "c" (v: double2x4) -> half2x4 { return half2x4(v) } +@(require_results) ashalf_double3x1 :: proc "c" (v: double3x1) -> half3x1 { return half3x1(v) } +@(require_results) ashalf_double3x2 :: proc "c" (v: double3x2) -> half3x2 { return half3x2(v) } +@(require_results) ashalf_double3x4 :: proc "c" (v: double3x4) -> half3x4 { return half3x4(v) } +@(require_results) ashalf_double4x1 :: proc "c" (v: double4x1) -> half4x1 { return half4x1(v) } +@(require_results) ashalf_double4x2 :: proc "c" (v: double4x2) -> half4x2 { return half4x2(v) } +@(require_results) ashalf_double4x3 :: proc "c" (v: double4x3) -> half4x3 { return half4x3(v) } +@(require_results) ashalf_double2 :: proc "c" (v: double2) -> half2 { return half2{half(v.x), half(v.y)} } +@(require_results) ashalf_double3 :: proc "c" (v: double3) -> half3 { return half3{half(v.x), half(v.y), half(v.z)} } +@(require_results) ashalf_double4 :: proc "c" (v: double4) -> half4 { return half4{half(v.x), half(v.y), half(v.z), half(v.w)} } asfloat :: proc{ + asfloat_half, asfloat_float, asfloat_double, asfloat_int, asfloat_uint, + asfloat_half1x1, + asfloat_half2x2, + asfloat_half3x3, + asfloat_half4x4, + asfloat_half1x2, + asfloat_half1x3, + asfloat_half1x4, + asfloat_half2x1, + asfloat_half2x3, + asfloat_half2x4, + asfloat_half3x1, + asfloat_half3x2, + asfloat_half3x4, + asfloat_half4x1, + asfloat_half4x2, + asfloat_half4x3, + asfloat_half2, + asfloat_half3, + asfloat_half4, asfloat_float1x1, asfloat_float2x2, asfloat_float3x3, @@ -1861,10 +2499,30 @@ asfloat :: proc{ asfloat_double3, asfloat_double4, } +@(require_results) asfloat_half :: proc "c" (v: half) -> float { return float(v) } @(require_results) asfloat_float :: proc "c" (v: float) -> float { return float(v) } @(require_results) asfloat_double :: proc "c" (v: double) -> float { return float(v) } @(require_results) asfloat_int :: proc "c" (v: int) -> float { return float(v) } @(require_results) asfloat_uint :: proc "c" (v: uint) -> float { return float(v) } +@(require_results) asfloat_half1x1 :: proc "c" (v: half1x1) -> float1x1 { return float1x1(v) } +@(require_results) asfloat_half2x2 :: proc "c" (v: half2x2) -> float2x2 { return float2x2(v) } +@(require_results) asfloat_half3x3 :: proc "c" (v: half3x3) -> float3x3 { return float3x3(v) } +@(require_results) asfloat_half4x4 :: proc "c" (v: half4x4) -> float4x4 { return float4x4(v) } +@(require_results) asfloat_half1x2 :: proc "c" (v: half1x2) -> float1x2 { return float1x2(v) } +@(require_results) asfloat_half1x3 :: proc "c" (v: half1x3) -> float1x3 { return float1x3(v) } +@(require_results) asfloat_half1x4 :: proc "c" (v: half1x4) -> float1x4 { return float1x4(v) } +@(require_results) asfloat_half2x1 :: proc "c" (v: half2x1) -> float2x1 { return float2x1(v) } +@(require_results) asfloat_half2x3 :: proc "c" (v: half2x3) -> float2x3 { return float2x3(v) } +@(require_results) asfloat_half2x4 :: proc "c" (v: half2x4) -> float2x4 { return float2x4(v) } +@(require_results) asfloat_half3x1 :: proc "c" (v: half3x1) -> float3x1 { return float3x1(v) } +@(require_results) asfloat_half3x2 :: proc "c" (v: half3x2) -> float3x2 { return float3x2(v) } +@(require_results) asfloat_half3x4 :: proc "c" (v: half3x4) -> float3x4 { return float3x4(v) } +@(require_results) asfloat_half4x1 :: proc "c" (v: half4x1) -> float4x1 { return float4x1(v) } +@(require_results) asfloat_half4x2 :: proc "c" (v: half4x2) -> float4x2 { return float4x2(v) } +@(require_results) asfloat_half4x3 :: proc "c" (v: half4x3) -> float4x3 { return float4x3(v) } +@(require_results) asfloat_half2 :: proc "c" (v: half2) -> float2 { return float2{float(v.x), float(v.y)} } +@(require_results) asfloat_half3 :: proc "c" (v: half3) -> float3 { return float3{float(v.x), float(v.y), float(v.z)} } +@(require_results) asfloat_half4 :: proc "c" (v: half4) -> float4 { return float4{float(v.x), float(v.y), float(v.z), float(v.w)} } @(require_results) asfloat_float1x1 :: proc "c" (v: float1x1) -> float1x1 { return float1x1(v) } @(require_results) asfloat_float2x2 :: proc "c" (v: float2x2) -> float2x2 { return float2x2(v) } @(require_results) asfloat_float3x3 :: proc "c" (v: float3x3) -> float3x3 { return float3x3(v) } @@ -1914,10 +2572,30 @@ asfloat :: proc{ @(require_results) asfloat_double4 :: proc "c" (v: double4) -> float4 { return float4{float(v.x), float(v.y), float(v.z), float(v.w)} } asdouble :: proc{ + asdouble_half, asdouble_float, asdouble_double, asdouble_int, asdouble_uint, + asdouble_half1x1, + asdouble_half2x2, + asdouble_half3x3, + asdouble_half4x4, + asdouble_half1x2, + asdouble_half1x3, + asdouble_half1x4, + asdouble_half2x1, + asdouble_half2x3, + asdouble_half2x4, + asdouble_half3x1, + asdouble_half3x2, + asdouble_half3x4, + asdouble_half4x1, + asdouble_half4x2, + asdouble_half4x3, + asdouble_half2, + asdouble_half3, + asdouble_half4, asdouble_float1x1, asdouble_float2x2, asdouble_float3x3, @@ -1966,10 +2644,30 @@ asdouble :: proc{ asdouble_double3, asdouble_double4, } +@(require_results) asdouble_half :: proc "c" (v: half) -> double { return double(v) } @(require_results) asdouble_float :: proc "c" (v: float) -> double { return double(v) } @(require_results) asdouble_double :: proc "c" (v: double) -> double { return double(v) } @(require_results) asdouble_int :: proc "c" (v: int) -> double { return double(v) } @(require_results) asdouble_uint :: proc "c" (v: uint) -> double { return double(v) } +@(require_results) asdouble_half1x1 :: proc "c" (v: half1x1) -> double1x1 { return double1x1(v) } +@(require_results) asdouble_half2x2 :: proc "c" (v: half2x2) -> double2x2 { return double2x2(v) } +@(require_results) asdouble_half3x3 :: proc "c" (v: half3x3) -> double3x3 { return double3x3(v) } +@(require_results) asdouble_half4x4 :: proc "c" (v: half4x4) -> double4x4 { return double4x4(v) } +@(require_results) asdouble_half1x2 :: proc "c" (v: half1x2) -> double1x2 { return double1x2(v) } +@(require_results) asdouble_half1x3 :: proc "c" (v: half1x3) -> double1x3 { return double1x3(v) } +@(require_results) asdouble_half1x4 :: proc "c" (v: half1x4) -> double1x4 { return double1x4(v) } +@(require_results) asdouble_half2x1 :: proc "c" (v: half2x1) -> double2x1 { return double2x1(v) } +@(require_results) asdouble_half2x3 :: proc "c" (v: half2x3) -> double2x3 { return double2x3(v) } +@(require_results) asdouble_half2x4 :: proc "c" (v: half2x4) -> double2x4 { return double2x4(v) } +@(require_results) asdouble_half3x1 :: proc "c" (v: half3x1) -> double3x1 { return double3x1(v) } +@(require_results) asdouble_half3x2 :: proc "c" (v: half3x2) -> double3x2 { return double3x2(v) } +@(require_results) asdouble_half3x4 :: proc "c" (v: half3x4) -> double3x4 { return double3x4(v) } +@(require_results) asdouble_half4x1 :: proc "c" (v: half4x1) -> double4x1 { return double4x1(v) } +@(require_results) asdouble_half4x2 :: proc "c" (v: half4x2) -> double4x2 { return double4x2(v) } +@(require_results) asdouble_half4x3 :: proc "c" (v: half4x3) -> double4x3 { return double4x3(v) } +@(require_results) asdouble_half2 :: proc "c" (v: half2) -> double2 { return double2{double(v.x), double(v.y)} } +@(require_results) asdouble_half3 :: proc "c" (v: half3) -> double3 { return double3{double(v.x), double(v.y), double(v.z)} } +@(require_results) asdouble_half4 :: proc "c" (v: half4) -> double4 { return double4{double(v.x), double(v.y), double(v.z), double(v.w)} } @(require_results) asdouble_float1x1 :: proc "c" (v: float1x1) -> double1x1 { return double1x1(v) } @(require_results) asdouble_float2x2 :: proc "c" (v: float2x2) -> double2x2 { return double2x2(v) } @(require_results) asdouble_float3x3 :: proc "c" (v: float3x3) -> double3x3 { return double3x3(v) } @@ -2019,10 +2717,30 @@ asdouble :: proc{ @(require_results) asdouble_double4 :: proc "c" (v: double4) -> double4 { return double4{double(v.x), double(v.y), double(v.z), double(v.w)} } asint :: proc{ + asint_half, asint_float, asint_double, asint_int, asint_uint, + asint_half1x1, + asint_half2x2, + asint_half3x3, + asint_half4x4, + asint_half1x2, + asint_half1x3, + asint_half1x4, + asint_half2x1, + asint_half2x3, + asint_half2x4, + asint_half3x1, + asint_half3x2, + asint_half3x4, + asint_half4x1, + asint_half4x2, + asint_half4x3, + asint_half2, + asint_half3, + asint_half4, asint_float1x1, asint_float2x2, asint_float3x3, @@ -2071,10 +2789,30 @@ asint :: proc{ asint_double3, asint_double4, } +@(require_results) asint_half :: proc "c" (v: half) -> int { return int(v) } @(require_results) asint_float :: proc "c" (v: float) -> int { return int(v) } @(require_results) asint_double :: proc "c" (v: double) -> int { return int(v) } @(require_results) asint_int :: proc "c" (v: int) -> int { return int(v) } @(require_results) asint_uint :: proc "c" (v: uint) -> int { return int(v) } +@(require_results) asint_half1x1 :: proc "c" (v: half1x1) -> int1x1 { return int1x1(v) } +@(require_results) asint_half2x2 :: proc "c" (v: half2x2) -> int2x2 { return int2x2(v) } +@(require_results) asint_half3x3 :: proc "c" (v: half3x3) -> int3x3 { return int3x3(v) } +@(require_results) asint_half4x4 :: proc "c" (v: half4x4) -> int4x4 { return int4x4(v) } +@(require_results) asint_half1x2 :: proc "c" (v: half1x2) -> int1x2 { return int1x2(v) } +@(require_results) asint_half1x3 :: proc "c" (v: half1x3) -> int1x3 { return int1x3(v) } +@(require_results) asint_half1x4 :: proc "c" (v: half1x4) -> int1x4 { return int1x4(v) } +@(require_results) asint_half2x1 :: proc "c" (v: half2x1) -> int2x1 { return int2x1(v) } +@(require_results) asint_half2x3 :: proc "c" (v: half2x3) -> int2x3 { return int2x3(v) } +@(require_results) asint_half2x4 :: proc "c" (v: half2x4) -> int2x4 { return int2x4(v) } +@(require_results) asint_half3x1 :: proc "c" (v: half3x1) -> int3x1 { return int3x1(v) } +@(require_results) asint_half3x2 :: proc "c" (v: half3x2) -> int3x2 { return int3x2(v) } +@(require_results) asint_half3x4 :: proc "c" (v: half3x4) -> int3x4 { return int3x4(v) } +@(require_results) asint_half4x1 :: proc "c" (v: half4x1) -> int4x1 { return int4x1(v) } +@(require_results) asint_half4x2 :: proc "c" (v: half4x2) -> int4x2 { return int4x2(v) } +@(require_results) asint_half4x3 :: proc "c" (v: half4x3) -> int4x3 { return int4x3(v) } +@(require_results) asint_half2 :: proc "c" (v: half2) -> int2 { return int2{int(v.x), int(v.y)} } +@(require_results) asint_half3 :: proc "c" (v: half3) -> int3 { return int3{int(v.x), int(v.y), int(v.z)} } +@(require_results) asint_half4 :: proc "c" (v: half4) -> int4 { return int4{int(v.x), int(v.y), int(v.z), int(v.w)} } @(require_results) asint_float1x1 :: proc "c" (v: float1x1) -> int1x1 { return int1x1(v) } @(require_results) asint_float2x2 :: proc "c" (v: float2x2) -> int2x2 { return int2x2(v) } @(require_results) asint_float3x3 :: proc "c" (v: float3x3) -> int3x3 { return int3x3(v) } @@ -2125,10 +2863,14 @@ asint :: proc{ asuint :: proc{ + asuint_half, asuint_float, asuint_double, asuint_int, asuint_uint, + asuint_half2, + asuint_half3, + asuint_half4, asuint_float2, asuint_float3, asuint_float4, @@ -2145,10 +2887,14 @@ asuint :: proc{ asuint_double3, asuint_double4, } +@(require_results) asuint_half :: proc "c" (v: half) -> uint { return uint(v) } @(require_results) asuint_float :: proc "c" (v: float) -> uint { return uint(v) } @(require_results) asuint_double :: proc "c" (v: double) -> uint { return uint(v) } @(require_results) asuint_int :: proc "c" (v: int) -> uint { return uint(v) } @(require_results) asuint_uint :: proc "c" (v: uint) -> uint { return uint(v) } +@(require_results) asuint_half2 :: proc "c" (v: half2) -> uint2 { return uint2{uint(v.x), uint(v.y)} } +@(require_results) asuint_half3 :: proc "c" (v: half3) -> uint3 { return uint3{uint(v.x), uint(v.y), uint(v.z)} } +@(require_results) asuint_half4 :: proc "c" (v: half4) -> uint4 { return uint4{uint(v.x), uint(v.y), uint(v.z), uint(v.w)} } @(require_results) asuint_float2 :: proc "c" (v: float2) -> uint2 { return uint2{uint(v.x), uint(v.y)} } @(require_results) asuint_float3 :: proc "c" (v: float3) -> uint3 { return uint3{uint(v.x), uint(v.y), uint(v.z)} } @(require_results) asuint_float4 :: proc "c" (v: float4) -> uint4 { return uint4{uint(v.x), uint(v.y), uint(v.z), uint(v.w)} } diff --git a/core/math/linalg/hlsl/linalg_hlsl_math.odin b/core/math/linalg/hlsl/linalg_hlsl_math.odin index 5b8004342..92c741f03 100644 --- a/core/math/linalg/hlsl/linalg_hlsl_math.odin +++ b/core/math/linalg/hlsl/linalg_hlsl_math.odin @@ -2,6 +2,42 @@ package math_linalg_hlsl import "core:math" +@(require_results) cos_half :: proc "c" (x: half) -> half { return math.cos(x) } +@(require_results) sin_half :: proc "c" (x: half) -> half { return math.sin(x) } +@(require_results) tan_half :: proc "c" (x: half) -> half { return math.tan(x) } +@(require_results) acos_half :: proc "c" (x: half) -> half { return math.acos(x) } +@(require_results) asin_half :: proc "c" (x: half) -> half { return math.asin(x) } +@(require_results) atan_half :: proc "c" (x: half) -> half { return math.atan(x) } +@(require_results) atan2_half :: proc "c" (y, x: half) -> half { return math.atan2(y, x) } +@(require_results) cosh_half :: proc "c" (x: half) -> half { return math.cosh(x) } +@(require_results) sinh_half :: proc "c" (x: half) -> half { return math.sinh(x) } +@(require_results) tanh_half :: proc "c" (x: half) -> half { return math.tanh(x) } +@(require_results) acosh_half :: proc "c" (x: half) -> half { return math.acosh(x) } +@(require_results) asinh_half :: proc "c" (x: half) -> half { return math.asinh(x) } +@(require_results) atanh_half :: proc "c" (x: half) -> half { return math.atanh(x) } +@(require_results) sqrt_half :: proc "c" (x: half) -> half { return math.sqrt(x) } +@(require_results) rsqrt_half :: proc "c" (x: half) -> half { return 1.0/math.sqrt(x) } +@(require_results) rcp_half :: proc "c" (x: half) -> half { return 1.0/x } +@(require_results) pow_half :: proc "c" (x, y: half) -> half { return math.pow(x, y) } +@(require_results) exp_half :: proc "c" (x: half) -> half { return math.exp(x) } +@(require_results) log_half :: proc "c" (x: half) -> half { return math.ln(x) } +@(require_results) log2_half :: proc "c" (x: half) -> half { return math.log(x, 2) } +@(require_results) log10_half :: proc "c" (x: half) -> half { return math.log(x, 10) } +@(require_results) exp2_half :: proc "c" (x: half) -> half { return math.pow(half(2), x) } +@(require_results) sign_half :: proc "c" (x: half) -> half { return math.sign(x) } +@(require_results) floor_half :: proc "c" (x: half) -> half { return math.floor(x) } +@(require_results) round_half :: proc "c" (x: half) -> half { return math.round(x) } +@(require_results) ceil_half :: proc "c" (x: half) -> half { return math.ceil(x) } +@(require_results) isnan_half :: proc "c" (x: half) -> bool { return math.classify(x) == .NaN} +@(require_results) fmod_half :: proc "c" (x, y: half) -> half { return math.mod(x, y) } +@(require_results) +frac_half :: proc "c" (x: half) -> half { + if x >= 0 { + return x - math.trunc(x) + } + return math.trunc(-x) + x +} + @(require_results) cos_float :: proc "c" (x: float) -> float { return math.cos(x) } @(require_results) sin_float :: proc "c" (x: float) -> float { return math.sin(x) } @(require_results) tan_float :: proc "c" (x: float) -> float { return math.tan(x) } diff --git a/core/math/rand/rand.odin b/core/math/rand/rand.odin index 8e270b7df..e8383ca9e 100644 --- a/core/math/rand/rand.odin +++ b/core/math/rand/rand.odin @@ -208,7 +208,7 @@ Inputs: Returns: - val: A random 31 bit value in the range `[0, n)` -WARNING: Panics if n is less than 0 +WARNING: Panics if n is less than or equal to 0 Example: import "core:math/rand" @@ -249,7 +249,7 @@ Inputs: Returns: - val: A random 63 bit value in the range `[0, n)` -WARNING: Panics if n is less than 0 +WARNING: Panics if n is less than or equal to 0 Example: import "core:math/rand" @@ -290,7 +290,7 @@ Inputs: Returns: - val: A random 127 bit value in the range `[0, n)` -WARNING: Panics if n is less than 0 +WARNING: Panics if n is less than or equal to 0 Example: import "core:math/rand" @@ -331,7 +331,7 @@ Inputs: Returns: - val: A random integer value in the range `[0, n)` -WARNING: Panics if n is less than 0 +WARNING: Panics if n is less than or equal to 0 Example: import "core:math/rand" diff --git a/core/mem/allocators.odin b/core/mem/allocators.odin index 5b0b178f8..eea7a5b4f 100644 --- a/core/mem/allocators.odin +++ b/core/mem/allocators.odin @@ -99,8 +99,8 @@ panic_allocator :: proc() -> Allocator { panic_allocator_proc :: proc( allocator_data: rawptr, mode: Allocator_Mode, - size, alignment: int, - old_memory: rawptr, + size, alignment: int, + old_memory: rawptr, old_size: int, loc := #caller_location, ) -> ([]byte, Allocator_Error) { diff --git a/core/mem/mem.odin b/core/mem/mem.odin index 96ec1990a..8ce48d489 100644 --- a/core/mem/mem.odin +++ b/core/mem/mem.odin @@ -332,7 +332,7 @@ and returns an integer count of the `T` between them. - `b`: A pointer to a type T **Returns** -- `b` - `a` in items of T as an `int`. +- `a` - `b` in items of T as an `int`. Example: @@ -704,4 +704,4 @@ calc_padding_with_header :: proc "contextless" (ptr: uintptr, align: uintptr, he } } return int(padding) -} \ No newline at end of file +} diff --git a/core/mem/tlsf/tlsf.odin b/core/mem/tlsf/tlsf.odin index 37c6858ec..b1ef4406a 100644 --- a/core/mem/tlsf/tlsf.odin +++ b/core/mem/tlsf/tlsf.odin @@ -3,7 +3,7 @@ package mem_tlsf /* Copyright 2024 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under tlsf's LICENSE (BSD 3-clause). List of contributors: Matt Conte: Original C implementation, see LICENSE file in this package diff --git a/core/mem/tlsf/tlsf_internal.odin b/core/mem/tlsf/tlsf_internal.odin index e53d76d61..802c4a3fd 100644 --- a/core/mem/tlsf/tlsf_internal.odin +++ b/core/mem/tlsf/tlsf_internal.odin @@ -1,6 +1,6 @@ /* Copyright 2024 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under tlsf's LICENSE (BSD 3-clause). List of contributors: Matt Conte: Original C implementation, see LICENSE file in this package diff --git a/core/net/addr.odin b/core/net/addr.odin index c47c6f55e..fad0eddc4 100644 --- a/core/net/addr.odin +++ b/core/net/addr.odin @@ -11,7 +11,7 @@ package net Copyright 2022 Colin Davidson Copyright 2022 Jeroen van Rijn . Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Tetralux: Initial implementation diff --git a/core/net/common.odin b/core/net/common.odin index 7b33350c0..70523050f 100644 --- a/core/net/common.odin +++ b/core/net/common.odin @@ -14,7 +14,7 @@ package net Copyright 2022 Colin Davidson Copyright 2022 Jeroen van Rijn . Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Tetralux: Initial implementation diff --git a/core/net/dns.odin b/core/net/dns.odin index ed8c00d6a..540991fe7 100644 --- a/core/net/dns.odin +++ b/core/net/dns.odin @@ -12,7 +12,7 @@ package net Copyright 2022 Jeroen van Rijn . Copyright 2024 Feoramund . Copyright 2025 Christiano Haesbaert . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Tetralux: Initial implementation diff --git a/core/net/dns_unix.odin b/core/net/dns_unix.odin index 351d26dbc..fbc1909cd 100644 --- a/core/net/dns_unix.odin +++ b/core/net/dns_unix.odin @@ -10,7 +10,7 @@ package net Copyright 2022 Colin Davidson Copyright 2022 Jeroen van Rijn . Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Tetralux: Initial implementation diff --git a/core/net/dns_windows.odin b/core/net/dns_windows.odin index 7736851b8..b1e7da97d 100644 --- a/core/net/dns_windows.odin +++ b/core/net/dns_windows.odin @@ -11,7 +11,7 @@ package net Copyright 2022 Colin Davidson Copyright 2022 Jeroen van Rijn . Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Tetralux: Initial implementation diff --git a/core/net/doc.odin b/core/net/doc.odin index 082a1497a..8fd88904c 100644 --- a/core/net/doc.odin +++ b/core/net/doc.odin @@ -35,7 +35,7 @@ package net Copyright 2022 Colin Davidson Copyright 2022 Jeroen van Rijn . Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Tetralux: Initial implementation diff --git a/core/net/errors_darwin.odin b/core/net/errors_darwin.odin index 255bd351f..a35e96bc0 100644 --- a/core/net/errors_darwin.odin +++ b/core/net/errors_darwin.odin @@ -11,7 +11,7 @@ package net Copyright 2022 Colin Davidson Copyright 2022 Jeroen van Rijn . Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Tetralux: Initial implementation diff --git a/core/net/errors_freebsd.odin b/core/net/errors_freebsd.odin index 05de41746..29bdd3ff8 100644 --- a/core/net/errors_freebsd.odin +++ b/core/net/errors_freebsd.odin @@ -11,7 +11,7 @@ package net Copyright 2022 Colin Davidson Copyright 2022 Jeroen van Rijn . Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Tetralux: Initial implementation diff --git a/core/net/errors_linux.odin b/core/net/errors_linux.odin index 258560595..636ebb6f9 100644 --- a/core/net/errors_linux.odin +++ b/core/net/errors_linux.odin @@ -11,7 +11,7 @@ package net Copyright 2022 Colin Davidson Copyright 2022 Jeroen van Rijn . Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Tetralux: Initial implementation diff --git a/core/net/errors_windows.odin b/core/net/errors_windows.odin index 8e0e4cda3..83c45ee7f 100644 --- a/core/net/errors_windows.odin +++ b/core/net/errors_windows.odin @@ -11,7 +11,7 @@ package net Copyright 2022 Colin Davidson Copyright 2022 Jeroen van Rijn . Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Tetralux: Initial implementation diff --git a/core/net/interface.odin b/core/net/interface.odin index 4d499a008..182ef3584 100644 --- a/core/net/interface.odin +++ b/core/net/interface.odin @@ -11,7 +11,7 @@ package net Copyright 2022 Colin Davidson Copyright 2022 Jeroen van Rijn . Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Tetralux: Initial implementation diff --git a/core/net/interface_darwin.odin b/core/net/interface_darwin.odin index 9883c10af..f18cff995 100644 --- a/core/net/interface_darwin.odin +++ b/core/net/interface_darwin.odin @@ -11,7 +11,7 @@ package net Copyright 2022 Colin Davidson Copyright 2022 Jeroen van Rijn . Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Tetralux: Initial implementation diff --git a/core/net/interface_freebsd.odin b/core/net/interface_freebsd.odin index 90a538a04..056ad3ac6 100644 --- a/core/net/interface_freebsd.odin +++ b/core/net/interface_freebsd.odin @@ -11,7 +11,7 @@ package net Copyright 2022 Colin Davidson Copyright 2022 Jeroen van Rijn . Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Tetralux: Initial implementation diff --git a/core/net/interface_linux.odin b/core/net/interface_linux.odin index e329803c5..8680c39d8 100644 --- a/core/net/interface_linux.odin +++ b/core/net/interface_linux.odin @@ -11,7 +11,7 @@ package net Copyright 2022 Colin Davidson Copyright 2022 Jeroen van Rijn . Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Tetralux: Initial implementation diff --git a/core/net/interface_windows.odin b/core/net/interface_windows.odin index 571fb322f..c4e3c22eb 100644 --- a/core/net/interface_windows.odin +++ b/core/net/interface_windows.odin @@ -11,7 +11,7 @@ package net Copyright 2022 Colin Davidson Copyright 2022 Jeroen van Rijn . Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Tetralux: Initial implementation diff --git a/core/net/socket.odin b/core/net/socket.odin index f68508169..7e96ba2b2 100644 --- a/core/net/socket.odin +++ b/core/net/socket.odin @@ -11,7 +11,7 @@ package net Copyright 2022-2023 Colin Davidson Copyright 2022-2023 Jeroen van Rijn . Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Tetralux: Initial implementation diff --git a/core/net/socket_darwin.odin b/core/net/socket_darwin.odin index fe4b4c3b5..8e01eb4a8 100644 --- a/core/net/socket_darwin.odin +++ b/core/net/socket_darwin.odin @@ -11,7 +11,7 @@ package net Copyright 2022 Colin Davidson Copyright 2022 Jeroen van Rijn . Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Tetralux: Initial implementation diff --git a/core/net/socket_freebsd.odin b/core/net/socket_freebsd.odin index 78bd1cdae..504229e73 100644 --- a/core/net/socket_freebsd.odin +++ b/core/net/socket_freebsd.odin @@ -11,7 +11,7 @@ package net Copyright 2022 Colin Davidson Copyright 2022 Jeroen van Rijn . Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Tetralux: Initial implementation diff --git a/core/net/socket_linux.odin b/core/net/socket_linux.odin index bdb48fce8..9719ff61b 100644 --- a/core/net/socket_linux.odin +++ b/core/net/socket_linux.odin @@ -11,7 +11,7 @@ package net Copyright 2022 Colin Davidson Copyright 2022 Jeroen van Rijn . Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Tetralux: Initial implementation diff --git a/core/net/socket_windows.odin b/core/net/socket_windows.odin index 9127874de..6dd2f0458 100644 --- a/core/net/socket_windows.odin +++ b/core/net/socket_windows.odin @@ -11,7 +11,7 @@ package net Copyright 2022 Colin Davidson Copyright 2022 Jeroen van Rijn . Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Tetralux: Initial implementation diff --git a/core/net/url.odin b/core/net/url.odin index 41c315585..f20c41229 100644 --- a/core/net/url.odin +++ b/core/net/url.odin @@ -9,7 +9,7 @@ package net Copyright 2022 Colin Davidson Copyright 2022 Jeroen van Rijn . Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Tetralux: Initial implementation diff --git a/core/odin/parser/parser.odin b/core/odin/parser/parser.odin index 94ea649f9..9ce484a10 100644 --- a/core/odin/parser/parser.odin +++ b/core/odin/parser/parser.odin @@ -99,10 +99,8 @@ end_pos :: proc(tok: tokenizer.Token) -> tokenizer.Pos { pos := tok.pos pos.offset += len(tok.text) - if tok.kind == .Comment { - if tok.text[:2] != "/*" { - pos.column += len(tok.text) - } else { + if tok.kind == .Comment || tok.kind == .String { + if tok.text[:2] == "/*" || tok.text[:1] == "`" { for i := 0; i < len(tok.text); i += 1 { c := tok.text[i] if c == '\n' { @@ -112,6 +110,8 @@ end_pos :: proc(tok: tokenizer.Token) -> tokenizer.Pos { pos.column += 1 } } + } else { + pos.column += len(tok.text) } } else { pos.column += len(tok.text) @@ -3210,6 +3210,17 @@ parse_call_expr :: proc(p: ^Parser, operand: ^ast.Expr) -> ^ast.Expr { return ce } +empty_selector_expr :: proc(tok: tokenizer.Token, operand: ^ast.Expr) -> ^ast.Selector_Expr { + field := ast.new(ast.Ident, tok.pos, end_pos(tok)) + field.name = "" + + sel := ast.new(ast.Selector_Expr, operand.pos, field) + sel.expr = operand + sel.op = tok + sel.field = field + + return sel +} parse_atom_expr :: proc(p: ^Parser, value: ^ast.Expr, lhs: bool) -> (operand: ^ast.Expr) { operand = value @@ -3343,8 +3354,7 @@ parse_atom_expr :: proc(p: ^Parser, value: ^ast.Expr, lhs: bool) -> (operand: ^a case: error(p, p.curr_tok.pos, "expected a selector") - advance_token(p) - operand = ast.new(ast.Bad_Expr, operand.pos, end_pos(tok)) + operand = empty_selector_expr(tok, operand) } case .Arrow_Right: @@ -3361,8 +3371,7 @@ parse_atom_expr :: proc(p: ^Parser, value: ^ast.Expr, lhs: bool) -> (operand: ^a operand = sel case: error(p, p.curr_tok.pos, "expected a selector") - advance_token(p) - operand = ast.new(ast.Bad_Expr, operand.pos, end_pos(tok)) + operand = empty_selector_expr(tok, operand) } case .Pointer: diff --git a/core/os/os2/dir.odin b/core/os/os2/dir.odin index 10b06a8ce..f63754273 100644 --- a/core/os/os2/dir.odin +++ b/core/os/os2/dir.odin @@ -6,6 +6,10 @@ import "core:strings" read_dir :: read_directory +/* + Reads the file `f` (assuming it is a directory) and returns the unsorted directory entries. + This returns up to `n` entries OR all of them if `n <= 0`. +*/ @(require_results) read_directory :: proc(f: ^File, n: int, allocator: runtime.Allocator) -> (files: []File_Info, err: Error) { if f == nil { @@ -47,11 +51,18 @@ read_directory :: proc(f: ^File, n: int, allocator: runtime.Allocator) -> (files } +/* + Reads the file `f` (assuming it is a directory) and returns all of the unsorted directory entries. +*/ @(require_results) read_all_directory :: proc(f: ^File, allocator: runtime.Allocator) -> (fi: []File_Info, err: Error) { return read_directory(f, -1, allocator) } +/* + Reads the named directory by path (assuming it is a directory) and returns the unsorted directory entries. + This returns up to `n` entries OR all of them if `n <= 0`. +*/ @(require_results) read_directory_by_path :: proc(path: string, n: int, allocator: runtime.Allocator) -> (fi: []File_Info, err: Error) { f := open(path) or_return @@ -59,6 +70,9 @@ read_directory_by_path :: proc(path: string, n: int, allocator: runtime.Allocato return read_directory(f, n, allocator) } +/* + Reads the named directory by path (assuming it is a directory) and returns all of the unsorted directory entries. +*/ @(require_results) read_all_directory_by_path :: proc(path: string, allocator: runtime.Allocator) -> (fi: []File_Info, err: Error) { return read_directory_by_path(path, -1, allocator) diff --git a/core/os/os2/dir_windows.odin b/core/os/os2/dir_windows.odin index 6c754a677..a4dadca75 100644 --- a/core/os/os2/dir_windows.odin +++ b/core/os/os2/dir_windows.odin @@ -18,7 +18,7 @@ find_data_to_file_info :: proc(base_path: string, d: ^win32.WIN32_FIND_DATAW, al temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator }) path := concatenate({base_path, `\`, win32_wstring_to_utf8(cstring16(raw_data(d.cFileName[:])), temp_allocator) or_else ""}, allocator) or_return - handle := win32.HANDLE(_open_internal(path, {.Read}, 0o666) or_else 0) + handle := win32.HANDLE(_open_internal(path, {.Read}, Permissions_Read_Write_All) or_else 0) defer win32.CloseHandle(handle) fi.fullpath = path diff --git a/core/os/os2/errors.odin b/core/os/os2/errors.odin index 1cf7d765c..077697c0d 100644 --- a/core/os/os2/errors.odin +++ b/core/os/os2/errors.odin @@ -3,6 +3,10 @@ package os2 import "core:io" import "base:runtime" +/* + General errors that are common within this package which cannot + be categorized by `io.Error` nor `runtime.Allocator_Error`. +*/ General_Error :: enum u32 { None, @@ -33,8 +37,12 @@ General_Error :: enum u32 { Unsupported, } +// A platform specific error Platform_Error :: _Platform_Error +/* + `Error` is a union of different classes of errors that could be returned from procedures in this package. +*/ Error :: union #shared_nil { General_Error, io.Error, @@ -46,6 +54,7 @@ Error :: union #shared_nil { ERROR_NONE :: Error{} +// Attempts to convert an `Error` into a platform specific error as an integer. `ok` is false if not possible @(require_results) is_platform_error :: proc(ferr: Error) -> (err: i32, ok: bool) { v := ferr.(Platform_Error) or_else {} @@ -53,6 +62,7 @@ is_platform_error :: proc(ferr: Error) -> (err: i32, ok: bool) { } +// Attempts to return the error `ferr` as a string without any allocation @(require_results) error_string :: proc(ferr: Error) -> string { if ferr == nil { @@ -112,6 +122,9 @@ error_string :: proc(ferr: Error) -> string { return "unknown error" } +/* + `print_error` is a utility procedure which will print an error `ferr` to a specified file `f`. +*/ print_error :: proc(f: ^File, ferr: Error, msg: string) { temp_allocator := TEMP_ALLOCATOR_GUARD({}) err_str := error_string(ferr) @@ -127,3 +140,14 @@ print_error :: proc(f: ^File, ferr: Error, msg: string) { buf[length - 1] = '\n' write(f, buf) } + + + +// Attempts to convert an `Error` `ferr` into an `io.Error` +@(private) +error_to_io_error :: proc(ferr: Error) -> io.Error { + if ferr == nil { + return .None + } + return ferr.(io.Error) or_else .Unknown +} diff --git a/core/os/os2/file.odin b/core/os/os2/file.odin index a9878a563..85ebfcece 100644 --- a/core/os/os2/file.odin +++ b/core/os/os2/file.odin @@ -56,6 +56,7 @@ File_Type :: enum { Character_Device, } +// Represents the file flags for a file handle File_Flags :: distinct bit_set[File_Flag; uint] File_Flag :: enum { Read, @@ -90,17 +91,77 @@ O_SPARSE :: File_Flags{.Sparse} */ O_INHERITABLE :: File_Flags{.Inheritable} -stdin: ^File = nil // OS-Specific -stdout: ^File = nil // OS-Specific -stderr: ^File = nil // OS-Specific +Permissions :: distinct bit_set[Permission_Flag; u32] +Permission_Flag :: enum u32 { + Execute_Other = 0, + Write_Other = 1, + Read_Other = 2, -@(require_results) -create :: proc(name: string) -> (^File, Error) { - return open(name, {.Read, .Write, .Create}, 0o777) + Execute_Group = 3, + Write_Group = 4, + Read_Group = 5, + + Execute_User = 6, + Write_User = 7, + Read_User = 8, } +Permissions_Execute_All :: Permissions{.Execute_User, .Execute_Group, .Execute_Other} +Permissions_Write_All :: Permissions{.Write_User, .Write_Group, .Write_Other} +Permissions_Read_All :: Permissions{.Read_User, .Read_Group, .Read_Other} + +Permissions_Read_Write_All :: Permissions_Read_All + Permissions_Write_All + +Permissions_All :: Permissions_Read_All + Permissions_Write_All + Permissions_Execute_All + +Permissions_Default_File :: Permissions_Read_All + Permissions_Write_All +Permissions_Default_Directory :: Permissions_Read_All + Permissions_Write_All + Permissions_Execute_All +Permissions_Default :: Permissions_Default_Directory + +perm :: proc{ + perm_number, +} + +/* + `perm_number` converts an integer value `perm` to the bit set `Permissions` +*/ @(require_results) -open :: proc(name: string, flags := File_Flags{.Read}, perm := 0o777) -> (^File, Error) { +perm_number :: proc "contextless" (perm: int) -> Permissions { + return transmute(Permissions)u32(perm & 0o777) +} + + + +// `stdin` is an open file pointing to the standard input file stream +stdin: ^File = nil // OS-Specific + +// `stdout` is an open file pointing to the standard output file stream +stdout: ^File = nil // OS-Specific + +// `stderr` is an open file pointing to the standard error file stream +stderr: ^File = nil // OS-Specific + +/* + `create` creates or truncates a named file `name`. + If the file already exists, it is truncated. + If the file does not exist, it is created with the `Permissions_Default_File` permissions. + If successful, a `^File` is return which can be used for I/O. + And error is returned if any is encountered. +*/ +@(require_results) +create :: proc(name: string) -> (^File, Error) { + return open(name, {.Read, .Write, .Create, .Trunc}, Permissions_Default_File) +} + +/* + `open` is a generalized open call, which defaults to opening for reading. + If the file does not exist, and the `{.Create}` flag is passed, it is created with the permissions `perm`, + and please note that the containing directory must exist otherwise and an error will be returned. + If successful, a `^File` is return which can be used for I/O. + And error is returned if any is encountered. +*/ +@(require_results) +open :: proc(name: string, flags := File_Flags{.Read}, perm := Permissions_Default) -> (^File, Error) { return _open(name, flags, perm) } @@ -112,7 +173,10 @@ open :: proc(name: string, flags := File_Flags{.Read}, perm := 0o777) -> (^File, // return _open_buffered(name, buffer_size, flags, perm) // } - +/* + `new_file` returns a new `^File` with the given file descriptor `handle` and `name`. + The return value will only be `nil` IF the `handle` is not a valid file descriptor. +*/ @(require_results) new_file :: proc(handle: uintptr, name: string) -> ^File { file, err := _new_file(handle, name, file_allocator()) @@ -122,16 +186,25 @@ new_file :: proc(handle: uintptr, name: string) -> ^File { return file } +/* + `clone` returns a new `^File` based on the passed file `f` with the same underlying file descriptor. +*/ @(require_results) clone :: proc(f: ^File) -> (^File, Error) { return _clone(f) } +/* + `fd` returns the file descriptor of the file `f` passed. If the file is not valid, an invalid handle will be returned. +*/ @(require_results) fd :: proc(f: ^File) -> uintptr { return _fd(f) } +/* + `name` returns the name of the file. The lifetime of this string lasts as long as the file handle itself. +*/ @(require_results) name :: proc(f: ^File) -> string { return _name(f) @@ -150,6 +223,16 @@ close :: proc(f: ^File) -> Error { return nil } +/* + seek sets the offsets for the next read or write on a file to a specified `offset`, + according to what `whence` is set. + `.Start` is relative to the origin of the file. + `.Current` is relative to the current offset. + `.End` is relative to the end. + It returns the new offset and an error, if any is encountered. + Prefer `read_at` or `write_at` if the offset does not want to be changed. + +*/ seek :: proc(f: ^File, offset: i64, whence: io.Seek_From) -> (ret: i64, err: Error) { if f != nil { return io.seek(f.stream, offset, whence) @@ -157,6 +240,11 @@ seek :: proc(f: ^File, offset: i64, whence: io.Seek_From) -> (ret: i64, err: Err return 0, .Invalid_File } +/* + `read` reads up to len(p) bytes from the file `f`, and then stores them in `p`. + It returns the number of bytes read and an error, if any is encountered. + At the end of a file, it returns `0, io.EOF`. +*/ read :: proc(f: ^File, p: []byte) -> (n: int, err: Error) { if f != nil { return io.read(f.stream, p) @@ -164,6 +252,12 @@ read :: proc(f: ^File, p: []byte) -> (n: int, err: Error) { return 0, .Invalid_File } +/* + `read_at` reads up to len(p) bytes from the file `f` at the byte offset `offset`, and then stores them in `p`. + It returns the number of bytes read and an error, if any is encountered. + `read_at` always returns a non-nil error when `n < len(p)`. + At the end of a file, the error is `io.EOF`. +*/ read_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: int, err: Error) { if f != nil { return io.read_at(f.stream, p, offset) @@ -171,6 +265,11 @@ read_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: int, err: Error) { return 0, .Invalid_File } +/* + `write` writes `len(p)` bytes from `p` to the file `f`. It returns the number of bytes written to + and an error, if any is encountered. + `write` returns a non-nil error when `n != len(p)`. +*/ write :: proc(f: ^File, p: []byte) -> (n: int, err: Error) { if f != nil { return io.write(f.stream, p) @@ -178,6 +277,11 @@ write :: proc(f: ^File, p: []byte) -> (n: int, err: Error) { return 0, .Invalid_File } +/* + `write_at` writes `len(p)` bytes from `p` to the file `f` starting at byte offset `offset`. + It returns the number of bytes written to and an error, if any is encountered. + `write_at` returns a non-nil error when `n != len(p)`. +*/ write_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: int, err: Error) { if f != nil { return io.write_at(f.stream, p, offset) @@ -185,6 +289,9 @@ write_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: int, err: Error) { return 0, .Invalid_File } +/* + `file_size` returns the length of the file `f` in bytes and an error, if any is encountered. +*/ file_size :: proc(f: ^File) -> (n: i64, err: Error) { if f != nil { return io.size(f.stream) @@ -192,6 +299,9 @@ file_size :: proc(f: ^File) -> (n: i64, err: Error) { return 0, .Invalid_File } +/* + `flush` flushes a file `f` +*/ flush :: proc(f: ^File) -> Error { if f != nil { return io.flush(f.stream) @@ -199,31 +309,54 @@ flush :: proc(f: ^File) -> Error { return nil } +/* + `sync` commits the current contents of the file `f` to stable storage. + This usually means flushing the file system's in-memory copy to disk. +*/ sync :: proc(f: ^File) -> Error { return _sync(f) } +/* + `truncate` changes the size of the file `f` to `size` in bytes. + This can be used to shorten or lengthen a file. + It does not change the "offset" of the file. +*/ truncate :: proc(f: ^File, size: i64) -> Error { return _truncate(f, size) } +/* + `remove` removes a named file or (empty) directory. +*/ remove :: proc(name: string) -> Error { return _remove(name) } +/* + `rename` renames (moves) `old_path` to `new_path`. +*/ rename :: proc(old_path, new_path: string) -> Error { return _rename(old_path, new_path) } - +/* + `link` creates a `new_name` as a hard link to the `old_name` file. +*/ link :: proc(old_name, new_name: string) -> Error { return _link(old_name, new_name) } +/* + `symlink` creates a `new_name` as a symbolic link to the `old_name` file. +*/ symlink :: proc(old_name, new_name: string) -> Error { return _symlink(old_name, new_name) } +/* + `read_link` returns the destinction of the named symbolic link `name`. +*/ read_link :: proc(name: string, allocator: runtime.Allocator) -> (string, Error) { return _read_link(name,allocator) } @@ -231,36 +364,65 @@ read_link :: proc(name: string, allocator: runtime.Allocator) -> (string, Error) chdir :: change_directory +/* + Changes the current working directory to the named directory. +*/ change_directory :: proc(name: string) -> Error { return _chdir(name) } chmod :: change_mode -change_mode :: proc(name: string, mode: int) -> Error { +/* + Changes the mode/permissions of the named file to `mode`. + If the file is a symbolic link, it changes the mode of the link's target. + + On Windows, only `{.Write_User}` of `mode` is used, and controls whether or not + the file has a read-only attribute. Use `{.Read_User}` for a read-only file and + `{.Read_User, .Write_User}` for a readable & writable file. +*/ +change_mode :: proc(name: string, mode: Permissions) -> Error { return _chmod(name, mode) } chown :: change_owner +/* + Changes the numeric `uid` and `gid` of a named file. If the file is a symbolic link, + it changes the `uid` and `gid` of the link's target. + + On Windows, it always returns an error. +*/ change_owner :: proc(name: string, uid, gid: int) -> Error { return _chown(name, uid, gid) } fchdir :: fchange_directory +/* + Changes the current working directory to the file, which must be a directory. +*/ fchange_directory :: proc(f: ^File) -> Error { return _fchdir(f) } fchmod :: fchange_mode -fchange_mode :: proc(f: ^File, mode: int) -> Error { +/* + Changes the current `mode` permissions of the file `f`. +*/ +fchange_mode :: proc(f: ^File, mode: Permissions) -> Error { return _fchmod(f, mode) } fchown :: fchange_owner +/* + Changes the numeric `uid` and `gid` of the file `f`. If the file is a symbolic link, + it changes the `uid` and `gid` of the link's target. + + On Windows, it always returns an error. +*/ fchange_owner :: proc(f: ^File, uid, gid: int) -> Error { return _fchown(f, uid, gid) } @@ -268,27 +430,45 @@ fchange_owner :: proc(f: ^File, uid, gid: int) -> Error { lchown :: change_owner_do_not_follow_links +/* + Changes the numeric `uid` and `gid` of the file `f`. If the file is a symbolic link, + it changes the `uid` and `gid` of the lin itself. + + On Windows, it always returns an error. +*/ change_owner_do_not_follow_links :: proc(name: string, uid, gid: int) -> Error { return _lchown(name, uid, gid) } chtimes :: change_times +/* + Changes the access `atime` and modification `mtime` times of a named file. +*/ change_times :: proc(name: string, atime, mtime: time.Time) -> Error { return _chtimes(name, atime, mtime) } fchtimes :: fchange_times +/* + Changes the access `atime` and modification `mtime` times of the file `f`. +*/ fchange_times :: proc(f: ^File, atime, mtime: time.Time) -> Error { return _fchtimes(f, atime, mtime) } +/* + `exists` returns whether or not a named file exists. +*/ @(require_results) exists :: proc(path: string) -> bool { return _exists(path) } +/* + `is_file` returns whether or not the type of a named file is a `File_Type.Regular` file. +*/ @(require_results) is_file :: proc(path: string) -> bool { temp_allocator := TEMP_ALLOCATOR_GUARD({}) @@ -301,6 +481,9 @@ is_file :: proc(path: string) -> bool { is_dir :: is_directory +/* + Returns whether or not the type of a named file is a `File_Type.Directory` file. +*/ @(require_results) is_directory :: proc(path: string) -> bool { temp_allocator := TEMP_ALLOCATOR_GUARD({}) @@ -311,7 +494,9 @@ is_directory :: proc(path: string) -> bool { return fi.type == .Directory } - +/* + `copy_file` copies a file from `src_path` to `dst_path` and returns an error if any was encountered. +*/ copy_file :: proc(dst_path, src_path: string) -> Error { when #defined(_copy_file_native) { return _copy_file_native(dst_path, src_path) @@ -331,7 +516,7 @@ _copy_file :: proc(dst_path, src_path: string) -> Error { return .Invalid_File } - dst := open(dst_path, {.Read, .Write, .Create, .Trunc}, info.mode & 0o777) or_return + dst := open(dst_path, {.Read, .Write, .Create, .Trunc}, info.mode & Permissions_All) or_return defer close(dst) _, err := io.copy(to_writer(dst), to_reader(src)) diff --git a/core/os/os2/file_linux.odin b/core/os/os2/file_linux.odin index 92f0c1541..b2350d9b5 100644 --- a/core/os/os2/file_linux.odin +++ b/core/os/os2/file_linux.odin @@ -65,7 +65,7 @@ _standard_stream_init :: proc "contextless" () { stderr = new_std(&files[2], 2, "/proc/self/fd/2") } -_open :: proc(name: string, flags: File_Flags, perm: int) -> (f: ^File, err: Error) { +_open :: proc(name: string, flags: File_Flags, perm: Permissions) -> (f: ^File, err: Error) { temp_allocator := TEMP_ALLOCATOR_GUARD({}) name_cstr := clone_to_cstring(name, temp_allocator) or_return @@ -88,7 +88,7 @@ _open :: proc(name: string, flags: File_Flags, perm: int) -> (f: ^File, err: Err if .Trunc in flags { sys_flags += {.TRUNC} } if .Inheritable in flags { sys_flags -= {.CLOEXEC} } - fd, errno := linux.open(name_cstr, sys_flags, transmute(linux.Mode)u32(perm)) + fd, errno := linux.open(name_cstr, sys_flags, transmute(linux.Mode)transmute(u32)perm) if errno != .NONE { return nil, _get_platform_error(errno) } @@ -132,7 +132,7 @@ _clone :: proc(f: ^File) -> (clone: ^File, err: Error) { @(require_results) -_open_buffered :: proc(name: string, buffer_size: uint, flags := File_Flags{.Read}, perm := 0o777) -> (f: ^File, err: Error) { +_open_buffered :: proc(name: string, buffer_size: uint, flags := File_Flags{.Read}, perm: Permissions) -> (f: ^File, err: Error) { assert(buffer_size > 0) f, err = _open(name, flags, perm) if f != nil && err == nil { @@ -198,7 +198,7 @@ _seek :: proc(f: ^File_Impl, offset: i64, whence: io.Seek_From) -> (ret: i64, er case .NONE: return n, nil case: - return -1, _get_platform_error(errno) + return 0, _get_platform_error(errno) } } @@ -209,7 +209,7 @@ _read :: proc(f: ^File_Impl, p: []byte) -> (i64, Error) { n, errno := linux.read(f.fd, p[:min(len(p), MAX_RW)]) if errno != .NONE { - return -1, _get_platform_error(errno) + return 0, _get_platform_error(errno) } return i64(n), io.Error.EOF if n == 0 else nil } @@ -223,7 +223,7 @@ _read_at :: proc(f: ^File_Impl, p: []byte, offset: i64) -> (i64, Error) { } n, errno := linux.pread(f.fd, p[:min(len(p), MAX_RW)], offset) if errno != .NONE { - return -1, _get_platform_error(errno) + return 0, _get_platform_error(errno) } if n == 0 { return 0, .EOF @@ -276,7 +276,7 @@ _file_size :: proc(f: ^File_Impl) -> (n: i64, err: Error) { s: linux.Stat = --- errno := linux.fstat(f.fd, &s) if errno != .NONE { - return -1, _get_platform_error(errno) + return 0, _get_platform_error(errno) } if s.mode & linux.S_IFMT == linux.S_IFREG { @@ -369,15 +369,15 @@ _fchdir :: proc(f: ^File) -> Error { return _get_platform_error(linux.fchdir(impl.fd)) } -_chmod :: proc(name: string, mode: int) -> Error { +_chmod :: proc(name: string, mode: Permissions) -> Error { temp_allocator := TEMP_ALLOCATOR_GUARD({}) name_cstr := clone_to_cstring(name, temp_allocator) or_return - return _get_platform_error(linux.chmod(name_cstr, transmute(linux.Mode)(u32(mode)))) + return _get_platform_error(linux.chmod(name_cstr, transmute(linux.Mode)transmute(u32)mode)) } -_fchmod :: proc(f: ^File, mode: int) -> Error { +_fchmod :: proc(f: ^File, mode: Permissions) -> Error { impl := (^File_Impl)(f.impl) - return _get_platform_error(linux.fchmod(impl.fd, transmute(linux.Mode)(u32(mode)))) + return _get_platform_error(linux.fchmod(impl.fd, transmute(linux.Mode)transmute(u32)mode)) } // NOTE: will throw error without super user priviledges diff --git a/core/os/os2/file_posix.odin b/core/os/os2/file_posix.odin index fed8d766c..fd409b9d4 100644 --- a/core/os/os2/file_posix.odin +++ b/core/os/os2/file_posix.odin @@ -46,7 +46,7 @@ init_std_files :: proc "contextless" () { stderr = new_std(&files[2], posix.STDERR_FILENO, "/dev/stderr") } -_open :: proc(name: string, flags: File_Flags, perm: int) -> (f: ^File, err: Error) { +_open :: proc(name: string, flags: File_Flags, perm: Permissions) -> (f: ^File, err: Error) { if name == "" { err = .Invalid_Path return @@ -72,7 +72,7 @@ _open :: proc(name: string, flags: File_Flags, perm: int) -> (f: ^File, err: Err temp_allocator := TEMP_ALLOCATOR_GUARD({}) cname := clone_to_cstring(name, temp_allocator) or_return - fd := posix.open(cname, sys_flags, transmute(posix.mode_t)posix._mode_t(perm)) + fd := posix.open(cname, sys_flags, transmute(posix.mode_t)posix._mode_t(transmute(u32)perm)) if fd < 0 { err = _get_platform_error() return @@ -284,17 +284,17 @@ _fchdir :: proc(f: ^File) -> Error { return nil } -_fchmod :: proc(f: ^File, mode: int) -> Error { - if posix.fchmod(__fd(f), transmute(posix.mode_t)posix._mode_t(mode)) != .OK { +_fchmod :: proc(f: ^File, mode: Permissions) -> Error { + if posix.fchmod(__fd(f), transmute(posix.mode_t)posix._mode_t(transmute(u32)mode)) != .OK { return _get_platform_error() } return nil } -_chmod :: proc(name: string, mode: int) -> (err: Error) { +_chmod :: proc(name: string, mode: Permissions) -> (err: Error) { temp_allocator := TEMP_ALLOCATOR_GUARD({}) cname := clone_to_cstring(name, temp_allocator) or_return - if posix.chmod(cname, transmute(posix.mode_t)posix._mode_t(mode)) != .OK { + if posix.chmod(cname, transmute(posix.mode_t)posix._mode_t(transmute(u32)mode)) != .OK { return _get_platform_error() } return nil @@ -382,12 +382,14 @@ _file_stream_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, } to_read := uint(min(len(p), MAX_RW)) - n = i64(posix.read(fd, raw_data(p), to_read)) + _n := i64(posix.read(fd, raw_data(p), to_read)) switch { - case n == 0: + case _n == 0: err = .EOF - case n < 0: + case _n < 0: err = .Unknown + case: + n = _n } return @@ -402,12 +404,14 @@ _file_stream_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, } to_read := uint(min(len(p), MAX_RW)) - n = i64(posix.pread(fd, raw_data(p), to_read, posix.off_t(offset))) + _n := i64(posix.pread(fd, raw_data(p), to_read, posix.off_t(offset))) switch { - case n == 0: + case _n == 0: err = .EOF - case n < 0: + case _n < 0: err = .Unknown + case: + n = _n } return @@ -460,15 +464,18 @@ _file_stream_proc :: proc(stream_data: rawptr, mode: io.Stream_Mode, p: []byte, return } - n = i64(posix.lseek(fd, posix.off_t(offset), posix.Whence(whence))) - if n < 0 { + _n := i64(posix.lseek(fd, posix.off_t(offset), posix.Whence(whence))) + if _n < 0 { #partial switch posix.get_errno() { case .EINVAL: err = .Invalid_Offset case: err = .Unknown } + return } + + n = _n return case .Size: diff --git a/core/os/os2/file_posix_other.odin b/core/os/os2/file_posix_other.odin index d2946098b..8871a0062 100644 --- a/core/os/os2/file_posix_other.odin +++ b/core/os/os2/file_posix_other.odin @@ -8,7 +8,7 @@ import "core:sys/posix" _posix_absolute_path :: proc(fd: posix.FD, name: string, allocator: runtime.Allocator) -> (path: cstring, err: Error) { temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator }) - cname := clone_to_cstring(name, temp_allocator) + cname := clone_to_cstring(name, temp_allocator) or_return buf: [posix.PATH_MAX]byte path = posix.realpath(cname, raw_data(buf[:])) diff --git a/core/os/os2/file_stream.odin b/core/os/os2/file_stream.odin index 84176928d..e1c29a792 100644 --- a/core/os/os2/file_stream.odin +++ b/core/os/os2/file_stream.odin @@ -2,6 +2,7 @@ package os2 import "core:io" +// Converts a file `f` into an `io.Stream` to_stream :: proc(f: ^File) -> (s: io.Stream) { if f != nil { assert(f.stream.procedure != nil) @@ -10,14 +11,16 @@ to_stream :: proc(f: ^File) -> (s: io.Stream) { return } +/* + This is an alias of `to_stream` which converts a file `f` to an `io.Stream`. + It can be useful to indicate what the stream is meant to be used for as a writer, + even if it has no logical difference. +*/ to_writer :: to_stream + +/* + This is an alias of `to_stream` which converts a file `f` to an `io.Stream`. + It can be useful to indicate what the stream is meant to be used for as a reader, + even if it has no logical difference. +*/ to_reader :: to_stream - - -@(private) -error_to_io_error :: proc(ferr: Error) -> io.Error { - if ferr == nil { - return .None - } - return ferr.(io.Error) or_else .Unknown -} diff --git a/core/os/os2/file_util.odin b/core/os/os2/file_util.odin index 13d6db661..c2cf7c121 100644 --- a/core/os/os2/file_util.odin +++ b/core/os/os2/file_util.odin @@ -4,10 +4,18 @@ import "base:runtime" import "core:strconv" import "core:unicode/utf8" +/* + `write_string` writes a string `s` to file `f`. + Returns the number of bytes written and an error, if any is encountered. +*/ write_string :: proc(f: ^File, s: string) -> (n: int, err: Error) { return write(f, transmute([]byte)s) } +/* + `write_strings` writes a variadic list of strings `strings` to file `f`. + Returns the number of bytes written and an error, if any is encountered. +*/ write_strings :: proc(f: ^File, strings: ..string) -> (n: int, err: Error) { for s in strings { m: int @@ -19,11 +27,18 @@ write_strings :: proc(f: ^File, strings: ..string) -> (n: int, err: Error) { } return } - +/* + `write_byte` writes a byte `b` to file `f`. + Returns the number of bytes written and an error, if any is encountered. +*/ write_byte :: proc(f: ^File, b: byte) -> (n: int, err: Error) { return write(f, []byte{b}) } +/* + `write_rune` writes a rune `r` as an UTF-8 encoded string to file `f`. + Returns the number of bytes written and an error, if any is encountered. +*/ write_rune :: proc(f: ^File, r: rune) -> (n: int, err: Error) { if r < utf8.RUNE_SELF { return write_byte(f, byte(r)) @@ -34,6 +49,10 @@ write_rune :: proc(f: ^File, r: rune) -> (n: int, err: Error) { return write(f, b[:n]) } +/* + `write_encoded_rune` writes a rune `r` as an UTF-8 encoded string which with escaped control codes to file `f`. + Returns the number of bytes written and an error, if any is encountered. +*/ write_encoded_rune :: proc(f: ^File, r: rune) -> (n: int, err: Error) { wrap :: proc(m: int, merr: Error, n: ^int, err: ^Error) -> bool { n^ += m @@ -73,6 +92,31 @@ write_encoded_rune :: proc(f: ^File, r: rune) -> (n: int, err: Error) { return } +/* + `write_ptr` is a utility procedure that writes the bytes points at `data` with length `len`. + + It is equivalent to: `write(f, ([^]byte)(data)[:len])` +*/ +write_ptr :: proc(f: ^File, data: rawptr, len: int) -> (n: int, err: Error) { + return write(f, ([^]byte)(data)[:len]) +} + +/* + `read_ptr` is a utility procedure that reads the bytes points at `data` with length `len`. + + It is equivalent to: `read(f, ([^]byte)(data)[:len])` +*/ +read_ptr :: proc(f: ^File, data: rawptr, len: int) -> (n: int, err: Error) { + return read(f, ([^]byte)(data)[:len]) +} + + + +/* + `read_at_least` reads from `f` into `buf` until it has read at least `min` bytes. + It returns the number of bytes copied and an error if fewer bytes were read. + The error is only an `io.EOF` if no bytes were read. +*/ read_at_least :: proc(f: ^File, buf: []byte, min: int) -> (n: int, err: Error) { if len(buf) < min { return 0, .Short_Buffer @@ -88,17 +132,17 @@ read_at_least :: proc(f: ^File, buf: []byte, min: int) -> (n: int, err: Error) { return } +/* + `read_full` reads exactly `len(buf)` bytes from `f` into `buf`. + It returns the number of bytes copied and an error if fewer bytes were read. + The error is only an `io.EOF` if no bytes were read. + + It is equivalent to `read_at_least(f, buf, len(buf))`. +*/ read_full :: proc(f: ^File, buf: []byte) -> (n: int, err: Error) { return read_at_least(f, buf, len(buf)) } -write_ptr :: proc(f: ^File, data: rawptr, len: int) -> (n: int, err: Error) { - return write(f, ([^]byte)(data)[:len]) -} - -read_ptr :: proc(f: ^File, data: rawptr, len: int) -> (n: int, err: Error) { - return read(f, ([^]byte)(data)[:len]) -} read_entire_file :: proc{ @@ -106,18 +150,23 @@ read_entire_file :: proc{ read_entire_file_from_file, } +/* + `read_entire_file_from_path` reads the entire named file `name` into memory allocated with `allocator`. + A slice of bytes and an error is returned, if any error is encountered. +*/ @(require_results) -read_entire_file_from_path :: proc(name: string, allocator: runtime.Allocator) -> (data: []byte, err: Error) { - f, ferr := open(name) - if ferr != nil { - return nil, ferr - } +read_entire_file_from_path :: proc(name: string, allocator: runtime.Allocator, loc := #caller_location) -> (data: []byte, err: Error) { + f := open(name) or_return defer close(f) - return read_entire_file_from_file(f, allocator) + return read_entire_file_from_file(f, allocator, loc) } +/* + `read_entire_file_from_file` reads the entire file `f` into memory allocated with `allocator`. + A slice of bytes and an error is returned, if any error is encountered. +*/ @(require_results) -read_entire_file_from_file :: proc(f: ^File, allocator: runtime.Allocator) -> (data: []byte, err: Error) { +read_entire_file_from_file :: proc(f: ^File, allocator: runtime.Allocator, loc := #caller_location) -> (data: []byte, err: Error) { size: int has_size := false if size64, serr := file_size(f); serr == nil { @@ -129,7 +178,7 @@ read_entire_file_from_file :: proc(f: ^File, allocator: runtime.Allocator) -> (d if has_size && size > 0 { total: int - data = make([]byte, size, allocator) or_return + data = make([]byte, size, allocator, loc) or_return for total < len(data) { n: int n, err = read(f, data[total:]) @@ -145,13 +194,13 @@ read_entire_file_from_file :: proc(f: ^File, allocator: runtime.Allocator) -> (d return } else { buffer: [1024]u8 - out_buffer := make([dynamic]u8, 0, 0, allocator) + out_buffer := make([dynamic]u8, 0, 0, allocator, loc) total := 0 for { n: int n, err = read(f, buffer[:]) total += n - append_elems(&out_buffer, ..buffer[:n]) or_return + append_elems(&out_buffer, ..buffer[:n], loc=loc) or_return if err != nil { if err == .EOF || err == .Broken_Pipe { err = nil @@ -163,8 +212,23 @@ read_entire_file_from_file :: proc(f: ^File, allocator: runtime.Allocator) -> (d } } +/* + `write_entire_file` writes the contents of `data` into named file `name`. + It defaults with the permssions `perm := Permissions_Read_All + {.Write_User}`, and `truncate`s by default. + An error is returned if any is encountered. +*/ +write_entire_file :: proc{ + write_entire_file_from_bytes, + write_entire_file_from_string, +} + +/* + `write_entire_file_from_bytes` writes the contents of `data` into named file `name`. + It defaults with the permssions `perm := Permissions_Read_All + {.Write_User}`, and `truncate`s by default. + An error is returned if any is encountered. +*/ @(require_results) -write_entire_file :: proc(name: string, data: []byte, perm: int = 0o644, truncate := true) -> Error { +write_entire_file_from_bytes :: proc(name: string, data: []byte, perm := Permissions_Read_All + {.Write_User}, truncate := true) -> Error { flags := O_WRONLY|O_CREATE if truncate { flags |= O_TRUNC @@ -177,3 +241,14 @@ write_entire_file :: proc(name: string, data: []byte, perm: int = 0o644, truncat return err } + + +/* + `write_entire_file_from_string` writes the contents of `data` into named file `name`. + It defaults with the permssions `perm := Permissions_Read_All + {.Write_User}`, and `truncate`s by default. + An error is returned if any is encountered. +*/ +@(require_results) +write_entire_file_from_string :: proc(name: string, data: string, perm := Permissions_Read_All + {.Write_User}, truncate := true) -> Error { + return write_entire_file(name, transmute([]byte)data, perm, truncate) +} diff --git a/core/os/os2/file_wasi.odin b/core/os/os2/file_wasi.odin index 1d417ffb1..ec464fc52 100644 --- a/core/os/os2/file_wasi.odin +++ b/core/os/os2/file_wasi.odin @@ -51,8 +51,8 @@ init_std_files :: proc "contextless" () { } @(init) -init_preopens :: proc() { - strip_prefixes :: proc(path: string) -> string { +init_preopens :: proc "contextless" () { + strip_prefixes :: proc "contextless" (path: string) -> string { path := path loop: for len(path) > 0 { switch { @@ -69,6 +69,8 @@ init_preopens :: proc() { return path } + context = runtime.default_context() + n: int n_loop: for fd := wasi.fd_t(3); ; fd += 1 { _, err := wasi.fd_prestat_get(fd) @@ -171,7 +173,7 @@ match_preopen :: proc(path: string) -> (wasi.fd_t, string, bool) { return match.fd, relative, true } -_open :: proc(name: string, flags: File_Flags, perm: int) -> (f: ^File, err: Error) { +_open :: proc(name: string, flags: File_Flags, perm: Permissions) -> (f: ^File, err: Error) { dir_fd, relative, ok := match_preopen(name) if !ok { return nil, .Invalid_Path @@ -373,11 +375,11 @@ _fchdir :: proc(f: ^File) -> Error { return .Unsupported } -_fchmod :: proc(f: ^File, mode: int) -> Error { +_fchmod :: proc(f: ^File, mode: Permissions) -> Error { return .Unsupported } -_chmod :: proc(name: string, mode: int) -> Error { +_chmod :: proc(name: string, mode: Permissions) -> Error { return .Unsupported } diff --git a/core/os/os2/file_windows.odin b/core/os/os2/file_windows.odin index b39e65fe2..be5aeb8ab 100644 --- a/core/os/os2/file_windows.odin +++ b/core/os/os2/file_windows.odin @@ -12,7 +12,6 @@ import win32 "core:sys/windows" INVALID_HANDLE :: ~uintptr(0) -S_IWRITE :: 0o200 _ERROR_BAD_NETPATH :: 53 MAX_RW :: 1<<30 @@ -81,7 +80,7 @@ _handle :: proc "contextless" (f: ^File) -> win32.HANDLE { return win32.HANDLE(_fd(f)) } -_open_internal :: proc(name: string, flags: File_Flags, perm: int) -> (handle: uintptr, err: Error) { +_open_internal :: proc(name: string, flags: File_Flags, perm: Permissions) -> (handle: uintptr, err: Error) { if len(name) == 0 { err = .Not_Exist return @@ -122,7 +121,7 @@ _open_internal :: proc(name: string, flags: File_Flags, perm: int) -> (handle: u } attrs: u32 = win32.FILE_ATTRIBUTE_NORMAL|win32.FILE_FLAG_BACKUP_SEMANTICS - if perm & S_IWRITE == 0 { + if .Write_User not_in perm { attrs = win32.FILE_ATTRIBUTE_READONLY if create_mode == win32.CREATE_ALWAYS { // NOTE(bill): Open has just asked to create a file in read-only mode. @@ -150,7 +149,7 @@ _open_internal :: proc(name: string, flags: File_Flags, perm: int) -> (handle: u } -_open :: proc(name: string, flags: File_Flags, perm: int) -> (f: ^File, err: Error) { +_open :: proc(name: string, flags: File_Flags, perm: Permissions) -> (f: ^File, err: Error) { flags := flags if flags != nil else {.Read} handle := _open_internal(name, flags, perm) or_return return _new_file(handle, name, file_allocator()) @@ -193,7 +192,7 @@ _new_file :: proc(handle: uintptr, name: string, allocator: runtime.Allocator) - @(require_results) -_open_buffered :: proc(name: string, buffer_size: uint, flags := File_Flags{.Read}, perm := 0o777) -> (f: ^File, err: Error) { +_open_buffered :: proc(name: string, buffer_size: uint, flags := File_Flags{.Read}, perm: Permissions) -> (f: ^File, err: Error) { assert(buffer_size > 0) flags := flags if flags != nil else {.Read} handle := _open_internal(name, flags, perm) or_return @@ -744,7 +743,7 @@ _fchdir :: proc(f: ^File) -> Error { return nil } -_fchmod :: proc(f: ^File, mode: int) -> Error { +_fchmod :: proc(f: ^File, mode: Permissions) -> Error { if f == nil || f.impl == nil { return nil } @@ -753,7 +752,7 @@ _fchmod :: proc(f: ^File, mode: int) -> Error { return _get_platform_error() } attrs := d.dwFileAttributes - if mode & S_IWRITE != 0 { + if .Write_User in mode { attrs &~= win32.FILE_ATTRIBUTE_READONLY } else { attrs |= win32.FILE_ATTRIBUTE_READONLY @@ -780,7 +779,7 @@ _chdir :: proc(name: string) -> Error { return nil } -_chmod :: proc(name: string, mode: int) -> Error { +_chmod :: proc(name: string, mode: Permissions) -> Error { f := open(name, {.Write}) or_return defer close(f) return _fchmod(f, mode) diff --git a/core/os/os2/heap.odin b/core/os/os2/heap.odin index 8f9c7680a..b1db54dc7 100644 --- a/core/os/os2/heap.odin +++ b/core/os/os2/heap.odin @@ -2,6 +2,9 @@ package os2 import "base:runtime" +/* + Returns the default `heap_allocator` for this specific platform. +*/ @(require_results) heap_allocator :: proc() -> runtime.Allocator { return runtime.Allocator{ diff --git a/core/os/os2/path_wasi.odin b/core/os/os2/path_wasi.odin index b8240e188..f26e16158 100644 --- a/core/os/os2/path_wasi.odin +++ b/core/os/os2/path_wasi.odin @@ -34,7 +34,7 @@ _mkdir_all :: proc(path: string, perm: int) -> Error { return .Exist } - clean_path := clean_path(path, temp_allocator) + clean_path := clean_path(path, temp_allocator) or_return return internal_mkdir_all(clean_path) internal_mkdir_all :: proc(path: string) -> Error { @@ -114,3 +114,7 @@ _get_executable_path :: proc(allocator: runtime.Allocator) -> (path: string, err return concatenate({"/", arg}, allocator) } + +_get_absolute_path :: proc(path: string, allocator: runtime.Allocator) -> (absolute_path: string, err: Error) { + return "", .Unsupported +} diff --git a/core/os/os2/process.odin b/core/os/os2/process.odin index 635befc64..def561e28 100644 --- a/core/os/os2/process.odin +++ b/core/os/os2/process.odin @@ -35,7 +35,7 @@ delete_args :: proc "contextless" () { Exit the current process. */ exit :: proc "contextless" (code: int) -> ! { - _exit(code) + runtime.exit(code) } /* diff --git a/core/os/os2/process_linux.odin b/core/os/os2/process_linux.odin index 170f0ea1a..197693dc3 100644 --- a/core/os/os2/process_linux.odin +++ b/core/os/os2/process_linux.odin @@ -13,11 +13,6 @@ import "core:sys/linux" PIDFD_UNASSIGNED :: ~uintptr(0) -@(private="package") -_exit :: proc "contextless" (code: int) -> ! { - linux.exit_group(i32(code)) -} - @(private="package") _get_uid :: proc() -> int { return int(linux.getuid()) @@ -427,7 +422,8 @@ _process_start :: proc(desc: Process_Desc) -> (process: Process, err: Error) { strings.write_string(&exe_builder, executable_name) exe_path = strings.to_cstring(&exe_builder) or_return - if linux.access(exe_path, linux.X_OK) == .NONE { + stat := linux.Stat{} + if linux.stat(exe_path, &stat) == .NONE && .IFREG in stat.mode && .IXUSR in stat.mode { found = true break } diff --git a/core/os/os2/process_posix.odin b/core/os/os2/process_posix.odin index fcacdf654..a48e44900 100644 --- a/core/os/os2/process_posix.odin +++ b/core/os/os2/process_posix.odin @@ -10,10 +10,6 @@ import "core:strings" import kq "core:sys/kqueue" import "core:sys/posix" -_exit :: proc "contextless" (code: int) -> ! { - posix.exit(i32(code)) -} - _get_uid :: proc() -> int { return int(posix.getuid()) } diff --git a/core/os/os2/process_wasi.odin b/core/os/os2/process_wasi.odin index 9f4d61649..52fdb1680 100644 --- a/core/os/os2/process_wasi.odin +++ b/core/os/os2/process_wasi.odin @@ -4,11 +4,7 @@ package os2 import "base:runtime" import "core:time" -import "core:sys/wasm/wasi" - -_exit :: proc "contextless" (code: int) -> ! { - wasi.proc_exit(wasi.exitcode_t(code)) -} +// import "core:sys/wasm/wasi" _get_uid :: proc() -> int { return 0 diff --git a/core/os/os2/process_windows.odin b/core/os/os2/process_windows.odin index 990da6616..05ac9da93 100644 --- a/core/os/os2/process_windows.odin +++ b/core/os/os2/process_windows.odin @@ -7,11 +7,6 @@ import "core:strings" import win32 "core:sys/windows" import "core:time" -@(private="package") -_exit :: proc "contextless" (code: int) -> ! { - win32.ExitProcess(u32(code)) -} - @(private="package") _get_uid :: proc() -> int { return -1 diff --git a/core/os/os2/stat.odin b/core/os/os2/stat.odin index d6b524684..f87afc4c9 100644 --- a/core/os/os2/stat.odin +++ b/core/os/os2/stat.odin @@ -6,13 +6,16 @@ import "core:time" Fstat_Callback :: proc(f: ^File, allocator: runtime.Allocator) -> (File_Info, Error) +/* + `File_Info` describes a file and is returned from `stat`, `fstat`, and `lstat`. +*/ File_Info :: struct { - fullpath: string, - name: string, + fullpath: string, // fullpath of the file + name: string, // base name of the file - inode: u128, // might be zero if cannot be determined - size: i64 `fmt:"M"`, - mode: int `fmt:"o"`, + inode: u128, // might be zero if cannot be determined + size: i64 `fmt:"M"`, // length in bytes for regular files; system-dependent for other file types + mode: Permissions, // file permission flags type: File_Type, creation_time: time.Time, @@ -49,6 +52,10 @@ fstat :: proc(f: ^File, allocator: runtime.Allocator) -> (File_Info, Error) { return {}, .Invalid_Callback } +/* + `stat` returns a `File_Info` describing the named file from the file system. + The resulting `File_Info` must be deleted with `file_info_delete`. +*/ @(require_results) stat :: proc(name: string, allocator: runtime.Allocator) -> (File_Info, Error) { return _stat(name, allocator) @@ -56,12 +63,21 @@ stat :: proc(name: string, allocator: runtime.Allocator) -> (File_Info, Error) { lstat :: stat_do_not_follow_links +/* + Returns a `File_Info` describing the named file from the file system. + If the file is a symbolic link, the `File_Info` returns describes the symbolic link, + rather than following the link. + The resulting `File_Info` must be deleted with `file_info_delete`. +*/ @(require_results) stat_do_not_follow_links :: proc(name: string, allocator: runtime.Allocator) -> (File_Info, Error) { return _lstat(name, allocator) } +/* + Returns true if two `File_Info`s are equivalent. +*/ @(require_results) same_file :: proc(fi1, fi2: File_Info) -> bool { return _same_file(fi1, fi2) @@ -71,6 +87,10 @@ same_file :: proc(fi1, fi2: File_Info) -> bool { last_write_time :: modification_time last_write_time_by_name :: modification_time_by_path +/* + Returns the modification time of the file `f`. + The resolution of the timestamp is system-dependent. +*/ @(require_results) modification_time :: proc(f: ^File) -> (time.Time, Error) { temp_allocator := TEMP_ALLOCATOR_GUARD({}) @@ -78,6 +98,10 @@ modification_time :: proc(f: ^File) -> (time.Time, Error) { return fi.modification_time, err } +/* + Returns the modification time of the named file `path`. + The resolution of the timestamp is system-dependent. +*/ @(require_results) modification_time_by_path :: proc(path: string) -> (time.Time, Error) { temp_allocator := TEMP_ALLOCATOR_GUARD({}) diff --git a/core/os/os2/stat_linux.odin b/core/os/os2/stat_linux.odin index 373765be5..6185252cf 100644 --- a/core/os/os2/stat_linux.odin +++ b/core/os/os2/stat_linux.odin @@ -26,7 +26,7 @@ _fstat_internal :: proc(fd: linux.Fd, allocator: runtime.Allocator) -> (fi: File case linux.S_IFREG: type = .Regular case linux.S_IFSOCK: type = .Socket } - mode := int(0o7777 & transmute(u32)s.mode) + mode := transmute(Permissions)(0o7777 & transmute(u32)s.mode) // TODO: As of Linux 4.11, the new statx syscall can retrieve creation_time fi = File_Info { diff --git a/core/os/os2/stat_posix.odin b/core/os/os2/stat_posix.odin index 6ffbdf1da..4ed96b389 100644 --- a/core/os/os2/stat_posix.odin +++ b/core/os/os2/stat_posix.odin @@ -14,7 +14,7 @@ internal_stat :: proc(stat: posix.stat_t, fullpath: string) -> (fi: File_Info) { fi.inode = u128(stat.st_ino) fi.size = i64(stat.st_size) - fi.mode = int(transmute(posix._mode_t)(stat.st_mode - posix.S_IFMT)) + fi.mode = transmute(Permissions)u32(transmute(posix._mode_t)(stat.st_mode - posix.S_IFMT)) fi.type = .Undetermined switch { diff --git a/core/os/os2/stat_windows.odin b/core/os/os2/stat_windows.odin index 3dee42be6..20a708145 100644 --- a/core/os/os2/stat_windows.odin +++ b/core/os/os2/stat_windows.odin @@ -211,11 +211,11 @@ _file_type_from_create_file :: proc(wname: win32.wstring, create_file_attributes return file_type(h) } -_file_type_mode_from_file_attributes :: proc(file_attributes: win32.DWORD, h: win32.HANDLE, ReparseTag: win32.DWORD) -> (type: File_Type, mode: int) { +_file_type_mode_from_file_attributes :: proc(file_attributes: win32.DWORD, h: win32.HANDLE, ReparseTag: win32.DWORD) -> (type: File_Type, mode: Permissions) { if file_attributes & win32.FILE_ATTRIBUTE_READONLY != 0 { - mode |= 0o444 + mode += Permissions_Write_All } else { - mode |= 0o666 + mode += Permissions_Read_Write_All } is_sym := false @@ -229,7 +229,7 @@ _file_type_mode_from_file_attributes :: proc(file_attributes: win32.DWORD, h: wi type = .Symlink } else if file_attributes & win32.FILE_ATTRIBUTE_DIRECTORY != 0 { type = .Directory - mode |= 0o111 + mode += Permissions_Execute_All } else if h != nil { type = file_type(h) } diff --git a/core/os/os2/temp_file.odin b/core/os/os2/temp_file.odin index e3e74bd11..f0bc3788e 100644 --- a/core/os/os2/temp_file.odin +++ b/core/os/os2/temp_file.odin @@ -7,7 +7,7 @@ MAX_ATTEMPTS :: 1<<13 // Should be enough for everyone, right? // Creates a new temperatory file in the directory `dir`. // -// Opens the file for reading and writing, with 0o666 permissions, and returns the new `^File`. +// Opens the file for reading and writing, with `Permissions_Read_Write_All` permissions, and returns the new `^File`. // The filename is generated by taking a pattern, and adding a randomized string to the end. // If the pattern includes an "*", the random string replaces the last "*". // If `dir` is an empty string, `temp_directory()` will be used. @@ -26,7 +26,7 @@ create_temp_file :: proc(dir, pattern: string) -> (f: ^File, err: Error) { attempts := 0 for { name := concatenate_strings_from_buffer(name_buf[:], prefix, random_string(rand_buf[:]), suffix) - f, err = open(name, {.Read, .Write, .Create, .Excl}, 0o666) + f, err = open(name, {.Read, .Write, .Create, .Excl}, Permissions_Read_Write_All) if err == .Exist { close(f) attempts += 1 @@ -80,6 +80,19 @@ make_directory_temp :: proc(dir, pattern: string, allocator: runtime.Allocator) } temp_dir :: temp_directory + +/* + Returns the default directory to use for temporary files. + + On Unix systems, it typically returns $TMPDIR if non-empty, otherwlse `/tmp`. + On Windows, it uses `GetTempPathW`, returning the first non-empty value from one of the following: + * `%TMP%` + * `%TEMP%` + * `%USERPROFILE %` + * or the Windows directory + See https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppathw for more information. + On wasi, it returns `/tmp`. +*/ @(require_results) temp_directory :: proc(allocator: runtime.Allocator) -> (string, Error) { return _temp_dir(allocator) diff --git a/core/os/os2/user_posix.odin b/core/os/os2/user_posix.odin index 691745b7a..09134d847 100644 --- a/core/os/os2/user_posix.odin +++ b/core/os/os2/user_posix.odin @@ -2,7 +2,6 @@ package os2 import "base:runtime" -import "core:encoding/ini" import "core:strings" _user_cache_dir :: proc(allocator: runtime.Allocator) -> (dir: string, err: Error) { @@ -157,18 +156,19 @@ _xdg_user_dirs_lookup :: proc(xdg_key: string, allocator: runtime.Allocator) -> user_dirs_path := concatenate({config_dir, "/user-dirs.dirs"}, temp_allocator) or_return content := read_entire_file(user_dirs_path, temp_allocator) or_return - it := ini.Iterator{ - section = "", - _src = string(content), - options = ini.Options{ - comment = "#", - key_lower_case = false, - }, - } + xdg_dirs := string(content) + for line in strings.split_lines_iterator(&xdg_dirs) { + if len(line) > 0 && line[0] == '#' { + continue + } - for k, v in ini.iterate(&it) { - if k == xdg_key { - return replace_environment_placeholders(v, allocator), nil + equals := strings.index(line, "=") + if equals > -1 { + if line[:equals] == xdg_key { + // Unquote to return a bare path string as we do on Windows + val := strings.trim(line[equals+1:], "\"") + return replace_environment_placeholders(val, allocator), nil + } } } return diff --git a/core/simd/simd.odin b/core/simd/simd.odin index bca661757..f065a3cec 100644 --- a/core/simd/simd.odin +++ b/core/simd/simd.odin @@ -2690,7 +2690,7 @@ Example: +------+------+------+------+ */ bit_not :: #force_inline proc "contextless" (v: $T/#simd[$LANES]$E) -> T where intrinsics.type_is_integer(E) { - return xor(v, T(~E(0))) + return bit_xor(v, T(~E(0))) } /* diff --git a/core/slice/heap/heap.odin b/core/slice/heap/heap.odin index dd088f250..de6dfb43b 100644 --- a/core/slice/heap/heap.odin +++ b/core/slice/heap/heap.odin @@ -3,7 +3,7 @@ package heap /* Copyright 2022 Dale Weiler . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Dale Weiler: Initial implementation diff --git a/core/strings/strings.odin b/core/strings/strings.odin index d13b45022..beaa8bda1 100644 --- a/core/strings/strings.odin +++ b/core/strings/strings.odin @@ -2932,7 +2932,6 @@ Output: abc1 abc2 abc3 */ - expand_tabs :: proc(s: string, tab_size: int, allocator := context.allocator) -> (res: string, err: mem.Allocator_Error) #optional_allocator_error { if tab_size <= 0 { panic("tab size must be positive") diff --git a/core/sys/darwin/Foundation/NSApplication.odin b/core/sys/darwin/Foundation/NSApplication.odin index a5e9f2e24..6cb3df979 100644 --- a/core/sys/darwin/Foundation/NSApplication.odin +++ b/core/sys/darwin/Foundation/NSApplication.odin @@ -132,6 +132,11 @@ Application_finishLaunching :: proc "c" (self: ^Application) { msgSend(nil, self, "finishLaunching") } +@(objc_type=Application, objc_name="stop") +Application_stop :: proc "c" (self: ^Application, sender: ^Object) { + msgSend(nil, self, "stop:", sender) +} + @(objc_type=Application, objc_name="terminate") Application_terminate :: proc "c" (self: ^Application, sender: ^Object) { msgSend(nil, self, "terminate:", sender) @@ -156,6 +161,12 @@ Application_nextEventMatchingMask :: proc "c" (self: ^Application, mask: EventMa Application_sendEvent :: proc "c" (self: ^Application, event: ^Event) { msgSend(nil, self, "sendEvent:", event) } + +@(objc_type=Application, objc_name="postEvent") +Application_postEvent :: proc "c" (self: ^Application, event: ^Event, atStart: BOOL) { + msgSend(nil, self, "postEvent:atStart:", event, atStart) +} + @(objc_type=Application, objc_name="updateWindows") Application_updateWindows :: proc "c" (self: ^Application) { msgSend(nil, self, "updateWindows") @@ -175,6 +186,11 @@ RunningApplication_localizedName :: proc "c" (self: ^RunningApplication) -> ^Str return msgSend(^String, self, "localizedName") } +@(objc_type=RunningApplication, objc_name="finishedLaunching") +RunningApplication_finishedLaunching :: proc "c" (self: ^RunningApplication) -> BOOL { + return msgSend(BOOL, self, "isFinishedLaunching") +} + ApplicationDelegateTemplate :: struct { // Launching Applications applicationWillFinishLaunching: proc(notification: ^Notification), diff --git a/core/sys/darwin/Foundation/NSEvent.odin b/core/sys/darwin/Foundation/NSEvent.odin index 548c5c172..3bd0c1879 100644 --- a/core/sys/darwin/Foundation/NSEvent.odin +++ b/core/sys/darwin/Foundation/NSEvent.odin @@ -250,6 +250,35 @@ kVK :: enum { ISO_Section = 0x0A, } +/* class methods for creating events */ + +@(objc_type=Event, objc_name="otherEventWithType", objc_is_class_method=true) +Event_otherEventWithType :: proc "c" ( + type: EventType, + location: Point, + flags: EventModifierFlags, + time: TimeInterval, + window_number: Integer, + ctx: id, + subtype: i16, + data1: Integer, + data2: Integer, +) -> ^Event { + return msgSend( + ^Event, + Event, + "otherEventWithType:location:modifierFlags:timestamp:windowNumber:context:subtype:data1:data2:", + type, + location, + flags, + time, + window_number, + ctx, + subtype, + data1, + data2, + ) +} /* these messages are valid for all events */ diff --git a/core/sys/darwin/Foundation/NSWindow.odin b/core/sys/darwin/Foundation/NSWindow.odin index e1b027a89..e5bc10074 100644 --- a/core/sys/darwin/Foundation/NSWindow.odin +++ b/core/sys/darwin/Foundation/NSWindow.odin @@ -56,6 +56,60 @@ BackingStoreType :: enum UInteger { Buffered = 2, } +WindowCollectionBehaviorFlag :: enum UInteger { + CanJoinAllSpaces = 0, + MoveToActiveSpace = 1, + Managed = 2, + Transient = 3, + Stationary = 4, + ParticipatesInCycle = 5, + IgnoresCycle = 6, + FullScreenPrimary = 7, + FullScreenAuxiliary = 8, + FullScreenNone = 9, + FullScreenAllowsTiling = 11, + FullScreenDisallowsTiling = 12, + Primary = 16, + Auxiliary = 17, + CanJoinAllApplications = 18, +} +WindowCollectionBehavior :: distinct bit_set[WindowCollectionBehaviorFlag; UInteger] +WindowCollectionBehaviorDefault :: WindowCollectionBehavior{} +WindowCollectionBehaviorPrimary :: WindowCollectionBehavior{.Primary, .FullScreenAuxiliary} +WindowCollectionBehaviorAuxiliary :: WindowCollectionBehavior{.Auxiliary, .FullScreenNone} +WindowCollectionBehaviorCanJoinAllApplications :: WindowCollectionBehavior{.CanJoinAllApplications} +WindowCollectionBehaviorCanJoinAllSpaces :: WindowCollectionBehavior{.CanJoinAllSpaces} +WindowCollectionBehaviorMoveToActiveSpace :: WindowCollectionBehavior{.MoveToActiveSpace} +WindowCollectionBehaviorStationary :: WindowCollectionBehavior{.Stationary} +WindowCollectionBehaviorManaged :: WindowCollectionBehavior{.Managed} +WindowCollectionBehaviorTransient :: WindowCollectionBehavior{.Transient} +WindowCollectionBehaviorFullScreenPrimary :: WindowCollectionBehavior{.FullScreenPrimary} +WindowCollectionBehaviorFullScreenAuxiliary :: WindowCollectionBehavior{.FullScreenAuxiliary} +WindowCollectionBehaviorFullScreenNone :: WindowCollectionBehavior{.FullScreenNone} +WindowCollectionBehaviorFullScreenAllowsTiling :: WindowCollectionBehavior{.FullScreenAllowsTiling} +WindowCollectionBehaviorFullScreenDisallowsTiling :: WindowCollectionBehavior{.FullScreenDisallowsTiling} +WindowCollectionBehaviorParticipatesInCycle :: WindowCollectionBehavior{.ParticipatesInCycle} +WindowCollectionBehaviorIgnoresCycle :: WindowCollectionBehavior{.IgnoresCycle} + +WindowLevel :: enum Integer { + Normal = 0, + Floating = 3, + Submenu = 3, + TornOffMenu = 3, + ModalPanel = 8, + MainMenu = 24, + Status = 25, + PopUpMenu = 101, + ScreenSaver = 1000, +} + +WindowTabbingMode :: enum Integer { + Automatic = 0, + Preferred = 1, + Disallowed = 2, +} + + WindowDelegateTemplate :: struct { // Managing Sheets windowWillPositionSheetUsingRect: proc(window: ^Window, sheet: ^Window, rect: Rect) -> Rect, @@ -600,6 +654,10 @@ Responder :: struct {using _: Object} @(objc_class="NSView") View :: struct {using _: Responder} +@(objc_type=View, objc_name="alloc", objc_is_class_method=true) +View_alloc :: proc "c" () -> ^View { + return msgSend(^View, View, "alloc") +} @(objc_type=View, objc_name="initWithFrame") View_initWithFrame :: proc "c" (self: ^View, frame: Rect) -> ^View { @@ -670,6 +728,10 @@ Window_setFrame :: proc "c" (self: ^Window, frame: Rect, display: BOOL) { Window_setFrameOrigin :: proc "c" (self: ^Window, origin: Point) { msgSend(nil, self, "setFrameOrigin:", origin) } +@(objc_type=Window, objc_name="center") +Window_center :: proc "c" (self: ^Window) { + msgSend(nil, self, "center") +} @(objc_type=Window, objc_name="opaque") Window_opaque :: proc "c" (self: ^Window) -> BOOL { return msgSend(BOOL, self, "opaque") @@ -686,6 +748,14 @@ Window_backgroundColor :: proc "c" (self: ^Window) -> ^Color { Window_setBackgroundColor :: proc "c" (self: ^Window, color: ^Color) { msgSend(nil, self, "setBackgroundColor:", color) } +@(objc_type = Window, objc_name = "orderFront") +Window_orderFront :: proc "c" (self: ^Window, sender: id) { + msgSend(nil, self, "orderFront:", sender) +} +@(objc_type = Window, objc_name = "orderOut") +Window_orderOut :: proc "c" (self: ^Window, sender: id) { + msgSend(nil, self, "orderOut:", sender) +} @(objc_type=Window, objc_name="makeKeyAndOrderFront") Window_makeKeyAndOrderFront :: proc "c" (self: ^Window, key: ^Object) { msgSend(nil, self, "makeKeyAndOrderFront:", key) @@ -722,6 +792,10 @@ Window_close :: proc "c" (self: ^Window) { Window_setDelegate :: proc "c" (self: ^Window, delegate: ^WindowDelegate) { msgSend(nil, self, "setDelegate:", delegate) } +@(objc_type = Window, objc_name = "delegate") +Window_delegate :: proc "c" (self: ^Window) -> ^WindowDelegate { + return msgSend(^WindowDelegate, self, "delegate") +} @(objc_type=Window, objc_name="backingScaleFactor") Window_backingScaleFactor :: proc "c" (self: ^Window) -> Float { return msgSend(Float, self, "backingScaleFactor") @@ -798,3 +872,35 @@ Window_performWindowDragWithEvent :: proc "c" (self: ^Window, event: ^Event) { Window_setToolbar :: proc "c" (self: ^Window, toolbar: ^Toolbar) { msgSend(nil, self, "setToolbar:", toolbar) } +@(objc_type = Window, objc_name = "setCollectionBehavior") +Window_setCollectionBehavior :: proc "c" (self: ^Window, behavior: WindowCollectionBehavior) { + msgSend(nil, self, "setCollectionBehavior:", behavior) +} +@(objc_type = Window, objc_name = "collectionBehavior") +Window_collectionBehavior :: proc "c" (self: ^Window) -> WindowCollectionBehavior { + return msgSend(WindowCollectionBehavior, self, "collectionBehavior") +} +@(objc_type = Window, objc_name = "setLevel") +Window_setLevel :: proc "c" (self: ^Window, level: WindowLevel) { + msgSend(nil, self, "setLevel:", level) +} +@(objc_type = Window, objc_name = "setReleasedWhenClosed") +Window_setReleasedWhenClosed :: proc "c" (self: ^Window, flag: BOOL) { + msgSend(nil, self, "setReleasedWhenClosed:", flag) +} +@(objc_type = Window, objc_name = "makeFirstResponder") +Window_makeFirstResponder :: proc "c" (self: ^Window, responder: ^Responder) -> BOOL { + return msgSend(BOOL, self, "makeFirstResponder:", responder) +} +@(objc_type = Window, objc_name = "setRestorable") +Window_setRestorable :: proc "c" (self: ^Window, flag: BOOL) { + msgSend(nil, self, "setRestorable:", flag) +} +@(objc_type = Window, objc_name = "setTabbingMode") +Window_setTabbingMode :: proc "c" (self: ^Window, mode: WindowTabbingMode) { + msgSend(nil, self, "setTabbingMode:", mode) +} +@(objc_type = Window, objc_name = "toggleFullScreen") +Window_toggleFullScreen :: proc "c" (self: ^Window, sender: id) { + msgSend(nil, self, "toggleFullScreen:", sender) +} diff --git a/core/sys/freebsd/syscalls.odin b/core/sys/freebsd/syscalls.odin index 96fd9ac3f..452914eea 100644 --- a/core/sys/freebsd/syscalls.odin +++ b/core/sys/freebsd/syscalls.odin @@ -2,7 +2,7 @@ package sys_freebsd /* (c) Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Feoramund: Initial implementation. diff --git a/core/sys/freebsd/types.odin b/core/sys/freebsd/types.odin index 37e8abf68..c6b13ef91 100644 --- a/core/sys/freebsd/types.odin +++ b/core/sys/freebsd/types.odin @@ -2,7 +2,7 @@ package sys_freebsd /* (c) Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Feoramund: Initial implementation. diff --git a/core/sys/info/doc.odin b/core/sys/info/doc.odin index 7859b4e60..10ad7a127 100644 --- a/core/sys/info/doc.odin +++ b/core/sys/info/doc.odin @@ -81,7 +81,7 @@ package sysinfo /* Copyright 2022 Jeroen van Rijn . -Made available under Odin's BSD-3 license. +Made available under Odin's license. List of contributors: Jeroen van Rijn: Initial implementation. diff --git a/core/sys/linux/types.odin b/core/sys/linux/types.odin index c2948c36e..38b413cdd 100644 --- a/core/sys/linux/types.odin +++ b/core/sys/linux/types.odin @@ -1446,9 +1446,25 @@ EPoll_Data :: struct #raw_union { u64: u64, } -EPoll_Event :: struct #packed { - events: EPoll_Event_Set, - data: EPoll_Data, +/* + Linux kernel only packs this struct on x86_64. + include/uapi/linux/eventpoll.h: + #ifdef __x86_64__ + #define EPOLL_PACKED __attribute__((packed)) + #else + #define EPOLL_PACKED + #endif +*/ +when ODIN_ARCH == .amd64 { + EPoll_Event :: struct #packed { + events: EPoll_Event_Set, + data: EPoll_Data, + } +} else { + EPoll_Event :: struct { + events: EPoll_Event_Set, + data: EPoll_Data, + } } /* diff --git a/core/sys/wasm/js/odin.js b/core/sys/wasm/js/odin.js index f4f73a42a..43a6b002a 100644 --- a/core/sys/wasm/js/odin.js +++ b/core/sys/wasm/js/odin.js @@ -2112,7 +2112,9 @@ async function runWasm(wasmPath, consoleElement, extraForeignImports, wasmMemory wasmMemoryInterface.setMemory(exports.memory); } - exports._start(); + if (exports._start) { + exports._start(); + } // Define a `@export step :: proc(delta_time: f64) -> (keep_going: bool) {` // in your app and it will get called every frame. @@ -2130,7 +2132,9 @@ async function runWasm(wasmPath, consoleElement, extraForeignImports, wasmMemory prevTimeStamp = currTimeStamp; if (!exports.step(dt, odin_ctx)) { - exports._end(); + if (exports._end) { + exports._end(); + } return; } @@ -2139,7 +2143,9 @@ async function runWasm(wasmPath, consoleElement, extraForeignImports, wasmMemory window.requestAnimationFrame(step); } else { - exports._end(); + if (exports._end) { + exports._end(); + } } return; diff --git a/core/testing/events.odin b/core/testing/events.odin index 1a47e2d68..1d07e8c5b 100644 --- a/core/testing/events.odin +++ b/core/testing/events.odin @@ -3,7 +3,7 @@ package testing /* (c) Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Feoramund: Total rewrite. diff --git a/core/testing/logging.odin b/core/testing/logging.odin index 041489dab..3138a745b 100644 --- a/core/testing/logging.odin +++ b/core/testing/logging.odin @@ -3,7 +3,7 @@ package testing /* (c) Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Ginger Bill: Initial implementation. @@ -83,7 +83,31 @@ format_log_text :: proc(level: runtime.Logger_Level, text: string, options: runt log.do_level_header(options, &buf, level) log.do_time_header(options, &buf, at_time) - log.do_location_header(options, &buf, location) - + when GO_TO_ERROR { + do_go_to_error_friendly_location(options, &buf, location) + } else { + log.do_location_header(options, &buf, location) + } return fmt.aprintf("%s%s", strings.to_string(buf), text, allocator = allocator) } + +do_go_to_error_friendly_location :: proc(opts: log.Options, buf: ^strings.Builder, location := #caller_location) { + if log.Location_Header_Opts & opts == nil { + return + } + fmt.sbprint(buf, "\n") + + file := location.file_path + fmt.sbprint(buf, file) + + fmt.sbprint(buf, "(") + fmt.sbprint(buf, location.line) + fmt.sbprint(buf, ":") + fmt.sbprint(buf, location.column) + fmt.sbprint(buf, ")") + + if .Procedure in opts { + fmt.sbprintf(buf, ":%s()", location.procedure) + } + fmt.sbprint(buf, " ") +} \ No newline at end of file diff --git a/core/testing/reporting.odin b/core/testing/reporting.odin index 7c7eb7b2d..e72be3a04 100644 --- a/core/testing/reporting.odin +++ b/core/testing/reporting.odin @@ -3,7 +3,7 @@ package testing /* (c) Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Feoramund: Total rewrite. diff --git a/core/testing/runner.odin b/core/testing/runner.odin index b53bd8722..9ce4f35cb 100644 --- a/core/testing/runner.odin +++ b/core/testing/runner.odin @@ -3,7 +3,7 @@ package testing /* (c) Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Ginger Bill: Initial implementation. @@ -63,6 +63,9 @@ LOG_STATE_CHANGES : bool : #config(ODIN_TEST_LOG_STATE_CHANGES, false) USING_SHORT_LOGS : bool : #config(ODIN_TEST_SHORT_LOGS, false) // Output a report of the tests to the given path. JSON_REPORT : string : #config(ODIN_TEST_JSON_REPORT, "") +// Print the full file path for failed test cases on a new line +// in a way that's friendly to regex capture for an editor's "go to error". +GO_TO_ERROR : bool : #config(ODIN_TEST_GO_TO_ERROR, false) get_log_level :: #force_inline proc() -> runtime.Logger_Level { when LOG_LEVEL == "debug" { return .Debug } else @@ -803,7 +806,7 @@ runner :: proc(internal_tests: []Internal_Test) -> bool { } } else { if total_done_count != last_done_count { - if !global_ansi_disabled { + if !(global_ansi_disabled || !FANCY_OUTPUT) { fmt.wprintf(stdout, OSC_WINDOW_TITLE, total_done_count, total_test_count) } last_done_count = total_done_count diff --git a/core/testing/signal_handler.odin b/core/testing/signal_handler.odin index 73ed362f0..b33732a30 100644 --- a/core/testing/signal_handler.odin +++ b/core/testing/signal_handler.odin @@ -3,7 +3,7 @@ package testing /* (c) Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Feoramund: Total rewrite. diff --git a/core/testing/signal_handler_libc.odin b/core/testing/signal_handler_libc.odin index 961f5c7ce..a1441f29d 100644 --- a/core/testing/signal_handler_libc.odin +++ b/core/testing/signal_handler_libc.odin @@ -4,7 +4,7 @@ package testing /* (c) Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Feoramund: Total rewrite. diff --git a/core/testing/signal_handler_other.odin b/core/testing/signal_handler_other.odin index 81f575495..b0d5f00fb 100644 --- a/core/testing/signal_handler_other.odin +++ b/core/testing/signal_handler_other.odin @@ -10,7 +10,7 @@ package testing /* (c) Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Feoramund: Total rewrite. diff --git a/core/testing/testing.odin b/core/testing/testing.odin index a0b046a46..d6bf6ea33 100644 --- a/core/testing/testing.odin +++ b/core/testing/testing.odin @@ -3,7 +3,7 @@ package testing /* (c) Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Ginger Bill: Initial implementation. diff --git a/core/text/i18n/gettext.odin b/core/text/i18n/gettext.odin index 3ac9109ef..a29fdc003 100644 --- a/core/text/i18n/gettext.odin +++ b/core/text/i18n/gettext.odin @@ -3,7 +3,7 @@ package i18n A parser for GNU GetText .MO files. Copyright 2021-2022 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under Odin's license. A from-scratch implementation based after the specification found here: https://www.gnu.org/software/gettext/manual/html_node/MO-Files.html diff --git a/core/text/i18n/i18n.odin b/core/text/i18n/i18n.odin index 0190ef0f7..b978bffc4 100644 --- a/core/text/i18n/i18n.odin +++ b/core/text/i18n/i18n.odin @@ -3,7 +3,7 @@ package i18n Internationalization helpers. Copyright 2021-2022 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Jeroen van Rijn: Initial implementation. diff --git a/core/text/i18n/qt_linguist.odin b/core/text/i18n/qt_linguist.odin index bdd3f5fd7..2fc5efe7b 100644 --- a/core/text/i18n/qt_linguist.odin +++ b/core/text/i18n/qt_linguist.odin @@ -3,7 +3,7 @@ package i18n A parser for Qt Linguist TS files. Copyright 2022 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under Odin's license. A from-scratch implementation based after the specification found here: https://doc.qt.io/qt-5/linguist-ts-file-format.html diff --git a/core/text/regex/common/common.odin b/core/text/regex/common/common.odin index 0abd48e4b..24b44833f 100644 --- a/core/text/regex/common/common.odin +++ b/core/text/regex/common/common.odin @@ -3,7 +3,7 @@ package regex_common /* (c) Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Feoramund: Initial implementation. diff --git a/core/text/regex/common/debugging.odin b/core/text/regex/common/debugging.odin index 0e4161a92..1a241e136 100644 --- a/core/text/regex/common/debugging.odin +++ b/core/text/regex/common/debugging.odin @@ -2,7 +2,7 @@ package regex_common /* (c) Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Feoramund: Initial implementation. diff --git a/core/text/regex/compiler/compiler.odin b/core/text/regex/compiler/compiler.odin index 2f0f183e9..dbfe3fe1c 100644 --- a/core/text/regex/compiler/compiler.odin +++ b/core/text/regex/compiler/compiler.odin @@ -2,7 +2,7 @@ package regex_compiler /* (c) Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Feoramund: Initial implementation. diff --git a/core/text/regex/compiler/debugging.odin b/core/text/regex/compiler/debugging.odin index 142cb8839..864049451 100644 --- a/core/text/regex/compiler/debugging.odin +++ b/core/text/regex/compiler/debugging.odin @@ -2,7 +2,7 @@ package regex_compiler /* (c) Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Feoramund: Initial implementation. diff --git a/core/text/regex/optimizer/optimizer.odin b/core/text/regex/optimizer/optimizer.odin index e23cc1bc5..93d7e6eef 100644 --- a/core/text/regex/optimizer/optimizer.odin +++ b/core/text/regex/optimizer/optimizer.odin @@ -2,7 +2,7 @@ package regex_optimizer /* (c) Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Feoramund: Initial implementation. diff --git a/core/text/regex/parser/debugging.odin b/core/text/regex/parser/debugging.odin index e060f58c2..f910db796 100644 --- a/core/text/regex/parser/debugging.odin +++ b/core/text/regex/parser/debugging.odin @@ -2,7 +2,7 @@ package regex_parser /* (c) Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Feoramund: Initial implementation. diff --git a/core/text/regex/parser/parser.odin b/core/text/regex/parser/parser.odin index 038d4cb85..38561a077 100644 --- a/core/text/regex/parser/parser.odin +++ b/core/text/regex/parser/parser.odin @@ -2,7 +2,7 @@ package regex_parser /* (c) Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Feoramund: Initial implementation. diff --git a/core/text/regex/regex.odin b/core/text/regex/regex.odin index bff82c407..c22371f3f 100644 --- a/core/text/regex/regex.odin +++ b/core/text/regex/regex.odin @@ -2,7 +2,7 @@ package regex /* (c) Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Feoramund: Initial implementation. diff --git a/core/text/regex/tokenizer/tokenizer.odin b/core/text/regex/tokenizer/tokenizer.odin index 556423a07..6ce34324e 100644 --- a/core/text/regex/tokenizer/tokenizer.odin +++ b/core/text/regex/tokenizer/tokenizer.odin @@ -3,7 +3,7 @@ package regex_tokenizer /* (c) Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Feoramund: Initial implementation. diff --git a/core/text/regex/virtual_machine/util.odin b/core/text/regex/virtual_machine/util.odin index 79c781e4a..3809ca98a 100644 --- a/core/text/regex/virtual_machine/util.odin +++ b/core/text/regex/virtual_machine/util.odin @@ -2,7 +2,7 @@ package regex_vm /* (c) Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Feoramund: Initial implementation. diff --git a/core/text/regex/virtual_machine/virtual_machine.odin b/core/text/regex/virtual_machine/virtual_machine.odin index c292b0e99..169d8132d 100644 --- a/core/text/regex/virtual_machine/virtual_machine.odin +++ b/core/text/regex/virtual_machine/virtual_machine.odin @@ -2,7 +2,7 @@ package regex_vm /* (c) Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Feoramund: Initial implementation. diff --git a/core/text/scanner/scanner.odin b/core/text/scanner/scanner.odin index 649b4d2d7..9445df58c 100644 --- a/core/text/scanner/scanner.odin +++ b/core/text/scanner/scanner.odin @@ -341,8 +341,10 @@ scan_number :: proc(s: ^Scanner, ch: rune, seen_dot: bool) -> (rune, rune) { case 'x': ch = advance(s) base, prefix = 16, 'x' - case: + case 'o': + ch = advance(s) base, prefix = 8, 'o' + case: digsep = 1 // Leading zero } } else { diff --git a/core/text/table/table.odin b/core/text/table/table.odin index 66a7d442b..204263e54 100644 --- a/core/text/table/table.odin +++ b/core/text/table/table.odin @@ -1,6 +1,6 @@ /* Copyright 2023 oskarnp - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: oskarnp: Initial implementation. diff --git a/core/thread/thread_pool.odin b/core/thread/thread_pool.odin index 15b3a28d2..d7a03d04c 100644 --- a/core/thread/thread_pool.odin +++ b/core/thread/thread_pool.odin @@ -3,7 +3,7 @@ package thread /* thread.Pool Copyright 2022 eisbehr - Made available under Odin's BSD-3 license. + Made available under Odin's license. */ import "base:intrinsics" diff --git a/core/time/time.odin b/core/time/time.odin index ac68346b3..2af11c755 100644 --- a/core/time/time.odin +++ b/core/time/time.odin @@ -916,7 +916,7 @@ This procedure calculates the time from datetime components supplied in the arguments to this procedure. If the datetime components don't represent a valid datetime, the function returns `false` in the second argument. */ -components_to_time :: proc "contextless" (#any_int year, #any_int month, #any_int day, #any_int hour, #any_int minute, #any_int second: i64, #any_int nsec := i64(0)) -> (t: Time, ok: bool) { +components_to_time :: proc "contextless" (#any_int year, #any_int month, #any_int day, #any_int hour, #any_int minute, #any_int second: i64, #any_int nsec := i64(0)) -> (t: Time, ok: bool) #optional_ok { this_date, err := dt.components_to_datetime(year, month, day, hour, minute, second, nsec) if err != .None { return diff --git a/core/unicode/utf8/grapheme.odin b/core/unicode/utf8/grapheme.odin index 50d1789ab..d8f6557b6 100644 --- a/core/unicode/utf8/grapheme.odin +++ b/core/unicode/utf8/grapheme.odin @@ -23,9 +23,40 @@ normalized_east_asian_width :: unicode.normalized_east_asian_width Grapheme :: struct { byte_index: int, rune_index: int, - width: int, + width: int, } + +Grapheme_Cluster_Sequence :: enum { + None, + Indic, + Emoji, + Regional, +} + +Grapheme_Iterator :: struct { + str: string, + curr_offset: int, + + grapheme_count: int, // The number of graphemes in the string + rune_count: int, // The number of runes in the string + width: int, // The widrth of the string in number of monospace cells + + last_rune: rune, + last_rune_breaks_forward: bool, + + last_width: int, + last_grapheme_count: int, + + bypass_next_rune: bool, + + regional_indicator_counter: int, + + current_sequence: Grapheme_Cluster_Sequence, + continue_sequence: bool, +} + + /* Count the individual graphemes in a UTF-8 string. @@ -39,7 +70,9 @@ Returns: */ @(require_results) grapheme_count :: proc(str: string) -> (graphemes, runes, width: int) { - _, graphemes, runes, width = decode_grapheme_clusters(str, false) + it := decode_grapheme_iterator_make(str) + for _, _ in decode_grapheme_iterate(&it) {/**/} + graphemes, runes, width = it.grapheme_count, it.rune_count, it.width return } @@ -70,155 +103,100 @@ decode_grapheme_clusters :: proc( rune_count: int, width: int, ) { - // The following procedure implements text segmentation by breaking on - // Grapheme Cluster Boundaries[1], using the values[2] and rules[3] from - // the Unicode® Standard Annex #29, entitled: - // - // UNICODE TEXT SEGMENTATION - // - // Version: Unicode 15.1.0 - // Date: 2023-08-16 - // Revision: 43 - // - // This procedure is conformant[4] to UAX29-C1-1, otherwise known as the - // extended, non-legacy ruleset. - // - // Please see the references below for more information. - // - // - // NOTE(Feoramund): This procedure has not been highly optimized. - // A couple opportunities were taken to bypass repeated checking when a - // rune is outside of certain codepoint ranges, but little else has been - // done. Standard switches, conditionals, and binary search are used to - // see if a rune fits into a certain category. - // - // I did find that only one prior rune of state was necessary to build an - // algorithm that successfully passes all 4,835 test cases provided with - // this implementation from the Unicode organization's website. - // - // My initial implementation tracked explicit breaks and counted them once - // the string iteration had terminated. I've found this current - // implementation to be far simpler and need no allocations (unless the - // caller wants position data). - // - // Most rules work backwards instead of forwards which has helped keep this - // simple, despite its length and verbosity. - // - // - // The implementation has been left verbose and in the order described by - // the specification, to enable better readability and future upkeep. - // - // Some possible optimizations might include: - // - // - saving the type of `last_rune` instead of the exact rune. - // - reordering rules. - // - combining tables. - // - // - // [1]: https://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries - // [2]: https://www.unicode.org/reports/tr29/#Default_Grapheme_Cluster_Table - // [3]: https://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundary_Rules - // [4]: https://www.unicode.org/reports/tr29/#Conformance - - // Additionally, this procedure now takes into account Standard Annex #11, - // in order to estimate how visually wide the string will appear on a - // monospaced display. This can only ever be a rough guess, as this tends - // to be an implementation detail relating to which fonts are being used, - // how codepoints are interpreted and drawn, if codepoint sequences are - // interpreted correctly, and et cetera. - // - // For example, a program may not properly interpret an emoji modifier - // sequence and print the component glyphs instead of one whole glyph. - // - // See here for more information: https://www.unicode.org/reports/tr11/ - // - // NOTE: There is no explicit mention of what to do with zero-width spaces - // as far as grapheme cluster segmentation goes, therefore this - // implementation may count and return graphemes with a `width` of zero. - // - // Treat them as any other space. - - Grapheme_Cluster_Sequence :: enum { - None, - Indic, - Emoji, - Regional, - } - context.allocator = allocator - last_rune: rune - last_rune_breaks_forward: bool + it := decode_grapheme_iterator_make(str) + for _, grapheme in decode_grapheme_iterate(&it) { + if track_graphemes { + append(&graphemes, grapheme) + } + } - last_width: int - last_grapheme_count: int + grapheme_count = it.grapheme_count + rune_count = it.rune_count + width = it.width + return +} - bypass_next_rune: bool +@(require_results) +decode_grapheme_iterator_make :: proc(str: string) -> (it: Grapheme_Iterator) { + it.str = str + return +} - regional_indicator_counter: int +@(require_results) +decode_grapheme_iterate :: proc(it: ^Grapheme_Iterator) -> (text: string, grapheme: Grapheme, ok: bool) { + for it.curr_offset < len(it.str) { + if ok { + return + } - current_sequence: Grapheme_Cluster_Sequence - continue_sequence: bool + str := it.str[it.curr_offset:] + this_rune, this_rune_width := decode_rune(str) + byte_index := it.curr_offset + it.curr_offset += this_rune_width - for this_rune, byte_index in str { defer { // "Break at the start and end of text, unless the text is empty." // // GB1: sot ÷ Any // GB2: Any ÷ eot - if rune_count == 0 && grapheme_count == 0 { - grapheme_count += 1 + if it.rune_count == 0 && it.grapheme_count == 0 { + it.grapheme_count += 1 } - if grapheme_count > last_grapheme_count { - width += normalized_east_asian_width(this_rune) - if track_graphemes { - append(&graphemes, Grapheme{ - byte_index, - rune_count, - width - last_width, - }) + if it.grapheme_count > it.last_grapheme_count { + it.width += normalized_east_asian_width(this_rune) + grapheme = Grapheme{ + byte_index, + it.rune_count, + it.width - it.last_width, } - last_grapheme_count = grapheme_count - last_width = width + text = it.str[byte_index:][:grapheme.width] + ok = true + + + it.last_grapheme_count = it.grapheme_count + it.last_width = it.width } - last_rune = this_rune - rune_count += 1 + it.last_rune = this_rune + it.rune_count += 1 - if !continue_sequence { - current_sequence = .None - regional_indicator_counter = 0 + if !it.continue_sequence { + it.current_sequence = .None + it.regional_indicator_counter = 0 } - continue_sequence = false + it.continue_sequence = false } + // "Do not break between a CR and LF. Otherwise, break before and after controls." // // GB3: CR × LF // GB4: (Control | CR | LF) ÷ // GB5: ÷ (Control | CR | LF) - if this_rune == '\n' && last_rune == '\r' { - last_rune_breaks_forward = false - bypass_next_rune = false + if this_rune == '\n' && it.last_rune == '\r' { + it.last_rune_breaks_forward = false + it.bypass_next_rune = false continue } if is_control(this_rune) { - grapheme_count += 1 - last_rune_breaks_forward = true - bypass_next_rune = true + it.grapheme_count += 1 + it.last_rune_breaks_forward = true + it.bypass_next_rune = true continue } // (This check is for rules that work forwards, instead of backwards.) - if bypass_next_rune { - if last_rune_breaks_forward { - grapheme_count += 1 - last_rune_breaks_forward = false + if it.bypass_next_rune { + if it.last_rune_breaks_forward { + it.grapheme_count += 1 + it.last_rune_breaks_forward = false } - bypass_next_rune = false + it.bypass_next_rune = false continue } @@ -227,7 +205,7 @@ decode_grapheme_clusters :: proc( // * 0xA9 and 0xAE are in the Extended_Pictographic range, // which is checked later in GB11. if this_rune != 0xA9 && this_rune != 0xAE && this_rune <= 0x2FF { - grapheme_count += 1 + it.grapheme_count += 1 continue } @@ -241,30 +219,30 @@ decode_grapheme_clusters :: proc( if is_hangul_syllable_leading(this_rune) || is_hangul_syllable_lv(this_rune) || is_hangul_syllable_lvt(this_rune) { - if !is_hangul_syllable_leading(last_rune) { - grapheme_count += 1 + if !is_hangul_syllable_leading(it.last_rune) { + it.grapheme_count += 1 } continue } if is_hangul_syllable_vowel(this_rune) { - if is_hangul_syllable_leading(last_rune) || - is_hangul_syllable_vowel(last_rune) || - is_hangul_syllable_lv(last_rune) { + if is_hangul_syllable_leading(it.last_rune) || + is_hangul_syllable_vowel(it.last_rune) || + is_hangul_syllable_lv(it.last_rune) { continue } - grapheme_count += 1 + it.grapheme_count += 1 continue } if is_hangul_syllable_trailing(this_rune) { - if is_hangul_syllable_trailing(last_rune) || - is_hangul_syllable_lvt(last_rune) || - is_hangul_syllable_lv(last_rune) || - is_hangul_syllable_vowel(last_rune) { + if is_hangul_syllable_trailing(it.last_rune) || + is_hangul_syllable_lvt(it.last_rune) || + is_hangul_syllable_lv(it.last_rune) || + is_hangul_syllable_vowel(it.last_rune) { continue } - grapheme_count += 1 + it.grapheme_count += 1 continue } } @@ -273,25 +251,25 @@ decode_grapheme_clusters :: proc( // // GB9: × (Extend | ZWJ) if this_rune == ZERO_WIDTH_JOINER { - continue_sequence = true + it.continue_sequence = true continue } if is_gcb_extend_class(this_rune) { // (Support for GB9c.) - if current_sequence == .Indic { + if it.current_sequence == .Indic { if is_indic_conjunct_break_extend(this_rune) && ( - is_indic_conjunct_break_linker(last_rune) || - is_indic_conjunct_break_consonant(last_rune) ) { - continue_sequence = true + is_indic_conjunct_break_linker(it.last_rune) || + is_indic_conjunct_break_consonant(it.last_rune) ) { + it.continue_sequence = true continue } - if is_indic_conjunct_break_linker(this_rune) && ( - is_indic_conjunct_break_linker(last_rune) || - is_indic_conjunct_break_extend(last_rune) || - is_indic_conjunct_break_consonant(last_rune) ) { - continue_sequence = true + if is_indic_conjunct_break_linker(this_rune) && ( + is_indic_conjunct_break_linker(it.last_rune) || + is_indic_conjunct_break_extend(it.last_rune) || + is_indic_conjunct_break_consonant(it.last_rune) ) { + it.continue_sequence = true continue } @@ -299,10 +277,10 @@ decode_grapheme_clusters :: proc( } // (Support for GB11.) - if current_sequence == .Emoji && ( - is_gcb_extend_class(last_rune) || - is_emoji_extended_pictographic(last_rune) ) { - continue_sequence = true + if it.current_sequence == .Emoji && ( + is_gcb_extend_class(it.last_rune) || + is_emoji_extended_pictographic(it.last_rune) ) { + it.continue_sequence = true } continue @@ -318,8 +296,8 @@ decode_grapheme_clusters :: proc( } if is_gcb_prepend_class(this_rune) { - grapheme_count += 1 - bypass_next_rune = true + it.grapheme_count += 1 + it.bypass_next_rune = true continue } @@ -328,40 +306,40 @@ decode_grapheme_clusters :: proc( // // GB9c: \p{InCB=Consonant} [ \p{InCB=Extend} \p{InCB=Linker} ]* \p{InCB=Linker} [ \p{InCB=Extend} \p{InCB=Linker} ]* × \p{InCB=Consonant} if is_indic_conjunct_break_consonant(this_rune) { - if current_sequence == .Indic { - if last_rune == ZERO_WIDTH_JOINER || - is_indic_conjunct_break_linker(last_rune) { - continue_sequence = true + if it.current_sequence == .Indic { + if it.last_rune == ZERO_WIDTH_JOINER || + is_indic_conjunct_break_linker(it.last_rune) { + it.continue_sequence = true } else { - grapheme_count += 1 + it.grapheme_count += 1 } } else { - grapheme_count += 1 - current_sequence = .Indic - continue_sequence = true + it.grapheme_count += 1 + it.current_sequence = .Indic + it.continue_sequence = true } continue } if is_indic_conjunct_break_extend(this_rune) { - if current_sequence == .Indic { - if is_indic_conjunct_break_consonant(last_rune) || - is_indic_conjunct_break_linker(last_rune) { - continue_sequence = true + if it.current_sequence == .Indic { + if is_indic_conjunct_break_consonant(it.last_rune) || + is_indic_conjunct_break_linker(it.last_rune) { + it.continue_sequence = true } else { - grapheme_count += 1 + it.grapheme_count += 1 } } continue } if is_indic_conjunct_break_linker(this_rune) { - if current_sequence == .Indic { - if is_indic_conjunct_break_extend(last_rune) || - is_indic_conjunct_break_linker(last_rune) { - continue_sequence = true + if it.current_sequence == .Indic { + if is_indic_conjunct_break_extend(it.last_rune) || + is_indic_conjunct_break_linker(it.last_rune) { + it.continue_sequence = true } else { - grapheme_count += 1 + it.grapheme_count += 1 } } continue @@ -375,11 +353,11 @@ decode_grapheme_clusters :: proc( // // GB11: \p{Extended_Pictographic} Extend* ZWJ × \p{Extended_Pictographic} if is_emoji_extended_pictographic(this_rune) { - if current_sequence != .Emoji || last_rune != ZERO_WIDTH_JOINER { - grapheme_count += 1 + if it.current_sequence != .Emoji || it.last_rune != ZERO_WIDTH_JOINER { + it.grapheme_count += 1 } - current_sequence = .Emoji - continue_sequence = true + it.current_sequence = .Emoji + it.continue_sequence = true continue } @@ -390,13 +368,13 @@ decode_grapheme_clusters :: proc( // GB12: sot (RI RI)* RI × RI // GB13: [^RI] (RI RI)* RI × RI if is_regional_indicator(this_rune) { - if regional_indicator_counter & 1 == 0 { - grapheme_count += 1 + if it.regional_indicator_counter & 1 == 0 { + it.grapheme_count += 1 } - current_sequence = .Regional - continue_sequence = true - regional_indicator_counter += 1 + it.current_sequence = .Regional + it.continue_sequence = true + it.regional_indicator_counter += 1 continue } @@ -404,8 +382,8 @@ decode_grapheme_clusters :: proc( // "Otherwise, break everywhere." // // GB999: Any ÷ Any - grapheme_count += 1 + it.grapheme_count += 1 } return -} +} \ No newline at end of file diff --git a/examples/all/all_main.odin b/examples/all/all_main.odin index 205eb2a3c..cda04278e 100644 --- a/examples/all/all_main.odin +++ b/examples/all/all_main.odin @@ -111,6 +111,7 @@ package all @(require) import "core:prof/spall" @(require) import "core:os" +@(require) import "core:os/os2" @(require) import "core:path/slashpath" @(require) import "core:path/filepath" diff --git a/misc/shell.bat b/misc/shell.bat index 73232da61..bfd3780e9 100644 --- a/misc/shell.bat +++ b/misc/shell.bat @@ -5,7 +5,7 @@ rem call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" rem call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x64 1> NUL rem call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" x86 1> NUL rem call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" x64 1> NUL -call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" x64 1> NUL +call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" amd64 1> NUL set _NO_DEBUG_HEAP=1 set ODIN_IGNORE_MSVC_CHECK=1 diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 53953600e..757df95f7 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -509,6 +509,7 @@ struct BuildContext { bool show_more_timings; bool show_defineables; String export_defineables_file; + bool ignore_unused_defineables; bool show_system_calls; bool keep_temp_files; bool ignore_unknown_attributes; @@ -575,6 +576,8 @@ struct BuildContext { bool min_link_libs; + String export_linked_libs_path; + bool print_linker_flags; RelocMode reloc_mode; @@ -2093,7 +2096,19 @@ gb_internal bool check_target_feature_is_enabled(String const &feature, String * for (;;) { String str = string_split_iterator(&it, ','); if (str == "") break; + if (!string_set_exists(&build_context.target_features_set, str)) { + String plus_str = concatenate_strings(temporary_allocator(), make_string_c("+"), str); + + if (!string_set_exists(&build_context.target_features_set, plus_str)) { + if (not_enabled) *not_enabled = str; + return false; + } + } + + String minus_str = concatenate_strings(temporary_allocator(), make_string_c("-"), str); + + if (string_set_exists(&build_context.target_features_set, minus_str)) { if (not_enabled) *not_enabled = str; return false; } diff --git a/src/build_settings_microarch.cpp b/src/build_settings_microarch.cpp index 16fb2196f..0755aa62d 100644 --- a/src/build_settings_microarch.cpp +++ b/src/build_settings_microarch.cpp @@ -2,7 +2,581 @@ #error "LLVM_VERSION_MAJOR is not defined!" #endif -#if LLVM_VERSION_MAJOR >= 20 +#if LLVM_VERSION_MAJOR >= 21 +// Generated with the featuregen script in `misc/featuregen` +gb_global String target_microarch_list[TargetArch_COUNT] = { + // TargetArch_Invalid: + str_lit(""), + // TargetArch_amd64: + str_lit("alderlake,amdfam10,arrowlake,arrowlake-s,arrowlake_s,athlon,athlon-4,athlon-fx,athlon-mp,athlon-tbird,athlon-xp,athlon64,athlon64-sse3,atom,atom_sse4_2,atom_sse4_2_movbe,barcelona,bdver1,bdver2,bdver3,bdver4,bonnell,broadwell,btver1,btver2,c3,c3-2,cannonlake,cascadelake,clearwaterforest,cooperlake,core-avx-i,core-avx2,core2,core_2_duo_sse4_1,core_2_duo_ssse3,core_2nd_gen_avx,core_3rd_gen_avx,core_4th_gen_avx,core_4th_gen_avx_tsx,core_5th_gen_avx,core_5th_gen_avx_tsx,core_aes_pclmulqdq,core_i7_sse4_2,corei7,corei7-avx,diamondrapids,emeraldrapids,generic,geode,goldmont,goldmont-plus,goldmont_plus,gracemont,grandridge,graniterapids,graniterapids-d,graniterapids_d,haswell,i386,i486,i586,i686,icelake-client,icelake-server,icelake_client,icelake_server,ivybridge,k6,k6-2,k6-3,k8,k8-sse3,knl,knm,lakemont,lunarlake,meteorlake,mic_avx512,nehalem,nocona,opteron,opteron-sse3,pantherlake,penryn,pentium,pentium-m,pentium-mmx,pentium2,pentium3,pentium3m,pentium4,pentium4m,pentium_4,pentium_4_sse3,pentium_ii,pentium_iii,pentium_iii_no_xmm_regs,pentium_m,pentium_mmx,pentium_pro,pentiumpro,prescott,raptorlake,rocketlake,sandybridge,sapphirerapids,sierraforest,silvermont,skx,skylake,skylake-avx512,skylake_avx512,slm,tigerlake,tremont,westmere,winchip-c6,winchip2,x86-64,x86-64-v2,x86-64-v3,x86-64-v4,yonah,znver1,znver2,znver3,znver4,znver5"), + // TargetArch_i386: + str_lit("alderlake,amdfam10,arrowlake,arrowlake-s,arrowlake_s,athlon,athlon-4,athlon-fx,athlon-mp,athlon-tbird,athlon-xp,athlon64,athlon64-sse3,atom,atom_sse4_2,atom_sse4_2_movbe,barcelona,bdver1,bdver2,bdver3,bdver4,bonnell,broadwell,btver1,btver2,c3,c3-2,cannonlake,cascadelake,clearwaterforest,cooperlake,core-avx-i,core-avx2,core2,core_2_duo_sse4_1,core_2_duo_ssse3,core_2nd_gen_avx,core_3rd_gen_avx,core_4th_gen_avx,core_4th_gen_avx_tsx,core_5th_gen_avx,core_5th_gen_avx_tsx,core_aes_pclmulqdq,core_i7_sse4_2,corei7,corei7-avx,diamondrapids,emeraldrapids,generic,geode,goldmont,goldmont-plus,goldmont_plus,gracemont,grandridge,graniterapids,graniterapids-d,graniterapids_d,haswell,i386,i486,i586,i686,icelake-client,icelake-server,icelake_client,icelake_server,ivybridge,k6,k6-2,k6-3,k8,k8-sse3,knl,knm,lakemont,lunarlake,meteorlake,mic_avx512,nehalem,nocona,opteron,opteron-sse3,pantherlake,penryn,pentium,pentium-m,pentium-mmx,pentium2,pentium3,pentium3m,pentium4,pentium4m,pentium_4,pentium_4_sse3,pentium_ii,pentium_iii,pentium_iii_no_xmm_regs,pentium_m,pentium_mmx,pentium_pro,pentiumpro,prescott,raptorlake,rocketlake,sandybridge,sapphirerapids,sierraforest,silvermont,skx,skylake,skylake-avx512,skylake_avx512,slm,tigerlake,tremont,westmere,winchip-c6,winchip2,x86-64,x86-64-v2,x86-64-v3,x86-64-v4,yonah,znver1,znver2,znver3,znver4,znver5"), + // TargetArch_arm32: + str_lit("arm1020e,arm1020t,arm1022e,arm10e,arm10tdmi,arm1136j-s,arm1136jf-s,arm1156t2-s,arm1156t2f-s,arm1176jz-s,arm1176jzf-s,arm710t,arm720t,arm7tdmi,arm7tdmi-s,arm8,arm810,arm9,arm920,arm920t,arm922t,arm926ej-s,arm940t,arm946e-s,arm966e-s,arm968e-s,arm9e,arm9tdmi,cortex-a12,cortex-a15,cortex-a17,cortex-a32,cortex-a35,cortex-a5,cortex-a510,cortex-a53,cortex-a55,cortex-a57,cortex-a7,cortex-a710,cortex-a72,cortex-a73,cortex-a75,cortex-a76,cortex-a76ae,cortex-a77,cortex-a78,cortex-a78ae,cortex-a78c,cortex-a8,cortex-a9,cortex-m0,cortex-m0plus,cortex-m1,cortex-m23,cortex-m3,cortex-m33,cortex-m35p,cortex-m4,cortex-m52,cortex-m55,cortex-m7,cortex-m85,cortex-r4,cortex-r4f,cortex-r5,cortex-r52,cortex-r52plus,cortex-r7,cortex-r8,cortex-x1,cortex-x1c,cyclone,ep9312,exynos-m3,exynos-m4,exynos-m5,generic,iwmmxt,krait,kryo,mpcore,mpcorenovfp,neoverse-n1,neoverse-n2,neoverse-v1,sc000,sc300,star-mc1,strongarm,strongarm110,strongarm1100,strongarm1110,swift,xscale"), + // TargetArch_arm64: + str_lit("a64fx,ampere1,ampere1a,ampere1b,apple-a10,apple-a11,apple-a12,apple-a13,apple-a14,apple-a15,apple-a16,apple-a17,apple-a18,apple-a7,apple-a8,apple-a9,apple-m1,apple-m2,apple-m3,apple-m4,apple-s10,apple-s4,apple-s5,apple-s6,apple-s7,apple-s8,apple-s9,carmel,cobalt-100,cortex-a320,cortex-a34,cortex-a35,cortex-a510,cortex-a520,cortex-a520ae,cortex-a53,cortex-a55,cortex-a57,cortex-a65,cortex-a65ae,cortex-a710,cortex-a715,cortex-a72,cortex-a720,cortex-a720ae,cortex-a725,cortex-a73,cortex-a75,cortex-a76,cortex-a76ae,cortex-a77,cortex-a78,cortex-a78ae,cortex-a78c,cortex-r82,cortex-r82ae,cortex-x1,cortex-x1c,cortex-x2,cortex-x3,cortex-x4,cortex-x925,cyclone,exynos-m3,exynos-m4,exynos-m5,falkor,fujitsu-monaka,gb10,generic,grace,kryo,neoverse-512tvb,neoverse-e1,neoverse-n1,neoverse-n2,neoverse-n3,neoverse-v1,neoverse-v2,neoverse-v3,neoverse-v3ae,olympus,oryon-1,saphira,thunderx,thunderx2t99,thunderx3t110,thunderxt81,thunderxt83,thunderxt88,tsv110"), + // TargetArch_wasm32: + str_lit("bleeding-edge,generic,lime1,mvp"), + // TargetArch_wasm64p32: + str_lit("bleeding-edge,generic,lime1,mvp"), + // TargetArch_riscv64: + str_lit("andes-45-series,andes-a25,andes-a45,andes-ax25,andes-ax45,andes-ax45mpv,andes-n45,andes-nx45,generic,generic-ooo,generic-rv32,generic-rv64,mips-p8700,rocket,rocket-rv32,rocket-rv64,rp2350-hazard3,sifive-7-series,sifive-e20,sifive-e21,sifive-e24,sifive-e31,sifive-e34,sifive-e76,sifive-p450,sifive-p470,sifive-p550,sifive-p670,sifive-p870,sifive-s21,sifive-s51,sifive-s54,sifive-s76,sifive-u54,sifive-u74,sifive-x280,sifive-x390,spacemit-x60,syntacore-scr1-base,syntacore-scr1-max,syntacore-scr3-rv32,syntacore-scr3-rv64,syntacore-scr4-rv32,syntacore-scr4-rv64,syntacore-scr5-rv32,syntacore-scr5-rv64,syntacore-scr7,tt-ascalon-d8,veyron-v1,xiangshan-kunminghu,xiangshan-nanhu"), +}; + +// Generated with the featuregen script in `misc/featuregen` +gb_global String target_features_list[TargetArch_COUNT] = { + // TargetArch_Invalid: + str_lit(""), + // TargetArch_amd64: + str_lit("16bit-mode,32bit-mode,64bit,64bit-mode,adx,aes,allow-light-256-bit,amx-avx512,amx-bf16,amx-complex,amx-fp16,amx-fp8,amx-int8,amx-movrs,amx-tf32,amx-tile,amx-transpose,avx,avx10.1-256,avx10.1-512,avx10.2-256,avx10.2-512,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vp2intersect,avx512vpopcntdq,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,branch-hint,branchfusion,ccmp,cf,cldemote,clflushopt,clwb,clzero,cmov,cmpccxadd,crc32,cx16,cx8,egpr,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-lzcnt-tzcnt,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-popcnt,false-deps-range,fast-11bytenop,fast-15bytenop,fast-7bytenop,fast-bextr,fast-dpwssd,fast-gather,fast-hops,fast-imm16,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fast-vector-shift-masks,faster-shift-than-shuffle,fma,fma4,fsgsbase,fsrm,fxsr,gfni,harden-sls-ijmp,harden-sls-ret,hreset,idivl-to-divb,idivq-to-divl,inline-asm-use-gpr32,invpcid,kl,lea-sp,lea-uses-ag,lvi-cfi,lvi-load-hardening,lwp,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,movrs,mwaitx,ndd,nf,no-bypass-delay,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pad-short-functions,pclmul,pconfig,pku,popcnt,ppx,prefer-128-bit,prefer-256-bit,prefer-mask-registers,prefer-movmsk-over-vtest,prefer-no-gather,prefer-no-scatter,prefetchi,prfchw,ptwrite,push2pop2,raoint,rdpid,rdpru,rdrnd,rdseed,retpoline,retpoline-external-thunk,retpoline-indirect-branches,retpoline-indirect-calls,rtm,sahf,sbb-dep-breaking,serialize,seses,sgx,sha,sha512,shstk,slow-3ops-lea,slow-incdec,slow-lea,slow-pmaddwd,slow-pmulld,slow-shld,slow-two-mem-ops,slow-unaligned-mem-16,slow-unaligned-mem-32,sm3,sm4,soft-float,sse,sse-unaligned-mem,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,tagged-globals,tbm,tsxldtrk,tuning-fast-imm-vector-shift,uintr,use-glm-div-sqrt-costs,use-slm-arith-costs,usermsr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,widekl,x87,xop,xsave,xsavec,xsaveopt,xsaves,zu"), + // TargetArch_i386: + str_lit("16bit-mode,32bit-mode,64bit,64bit-mode,adx,aes,allow-light-256-bit,amx-avx512,amx-bf16,amx-complex,amx-fp16,amx-fp8,amx-int8,amx-movrs,amx-tf32,amx-tile,amx-transpose,avx,avx10.1-256,avx10.1-512,avx10.2-256,avx10.2-512,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vp2intersect,avx512vpopcntdq,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,branch-hint,branchfusion,ccmp,cf,cldemote,clflushopt,clwb,clzero,cmov,cmpccxadd,crc32,cx16,cx8,egpr,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-lzcnt-tzcnt,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-popcnt,false-deps-range,fast-11bytenop,fast-15bytenop,fast-7bytenop,fast-bextr,fast-dpwssd,fast-gather,fast-hops,fast-imm16,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fast-vector-shift-masks,faster-shift-than-shuffle,fma,fma4,fsgsbase,fsrm,fxsr,gfni,harden-sls-ijmp,harden-sls-ret,hreset,idivl-to-divb,idivq-to-divl,inline-asm-use-gpr32,invpcid,kl,lea-sp,lea-uses-ag,lvi-cfi,lvi-load-hardening,lwp,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,movrs,mwaitx,ndd,nf,no-bypass-delay,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pad-short-functions,pclmul,pconfig,pku,popcnt,ppx,prefer-128-bit,prefer-256-bit,prefer-mask-registers,prefer-movmsk-over-vtest,prefer-no-gather,prefer-no-scatter,prefetchi,prfchw,ptwrite,push2pop2,raoint,rdpid,rdpru,rdrnd,rdseed,retpoline,retpoline-external-thunk,retpoline-indirect-branches,retpoline-indirect-calls,rtm,sahf,sbb-dep-breaking,serialize,seses,sgx,sha,sha512,shstk,slow-3ops-lea,slow-incdec,slow-lea,slow-pmaddwd,slow-pmulld,slow-shld,slow-two-mem-ops,slow-unaligned-mem-16,slow-unaligned-mem-32,sm3,sm4,soft-float,sse,sse-unaligned-mem,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,tagged-globals,tbm,tsxldtrk,tuning-fast-imm-vector-shift,uintr,use-glm-div-sqrt-costs,use-slm-arith-costs,usermsr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,widekl,x87,xop,xsave,xsavec,xsaveopt,xsaves,zu"), + // TargetArch_arm32: + str_lit("32bit,8msecext,a12,a15,a17,a32,a35,a5,a53,a55,a57,a7,a72,a73,a75,a76,a77,a78c,a8,a9,aapcs-frame-chain,aclass,acquire-release,aes,armv4,armv4t,armv5t,armv5te,armv5tej,armv6,armv6-m,armv6j,armv6k,armv6kz,armv6s-m,armv6t2,armv7-a,armv7-m,armv7-r,armv7e-m,armv7k,armv7s,armv7ve,armv8-a,armv8-m.base,armv8-m.main,armv8-r,armv8.1-a,armv8.1-m.main,armv8.2-a,armv8.3-a,armv8.4-a,armv8.5-a,armv8.6-a,armv8.7-a,armv8.8-a,armv8.9-a,armv9-a,armv9.1-a,armv9.2-a,armv9.3-a,armv9.4-a,armv9.5-a,armv9.6-a,atomics-32,avoid-movs-shop,avoid-muls,avoid-partial-cpsr,bf16,big-endian-instructions,branch-align-64,cde,cdecp0,cdecp1,cdecp2,cdecp3,cdecp4,cdecp5,cdecp6,cdecp7,cheap-predicable-cpsr,clrbhb,cortex-a510,cortex-a710,cortex-a78,cortex-a78ae,cortex-x1,cortex-x1c,crc,crypto,d32,db,dfb,disable-postra-scheduler,dont-widen-vmovs,dotprod,dsp,execute-only,expand-fp-mlx,exynos,fix-cmse-cve-2021-35465,fix-cortex-a57-aes-1742098,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp16fml,fp64,fpao,fpregs,fpregs16,fpregs64,fullfp16,fuse-aes,fuse-literals,harden-sls-blr,harden-sls-nocomdat,harden-sls-retbr,hwdiv,hwdiv-arm,i8mm,iwmmxt,iwmmxt2,krait,kryo,lob,long-calls,loop-align,m3,m55,m7,m85,mclass,mp,muxed-units,mve,mve.fp,mve1beat,mve2beat,mve4beat,nacl-trap,neon,neon-fpmovs,neonfp,neoverse-v1,no-branch-predictor,no-bti-at-return-twice,no-movt,no-neg-immediates,noarm,nonpipelined-vfp,pacbti,perfmon,prefer-ishst,prefer-vmovsr,prof-unpr,r4,r5,r52,r52plus,r7,ras,rclass,read-tp-tpidrprw,read-tp-tpidruro,read-tp-tpidrurw,reserve-r9,ret-addr-stack,sb,sha2,slow-fp-brcc,slow-load-D-subreg,slow-odd-reg,slow-vdup32,slow-vgetlni32,slowfpvfmx,slowfpvmlx,soft-float,splat-vfp-neon,strict-align,swift,thumb-mode,thumb2,trustzone,use-mipipeliner,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.1m.main,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8.8a,v8.9a,v8m,v8m.main,v9.1a,v9.2a,v9.3a,v9.4a,v9.5a,v9.6a,v9a,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,vldn-align,vmlx-forwarding,vmlx-hazards,wide-stride-vfp,xscale,zcz"), + // TargetArch_arm64: + str_lit("CONTEXTIDREL2,a320,a35,a510,a520,a520ae,a53,a55,a57,a64fx,a65,a710,a715,a72,a720,a720ae,a73,a75,a76,a77,a78,a78ae,a78c,addr-lsl-slow-14,aes,aggressive-fma,all,alternate-sextload-cvt-f32-pattern,altnzcv,alu-lsl-fast,am,ampere1,ampere1a,ampere1b,amvs,apple-a10,apple-a11,apple-a12,apple-a13,apple-a14,apple-a15,apple-a16,apple-a17,apple-a7,apple-m4,arith-bcc-fusion,arith-cbz-fusion,ascend-store-address,avoid-ldapur,balance-fp-ops,bf16,brbe,bti,call-saved-x10,call-saved-x11,call-saved-x12,call-saved-x13,call-saved-x14,call-saved-x15,call-saved-x18,call-saved-x8,call-saved-x9,carmel,ccdp,ccidx,ccpp,chk,clrbhb,cmp-bcc-fusion,cmpbr,complxnum,cortex-a725,cortex-r82,cortex-r82ae,cortex-x1,cortex-x2,cortex-x3,cortex-x4,cortex-x925,cpa,crc,crypto,cssc,d128,disable-fast-inc-vl,disable-latency-sched-heuristic,disable-ldp,disable-stp,dit,dotprod,ecv,el2vmsa,el3,enable-select-opt,ete,execute-only,exynos-cheap-as-move,exynosm3,exynosm4,f32mm,f64mm,f8f16mm,f8f32mm,falkor,faminmax,fgt,fix-cortex-a53-835769,flagm,fmv,force-32bit-jump-tables,fp-armv8,fp16fml,fp8,fp8dot2,fp8dot4,fp8fma,fpac,fprcvt,fptoint,fujitsu-monaka,fullfp16,fuse-address,fuse-addsub-2reg-const1,fuse-adrp-add,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,gcs,harden-sls-blr,harden-sls-nocomdat,harden-sls-retbr,hbc,hcx,i8mm,ite,jsconv,kryo,ldp-aligned-only,lor,ls64,lse,lse128,lse2,lsfe,lsui,lut,mec,mops,mpam,mte,neon,neoverse512tvb,neoversee1,neoversen1,neoversen2,neoversen3,neoversev1,neoversev2,neoversev3,neoversev3AE,nmi,no-bti-at-return-twice,no-neg-immediates,no-sve-fp-ld1r,no-zcz-fp,nv,occmo,olympus,oryon-1,outline-atomics,pan,pan-rwv,pauth,pauth-lr,pcdphint,perfmon,pops,predictable-select-expensive,predres,prfm-slc-target,rand,ras,rasv2,rcpc,rcpc-immo,rcpc3,rdm,reserve-lr-for-ra,reserve-x1,reserve-x10,reserve-x11,reserve-x12,reserve-x13,reserve-x14,reserve-x15,reserve-x18,reserve-x2,reserve-x20,reserve-x21,reserve-x22,reserve-x23,reserve-x24,reserve-x25,reserve-x26,reserve-x27,reserve-x28,reserve-x3,reserve-x4,reserve-x5,reserve-x6,reserve-x7,reserve-x9,rme,saphira,sb,sel2,sha2,sha3,slow-misaligned-128store,slow-paired-128,slow-strqro-store,sm4,sme,sme-b16b16,sme-f16f16,sme-f64f64,sme-f8f16,sme-f8f32,sme-fa64,sme-i16i64,sme-lutv2,sme-mop4,sme-tmop,sme2,sme2p1,sme2p2,spe,spe-eef,specres2,specrestrict,ssbs,ssve-aes,ssve-bitperm,ssve-fexpa,ssve-fp8dot2,ssve-fp8dot4,ssve-fp8fma,store-pair-suppress,stp-aligned-only,strict-align,sve,sve-aes,sve-aes2,sve-b16b16,sve-bfscale,sve-bitperm,sve-f16f32mm,sve-sha3,sve-sm4,sve2,sve2-aes,sve2-bitperm,sve2-sha3,sve2-sm4,sve2p1,sve2p2,tagged-globals,the,thunderx,thunderx2t99,thunderx3t110,thunderxt81,thunderxt83,thunderxt88,tlb-rmi,tlbiw,tme,tpidr-el1,tpidr-el2,tpidr-el3,tpidrro-el0,tracev8.4,trbe,tsv110,uaops,use-experimental-zeroing-pseudos,use-fixed-over-scalable-if-equal-cost,use-postra-scheduler,use-reciprocal-square-root,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8.8a,v8.9a,v8a,v8r,v9.1a,v9.2a,v9.3a,v9.4a,v9.5a,v9.6a,v9a,vh,wfxt,xs,zcm-fpr32,zcm-fpr64,zcm-gpr32,zcm-gpr64,zcz,zcz-fp-workaround,zcz-gp"), + // TargetArch_wasm32: + str_lit("atomics,bulk-memory,bulk-memory-opt,call-indirect-overlong,exception-handling,extended-const,fp16,multimemory,multivalue,mutable-globals,nontrapping-fptoint,reference-types,relaxed-simd,sign-ext,simd128,tail-call,wide-arithmetic"), + // TargetArch_wasm64p32: + str_lit("atomics,bulk-memory,bulk-memory-opt,call-indirect-overlong,exception-handling,extended-const,fp16,multimemory,multivalue,mutable-globals,nontrapping-fptoint,reference-types,relaxed-simd,sign-ext,simd128,tail-call,wide-arithmetic"), + // TargetArch_riscv64: + str_lit("32bit,64bit,a,andes45,auipc-addi-fusion,b,c,conditional-cmv-fusion,d,disable-latency-sched-heuristic,dlen-factor-2,e,exact-asm,experimental,experimental-p,experimental-rvm23u32,experimental-smctr,experimental-ssctr,experimental-svukte,experimental-xqccmp,experimental-xqcia,experimental-xqciac,experimental-xqcibi,experimental-xqcibm,experimental-xqcicli,experimental-xqcicm,experimental-xqcics,experimental-xqcicsr,experimental-xqciint,experimental-xqciio,experimental-xqcilb,experimental-xqcili,experimental-xqcilia,experimental-xqcilo,experimental-xqcilsm,experimental-xqcisim,experimental-xqcisls,experimental-xqcisync,experimental-xrivosvisni,experimental-xrivosvizip,experimental-xsfmclic,experimental-xsfsclic,experimental-zalasr,experimental-zicfilp,experimental-zicfiss,experimental-zvbc32e,experimental-zvkgs,experimental-zvqdotq,f,forced-atomics,h,i,ld-add-fusion,log-vrgather,lui-addi-fusion,m,mips-p8700,no-default-unroll,no-sink-splat-operands,no-trailing-seq-cst-fence,optimized-nf2-segment-load-store,optimized-nf3-segment-load-store,optimized-nf4-segment-load-store,optimized-nf5-segment-load-store,optimized-nf6-segment-load-store,optimized-nf7-segment-load-store,optimized-nf8-segment-load-store,optimized-zero-stride-load,predictable-select-expensive,prefer-vsetvli-over-read-vlenb,prefer-w-inst,q,relax,reserve-x1,reserve-x10,reserve-x11,reserve-x12,reserve-x13,reserve-x14,reserve-x15,reserve-x16,reserve-x17,reserve-x18,reserve-x19,reserve-x2,reserve-x20,reserve-x21,reserve-x22,reserve-x23,reserve-x24,reserve-x25,reserve-x26,reserve-x27,reserve-x28,reserve-x29,reserve-x3,reserve-x30,reserve-x31,reserve-x4,reserve-x5,reserve-x6,reserve-x7,reserve-x8,reserve-x9,rva20s64,rva20u64,rva22s64,rva22u64,rva23s64,rva23u64,rvb23s64,rvb23u64,rvi20u32,rvi20u64,save-restore,sdext,sdtrig,sha,shcounterenw,shgatpa,shifted-zextw-fusion,shlcofideleg,short-forward-branch-opt,shtvala,shvsatpa,shvstvala,shvstvecd,sifive7,smaia,smcdeleg,smcntrpmf,smcsrind,smdbltrp,smepmp,smmpm,smnpm,smrnmi,smstateen,ssaia,ssccfg,ssccptr,sscofpmf,sscounterenw,sscsrind,ssdbltrp,ssnpm,sspm,ssqosid,ssstateen,ssstrict,sstc,sstvala,sstvecd,ssu64xl,supm,svade,svadu,svbare,svinval,svnapot,svpbmt,svvptc,tagged-globals,unaligned-scalar-mem,unaligned-vector-mem,use-postra-scheduler,v,ventana-veyron,vl-dependent-latency,vxrm-pipeline-flush,xandesbfhcvt,xandesperf,xandesvbfhcvt,xandesvdot,xandesvpackfph,xandesvsintload,xcvalu,xcvbi,xcvbitmanip,xcvelw,xcvmac,xcvmem,xcvsimd,xmipscbop,xmipscmov,xmipslsp,xsfcease,xsfmm128t,xsfmm16t,xsfmm32a16f,xsfmm32a32f,xsfmm32a8f,xsfmm32a8i,xsfmm32t,xsfmm64a64f,xsfmm64t,xsfmmbase,xsfvcp,xsfvfnrclipxfqf,xsfvfwmaccqqq,xsfvqmaccdod,xsfvqmaccqoq,xsifivecdiscarddlone,xsifivecflushdlone,xtheadba,xtheadbb,xtheadbs,xtheadcmo,xtheadcondmov,xtheadfmemidx,xtheadmac,xtheadmemidx,xtheadmempair,xtheadsync,xtheadvdot,xventanacondops,xwchc,za128rs,za64rs,zaamo,zabha,zacas,zalrsc,zama16b,zawrs,zba,zbb,zbc,zbkb,zbkc,zbkx,zbs,zca,zcb,zcd,zce,zcf,zclsd,zcmop,zcmp,zcmt,zdinx,zexth-fusion,zextw-fusion,zfa,zfbfmin,zfh,zfhmin,zfinx,zhinx,zhinxmin,zic64b,zicbom,zicbop,zicboz,ziccamoa,ziccamoc,ziccif,zicclsm,ziccrse,zicntr,zicond,zicsr,zifencei,zihintntl,zihintpause,zihpm,zilsd,zimop,zk,zkn,zknd,zkne,zknh,zkr,zks,zksed,zksh,zkt,zmmul,ztso,zvbb,zvbc,zve32f,zve32x,zve64d,zve64f,zve64x,zvfbfmin,zvfbfwma,zvfh,zvfhmin,zvkb,zvkg,zvkn,zvknc,zvkned,zvkng,zvknha,zvknhb,zvks,zvksc,zvksed,zvksg,zvksh,zvkt,zvl1024b,zvl128b,zvl16384b,zvl2048b,zvl256b,zvl32768b,zvl32b,zvl4096b,zvl512b,zvl64b,zvl65536b,zvl8192b"), +}; + +// Generated with the featuregen script in `misc/featuregen` +gb_global int target_microarch_counts[TargetArch_COUNT] = { + // TargetArch_Invalid: + 0, + // TargetArch_amd64: + 129, + // TargetArch_i386: + 129, + // TargetArch_arm32: + 95, + // TargetArch_arm64: + 91, + // TargetArch_wasm32: + 4, + // TargetArch_wasm64p32: + 4, + // TargetArch_riscv64: + 51, +}; + +// Generated with the featuregen script in `misc/featuregen` +gb_global MicroarchFeatureList microarch_features_list[] = { + // TargetArch_amd64: + { str_lit("alderlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avxvnni,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("amdfam10"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,idivq-to-divl,lzcnt,nopl,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4a,vzeroupper,x87") }, + { str_lit("arrowlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint8,bmi,bmi2,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("arrowlake-s"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,sha512,shstk,slow-3ops-lea,sm3,sm4,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("arrowlake_s"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,sha512,shstk,slow-3ops-lea,sm3,sm4,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("athlon"), str_lit("64bit-mode,cmov,cx8,mmx,nopl,prfchw,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("athlon-4"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,prfchw,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("athlon-fx"), str_lit("64bit,64bit-mode,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,prfchw,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("athlon-mp"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,prfchw,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("athlon-tbird"), str_lit("64bit-mode,cmov,cx8,mmx,nopl,prfchw,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("athlon-xp"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,prfchw,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("athlon64"), str_lit("64bit,64bit-mode,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,prfchw,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("athlon64-sse3"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,prfchw,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, + { str_lit("atom"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fast-imm16,fxsr,idivl-to-divb,idivq-to-divl,lea-sp,lea-uses-ag,mmx,movbe,no-bypass-delay,nopl,pad-short-functions,sahf,slow-two-mem-ops,slow-unaligned-mem-16,sse,sse2,sse3,ssse3,vzeroupper,x87") }, + { str_lit("atom_sse4_2"), str_lit("64bit,64bit-mode,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-7bytenop,fast-imm16,fast-movbe,fxsr,idivq-to-divl,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,sahf,slow-incdec,slow-lea,slow-pmulld,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-slm-arith-costs,vzeroupper,x87") }, + { str_lit("atom_sse4_2_movbe"), str_lit("64bit,64bit-mode,aes,clflushopt,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-7bytenop,fast-imm16,fast-movbe,fsgsbase,fxsr,idivq-to-divl,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-pmulld,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-slm-arith-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("barcelona"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,idivq-to-divl,lzcnt,nopl,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4a,vzeroupper,x87") }, + { str_lit("bdver1"), str_lit("64bit,64bit-mode,aes,avx,branchfusion,cmov,crc32,cx16,cx8,fast-11bytenop,fast-scalar-shift-masks,fma4,fxsr,idivq-to-divl,lwp,lzcnt,mmx,nopl,pclmul,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vzeroupper,x87,xop,xsave") }, + { str_lit("bdver2"), str_lit("64bit,64bit-mode,aes,avx,bmi,branchfusion,cmov,crc32,cx16,cx8,f16c,fast-11bytenop,fast-bextr,fast-movbe,fast-scalar-shift-masks,fma,fma4,fxsr,idivq-to-divl,lwp,lzcnt,mmx,nopl,pclmul,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,tbm,vzeroupper,x87,xop,xsave") }, + { str_lit("bdver3"), str_lit("64bit,64bit-mode,aes,avx,bmi,branchfusion,cmov,crc32,cx16,cx8,f16c,fast-11bytenop,fast-bextr,fast-movbe,fast-scalar-shift-masks,fma,fma4,fsgsbase,fxsr,idivq-to-divl,lwp,lzcnt,mmx,nopl,pclmul,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,tbm,vzeroupper,x87,xop,xsave,xsaveopt") }, + { str_lit("bdver4"), str_lit("64bit,64bit-mode,aes,avx,avx2,bmi,bmi2,branchfusion,cmov,crc32,cx16,cx8,f16c,fast-11bytenop,fast-bextr,fast-movbe,fast-scalar-shift-masks,fma,fma4,fsgsbase,fxsr,idivq-to-divl,lwp,lzcnt,mmx,movbe,mwaitx,nopl,pclmul,popcnt,prfchw,rdrnd,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,tbm,vzeroupper,x87,xop,xsave,xsaveopt") }, + { str_lit("bonnell"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fast-imm16,fxsr,idivl-to-divb,idivq-to-divl,lea-sp,lea-uses-ag,mmx,movbe,no-bypass-delay,nopl,pad-short-functions,sahf,slow-two-mem-ops,slow-unaligned-mem-16,sse,sse2,sse3,ssse3,vzeroupper,x87") }, + { str_lit("broadwell"), str_lit("64bit,64bit-mode,adx,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("btver1"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fast-15bytenop,fast-imm16,fast-scalar-shift-masks,fast-vector-shift-masks,fxsr,idivq-to-divl,lzcnt,mmx,nopl,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4a,ssse3,vzeroupper,x87") }, + { str_lit("btver2"), str_lit("64bit,64bit-mode,aes,avx,bmi,cmov,crc32,cx16,cx8,f16c,fast-15bytenop,fast-bextr,fast-hops,fast-imm16,fast-lzcnt,fast-movbe,fast-scalar-shift-masks,fast-vector-shift-masks,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,x87,xsave,xsaveopt") }, + { str_lit("c3"), str_lit("64bit-mode,mmx,prfchw,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("c3-2"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("cannonlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vl,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,sha,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("cascadelake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,avx512vnni,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("clearwaterforest"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,cldemote,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prefetchi,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,sha512,shstk,slow-3ops-lea,sm3,sm4,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,uintr,usermsr,vaes,vpclmulqdq,vzeroupper,waitpkg,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("cooperlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bf16,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,avx512vnni,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("core-avx-i"), str_lit("64bit,64bit-mode,avx,cmov,crc32,cx16,cx8,f16c,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fsgsbase,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core-avx2"), str_lit("64bit,64bit-mode,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core2"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fxsr,macrofusion,mmx,nopl,sahf,slow-unaligned-mem-16,sse,sse2,sse3,ssse3,vzeroupper,x87") }, + { str_lit("core_2_duo_sse4_1"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fxsr,macrofusion,mmx,nopl,sahf,slow-unaligned-mem-16,sse,sse2,sse3,sse4.1,ssse3,vzeroupper,x87") }, + { str_lit("core_2_duo_ssse3"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fxsr,macrofusion,mmx,nopl,sahf,slow-unaligned-mem-16,sse,sse2,sse3,ssse3,vzeroupper,x87") }, + { str_lit("core_2nd_gen_avx"), str_lit("64bit,64bit-mode,avx,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core_3rd_gen_avx"), str_lit("64bit,64bit-mode,avx,cmov,crc32,cx16,cx8,f16c,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fsgsbase,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core_4th_gen_avx"), str_lit("64bit,64bit-mode,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core_4th_gen_avx_tsx"), str_lit("64bit,64bit-mode,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core_5th_gen_avx"), str_lit("64bit,64bit-mode,adx,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core_5th_gen_avx_tsx"), str_lit("64bit,64bit-mode,adx,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core_aes_pclmulqdq"), str_lit("64bit,64bit-mode,cmov,crc32,cx16,cx8,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, + { str_lit("core_i7_sse4_2"), str_lit("64bit,64bit-mode,cmov,crc32,cx16,cx8,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, + { str_lit("corei7"), str_lit("64bit,64bit-mode,cmov,crc32,cx16,cx8,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, + { str_lit("corei7-avx"), str_lit("64bit,64bit-mode,avx,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("diamondrapids"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,amx-avx512,amx-bf16,amx-complex,amx-fp16,amx-fp8,amx-int8,amx-movrs,amx-tf32,amx-tile,amx-transpose,avx,avx10.1-256,avx10.1-512,avx10.2-256,avx10.2-512,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,branch-hint,ccmp,cf,cldemote,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,egpr,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,movrs,ndd,nf,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,ppx,prefer-256-bit,prefetchi,prfchw,ptwrite,push2pop2,rdpid,rdrnd,rdseed,sahf,serialize,sha,sha512,shstk,sm3,sm4,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,usermsr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves,zu") }, + { str_lit("emeraldrapids"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,amx-bf16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("generic"), str_lit("64bit,64bit-mode,cx8,fast-15bytenop,fast-scalar-fsqrt,idivq-to-divl,macrofusion,slow-3ops-lea,sse,sse2,vzeroupper,x87") }, + { str_lit("geode"), str_lit("64bit-mode,cx8,mmx,prfchw,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("goldmont"), str_lit("64bit,64bit-mode,aes,clflushopt,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-imm16,fast-movbe,fsgsbase,fxsr,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-glm-div-sqrt-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("goldmont-plus"), str_lit("64bit,64bit-mode,aes,clflushopt,cmov,crc32,cx16,cx8,fast-imm16,fast-movbe,fsgsbase,fxsr,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-glm-div-sqrt-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("goldmont_plus"), str_lit("64bit,64bit-mode,aes,clflushopt,cmov,crc32,cx16,cx8,fast-imm16,fast-movbe,fsgsbase,fxsr,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-glm-div-sqrt-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("gracemont"), str_lit("64bit,64bit-mode,adx,aes,avx,avx2,avxvnni,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,f16c,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,nopl,pclmul,pconfig,pku,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("grandridge"), str_lit("64bit,64bit-mode,adx,aes,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint8,bmi,bmi2,cldemote,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,nopl,pclmul,pconfig,pku,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("graniterapids"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,amx-bf16,amx-fp16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,branch-hint,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prefetchi,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("graniterapids-d"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,amx-bf16,amx-complex,amx-fp16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,branch-hint,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prefetchi,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("graniterapids_d"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,amx-bf16,amx-complex,amx-fp16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,branch-hint,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prefetchi,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("haswell"), str_lit("64bit,64bit-mode,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("i386"), str_lit("64bit-mode,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("i486"), str_lit("64bit-mode,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("i586"), str_lit("64bit-mode,cx8,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("i686"), str_lit("64bit-mode,cmov,cx8,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("icelake-client"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("icelake-server"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("icelake_client"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("icelake_server"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("ivybridge"), str_lit("64bit,64bit-mode,avx,cmov,crc32,cx16,cx8,f16c,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fsgsbase,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("k6"), str_lit("64bit-mode,cx8,mmx,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("k6-2"), str_lit("64bit-mode,cx8,mmx,prfchw,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("k6-3"), str_lit("64bit-mode,cx8,mmx,prfchw,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("k8"), str_lit("64bit,64bit-mode,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,prfchw,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("k8-sse3"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,prfchw,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, + { str_lit("knl"), str_lit("64bit,64bit-mode,adx,aes,avx,avx2,avx512cd,avx512f,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-imm16,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,slow-incdec,slow-pmaddwd,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,x87,xsave,xsaveopt") }, + { str_lit("knm"), str_lit("64bit,64bit-mode,adx,aes,avx,avx2,avx512cd,avx512f,avx512vpopcntdq,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-imm16,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,slow-incdec,slow-pmaddwd,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,x87,xsave,xsaveopt") }, + { str_lit("lakemont"), str_lit("64bit-mode,cx8,slow-unaligned-mem-16,sse,sse2,vzeroupper") }, + { str_lit("lunarlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,sha512,shstk,slow-3ops-lea,sm3,sm4,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("meteorlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avxvnni,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("mic_avx512"), str_lit("64bit,64bit-mode,adx,aes,avx,avx2,avx512cd,avx512f,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-imm16,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,slow-incdec,slow-pmaddwd,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,x87,xsave,xsaveopt") }, + { str_lit("nehalem"), str_lit("64bit,64bit-mode,cmov,crc32,cx16,cx8,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, + { str_lit("nocona"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, + { str_lit("opteron"), str_lit("64bit,64bit-mode,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,prfchw,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("opteron-sse3"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,prfchw,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, + { str_lit("pantherlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prefetchi,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,sha512,shstk,slow-3ops-lea,sm3,sm4,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("penryn"), str_lit("64bit,64bit-mode,cmov,cx16,cx8,fxsr,macrofusion,mmx,nopl,sahf,slow-unaligned-mem-16,sse,sse2,sse3,sse4.1,ssse3,vzeroupper,x87") }, + { str_lit("pentium"), str_lit("64bit-mode,cx8,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium-m"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium-mmx"), str_lit("64bit-mode,cx8,mmx,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium2"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium3"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium3m"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium4"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium4m"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium_4"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium_4_sse3"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, + { str_lit("pentium_ii"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium_iii"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium_iii_no_xmm_regs"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium_m"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium_mmx"), str_lit("64bit-mode,cx8,mmx,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium_pro"), str_lit("64bit-mode,cmov,cx8,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentiumpro"), str_lit("64bit-mode,cmov,cx8,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("prescott"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, + { str_lit("raptorlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avxvnni,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("rocketlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("sandybridge"), str_lit("64bit,64bit-mode,avx,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("sapphirerapids"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,amx-bf16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("sierraforest"), str_lit("64bit,64bit-mode,adx,aes,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint8,bmi,bmi2,cldemote,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,nopl,pclmul,pconfig,pku,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("silvermont"), str_lit("64bit,64bit-mode,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-7bytenop,fast-imm16,fast-movbe,fxsr,idivq-to-divl,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,sahf,slow-incdec,slow-lea,slow-pmulld,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-slm-arith-costs,vzeroupper,x87") }, + { str_lit("skx"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("skylake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("skylake-avx512"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("skylake_avx512"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("slm"), str_lit("64bit,64bit-mode,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-7bytenop,fast-imm16,fast-movbe,fxsr,idivq-to-divl,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,sahf,slow-incdec,slow-lea,slow-pmulld,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-slm-arith-costs,vzeroupper,x87") }, + { str_lit("tigerlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vp2intersect,avx512vpopcntdq,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("tremont"), str_lit("64bit,64bit-mode,aes,clflushopt,clwb,cmov,crc32,cx16,cx8,fast-imm16,fast-movbe,fsgsbase,fxsr,gfni,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-glm-div-sqrt-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("westmere"), str_lit("64bit,64bit-mode,cmov,crc32,cx16,cx8,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, + { str_lit("winchip-c6"), str_lit("64bit-mode,mmx,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("winchip2"), str_lit("64bit-mode,mmx,prfchw,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("x86-64"), str_lit("64bit,64bit-mode,cmov,cx8,fxsr,idivq-to-divl,macrofusion,mmx,nopl,slow-3ops-lea,slow-incdec,sse,sse2,vzeroupper,x87") }, + { str_lit("x86-64-v2"), str_lit("64bit,64bit-mode,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fxsr,idivq-to-divl,macrofusion,mmx,nopl,popcnt,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, + { str_lit("x86-64-v3"), str_lit("64bit,64bit-mode,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fxsr,idivq-to-divl,lzcnt,macrofusion,mmx,movbe,nopl,popcnt,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave") }, + { str_lit("x86-64-v4"), str_lit("64bit,64bit-mode,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fxsr,idivq-to-divl,lzcnt,macrofusion,mmx,movbe,nopl,popcnt,prefer-256-bit,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave") }, + { str_lit("yonah"), str_lit("64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, + { str_lit("znver1"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,bmi,bmi2,branchfusion,clflushopt,clzero,cmov,crc32,cx16,cx8,f16c,fast-15bytenop,fast-bextr,fast-imm16,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,mwaitx,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("znver2"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,bmi,bmi2,branchfusion,clflushopt,clwb,clzero,cmov,crc32,cx16,cx8,f16c,fast-15bytenop,fast-bextr,fast-imm16,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,mwaitx,nopl,pclmul,popcnt,prfchw,rdpid,rdpru,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("znver3"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,bmi,bmi2,branchfusion,clflushopt,clwb,clzero,cmov,crc32,cx16,cx8,f16c,fast-15bytenop,fast-bextr,fast-imm16,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,mwaitx,nopl,pclmul,pku,popcnt,prfchw,rdpid,rdpru,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vaes,vpclmulqdq,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("znver4"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,branchfusion,clflushopt,clwb,clzero,cmov,crc32,cx16,cx8,evex512,f16c,fast-15bytenop,fast-bextr,fast-dpwssd,fast-imm16,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,mwaitx,nopl,pclmul,pku,popcnt,prfchw,rdpid,rdpru,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vaes,vpclmulqdq,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("znver5"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vp2intersect,avx512vpopcntdq,avxvnni,bmi,bmi2,branchfusion,clflushopt,clwb,clzero,cmov,crc32,cx16,cx8,evex512,f16c,fast-15bytenop,fast-bextr,fast-dpwssd,fast-imm16,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,mwaitx,nopl,pclmul,pku,popcnt,prefetchi,prfchw,rdpid,rdpru,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vaes,vpclmulqdq,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + // TargetArch_i386: + { str_lit("alderlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avxvnni,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("amdfam10"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,idivq-to-divl,lzcnt,nopl,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4a,vzeroupper,x87") }, + { str_lit("arrowlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint8,bmi,bmi2,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("arrowlake-s"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,sha512,shstk,slow-3ops-lea,sm3,sm4,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("arrowlake_s"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,sha512,shstk,slow-3ops-lea,sm3,sm4,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("athlon"), str_lit("32bit-mode,cmov,cx8,mmx,nopl,prfchw,slow-shld,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("athlon-4"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,prfchw,slow-shld,slow-unaligned-mem-16,sse,vzeroupper,x87") }, + { str_lit("athlon-fx"), str_lit("32bit-mode,64bit,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,prfchw,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("athlon-mp"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,prfchw,slow-shld,slow-unaligned-mem-16,sse,vzeroupper,x87") }, + { str_lit("athlon-tbird"), str_lit("32bit-mode,cmov,cx8,mmx,nopl,prfchw,slow-shld,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("athlon-xp"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,prfchw,slow-shld,slow-unaligned-mem-16,sse,vzeroupper,x87") }, + { str_lit("athlon64"), str_lit("32bit-mode,64bit,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,prfchw,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("athlon64-sse3"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,prfchw,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, + { str_lit("atom"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fast-imm16,fxsr,idivl-to-divb,idivq-to-divl,lea-sp,lea-uses-ag,mmx,movbe,no-bypass-delay,nopl,pad-short-functions,sahf,slow-two-mem-ops,slow-unaligned-mem-16,sse,sse2,sse3,ssse3,vzeroupper,x87") }, + { str_lit("atom_sse4_2"), str_lit("32bit-mode,64bit,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-7bytenop,fast-imm16,fast-movbe,fxsr,idivq-to-divl,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,sahf,slow-incdec,slow-lea,slow-pmulld,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-slm-arith-costs,vzeroupper,x87") }, + { str_lit("atom_sse4_2_movbe"), str_lit("32bit-mode,64bit,aes,clflushopt,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-7bytenop,fast-imm16,fast-movbe,fsgsbase,fxsr,idivq-to-divl,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-pmulld,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-slm-arith-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("barcelona"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,idivq-to-divl,lzcnt,nopl,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4a,vzeroupper,x87") }, + { str_lit("bdver1"), str_lit("32bit-mode,64bit,aes,avx,branchfusion,cmov,crc32,cx16,cx8,fast-11bytenop,fast-scalar-shift-masks,fma4,fxsr,idivq-to-divl,lwp,lzcnt,mmx,nopl,pclmul,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vzeroupper,x87,xop,xsave") }, + { str_lit("bdver2"), str_lit("32bit-mode,64bit,aes,avx,bmi,branchfusion,cmov,crc32,cx16,cx8,f16c,fast-11bytenop,fast-bextr,fast-movbe,fast-scalar-shift-masks,fma,fma4,fxsr,idivq-to-divl,lwp,lzcnt,mmx,nopl,pclmul,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,tbm,vzeroupper,x87,xop,xsave") }, + { str_lit("bdver3"), str_lit("32bit-mode,64bit,aes,avx,bmi,branchfusion,cmov,crc32,cx16,cx8,f16c,fast-11bytenop,fast-bextr,fast-movbe,fast-scalar-shift-masks,fma,fma4,fsgsbase,fxsr,idivq-to-divl,lwp,lzcnt,mmx,nopl,pclmul,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,tbm,vzeroupper,x87,xop,xsave,xsaveopt") }, + { str_lit("bdver4"), str_lit("32bit-mode,64bit,aes,avx,avx2,bmi,bmi2,branchfusion,cmov,crc32,cx16,cx8,f16c,fast-11bytenop,fast-bextr,fast-movbe,fast-scalar-shift-masks,fma,fma4,fsgsbase,fxsr,idivq-to-divl,lwp,lzcnt,mmx,movbe,mwaitx,nopl,pclmul,popcnt,prfchw,rdrnd,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,tbm,vzeroupper,x87,xop,xsave,xsaveopt") }, + { str_lit("bonnell"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fast-imm16,fxsr,idivl-to-divb,idivq-to-divl,lea-sp,lea-uses-ag,mmx,movbe,no-bypass-delay,nopl,pad-short-functions,sahf,slow-two-mem-ops,slow-unaligned-mem-16,sse,sse2,sse3,ssse3,vzeroupper,x87") }, + { str_lit("broadwell"), str_lit("32bit-mode,64bit,adx,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("btver1"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fast-15bytenop,fast-imm16,fast-scalar-shift-masks,fast-vector-shift-masks,fxsr,idivq-to-divl,lzcnt,mmx,nopl,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4a,ssse3,vzeroupper,x87") }, + { str_lit("btver2"), str_lit("32bit-mode,64bit,aes,avx,bmi,cmov,crc32,cx16,cx8,f16c,fast-15bytenop,fast-bextr,fast-hops,fast-imm16,fast-lzcnt,fast-movbe,fast-scalar-shift-masks,fast-vector-shift-masks,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,x87,xsave,xsaveopt") }, + { str_lit("c3"), str_lit("32bit-mode,mmx,prfchw,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("c3-2"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,slow-unaligned-mem-16,sse,vzeroupper,x87") }, + { str_lit("cannonlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vl,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,sha,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("cascadelake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,avx512vnni,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("clearwaterforest"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,cldemote,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prefetchi,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,sha512,shstk,slow-3ops-lea,sm3,sm4,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,uintr,usermsr,vaes,vpclmulqdq,vzeroupper,waitpkg,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("cooperlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bf16,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,avx512vnni,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("core-avx-i"), str_lit("32bit-mode,64bit,avx,cmov,crc32,cx16,cx8,f16c,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fsgsbase,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core-avx2"), str_lit("32bit-mode,64bit,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core2"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fxsr,macrofusion,mmx,nopl,sahf,slow-unaligned-mem-16,sse,sse2,sse3,ssse3,vzeroupper,x87") }, + { str_lit("core_2_duo_sse4_1"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fxsr,macrofusion,mmx,nopl,sahf,slow-unaligned-mem-16,sse,sse2,sse3,sse4.1,ssse3,vzeroupper,x87") }, + { str_lit("core_2_duo_ssse3"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fxsr,macrofusion,mmx,nopl,sahf,slow-unaligned-mem-16,sse,sse2,sse3,ssse3,vzeroupper,x87") }, + { str_lit("core_2nd_gen_avx"), str_lit("32bit-mode,64bit,avx,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core_3rd_gen_avx"), str_lit("32bit-mode,64bit,avx,cmov,crc32,cx16,cx8,f16c,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fsgsbase,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core_4th_gen_avx"), str_lit("32bit-mode,64bit,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core_4th_gen_avx_tsx"), str_lit("32bit-mode,64bit,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core_5th_gen_avx"), str_lit("32bit-mode,64bit,adx,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core_5th_gen_avx_tsx"), str_lit("32bit-mode,64bit,adx,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("core_aes_pclmulqdq"), str_lit("32bit-mode,64bit,cmov,crc32,cx16,cx8,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, + { str_lit("core_i7_sse4_2"), str_lit("32bit-mode,64bit,cmov,crc32,cx16,cx8,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, + { str_lit("corei7"), str_lit("32bit-mode,64bit,cmov,crc32,cx16,cx8,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, + { str_lit("corei7-avx"), str_lit("32bit-mode,64bit,avx,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("diamondrapids"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,amx-avx512,amx-bf16,amx-complex,amx-fp16,amx-fp8,amx-int8,amx-movrs,amx-tf32,amx-tile,amx-transpose,avx,avx10.1-256,avx10.1-512,avx10.2-256,avx10.2-512,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,branch-hint,ccmp,cf,cldemote,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,egpr,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,movrs,ndd,nf,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,ppx,prefer-256-bit,prefetchi,prfchw,ptwrite,push2pop2,rdpid,rdrnd,rdseed,sahf,serialize,sha,sha512,shstk,sm3,sm4,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,usermsr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves,zu") }, + { str_lit("emeraldrapids"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,amx-bf16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("generic"), str_lit("32bit-mode,64bit,cx8,fast-15bytenop,fast-scalar-fsqrt,idivq-to-divl,macrofusion,slow-3ops-lea,vzeroupper,x87") }, + { str_lit("geode"), str_lit("32bit-mode,cx8,mmx,prfchw,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("goldmont"), str_lit("32bit-mode,64bit,aes,clflushopt,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-imm16,fast-movbe,fsgsbase,fxsr,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-glm-div-sqrt-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("goldmont-plus"), str_lit("32bit-mode,64bit,aes,clflushopt,cmov,crc32,cx16,cx8,fast-imm16,fast-movbe,fsgsbase,fxsr,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-glm-div-sqrt-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("goldmont_plus"), str_lit("32bit-mode,64bit,aes,clflushopt,cmov,crc32,cx16,cx8,fast-imm16,fast-movbe,fsgsbase,fxsr,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-glm-div-sqrt-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("gracemont"), str_lit("32bit-mode,64bit,adx,aes,avx,avx2,avxvnni,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,f16c,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,nopl,pclmul,pconfig,pku,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("grandridge"), str_lit("32bit-mode,64bit,adx,aes,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint8,bmi,bmi2,cldemote,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,nopl,pclmul,pconfig,pku,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("graniterapids"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,amx-bf16,amx-fp16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,branch-hint,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prefetchi,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("graniterapids-d"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,amx-bf16,amx-complex,amx-fp16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,branch-hint,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prefetchi,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("graniterapids_d"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,amx-bf16,amx-complex,amx-fp16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,branch-hint,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prefetchi,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("haswell"), str_lit("32bit-mode,64bit,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("i386"), str_lit("32bit-mode,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("i486"), str_lit("32bit-mode,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("i586"), str_lit("32bit-mode,cx8,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("i686"), str_lit("32bit-mode,cmov,cx8,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("icelake-client"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("icelake-server"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("icelake_client"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("icelake_server"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("ivybridge"), str_lit("32bit-mode,64bit,avx,cmov,crc32,cx16,cx8,f16c,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fsgsbase,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,rdrnd,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("k6"), str_lit("32bit-mode,cx8,mmx,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("k6-2"), str_lit("32bit-mode,cx8,mmx,prfchw,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("k6-3"), str_lit("32bit-mode,cx8,mmx,prfchw,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("k8"), str_lit("32bit-mode,64bit,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,prfchw,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("k8-sse3"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,prfchw,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, + { str_lit("knl"), str_lit("32bit-mode,64bit,adx,aes,avx,avx2,avx512cd,avx512f,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-imm16,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,slow-incdec,slow-pmaddwd,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,x87,xsave,xsaveopt") }, + { str_lit("knm"), str_lit("32bit-mode,64bit,adx,aes,avx,avx2,avx512cd,avx512f,avx512vpopcntdq,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-imm16,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,slow-incdec,slow-pmaddwd,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,x87,xsave,xsaveopt") }, + { str_lit("lakemont"), str_lit("32bit-mode,cx8,slow-unaligned-mem-16,vzeroupper") }, + { str_lit("lunarlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,sha512,shstk,slow-3ops-lea,sm3,sm4,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("meteorlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avxvnni,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("mic_avx512"), str_lit("32bit-mode,64bit,adx,aes,avx,avx2,avx512cd,avx512f,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-imm16,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,slow-incdec,slow-pmaddwd,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,x87,xsave,xsaveopt") }, + { str_lit("nehalem"), str_lit("32bit-mode,64bit,cmov,crc32,cx16,cx8,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, + { str_lit("nocona"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, + { str_lit("opteron"), str_lit("32bit-mode,64bit,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,prfchw,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("opteron-sse3"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,prfchw,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, + { str_lit("pantherlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prefetchi,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,sha512,shstk,slow-3ops-lea,sm3,sm4,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("penryn"), str_lit("32bit-mode,64bit,cmov,cx16,cx8,fxsr,macrofusion,mmx,nopl,sahf,slow-unaligned-mem-16,sse,sse2,sse3,sse4.1,ssse3,vzeroupper,x87") }, + { str_lit("pentium"), str_lit("32bit-mode,cx8,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("pentium-m"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium-mmx"), str_lit("32bit-mode,cx8,mmx,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("pentium2"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("pentium3"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,vzeroupper,x87") }, + { str_lit("pentium3m"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,vzeroupper,x87") }, + { str_lit("pentium4"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium4m"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium_4"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium_4_sse3"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, + { str_lit("pentium_ii"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("pentium_iii"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,vzeroupper,x87") }, + { str_lit("pentium_iii_no_xmm_regs"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,vzeroupper,x87") }, + { str_lit("pentium_m"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("pentium_mmx"), str_lit("32bit-mode,cx8,mmx,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("pentium_pro"), str_lit("32bit-mode,cmov,cx8,nopl,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("pentiumpro"), str_lit("32bit-mode,cmov,cx8,nopl,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("prescott"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, + { str_lit("raptorlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avxvnni,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,f16c,false-deps-perm,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,idivq-to-divl,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-movmsk-over-vtest,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("rocketlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("sandybridge"), str_lit("32bit-mode,64bit,avx,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsaveopt") }, + { str_lit("sapphirerapids"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,amx-bf16,amx-int8,amx-tile,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512fp16,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,avxvnni,bmi,bmi2,cldemote,clflushopt,clwb,cmov,crc32,cx16,cx8,enqcmd,ermsb,evex512,f16c,false-deps-getmant,false-deps-mulc,false-deps-mullq,false-deps-perm,false-deps-range,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pconfig,pku,popcnt,prefer-256-bit,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tsxldtrk,tuning-fast-imm-vector-shift,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("sierraforest"), str_lit("32bit-mode,64bit,adx,aes,avx,avx2,avxifma,avxneconvert,avxvnni,avxvnniint8,bmi,bmi2,cldemote,clflushopt,clwb,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,f16c,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,gfni,hreset,invpcid,kl,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,nopl,pclmul,pconfig,pku,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,uintr,vaes,vpclmulqdq,vzeroupper,waitpkg,widekl,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("silvermont"), str_lit("32bit-mode,64bit,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-7bytenop,fast-imm16,fast-movbe,fxsr,idivq-to-divl,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,sahf,slow-incdec,slow-lea,slow-pmulld,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-slm-arith-costs,vzeroupper,x87") }, + { str_lit("skx"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("skylake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,bmi,bmi2,clflushopt,cmov,crc32,cx16,cx8,ermsb,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("skylake-avx512"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("skylake_avx512"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,faster-shift-than-shuffle,fma,fsgsbase,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdrnd,rdseed,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("slm"), str_lit("32bit-mode,64bit,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-7bytenop,fast-imm16,fast-movbe,fxsr,idivq-to-divl,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,rdrnd,sahf,slow-incdec,slow-lea,slow-pmulld,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-slm-arith-costs,vzeroupper,x87") }, + { str_lit("tigerlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vp2intersect,avx512vpopcntdq,bmi,bmi2,clflushopt,clwb,cmov,crc32,cx16,cx8,ermsb,evex512,f16c,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pclmul,pku,popcnt,prefer-256-bit,prfchw,rdpid,rdrnd,rdseed,sahf,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,ssse3,tuning-fast-imm-vector-shift,vaes,vpclmulqdq,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("tremont"), str_lit("32bit-mode,64bit,aes,clflushopt,clwb,cmov,crc32,cx16,cx8,fast-imm16,fast-movbe,fsgsbase,fxsr,gfni,mmx,movbe,no-bypass-delay,nopl,pclmul,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,sha,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,use-glm-div-sqrt-costs,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("westmere"), str_lit("32bit-mode,64bit,cmov,crc32,cx16,cx8,fxsr,idivq-to-divl,macrofusion,mmx,no-bypass-delay-mov,nopl,pclmul,popcnt,sahf,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, + { str_lit("winchip-c6"), str_lit("32bit-mode,mmx,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("winchip2"), str_lit("32bit-mode,mmx,prfchw,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("x86-64"), str_lit("32bit-mode,64bit,cmov,cx8,fxsr,idivq-to-divl,macrofusion,mmx,nopl,slow-3ops-lea,slow-incdec,sse,sse2,vzeroupper,x87") }, + { str_lit("x86-64-v2"), str_lit("32bit-mode,64bit,cmov,crc32,cx16,cx8,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fxsr,idivq-to-divl,macrofusion,mmx,nopl,popcnt,sahf,slow-3ops-lea,slow-unaligned-mem-32,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87") }, + { str_lit("x86-64-v3"), str_lit("32bit-mode,64bit,allow-light-256-bit,avx,avx2,bmi,bmi2,cmov,crc32,cx16,cx8,f16c,false-deps-lzcnt-tzcnt,false-deps-popcnt,fast-15bytenop,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fma,fxsr,idivq-to-divl,lzcnt,macrofusion,mmx,movbe,nopl,popcnt,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave") }, + { str_lit("x86-64-v4"), str_lit("32bit-mode,64bit,allow-light-256-bit,avx,avx2,avx512bw,avx512cd,avx512dq,avx512f,avx512vl,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,false-deps-popcnt,fast-15bytenop,fast-gather,fast-scalar-fsqrt,fast-shld-rotate,fast-variable-crosslane-shuffle,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fxsr,idivq-to-divl,lzcnt,macrofusion,mmx,movbe,nopl,popcnt,prefer-256-bit,sahf,slow-3ops-lea,sse,sse2,sse3,sse4.1,sse4.2,ssse3,vzeroupper,x87,xsave") }, + { str_lit("yonah"), str_lit("32bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, + { str_lit("znver1"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,bmi,bmi2,branchfusion,clflushopt,clzero,cmov,crc32,cx16,cx8,f16c,fast-15bytenop,fast-bextr,fast-imm16,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,mwaitx,nopl,pclmul,popcnt,prfchw,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vzeroupper,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("znver2"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,bmi,bmi2,branchfusion,clflushopt,clwb,clzero,cmov,crc32,cx16,cx8,f16c,fast-15bytenop,fast-bextr,fast-imm16,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,mwaitx,nopl,pclmul,popcnt,prfchw,rdpid,rdpru,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,slow-shld,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("znver3"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,bmi,bmi2,branchfusion,clflushopt,clwb,clzero,cmov,crc32,cx16,cx8,f16c,fast-15bytenop,fast-bextr,fast-imm16,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,mwaitx,nopl,pclmul,pku,popcnt,prfchw,rdpid,rdpru,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vaes,vpclmulqdq,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("znver4"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vpopcntdq,bmi,bmi2,branchfusion,clflushopt,clwb,clzero,cmov,crc32,cx16,cx8,evex512,f16c,fast-15bytenop,fast-bextr,fast-dpwssd,fast-imm16,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,mwaitx,nopl,pclmul,pku,popcnt,prfchw,rdpid,rdpru,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vaes,vpclmulqdq,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + { str_lit("znver5"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avx512bf16,avx512bitalg,avx512bw,avx512cd,avx512dq,avx512f,avx512ifma,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vp2intersect,avx512vpopcntdq,avxvnni,bmi,bmi2,branchfusion,clflushopt,clwb,clzero,cmov,crc32,cx16,cx8,evex512,f16c,fast-15bytenop,fast-bextr,fast-dpwssd,fast-imm16,fast-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,idivq-to-divl,invpcid,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,mwaitx,nopl,pclmul,pku,popcnt,prefetchi,prfchw,rdpid,rdpru,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,shstk,sse,sse2,sse3,sse4.1,sse4.2,sse4a,ssse3,vaes,vpclmulqdq,vzeroupper,wbnoinvd,x87,xsave,xsavec,xsaveopt,xsaves") }, + // TargetArch_arm32: + { str_lit("arm1020e"), str_lit("armv5te,v4t,v5t,v5te") }, + { str_lit("arm1020t"), str_lit("armv5t,v4t,v5t") }, + { str_lit("arm1022e"), str_lit("armv5te,v4t,v5t,v5te") }, + { str_lit("arm10e"), str_lit("armv5te,v4t,v5t,v5te") }, + { str_lit("arm10tdmi"), str_lit("armv5t,v4t,v5t") }, + { str_lit("arm1136j-s"), str_lit("armv6,dsp,v4t,v5t,v5te,v6") }, + { str_lit("arm1136jf-s"), str_lit("armv6,dsp,fp64,fpregs,fpregs64,slowfpvmlx,v4t,v5t,v5te,v6,vfp2,vfp2sp") }, + { str_lit("arm1156t2-s"), str_lit("armv6t2,dsp,thumb2,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v8m") }, + { str_lit("arm1156t2f-s"), str_lit("armv6t2,dsp,fp64,fpregs,fpregs64,slowfpvmlx,thumb2,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v8m,vfp2,vfp2sp") }, + { str_lit("arm1176jz-s"), str_lit("armv6kz,trustzone,v4t,v5t,v5te,v6,v6k") }, + { str_lit("arm1176jzf-s"), str_lit("armv6kz,fp64,fpregs,fpregs64,slowfpvmlx,trustzone,v4t,v5t,v5te,v6,v6k,vfp2,vfp2sp") }, + { str_lit("arm710t"), str_lit("armv4t,v4t") }, + { str_lit("arm720t"), str_lit("armv4t,v4t") }, + { str_lit("arm7tdmi"), str_lit("armv4t,v4t") }, + { str_lit("arm7tdmi-s"), str_lit("armv4t,v4t") }, + { str_lit("arm8"), str_lit("armv4") }, + { str_lit("arm810"), str_lit("armv4") }, + { str_lit("arm9"), str_lit("armv4t,v4t") }, + { str_lit("arm920"), str_lit("armv4t,v4t") }, + { str_lit("arm920t"), str_lit("armv4t,v4t") }, + { str_lit("arm922t"), str_lit("armv4t,v4t") }, + { str_lit("arm926ej-s"), str_lit("armv5te,v4t,v5t,v5te") }, + { str_lit("arm940t"), str_lit("armv4t,v4t") }, + { str_lit("arm946e-s"), str_lit("armv5te,v4t,v5t,v5te") }, + { str_lit("arm966e-s"), str_lit("armv5te,v4t,v5t,v5te") }, + { str_lit("arm968e-s"), str_lit("armv5te,v4t,v5t,v5te") }, + { str_lit("arm9e"), str_lit("armv5te,v4t,v5t,v5te") }, + { str_lit("arm9tdmi"), str_lit("armv4t,v4t") }, + { str_lit("cortex-a12"), str_lit("a12,aclass,armv7-a,avoid-partial-cpsr,d32,db,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,perfmon,ret-addr-stack,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,vmlx-forwarding") }, + { str_lit("cortex-a15"), str_lit("a15,aclass,armv7-a,avoid-partial-cpsr,d32,db,dont-widen-vmovs,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,muxed-units,perfmon,ret-addr-stack,splat-vfp-neon,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,vldn-align") }, + { str_lit("cortex-a17"), str_lit("a17,aclass,armv7-a,avoid-partial-cpsr,d32,db,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,perfmon,ret-addr-stack,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,vmlx-forwarding") }, + { str_lit("cortex-a32"), str_lit("aclass,acquire-release,aes,armv8-a,crc,crypto,d32,db,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-a35"), str_lit("a35,aclass,acquire-release,aes,armv8-a,crc,crypto,d32,db,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-a5"), str_lit("a5,aclass,armv7-a,d32,db,dsp,fp16,fp64,fpregs,fpregs64,mp,perfmon,ret-addr-stack,slow-fp-brcc,slowfpvfmx,slowfpvmlx,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,vmlx-forwarding") }, + { str_lit("cortex-a510"), str_lit("aclass,acquire-release,armv9-a,bf16,cortex-a710,crc,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp16fml,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,i8mm,mp,neon,perfmon,ras,sb,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8m,v9a,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-a53"), str_lit("a53,aclass,acquire-release,aes,armv8-a,crc,crypto,d32,db,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpao,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-a55"), str_lit("a55,aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-a57"), str_lit("a57,aclass,acquire-release,aes,armv8-a,avoid-partial-cpsr,cheap-predicable-cpsr,crc,crypto,d32,db,dsp,fix-cortex-a57-aes-1742098,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpao,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-a7"), str_lit("a7,aclass,armv7-a,d32,db,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,perfmon,ret-addr-stack,slow-fp-brcc,slowfpvfmx,slowfpvmlx,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,vmlx-forwarding,vmlx-hazards") }, + { str_lit("cortex-a710"), str_lit("aclass,acquire-release,armv9-a,bf16,cortex-a710,crc,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp16fml,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,i8mm,mp,neon,perfmon,ras,sb,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8m,v9a,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-a72"), str_lit("a72,aclass,acquire-release,aes,armv8-a,crc,crypto,d32,db,dsp,fix-cortex-a57-aes-1742098,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-a73"), str_lit("a73,aclass,acquire-release,aes,armv8-a,crc,crypto,d32,db,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-a75"), str_lit("a75,aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-a76"), str_lit("a76,aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-a76ae"), str_lit("a76,aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-a77"), str_lit("a77,aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-a78"), str_lit("aclass,acquire-release,aes,armv8.2-a,cortex-a78,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-a78ae"), str_lit("aclass,acquire-release,aes,armv8.2-a,cortex-a78ae,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-a78c"), str_lit("a78c,aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-a8"), str_lit("a8,aclass,armv7-a,d32,db,dsp,fp64,fpregs,fpregs64,nonpipelined-vfp,perfmon,ret-addr-stack,slow-fp-brcc,slowfpvfmx,slowfpvmlx,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vmlx-forwarding,vmlx-hazards") }, + { str_lit("cortex-a9"), str_lit("a9,aclass,armv7-a,avoid-partial-cpsr,d32,db,dsp,expand-fp-mlx,fp16,fp64,fpregs,fpregs64,mp,muxed-units,neon-fpmovs,perfmon,prefer-vmovsr,ret-addr-stack,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vldn-align,vmlx-forwarding,vmlx-hazards") }, + { str_lit("cortex-m0"), str_lit("armv6-m,db,mclass,no-branch-predictor,noarm,strict-align,thumb-mode,v4t,v5t,v5te,v6,v6m") }, + { str_lit("cortex-m0plus"), str_lit("armv6-m,db,mclass,no-branch-predictor,noarm,strict-align,thumb-mode,v4t,v5t,v5te,v6,v6m") }, + { str_lit("cortex-m1"), str_lit("armv6-m,db,mclass,no-branch-predictor,noarm,strict-align,thumb-mode,v4t,v5t,v5te,v6,v6m") }, + { str_lit("cortex-m23"), str_lit("8msecext,acquire-release,armv8-m.base,db,hwdiv,mclass,no-branch-predictor,no-movt,noarm,strict-align,thumb-mode,v4t,v5t,v5te,v6,v6m,v7clrex,v8m") }, + { str_lit("cortex-m3"), str_lit("armv7-m,db,hwdiv,loop-align,m3,mclass,no-branch-predictor,noarm,thumb-mode,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m") }, + { str_lit("cortex-m33"), str_lit("8msecext,acquire-release,armv8-m.main,avoid-muls,db,dsp,fix-cmse-cve-2021-35465,fp-armv8d16sp,fp16,fpregs,hwdiv,loop-align,mclass,no-branch-predictor,noarm,slowfpvfmx,slowfpvmlx,thumb-mode,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,v8m.main,vfp2sp,vfp3d16sp,vfp4d16sp") }, + { str_lit("cortex-m35p"), str_lit("8msecext,acquire-release,armv8-m.main,db,dsp,fix-cmse-cve-2021-35465,fp-armv8d16sp,fp16,fpregs,hwdiv,loop-align,mclass,no-branch-predictor,noarm,slowfpvfmx,slowfpvmlx,thumb-mode,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,v8m.main,vfp2sp,vfp3d16sp,vfp4d16sp") }, + { str_lit("cortex-m4"), str_lit("armv7e-m,db,dsp,fp16,fpregs,hwdiv,loop-align,mclass,no-branch-predictor,noarm,slowfpvfmx,slowfpvmlx,thumb-mode,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2sp,vfp3d16sp,vfp4d16sp") }, + { str_lit("cortex-m52"), str_lit("8msecext,acquire-release,armv8.1-m.main,db,dsp,fp-armv8d16,fp-armv8d16sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,lob,loop-align,mclass,mve,mve.fp,mve1beat,no-branch-predictor,noarm,pacbti,ras,slowfpvmlx,thumb-mode,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8.1m.main,v8m,v8m.main,vfp2,vfp2sp,vfp3d16,vfp3d16sp,vfp4d16,vfp4d16sp") }, + { str_lit("cortex-m55"), str_lit("8msecext,acquire-release,armv8.1-m.main,db,dsp,fix-cmse-cve-2021-35465,fp-armv8d16,fp-armv8d16sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,lob,loop-align,m55,mclass,mve,mve.fp,no-branch-predictor,noarm,ras,slowfpvmlx,thumb-mode,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8.1m.main,v8m,v8m.main,vfp2,vfp2sp,vfp3d16,vfp3d16sp,vfp4d16,vfp4d16sp") }, + { str_lit("cortex-m7"), str_lit("armv7e-m,branch-align-64,db,dsp,fp-armv8d16,fp-armv8d16sp,fp16,fp64,fpregs,fpregs64,hwdiv,m7,mclass,noarm,thumb-mode,thumb2,use-mipipeliner,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3d16,vfp3d16sp,vfp4d16,vfp4d16sp") }, + { str_lit("cortex-m85"), str_lit("8msecext,acquire-release,armv8.1-m.main,branch-align-64,db,dsp,fp-armv8d16,fp-armv8d16sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,lob,m85,mclass,mve,mve.fp,noarm,pacbti,ras,thumb-mode,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8.1m.main,v8m,v8m.main,vfp2,vfp2sp,vfp3d16,vfp3d16sp,vfp4d16,vfp4d16sp") }, + { str_lit("cortex-r4"), str_lit("armv7-r,avoid-partial-cpsr,db,dsp,hwdiv,perfmon,r4,rclass,ret-addr-stack,thumb2,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m") }, + { str_lit("cortex-r4f"), str_lit("armv7-r,avoid-partial-cpsr,db,dsp,fp64,fpregs,fpregs64,hwdiv,perfmon,r4,rclass,ret-addr-stack,slow-fp-brcc,slowfpvfmx,slowfpvmlx,thumb2,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3d16,vfp3d16sp") }, + { str_lit("cortex-r5"), str_lit("armv7-r,avoid-partial-cpsr,db,dsp,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,perfmon,r5,rclass,ret-addr-stack,slow-fp-brcc,slowfpvfmx,slowfpvmlx,thumb2,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3d16,vfp3d16sp") }, + { str_lit("cortex-r52"), str_lit("acquire-release,armv8-r,crc,d32,db,dfb,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpao,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,r52,rclass,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-r52plus"), str_lit("acquire-release,armv8-r,crc,d32,db,dfb,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpao,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,r52plus,rclass,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-r7"), str_lit("armv7-r,avoid-partial-cpsr,db,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,perfmon,r7,rclass,ret-addr-stack,slow-fp-brcc,slowfpvfmx,slowfpvmlx,thumb2,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3d16,vfp3d16sp") }, + { str_lit("cortex-r8"), str_lit("armv7-r,avoid-partial-cpsr,db,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,perfmon,rclass,ret-addr-stack,slow-fp-brcc,slowfpvfmx,slowfpvmlx,thumb2,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3d16,vfp3d16sp") }, + { str_lit("cortex-x1"), str_lit("aclass,acquire-release,aes,armv8.2-a,cortex-x1,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cortex-x1c"), str_lit("aclass,acquire-release,aes,armv8.2-a,cortex-x1c,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("cyclone"), str_lit("aclass,acquire-release,aes,armv8-a,avoid-movs-shop,avoid-partial-cpsr,crc,crypto,d32,db,disable-postra-scheduler,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,neonfp,perfmon,ret-addr-stack,sha2,slowfpvfmx,slowfpvmlx,swift,thumb2,trustzone,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,zcz") }, + { str_lit("ep9312"), str_lit("armv4t,v4t") }, + { str_lit("exynos-m3"), str_lit("aclass,acquire-release,aes,armv8-a,crc,crypto,d32,db,dont-widen-vmovs,dsp,expand-fp-mlx,exynos,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,fuse-aes,fuse-literals,hwdiv,hwdiv-arm,mp,neon,perfmon,prof-unpr,ret-addr-stack,sha2,slow-fp-brcc,slow-vdup32,slow-vgetlni32,slowfpvfmx,slowfpvmlx,splat-vfp-neon,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,wide-stride-vfp,zcz") }, + { str_lit("exynos-m4"), str_lit("aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dont-widen-vmovs,dotprod,dsp,expand-fp-mlx,exynos,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,fuse-aes,fuse-literals,hwdiv,hwdiv-arm,mp,neon,perfmon,prof-unpr,ras,ret-addr-stack,sha2,slow-fp-brcc,slow-vdup32,slow-vgetlni32,slowfpvfmx,slowfpvmlx,splat-vfp-neon,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,wide-stride-vfp,zcz") }, + { str_lit("exynos-m5"), str_lit("aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dont-widen-vmovs,dotprod,dsp,expand-fp-mlx,exynos,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,fuse-aes,fuse-literals,hwdiv,hwdiv-arm,mp,neon,perfmon,prof-unpr,ras,ret-addr-stack,sha2,slow-fp-brcc,slow-vdup32,slow-vgetlni32,slowfpvfmx,slowfpvmlx,splat-vfp-neon,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization,wide-stride-vfp,zcz") }, + { str_lit("generic"), str_lit("") }, + { str_lit("iwmmxt"), str_lit("armv5te,v4t,v5t,v5te") }, + { str_lit("krait"), str_lit("aclass,armv7-a,avoid-partial-cpsr,d32,db,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,krait,muxed-units,perfmon,ret-addr-stack,thumb2,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,vldn-align,vmlx-forwarding") }, + { str_lit("kryo"), str_lit("aclass,acquire-release,aes,armv8-a,crc,crypto,d32,db,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,kryo,mp,neon,perfmon,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("mpcore"), str_lit("armv6k,fp64,fpregs,fpregs64,slowfpvmlx,v4t,v5t,v5te,v6,v6k,vfp2,vfp2sp") }, + { str_lit("mpcorenovfp"), str_lit("armv6k,v4t,v5t,v5te,v6,v6k") }, + { str_lit("neoverse-n1"), str_lit("aclass,acquire-release,aes,armv8.2-a,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("neoverse-n2"), str_lit("aclass,acquire-release,armv9-a,bf16,crc,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp16fml,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,i8mm,mp,neon,perfmon,ras,sb,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8m,v9a,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("neoverse-v1"), str_lit("aclass,acquire-release,aes,armv8.4-a,bf16,crc,crypto,d32,db,dotprod,dsp,fp-armv8,fp-armv8d16,fp-armv8d16sp,fp-armv8sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,hwdiv-arm,i8mm,mp,neon,perfmon,ras,sha2,thumb2,trustzone,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8,v8.1a,v8.2a,v8.3a,v8.4a,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,virtualization") }, + { str_lit("sc000"), str_lit("armv6-m,db,mclass,no-branch-predictor,noarm,strict-align,thumb-mode,v4t,v5t,v5te,v6,v6m") }, + { str_lit("sc300"), str_lit("armv7-m,db,hwdiv,m3,mclass,no-branch-predictor,noarm,thumb-mode,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m") }, + { str_lit("star-mc1"), str_lit("8msecext,acquire-release,armv8-m.main,avoid-muls,db,dsp,fix-cmse-cve-2021-35465,fp-armv8d16sp,fp16,fpregs,hwdiv,loop-align,mclass,no-branch-predictor,noarm,slowfpvfmx,slowfpvmlx,thumb-mode,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,v8m.main,vfp2sp,vfp3d16sp,vfp4d16sp") }, + { str_lit("strongarm"), str_lit("armv4") }, + { str_lit("strongarm110"), str_lit("armv4") }, + { str_lit("strongarm1100"), str_lit("armv4") }, + { str_lit("strongarm1110"), str_lit("armv4") }, + { str_lit("swift"), str_lit("aclass,armv7-a,avoid-movs-shop,avoid-partial-cpsr,d32,db,disable-postra-scheduler,dsp,fp16,fp64,fpregs,fpregs64,hwdiv,hwdiv-arm,mp,neonfp,perfmon,prefer-ishst,prof-unpr,ret-addr-stack,slow-load-D-subreg,slow-odd-reg,slow-vdup32,slow-vgetlni32,slowfpvfmx,slowfpvmlx,swift,thumb2,use-misched,v4t,v5t,v5te,v6,v6k,v6m,v6t2,v7,v7clrex,v8m,vfp2,vfp2sp,vfp3,vfp3d16,vfp3d16sp,vfp3sp,vfp4,vfp4d16,vfp4d16sp,vfp4sp,vmlx-hazards,wide-stride-vfp") }, + { str_lit("xscale"), str_lit("armv5te,v4t,v5t,v5te") }, + // TargetArch_arm64: + { str_lit("a64fx"), str_lit("CONTEXTIDREL2,a64fx,aes,aggressive-fma,arith-bcc-fusion,ccpp,complxnum,crc,el2vmsa,el3,fp-armv8,fullfp16,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rdm,sha2,store-pair-suppress,sve,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") }, + { str_lit("ampere1"), str_lit("CONTEXTIDREL2,aes,aggressive-fma,altnzcv,alu-lsl-fast,am,ampere1,amvs,arith-bcc-fusion,bf16,bti,ccdp,ccidx,ccpp,cmp-bcc-fusion,complxnum,crc,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fptoint,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-literals,i8mm,jsconv,ldp-aligned-only,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,rand,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,stp-aligned-only,tlb-rmi,tracev8.4,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8a,vh") }, + { str_lit("ampere1a"), str_lit("CONTEXTIDREL2,aes,aggressive-fma,altnzcv,alu-lsl-fast,am,ampere1a,amvs,arith-bcc-fusion,bf16,bti,ccdp,ccidx,ccpp,cmp-bcc-fusion,complxnum,crc,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fptoint,fullfp16,fuse-address,fuse-addsub-2reg-const1,fuse-adrp-add,fuse-aes,fuse-literals,i8mm,jsconv,ldp-aligned-only,lor,lse,lse2,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predres,rand,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,sm4,specrestrict,ssbs,store-pair-suppress,stp-aligned-only,tlb-rmi,tracev8.4,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8a,vh") }, + { str_lit("ampere1b"), str_lit("CONTEXTIDREL2,aes,aggressive-fma,altnzcv,alu-lsl-fast,am,ampere1b,amvs,arith-bcc-fusion,bf16,bti,ccdp,ccidx,ccpp,cmp-bcc-fusion,complxnum,crc,cssc,dit,dotprod,ecv,el2vmsa,el3,enable-select-opt,fgt,flagm,fp-armv8,fptoint,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-literals,hcx,i8mm,jsconv,ldp-aligned-only,lor,lse,lse2,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,rand,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,sm4,specrestrict,ssbs,store-pair-suppress,stp-aligned-only,tlb-rmi,tracev8.4,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8a,vh,wfxt,xs") }, + { str_lit("apple-a10"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,apple-a10,arith-bcc-fusion,arith-cbz-fusion,crc,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fuse-aes,fuse-crypto-eor,lor,neon,pan,perfmon,rdm,sha2,store-pair-suppress,v8a,vh,zcm-fpr64,zcm-gpr64,zcz,zcz-gp") }, + { str_lit("apple-a11"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,apple-a11,arith-bcc-fusion,arith-cbz-fusion,ccpp,crc,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fullfp16,fuse-aes,fuse-crypto-eor,lor,lse,neon,pan,pan-rwv,perfmon,ras,rdm,sha2,store-pair-suppress,uaops,v8.1a,v8.2a,v8a,vh,zcm-fpr64,zcm-gpr64,zcz,zcz-gp") }, + { str_lit("apple-a12"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,apple-a12,arith-bcc-fusion,arith-cbz-fusion,ccpp,complxnum,crc,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fullfp16,fuse-aes,fuse-crypto-eor,jsconv,lor,lse,neon,pan,pan-rwv,pauth,perfmon,ras,rcpc,rdm,sha2,store-pair-suppress,uaops,v8.1a,v8.2a,v8.3a,v8a,vh,zcm-fpr64,zcm-gpr64,zcz,zcz-gp") }, + { str_lit("apple-a13"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,am,apple-a13,arith-bcc-fusion,arith-cbz-fusion,ccpp,complxnum,crc,disable-latency-sched-heuristic,dit,dotprod,el2vmsa,el3,flagm,fp-armv8,fp16fml,fullfp16,fuse-aes,fuse-crypto-eor,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,ras,rcpc,rcpc-immo,rdm,sel2,sha2,sha3,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8a,vh,zcm-fpr64,zcm-gpr64,zcz,zcz-gp") }, + { str_lit("apple-a14"), str_lit("CONTEXTIDREL2,aes,aggressive-fma,alternate-sextload-cvt-f32-pattern,altnzcv,am,apple-a14,arith-bcc-fusion,arith-cbz-fusion,ccdp,ccpp,complxnum,crc,disable-latency-sched-heuristic,dit,dotprod,el2vmsa,el3,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8a,vh,zcm-fpr64,zcm-gpr64,zcz,zcz-gp") }, + { str_lit("apple-a15"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,altnzcv,am,amvs,apple-a15,arith-bcc-fusion,arith-cbz-fusion,bf16,bti,ccdp,ccpp,complxnum,crc,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fpac,fptoint,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,i8mm,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8a,vh,zcm-fpr64,zcm-gpr64,zcz,zcz-gp") }, + { str_lit("apple-a16"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,altnzcv,am,amvs,apple-a16,arith-bcc-fusion,arith-cbz-fusion,bf16,bti,ccdp,ccpp,complxnum,crc,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fpac,fptoint,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,hcx,i8mm,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8a,vh,zcm-fpr64,zcm-gpr64,zcz,zcz-gp") }, + { str_lit("apple-a17"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,altnzcv,am,amvs,apple-a17,arith-bcc-fusion,arith-cbz-fusion,bf16,bti,ccdp,ccpp,complxnum,crc,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fpac,fptoint,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,hcx,i8mm,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8a,vh,zcm-fpr64,zcm-gpr64,zcz,zcz-gp") }, + { str_lit("apple-a18"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,altnzcv,am,amvs,apple-m4,arith-bcc-fusion,arith-cbz-fusion,bf16,bti,ccdp,ccpp,complxnum,crc,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fpac,fptoint,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,hcx,i8mm,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,sme,sme-f64f64,sme-i16i64,sme2,specrestrict,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8a,vh,wfxt,xs,zcm-fpr64,zcm-gpr64,zcz,zcz-gp") }, + { str_lit("apple-a7"), str_lit("aes,alternate-sextload-cvt-f32-pattern,apple-a7,arith-bcc-fusion,arith-cbz-fusion,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fuse-aes,fuse-crypto-eor,neon,perfmon,sha2,store-pair-suppress,v8a,zcm-fpr64,zcm-gpr64,zcz,zcz-fp-workaround,zcz-gp") }, + { str_lit("apple-a8"), str_lit("aes,alternate-sextload-cvt-f32-pattern,apple-a7,arith-bcc-fusion,arith-cbz-fusion,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fuse-aes,fuse-crypto-eor,neon,perfmon,sha2,store-pair-suppress,v8a,zcm-fpr64,zcm-gpr64,zcz,zcz-fp-workaround,zcz-gp") }, + { str_lit("apple-a9"), str_lit("aes,alternate-sextload-cvt-f32-pattern,apple-a7,arith-bcc-fusion,arith-cbz-fusion,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fuse-aes,fuse-crypto-eor,neon,perfmon,sha2,store-pair-suppress,v8a,zcm-fpr64,zcm-gpr64,zcz,zcz-fp-workaround,zcz-gp") }, + { str_lit("apple-m1"), str_lit("CONTEXTIDREL2,aes,aggressive-fma,alternate-sextload-cvt-f32-pattern,altnzcv,am,apple-a14,arith-bcc-fusion,arith-cbz-fusion,ccdp,ccpp,complxnum,crc,disable-latency-sched-heuristic,dit,dotprod,el2vmsa,el3,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8a,vh,zcm-fpr64,zcm-gpr64,zcz,zcz-gp") }, + { str_lit("apple-m2"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,altnzcv,am,amvs,apple-a15,arith-bcc-fusion,arith-cbz-fusion,bf16,bti,ccdp,ccpp,complxnum,crc,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fpac,fptoint,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,i8mm,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8a,vh,zcm-fpr64,zcm-gpr64,zcz,zcz-gp") }, + { str_lit("apple-m3"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,altnzcv,am,amvs,apple-a16,arith-bcc-fusion,arith-cbz-fusion,bf16,bti,ccdp,ccpp,complxnum,crc,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fpac,fptoint,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,hcx,i8mm,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8a,vh,zcm-fpr64,zcm-gpr64,zcz,zcz-gp") }, + { str_lit("apple-m4"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,altnzcv,am,amvs,apple-m4,arith-bcc-fusion,arith-cbz-fusion,bf16,bti,ccdp,ccpp,complxnum,crc,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fpac,fptoint,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,hcx,i8mm,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,sme,sme-f64f64,sme-i16i64,sme2,specrestrict,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8a,vh,wfxt,xs,zcm-fpr64,zcm-gpr64,zcz,zcz-gp") }, + { str_lit("apple-s10"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,altnzcv,am,amvs,apple-a16,arith-bcc-fusion,arith-cbz-fusion,bf16,bti,ccdp,ccpp,complxnum,crc,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fpac,fptoint,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,hcx,i8mm,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8a,vh,zcm-fpr64,zcm-gpr64,zcz,zcz-gp") }, + { str_lit("apple-s4"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,apple-a12,arith-bcc-fusion,arith-cbz-fusion,ccpp,complxnum,crc,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fullfp16,fuse-aes,fuse-crypto-eor,jsconv,lor,lse,neon,pan,pan-rwv,pauth,perfmon,ras,rcpc,rdm,sha2,store-pair-suppress,uaops,v8.1a,v8.2a,v8.3a,v8a,vh,zcm-fpr64,zcm-gpr64,zcz,zcz-gp") }, + { str_lit("apple-s5"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,apple-a12,arith-bcc-fusion,arith-cbz-fusion,ccpp,complxnum,crc,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fullfp16,fuse-aes,fuse-crypto-eor,jsconv,lor,lse,neon,pan,pan-rwv,pauth,perfmon,ras,rcpc,rdm,sha2,store-pair-suppress,uaops,v8.1a,v8.2a,v8.3a,v8a,vh,zcm-fpr64,zcm-gpr64,zcz,zcz-gp") }, + { str_lit("apple-s6"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,am,apple-a13,arith-bcc-fusion,arith-cbz-fusion,ccpp,complxnum,crc,disable-latency-sched-heuristic,dit,dotprod,el2vmsa,el3,flagm,fp-armv8,fp16fml,fullfp16,fuse-aes,fuse-crypto-eor,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,ras,rcpc,rcpc-immo,rdm,sel2,sha2,sha3,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8a,vh,zcm-fpr64,zcm-gpr64,zcz,zcz-gp") }, + { str_lit("apple-s7"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,am,apple-a13,arith-bcc-fusion,arith-cbz-fusion,ccpp,complxnum,crc,disable-latency-sched-heuristic,dit,dotprod,el2vmsa,el3,flagm,fp-armv8,fp16fml,fullfp16,fuse-aes,fuse-crypto-eor,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,ras,rcpc,rcpc-immo,rdm,sel2,sha2,sha3,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8a,vh,zcm-fpr64,zcm-gpr64,zcz,zcz-gp") }, + { str_lit("apple-s8"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,am,apple-a13,arith-bcc-fusion,arith-cbz-fusion,ccpp,complxnum,crc,disable-latency-sched-heuristic,dit,dotprod,el2vmsa,el3,flagm,fp-armv8,fp16fml,fullfp16,fuse-aes,fuse-crypto-eor,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,ras,rcpc,rcpc-immo,rdm,sel2,sha2,sha3,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8a,vh,zcm-fpr64,zcm-gpr64,zcz,zcz-gp") }, + { str_lit("apple-s9"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,altnzcv,am,amvs,apple-a16,arith-bcc-fusion,arith-cbz-fusion,bf16,bti,ccdp,ccpp,complxnum,crc,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fpac,fptoint,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-arith-logic,fuse-crypto-eor,fuse-csel,fuse-literals,hcx,i8mm,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,specrestrict,ssbs,store-pair-suppress,tlb-rmi,tracev8.4,uaops,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8a,vh,zcm-fpr64,zcm-gpr64,zcz,zcz-gp") }, + { str_lit("carmel"), str_lit("CONTEXTIDREL2,aes,carmel,ccpp,crc,el2vmsa,el3,fp-armv8,fullfp16,lor,lse,neon,pan,pan-rwv,ras,rdm,sha2,uaops,v8.1a,v8.2a,v8a,vh") }, + { str_lit("cobalt-100"), str_lit("CONTEXTIDREL2,altnzcv,alu-lsl-fast,am,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,dit,dotprod,el2vmsa,el3,enable-select-opt,ete,flagm,fp-armv8,fp16fml,fpac,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mpam,mte,neon,neoversen2,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,specrestrict,ssbs,sve,sve-bitperm,sve2,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, + { str_lit("cortex-a320"), str_lit("CONTEXTIDREL2,a320,altnzcv,am,amvs,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,dit,dotprod,ecv,el2vmsa,el3,ete,fgt,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-adrp-add,fuse-aes,hcx,i8mm,jsconv,lor,lse,lse2,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,specrestrict,ssbs,sve,sve-bitperm,sve2,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8a,v9.1a,v9.2a,v9a,vh,wfxt,xs") }, + { str_lit("cortex-a34"), str_lit("a35,aes,crc,el2vmsa,el3,fp-armv8,neon,perfmon,sha2,v8a") }, + { str_lit("cortex-a35"), str_lit("a35,aes,crc,el2vmsa,el3,fp-armv8,neon,perfmon,sha2,v8a") }, + { str_lit("cortex-a510"), str_lit("CONTEXTIDREL2,a510,altnzcv,am,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,dit,dotprod,el2vmsa,el3,ete,flagm,fp-armv8,fp16fml,fpac,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,specrestrict,ssbs,sve,sve-bitperm,sve2,tlb-rmi,tracev8.4,trbe,uaops,use-fixed-over-scalable-if-equal-cost,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, + { str_lit("cortex-a520"), str_lit("CONTEXTIDREL2,a520,altnzcv,am,amvs,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,dit,dotprod,ecv,el2vmsa,el3,ete,fgt,flagm,fp-armv8,fp16fml,fpac,fptoint,fullfp16,fuse-adrp-add,fuse-aes,hcx,i8mm,jsconv,lor,lse,lse2,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,specrestrict,ssbs,sve,sve-bitperm,sve2,tlb-rmi,tracev8.4,trbe,uaops,use-fixed-over-scalable-if-equal-cost,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8a,v9.1a,v9.2a,v9a,vh,wfxt,xs") }, + { str_lit("cortex-a520ae"), str_lit("CONTEXTIDREL2,a520ae,altnzcv,am,amvs,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,dit,dotprod,ecv,el2vmsa,el3,ete,fgt,flagm,fp-armv8,fp16fml,fpac,fptoint,fullfp16,fuse-adrp-add,fuse-aes,hcx,i8mm,jsconv,lor,lse,lse2,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,specrestrict,ssbs,sve,sve-bitperm,sve2,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8a,v9.1a,v9.2a,v9a,vh,wfxt,xs") }, + { str_lit("cortex-a53"), str_lit("a53,aes,balance-fp-ops,crc,el2vmsa,el3,fp-armv8,fuse-adrp-add,fuse-aes,neon,perfmon,sha2,use-postra-scheduler,v8a") }, + { str_lit("cortex-a55"), str_lit("CONTEXTIDREL2,a55,aes,ccpp,crc,dotprod,el2vmsa,el3,fp-armv8,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,lor,lse,neon,pan,pan-rwv,perfmon,ras,rcpc,rdm,sha2,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") }, + { str_lit("cortex-a57"), str_lit("a57,addr-lsl-slow-14,aes,balance-fp-ops,crc,el2vmsa,el3,enable-select-opt,fp-armv8,fuse-adrp-add,fuse-aes,fuse-literals,neon,perfmon,predictable-select-expensive,sha2,use-postra-scheduler,v8a") }, + { str_lit("cortex-a65"), str_lit("CONTEXTIDREL2,a65,aes,ccpp,crc,dotprod,el2vmsa,el3,enable-select-opt,fp-armv8,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-literals,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,ssbs,uaops,v8.1a,v8.2a,v8a,vh") }, + { str_lit("cortex-a65ae"), str_lit("CONTEXTIDREL2,a65,aes,ccpp,crc,dotprod,el2vmsa,el3,enable-select-opt,fp-armv8,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-literals,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,ssbs,uaops,v8.1a,v8.2a,v8a,vh") }, + { str_lit("cortex-a710"), str_lit("CONTEXTIDREL2,a710,altnzcv,alu-lsl-fast,am,bf16,bti,ccdp,ccidx,ccpp,cmp-bcc-fusion,complxnum,crc,dit,dotprod,el2vmsa,el3,enable-select-opt,ete,flagm,fp-armv8,fp16fml,fpac,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,specrestrict,ssbs,sve,sve-bitperm,sve2,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, + { str_lit("cortex-a715"), str_lit("CONTEXTIDREL2,a715,altnzcv,alu-lsl-fast,am,bf16,bti,ccdp,ccidx,ccpp,cmp-bcc-fusion,complxnum,crc,dit,dotprod,el2vmsa,el3,enable-select-opt,ete,flagm,fp-armv8,fp16fml,fpac,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,spe,specrestrict,ssbs,sve,sve-bitperm,sve2,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, + { str_lit("cortex-a72"), str_lit("a72,addr-lsl-slow-14,aes,crc,el2vmsa,el3,enable-select-opt,fp-armv8,fuse-adrp-add,fuse-aes,fuse-literals,neon,perfmon,predictable-select-expensive,sha2,v8a") }, + { str_lit("cortex-a720"), str_lit("CONTEXTIDREL2,a720,altnzcv,alu-lsl-fast,am,amvs,bf16,bti,ccdp,ccidx,ccpp,cmp-bcc-fusion,complxnum,crc,dit,dotprod,ecv,el2vmsa,el3,enable-select-opt,ete,fgt,flagm,fp-armv8,fp16fml,fpac,fptoint,fullfp16,fuse-adrp-add,fuse-aes,hcx,i8mm,jsconv,lor,lse,lse2,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,spe,spe-eef,specrestrict,ssbs,sve,sve-bitperm,sve2,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8a,v9.1a,v9.2a,v9a,vh,wfxt,xs") }, + { str_lit("cortex-a720ae"), str_lit("CONTEXTIDREL2,a720ae,altnzcv,alu-lsl-fast,am,amvs,bf16,bti,ccdp,ccidx,ccpp,cmp-bcc-fusion,complxnum,crc,dit,dotprod,ecv,el2vmsa,el3,enable-select-opt,ete,fgt,flagm,fp-armv8,fp16fml,fpac,fptoint,fullfp16,fuse-adrp-add,fuse-aes,hcx,i8mm,jsconv,lor,lse,lse2,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,spe,spe-eef,specrestrict,ssbs,sve,sve-bitperm,sve2,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8a,v9.1a,v9.2a,v9a,vh,wfxt,xs") }, + { str_lit("cortex-a725"), str_lit("CONTEXTIDREL2,altnzcv,alu-lsl-fast,am,amvs,bf16,bti,ccdp,ccidx,ccpp,cmp-bcc-fusion,complxnum,cortex-a725,crc,dit,dotprod,ecv,el2vmsa,el3,enable-select-opt,ete,fgt,flagm,fp-armv8,fp16fml,fpac,fptoint,fullfp16,fuse-adrp-add,fuse-aes,hcx,i8mm,jsconv,lor,lse,lse2,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,spe,spe-eef,specrestrict,ssbs,sve,sve-bitperm,sve2,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8a,v9.1a,v9.2a,v9a,vh,wfxt,xs") }, + { str_lit("cortex-a73"), str_lit("a73,addr-lsl-slow-14,aes,crc,el2vmsa,el3,enable-select-opt,fp-armv8,fuse-adrp-add,fuse-aes,neon,perfmon,predictable-select-expensive,sha2,v8a") }, + { str_lit("cortex-a75"), str_lit("CONTEXTIDREL2,a75,addr-lsl-slow-14,aes,ccpp,crc,dotprod,el2vmsa,el3,enable-select-opt,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,uaops,v8.1a,v8.2a,v8a,vh") }, + { str_lit("cortex-a76"), str_lit("CONTEXTIDREL2,a76,addr-lsl-slow-14,aes,alu-lsl-fast,ccpp,crc,dotprod,el2vmsa,el3,enable-select-opt,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,ssbs,uaops,v8.1a,v8.2a,v8a,vh") }, + { str_lit("cortex-a76ae"), str_lit("CONTEXTIDREL2,a76,addr-lsl-slow-14,aes,alu-lsl-fast,ccpp,crc,dotprod,el2vmsa,el3,enable-select-opt,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,ssbs,uaops,v8.1a,v8.2a,v8a,vh") }, + { str_lit("cortex-a77"), str_lit("CONTEXTIDREL2,a77,addr-lsl-slow-14,aes,alu-lsl-fast,ccpp,cmp-bcc-fusion,crc,dotprod,el2vmsa,el3,enable-select-opt,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,ssbs,uaops,v8.1a,v8.2a,v8a,vh") }, + { str_lit("cortex-a78"), str_lit("CONTEXTIDREL2,a78,addr-lsl-slow-14,aes,alu-lsl-fast,ccpp,cmp-bcc-fusion,crc,dotprod,el2vmsa,el3,enable-select-opt,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,spe,ssbs,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") }, + { str_lit("cortex-a78ae"), str_lit("CONTEXTIDREL2,a78ae,addr-lsl-slow-14,aes,alu-lsl-fast,ccpp,cmp-bcc-fusion,crc,dotprod,el2vmsa,el3,enable-select-opt,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,spe,ssbs,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") }, + { str_lit("cortex-a78c"), str_lit("CONTEXTIDREL2,a78c,addr-lsl-slow-14,aes,alu-lsl-fast,ccpp,cmp-bcc-fusion,crc,dotprod,el2vmsa,el3,enable-select-opt,flagm,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,neon,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,spe,ssbs,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") }, + { str_lit("cortex-r82"), str_lit("CONTEXTIDREL2,ccdp,ccpp,complxnum,cortex-r82,crc,dit,dotprod,flagm,fp-armv8,fp16fml,fpac,fullfp16,jsconv,lse,neon,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,specrestrict,ssbs,tlb-rmi,tracev8.4,uaops,use-postra-scheduler,v8r") }, + { str_lit("cortex-r82ae"), str_lit("CONTEXTIDREL2,ccdp,ccpp,complxnum,cortex-r82ae,crc,dit,dotprod,flagm,fp-armv8,fp16fml,fpac,fullfp16,jsconv,lse,neon,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,specrestrict,ssbs,tlb-rmi,tracev8.4,uaops,use-postra-scheduler,v8r") }, + { str_lit("cortex-x1"), str_lit("CONTEXTIDREL2,addr-lsl-slow-14,aes,alu-lsl-fast,ccpp,cmp-bcc-fusion,cortex-x1,crc,dotprod,el2vmsa,el3,enable-select-opt,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,neon,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,spe,ssbs,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") }, + { str_lit("cortex-x1c"), str_lit("CONTEXTIDREL2,addr-lsl-slow-14,aes,alu-lsl-fast,ccpp,cmp-bcc-fusion,cortex-x1,crc,dotprod,el2vmsa,el3,enable-select-opt,flagm,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,lse2,neon,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,ras,rcpc,rcpc-immo,rdm,sha2,spe,ssbs,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") }, + { str_lit("cortex-x2"), str_lit("CONTEXTIDREL2,altnzcv,alu-lsl-fast,am,bf16,bti,ccdp,ccidx,ccpp,cmp-bcc-fusion,complxnum,cortex-x2,crc,dit,dotprod,el2vmsa,el3,enable-select-opt,ete,flagm,fp-armv8,fp16fml,fpac,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,specrestrict,ssbs,sve,sve-bitperm,sve2,tlb-rmi,tracev8.4,trbe,uaops,use-fixed-over-scalable-if-equal-cost,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, + { str_lit("cortex-x3"), str_lit("CONTEXTIDREL2,altnzcv,alu-lsl-fast,am,avoid-ldapur,bf16,bti,ccdp,ccidx,ccpp,complxnum,cortex-x3,crc,dit,dotprod,el2vmsa,el3,enable-select-opt,ete,flagm,fp-armv8,fp16fml,fpac,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,spe,specrestrict,ssbs,sve,sve-bitperm,sve2,tlb-rmi,tracev8.4,trbe,uaops,use-fixed-over-scalable-if-equal-cost,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, + { str_lit("cortex-x4"), str_lit("CONTEXTIDREL2,altnzcv,alu-lsl-fast,am,amvs,avoid-ldapur,bf16,bti,ccdp,ccidx,ccpp,complxnum,cortex-x4,crc,dit,dotprod,ecv,el2vmsa,el3,enable-select-opt,ete,fgt,flagm,fp-armv8,fp16fml,fpac,fptoint,fullfp16,fuse-adrp-add,fuse-aes,hcx,i8mm,jsconv,lor,lse,lse2,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,spe,spe-eef,specrestrict,ssbs,sve,sve-bitperm,sve2,tlb-rmi,tracev8.4,trbe,uaops,use-fixed-over-scalable-if-equal-cost,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8a,v9.1a,v9.2a,v9a,vh,wfxt,xs") }, + { str_lit("cortex-x925"), str_lit("CONTEXTIDREL2,altnzcv,alu-lsl-fast,am,amvs,avoid-ldapur,bf16,bti,ccdp,ccidx,ccpp,complxnum,cortex-x925,crc,dit,dotprod,ecv,el2vmsa,el3,enable-select-opt,ete,fgt,flagm,fp-armv8,fp16fml,fpac,fptoint,fullfp16,fuse-adrp-add,fuse-aes,hcx,i8mm,jsconv,lor,lse,lse2,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,spe,spe-eef,specrestrict,ssbs,sve,sve-bitperm,sve2,tlb-rmi,tracev8.4,trbe,uaops,use-fixed-over-scalable-if-equal-cost,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8a,v9.1a,v9.2a,v9a,vh,wfxt,xs") }, + { str_lit("cyclone"), str_lit("aes,alternate-sextload-cvt-f32-pattern,apple-a7,arith-bcc-fusion,arith-cbz-fusion,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fuse-aes,fuse-crypto-eor,neon,perfmon,sha2,store-pair-suppress,v8a,zcm-fpr64,zcm-gpr64,zcz,zcz-fp-workaround,zcz-gp") }, + { str_lit("exynos-m3"), str_lit("aes,alu-lsl-fast,crc,el2vmsa,el3,exynos-cheap-as-move,exynosm3,force-32bit-jump-tables,fp-armv8,fuse-address,fuse-adrp-add,fuse-aes,fuse-csel,fuse-literals,neon,perfmon,predictable-select-expensive,sha2,store-pair-suppress,use-postra-scheduler,v8a") }, + { str_lit("exynos-m4"), str_lit("CONTEXTIDREL2,aes,alu-lsl-fast,arith-bcc-fusion,arith-cbz-fusion,ccpp,crc,dotprod,el2vmsa,el3,exynos-cheap-as-move,exynosm4,force-32bit-jump-tables,fp-armv8,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-arith-logic,fuse-csel,fuse-literals,lor,lse,neon,pan,pan-rwv,perfmon,ras,rdm,sha2,store-pair-suppress,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh,zcz,zcz-gp") }, + { str_lit("exynos-m5"), str_lit("CONTEXTIDREL2,aes,alu-lsl-fast,arith-bcc-fusion,arith-cbz-fusion,ccpp,crc,dotprod,el2vmsa,el3,exynos-cheap-as-move,exynosm4,force-32bit-jump-tables,fp-armv8,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-arith-logic,fuse-csel,fuse-literals,lor,lse,neon,pan,pan-rwv,perfmon,ras,rdm,sha2,store-pair-suppress,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh,zcz,zcz-gp") }, + { str_lit("falkor"), str_lit("aes,alu-lsl-fast,crc,el2vmsa,el3,falkor,fp-armv8,neon,perfmon,predictable-select-expensive,rdm,sha2,slow-strqro-store,store-pair-suppress,use-postra-scheduler,v8a,zcz,zcz-gp") }, + { str_lit("fujitsu-monaka"), str_lit("CONTEXTIDREL2,aes,altnzcv,am,amvs,arith-bcc-fusion,bf16,bti,ccdp,ccidx,ccpp,clrbhb,complxnum,crc,dit,dotprod,ecv,el2vmsa,el3,enable-select-opt,ete,faminmax,fgt,flagm,fp-armv8,fp16fml,fp8,fp8dot2,fp8dot4,fp8fma,fpac,fptoint,fujitsu-monaka,fullfp16,hbc,hcx,i8mm,jsconv,lor,ls64,lse,lse2,lut,mec,mops,mpam,neon,nmi,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,rand,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,sha2,sha3,sm4,specres2,specrestrict,ssbs,sve,sve-aes,sve-bitperm,sve-sha3,sve-sm4,sve2,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8.8a,v8a,v9.1a,v9.2a,v9.3a,v9a,vh,wfxt,xs") }, + { str_lit("gb10"), str_lit("CONTEXTIDREL2,aes,altnzcv,alu-lsl-fast,am,amvs,avoid-ldapur,bf16,bti,ccdp,ccidx,ccpp,complxnum,cortex-x925,crc,dit,dotprod,ecv,el2vmsa,el3,enable-select-opt,ete,fgt,flagm,fp-armv8,fp16fml,fpac,fptoint,fullfp16,fuse-adrp-add,fuse-aes,hcx,i8mm,jsconv,lor,lse,lse2,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,sm4,spe,spe-eef,specrestrict,ssbs,sve,sve-aes,sve-bitperm,sve-sha3,sve-sm4,sve2,tlb-rmi,tracev8.4,trbe,uaops,use-fixed-over-scalable-if-equal-cost,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8a,v9.1a,v9.2a,v9a,vh,wfxt,xs") }, + { str_lit("generic"), str_lit("enable-select-opt,ete,fp-armv8,fuse-adrp-add,fuse-aes,neon,trbe,use-postra-scheduler") }, + { str_lit("grace"), str_lit("CONTEXTIDREL2,aes,altnzcv,alu-lsl-fast,am,avoid-ldapur,bf16,bti,ccdp,ccidx,ccpp,cmp-bcc-fusion,complxnum,crc,disable-latency-sched-heuristic,dit,dotprod,el2vmsa,el3,enable-select-opt,ete,flagm,fp-armv8,fp16fml,fpac,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mpam,mte,neon,neoversev2,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,rand,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,sm4,spe,specrestrict,ssbs,sve,sve-aes,sve-bitperm,sve-sha3,sve-sm4,sve2,tlb-rmi,tracev8.4,trbe,uaops,use-fixed-over-scalable-if-equal-cost,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, + { str_lit("kryo"), str_lit("aes,alu-lsl-fast,crc,el2vmsa,el3,fp-armv8,kryo,neon,perfmon,predictable-select-expensive,sha2,store-pair-suppress,use-postra-scheduler,v8a,zcz,zcz-gp") }, + { str_lit("neoverse-512tvb"), str_lit("CONTEXTIDREL2,aes,alu-lsl-fast,am,bf16,ccdp,ccidx,ccpp,complxnum,crc,dit,dotprod,el2vmsa,el3,enable-select-opt,flagm,fp-armv8,fp16fml,fpac,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mpam,neon,neoverse512tvb,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,rand,ras,rcpc,rcpc-immo,rdm,sel2,sha2,sha3,sm4,spe,ssbs,sve,tlb-rmi,tracev8.4,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8a,vh") }, + { str_lit("neoverse-e1"), str_lit("CONTEXTIDREL2,aes,ccpp,crc,dotprod,el2vmsa,el3,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,neon,neoversee1,pan,pan-rwv,perfmon,ras,rcpc,rdm,sha2,ssbs,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") }, + { str_lit("neoverse-n1"), str_lit("CONTEXTIDREL2,addr-lsl-slow-14,aes,alu-lsl-fast,ccpp,crc,dotprod,el2vmsa,el3,enable-select-opt,fp-armv8,fullfp16,fuse-adrp-add,fuse-aes,lor,lse,neon,neoversen1,pan,pan-rwv,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,spe,ssbs,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") }, + { str_lit("neoverse-n2"), str_lit("CONTEXTIDREL2,altnzcv,alu-lsl-fast,am,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,dit,dotprod,el2vmsa,el3,enable-select-opt,ete,flagm,fp-armv8,fp16fml,fpac,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mpam,mte,neon,neoversen2,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,sb,sel2,specrestrict,ssbs,sve,sve-bitperm,sve2,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, + { str_lit("neoverse-n3"), str_lit("CONTEXTIDREL2,altnzcv,alu-lsl-fast,am,amvs,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,dit,dotprod,ecv,el2vmsa,el3,enable-select-opt,ete,fgt,flagm,fp-armv8,fp16fml,fpac,fptoint,fullfp16,fuse-adrp-add,fuse-aes,hcx,i8mm,jsconv,lor,lse,lse2,mpam,mte,neon,neoversen3,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,rand,ras,rcpc,rcpc-immo,rdm,sb,sel2,spe,spe-eef,specrestrict,ssbs,sve,sve-bitperm,sve2,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8a,v9.1a,v9.2a,v9a,vh,wfxt,xs") }, + { str_lit("neoverse-v1"), str_lit("CONTEXTIDREL2,addr-lsl-slow-14,aes,alu-lsl-fast,am,bf16,ccdp,ccidx,ccpp,complxnum,crc,dit,dotprod,el2vmsa,el3,enable-select-opt,flagm,fp-armv8,fp16fml,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mpam,neon,neoversev1,no-sve-fp-ld1r,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,rand,ras,rcpc,rcpc-immo,rdm,sel2,sha2,sha3,sm4,spe,ssbs,sve,tlb-rmi,tracev8.4,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8a,vh") }, + { str_lit("neoverse-v2"), str_lit("CONTEXTIDREL2,altnzcv,alu-lsl-fast,am,avoid-ldapur,bf16,bti,ccdp,ccidx,ccpp,cmp-bcc-fusion,complxnum,crc,disable-latency-sched-heuristic,dit,dotprod,el2vmsa,el3,enable-select-opt,ete,flagm,fp-armv8,fp16fml,fpac,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mpam,mte,neon,neoversev2,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,rand,ras,rcpc,rcpc-immo,rdm,sb,sel2,spe,specrestrict,ssbs,sve,sve-bitperm,sve2,tlb-rmi,tracev8.4,trbe,uaops,use-fixed-over-scalable-if-equal-cost,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, + { str_lit("neoverse-v3"), str_lit("CONTEXTIDREL2,altnzcv,alu-lsl-fast,am,amvs,avoid-ldapur,bf16,brbe,bti,ccdp,ccidx,ccpp,complxnum,crc,dit,dotprod,ecv,el2vmsa,el3,enable-select-opt,ete,fgt,flagm,fp-armv8,fp16fml,fpac,fptoint,fullfp16,fuse-adrp-add,fuse-aes,hcx,i8mm,jsconv,lor,ls64,lse,lse2,mpam,mte,neon,neoversev3,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,rand,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,spe,spe-eef,specrestrict,ssbs,sve,sve-bitperm,sve2,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8a,v9.1a,v9.2a,v9a,vh,wfxt,xs") }, + { str_lit("neoverse-v3ae"), str_lit("CONTEXTIDREL2,altnzcv,alu-lsl-fast,am,amvs,avoid-ldapur,bf16,brbe,bti,ccdp,ccidx,ccpp,complxnum,crc,dit,dotprod,ecv,el2vmsa,el3,enable-select-opt,ete,fgt,flagm,fp-armv8,fp16fml,fpac,fptoint,fullfp16,fuse-adrp-add,fuse-aes,hcx,i8mm,jsconv,lor,ls64,lse,lse2,mpam,mte,neon,neoversev3AE,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,rand,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,spe,spe-eef,specrestrict,ssbs,sve,sve-bitperm,sve2,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8a,v9.1a,v9.2a,v9a,vh,wfxt,xs") }, + { str_lit("olympus"), str_lit("CONTEXTIDREL2,aes,altnzcv,alu-lsl-fast,am,amvs,bf16,brbe,bti,ccdp,ccidx,ccpp,chk,cmp-bcc-fusion,complxnum,crc,dit,dotprod,ecv,el2vmsa,el3,enable-select-opt,ete,faminmax,fgt,flagm,fp-armv8,fp16fml,fp8,fp8dot2,fp8dot4,fp8fma,fpac,fptoint,fullfp16,fuse-adrp-add,fuse-aes,hcx,i8mm,jsconv,lor,ls64,lse,lse2,lut,mec,mpam,mte,neon,nv,olympus,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,rand,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,sha2,sha3,sm4,spe,spe-eef,specrestrict,ssbs,sve,sve-aes,sve-bitperm,sve-sha3,sve-sm4,sve2,tlb-rmi,tracev8.4,trbe,uaops,use-fixed-over-scalable-if-equal-cost,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8.7a,v8a,v9.1a,v9.2a,v9a,vh,wfxt,xs") }, + { str_lit("oryon-1"), str_lit("CONTEXTIDREL2,aes,altnzcv,am,amvs,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,dit,dotprod,ecv,el2vmsa,el3,enable-select-opt,fgt,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,fuse-adrp-add,fuse-aes,fuse-crypto-eor,i8mm,jsconv,lor,lse,lse2,mpam,neon,nv,oryon-1,pan,pan-rwv,pauth,perfmon,predres,rand,ras,rcpc,rcpc-immo,rdm,sb,sel2,sha2,sha3,sm4,spe,specrestrict,ssbs,tlb-rmi,tracev8.4,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8.6a,v8a,vh") }, + { str_lit("saphira"), str_lit("CONTEXTIDREL2,aes,alu-lsl-fast,am,ccidx,ccpp,complxnum,crc,dit,dotprod,el2vmsa,el3,flagm,fp-armv8,jsconv,lor,lse,lse2,mpam,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,ras,rcpc,rcpc-immo,rdm,saphira,sel2,sha2,spe,store-pair-suppress,tlb-rmi,tracev8.4,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8.4a,v8a,vh,zcz,zcz-gp") }, + { str_lit("thunderx"), str_lit("aes,crc,el2vmsa,el3,fp-armv8,neon,perfmon,predictable-select-expensive,sha2,store-pair-suppress,thunderx,use-postra-scheduler,v8a") }, + { str_lit("thunderx2t99"), str_lit("CONTEXTIDREL2,aes,aggressive-fma,arith-bcc-fusion,crc,el2vmsa,el3,fp-armv8,lor,lse,neon,pan,predictable-select-expensive,rdm,sha2,store-pair-suppress,thunderx2t99,use-postra-scheduler,v8.1a,v8a,vh") }, + { str_lit("thunderx3t110"), str_lit("CONTEXTIDREL2,aes,aggressive-fma,arith-bcc-fusion,balance-fp-ops,ccidx,ccpp,complxnum,crc,el2vmsa,el3,fp-armv8,jsconv,lor,lse,neon,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,ras,rcpc,rdm,sha2,store-pair-suppress,strict-align,thunderx3t110,uaops,use-postra-scheduler,v8.1a,v8.2a,v8.3a,v8a,vh") }, + { str_lit("thunderxt81"), str_lit("aes,crc,el2vmsa,el3,fp-armv8,neon,perfmon,predictable-select-expensive,sha2,store-pair-suppress,thunderxt81,use-postra-scheduler,v8a") }, + { str_lit("thunderxt83"), str_lit("aes,crc,el2vmsa,el3,fp-armv8,neon,perfmon,predictable-select-expensive,sha2,store-pair-suppress,thunderxt83,use-postra-scheduler,v8a") }, + { str_lit("thunderxt88"), str_lit("aes,crc,el2vmsa,el3,fp-armv8,neon,perfmon,predictable-select-expensive,sha2,store-pair-suppress,thunderxt88,use-postra-scheduler,v8a") }, + { str_lit("tsv110"), str_lit("CONTEXTIDREL2,aes,ccpp,complxnum,crc,dotprod,el2vmsa,el3,fp-armv8,fp16fml,fullfp16,fuse-aes,jsconv,lor,lse,neon,pan,pan-rwv,perfmon,ras,rdm,sha2,spe,store-pair-suppress,tsv110,uaops,use-postra-scheduler,v8.1a,v8.2a,v8a,vh") }, + // TargetArch_wasm32: + { str_lit("bleeding-edge"), str_lit("atomics,bulk-memory,bulk-memory-opt,call-indirect-overlong,exception-handling,extended-const,fp16,multimemory,multivalue,mutable-globals,nontrapping-fptoint,reference-types,relaxed-simd,sign-ext,simd128,tail-call") }, + { str_lit("generic"), str_lit("bulk-memory,bulk-memory-opt,call-indirect-overlong,multivalue,mutable-globals,nontrapping-fptoint,reference-types,sign-ext") }, + { str_lit("lime1"), str_lit("bulk-memory-opt,call-indirect-overlong,extended-const,multivalue,mutable-globals,nontrapping-fptoint,sign-ext") }, + { str_lit("mvp"), str_lit("") }, + // TargetArch_wasm64p32: + { str_lit("bleeding-edge"), str_lit("atomics,bulk-memory,bulk-memory-opt,call-indirect-overlong,exception-handling,extended-const,fp16,multimemory,multivalue,mutable-globals,nontrapping-fptoint,reference-types,relaxed-simd,sign-ext,simd128,tail-call") }, + { str_lit("generic"), str_lit("bulk-memory,bulk-memory-opt,call-indirect-overlong,multivalue,mutable-globals,nontrapping-fptoint,reference-types,sign-ext") }, + { str_lit("lime1"), str_lit("bulk-memory-opt,call-indirect-overlong,extended-const,multivalue,mutable-globals,nontrapping-fptoint,sign-ext") }, + { str_lit("mvp"), str_lit("") }, + // TargetArch_riscv64: + { str_lit("andes-45-series"), str_lit("andes45,no-default-unroll,short-forward-branch-opt,use-postra-scheduler") }, + { str_lit("andes-a25"), str_lit("32bit,a,c,d,f,i,m,xandesperf,zaamo,zalrsc,zca,zicsr,zifencei,zmmul") }, + { str_lit("andes-a45"), str_lit("32bit,a,andes45,c,d,f,i,m,no-default-unroll,short-forward-branch-opt,use-postra-scheduler,xandesperf,zaamo,zalrsc,zca,zicsr,zifencei,zmmul") }, + { str_lit("andes-ax25"), str_lit("64bit,a,c,d,f,i,m,xandesperf,zaamo,zalrsc,zca,zicsr,zifencei,zmmul") }, + { str_lit("andes-ax45"), str_lit("64bit,a,andes45,c,d,f,i,m,no-default-unroll,short-forward-branch-opt,use-postra-scheduler,xandesperf,zaamo,zalrsc,zca,zicsr,zifencei,zmmul") }, + { str_lit("andes-ax45mpv"), str_lit("64bit,a,andes45,c,d,f,i,m,no-default-unroll,short-forward-branch-opt,use-postra-scheduler,v,xandesperf,zaamo,zalrsc,zca,zicsr,zifencei,zmmul,zve32f,zve32x,zve64d,zve64f,zve64x,zvl128b,zvl32b,zvl64b") }, + { str_lit("andes-n45"), str_lit("32bit,a,andes45,c,d,f,i,m,no-default-unroll,short-forward-branch-opt,use-postra-scheduler,xandesperf,zaamo,zalrsc,zca,zicsr,zifencei,zmmul") }, + { str_lit("andes-nx45"), str_lit("64bit,a,andes45,c,d,f,i,m,no-default-unroll,short-forward-branch-opt,use-postra-scheduler,xandesperf,zaamo,zalrsc,zca,zicsr,zifencei,zmmul") }, + { str_lit("generic"), str_lit("64bit,i,optimized-nf2-segment-load-store") }, + { str_lit("generic-ooo"), str_lit("") }, + { str_lit("generic-rv32"), str_lit("32bit,i,optimized-nf2-segment-load-store") }, + { str_lit("generic-rv64"), str_lit("64bit,i,optimized-nf2-segment-load-store") }, + { str_lit("mips-p8700"), str_lit("64bit,a,c,d,f,i,m,mips-p8700,xmipscbop,xmipscmov,xmipslsp,zaamo,zalrsc,zba,zbb,zca,zicsr,zifencei,zmmul") }, + { str_lit("rocket"), str_lit("") }, + { str_lit("rocket-rv32"), str_lit("32bit,i,zicsr,zifencei") }, + { str_lit("rocket-rv64"), str_lit("64bit,i,zicsr,zifencei") }, + { str_lit("rp2350-hazard3"), str_lit("32bit,a,c,i,m,zaamo,zalrsc,zba,zbb,zbkb,zbs,zca,zcb,zcmp,zicsr,zifencei,zmmul") }, + { str_lit("sifive-7-series"), str_lit("no-default-unroll,short-forward-branch-opt,sifive7,use-postra-scheduler") }, + { str_lit("sifive-e20"), str_lit("32bit,c,i,m,zca,zicsr,zifencei,zmmul") }, + { str_lit("sifive-e21"), str_lit("32bit,a,c,i,m,zaamo,zalrsc,zca,zicsr,zifencei,zmmul") }, + { str_lit("sifive-e24"), str_lit("32bit,a,c,f,i,m,zaamo,zalrsc,zca,zicsr,zifencei,zmmul") }, + { str_lit("sifive-e31"), str_lit("32bit,a,c,i,m,zaamo,zalrsc,zca,zicsr,zifencei,zmmul") }, + { str_lit("sifive-e34"), str_lit("32bit,a,c,f,i,m,zaamo,zalrsc,zca,zicsr,zifencei,zmmul") }, + { str_lit("sifive-e76"), str_lit("32bit,a,c,f,i,m,no-default-unroll,short-forward-branch-opt,sifive7,use-postra-scheduler,zaamo,zalrsc,zca,zicsr,zifencei,zmmul") }, + { str_lit("sifive-p450"), str_lit("64bit,a,auipc-addi-fusion,b,c,conditional-cmv-fusion,d,f,i,lui-addi-fusion,m,no-default-unroll,unaligned-scalar-mem,unaligned-vector-mem,use-postra-scheduler,za64rs,zaamo,zalrsc,zba,zbb,zbs,zca,zfhmin,zic64b,zicbom,zicbop,zicboz,ziccamoa,ziccif,zicclsm,ziccrse,zicntr,zicsr,zifencei,zihintntl,zihintpause,zihpm,zkt,zmmul") }, + { str_lit("sifive-p470"), str_lit("64bit,a,auipc-addi-fusion,b,c,conditional-cmv-fusion,d,f,i,lui-addi-fusion,m,no-default-unroll,no-sink-splat-operands,unaligned-scalar-mem,unaligned-vector-mem,use-postra-scheduler,v,vxrm-pipeline-flush,xsifivecdiscarddlone,xsifivecflushdlone,za64rs,zaamo,zalrsc,zba,zbb,zbs,zca,zfhmin,zic64b,zicbom,zicbop,zicboz,ziccamoa,ziccif,zicclsm,ziccrse,zicntr,zicsr,zifencei,zihintntl,zihintpause,zihpm,zkt,zmmul,zvbb,zvbc,zve32f,zve32x,zve64d,zve64f,zve64x,zvkb,zvkg,zvkn,zvknc,zvkned,zvkng,zvknhb,zvks,zvksc,zvksed,zvksg,zvksh,zvkt,zvl128b,zvl32b,zvl64b") }, + { str_lit("sifive-p550"), str_lit("64bit,a,auipc-addi-fusion,c,conditional-cmv-fusion,d,f,i,lui-addi-fusion,m,no-default-unroll,use-postra-scheduler,zaamo,zalrsc,zba,zbb,zca,zicsr,zifencei,zmmul") }, + { str_lit("sifive-p670"), str_lit("64bit,a,auipc-addi-fusion,b,c,conditional-cmv-fusion,d,f,i,lui-addi-fusion,m,no-default-unroll,no-sink-splat-operands,unaligned-scalar-mem,unaligned-vector-mem,use-postra-scheduler,v,vxrm-pipeline-flush,za64rs,zaamo,zalrsc,zba,zbb,zbs,zca,zfhmin,zic64b,zicbom,zicbop,zicboz,ziccamoa,ziccif,zicclsm,ziccrse,zicntr,zicsr,zifencei,zihintntl,zihintpause,zihpm,zkt,zmmul,zvbb,zvbc,zve32f,zve32x,zve64d,zve64f,zve64x,zvkb,zvkg,zvkn,zvknc,zvkned,zvkng,zvknhb,zvks,zvksc,zvksed,zvksg,zvksh,zvkt,zvl128b,zvl32b,zvl64b") }, + { str_lit("sifive-p870"), str_lit("64bit,a,auipc-addi-fusion,b,c,conditional-cmv-fusion,d,f,i,lui-addi-fusion,m,no-default-unroll,no-sink-splat-operands,supm,unaligned-scalar-mem,unaligned-vector-mem,use-postra-scheduler,v,vxrm-pipeline-flush,za64rs,zaamo,zalrsc,zama16b,zawrs,zba,zbb,zbs,zca,zcb,zcmop,zfa,zfbfmin,zfh,zfhmin,zic64b,zicbom,zicbop,zicboz,ziccamoa,ziccif,zicclsm,ziccrse,zicntr,zicond,zicsr,zifencei,zihintntl,zihintpause,zihpm,zimop,zkr,zkt,zmmul,zvbb,zvbc,zve32f,zve32x,zve64d,zve64f,zve64x,zvfbfmin,zvfbfwma,zvfh,zvfhmin,zvkb,zvkg,zvkn,zvknc,zvkned,zvkng,zvknhb,zvks,zvksc,zvksed,zvksg,zvksh,zvkt,zvl128b,zvl32b,zvl64b") }, + { str_lit("sifive-s21"), str_lit("64bit,a,c,i,m,zaamo,zalrsc,zca,zicsr,zifencei,zmmul") }, + { str_lit("sifive-s51"), str_lit("64bit,a,c,i,m,zaamo,zalrsc,zca,zicsr,zifencei,zmmul") }, + { str_lit("sifive-s54"), str_lit("64bit,a,c,d,f,i,m,zaamo,zalrsc,zca,zicsr,zifencei,zmmul") }, + { str_lit("sifive-s76"), str_lit("64bit,a,c,d,f,i,m,no-default-unroll,short-forward-branch-opt,sifive7,use-postra-scheduler,zaamo,zalrsc,zca,zicsr,zifencei,zihintpause,zmmul") }, + { str_lit("sifive-u54"), str_lit("64bit,a,c,d,f,i,m,zaamo,zalrsc,zca,zicsr,zifencei,zmmul") }, + { str_lit("sifive-u74"), str_lit("64bit,a,c,d,f,i,m,no-default-unroll,short-forward-branch-opt,sifive7,use-postra-scheduler,zaamo,zalrsc,zca,zicsr,zifencei,zmmul") }, + { str_lit("sifive-x280"), str_lit("64bit,a,c,d,dlen-factor-2,f,i,m,no-default-unroll,optimized-nf2-segment-load-store,optimized-zero-stride-load,short-forward-branch-opt,sifive7,use-postra-scheduler,v,vl-dependent-latency,zaamo,zalrsc,zba,zbb,zca,zfh,zfhmin,zicsr,zifencei,zmmul,zve32f,zve32x,zve64d,zve64f,zve64x,zvfh,zvfhmin,zvl128b,zvl256b,zvl32b,zvl512b,zvl64b") }, + { str_lit("sifive-x390"), str_lit("64bit,a,b,c,d,dlen-factor-2,experimental-zicfilp,experimental-zicfiss,f,i,m,no-default-unroll,optimized-nf2-segment-load-store,optimized-zero-stride-load,short-forward-branch-opt,sifive7,use-postra-scheduler,v,vl-dependent-latency,xsifivecdiscarddlone,xsifivecflushdlone,za64rs,zaamo,zalrsc,zawrs,zba,zbb,zbs,zca,zcb,zcmop,zfa,zfbfmin,zfh,zfhmin,zic64b,zicbom,zicbop,zicboz,ziccamoa,ziccif,ziccrse,zicntr,zicond,zicsr,zifencei,zihintntl,zihintpause,zihpm,zimop,zkr,zkt,zmmul,zvbb,zve32f,zve32x,zve64d,zve64f,zve64x,zvfbfmin,zvfbfwma,zvfh,zvfhmin,zvkb,zvkt,zvl1024b,zvl128b,zvl256b,zvl32b,zvl512b,zvl64b") }, + { str_lit("spacemit-x60"), str_lit("64bit,a,b,c,d,dlen-factor-2,f,i,m,optimized-nf2-segment-load-store,optimized-nf3-segment-load-store,optimized-nf4-segment-load-store,ssccptr,sscofpmf,sscounterenw,sstc,sstvala,sstvecd,svade,svbare,svinval,svnapot,svpbmt,unaligned-scalar-mem,v,vxrm-pipeline-flush,za64rs,zaamo,zalrsc,zba,zbb,zbc,zbkc,zbs,zca,zfh,zfhmin,zic64b,zicbom,zicbop,zicboz,ziccamoa,ziccif,zicclsm,ziccrse,zicntr,zicond,zicsr,zifencei,zihintpause,zihpm,zkt,zmmul,zve32f,zve32x,zve64d,zve64f,zve64x,zvfh,zvfhmin,zvkt,zvl128b,zvl256b,zvl32b,zvl64b") }, + { str_lit("syntacore-scr1-base"), str_lit("32bit,c,i,no-default-unroll,zca,zicsr,zifencei") }, + { str_lit("syntacore-scr1-max"), str_lit("32bit,c,i,m,no-default-unroll,zca,zicsr,zifencei,zmmul") }, + { str_lit("syntacore-scr3-rv32"), str_lit("32bit,c,i,m,no-default-unroll,use-postra-scheduler,zca,zicsr,zifencei,zmmul") }, + { str_lit("syntacore-scr3-rv64"), str_lit("64bit,a,c,i,m,no-default-unroll,use-postra-scheduler,zaamo,zalrsc,zca,zicsr,zifencei,zmmul") }, + { str_lit("syntacore-scr4-rv32"), str_lit("32bit,c,d,f,i,m,no-default-unroll,use-postra-scheduler,zca,zicsr,zifencei,zmmul") }, + { str_lit("syntacore-scr4-rv64"), str_lit("64bit,a,c,d,f,i,m,no-default-unroll,use-postra-scheduler,zaamo,zalrsc,zca,zicsr,zifencei,zmmul") }, + { str_lit("syntacore-scr5-rv32"), str_lit("32bit,a,c,d,f,i,m,no-default-unroll,use-postra-scheduler,zaamo,zalrsc,zca,zicsr,zifencei,zmmul") }, + { str_lit("syntacore-scr5-rv64"), str_lit("64bit,a,c,d,f,i,m,no-default-unroll,use-postra-scheduler,zaamo,zalrsc,zca,zicsr,zifencei,zmmul") }, + { str_lit("syntacore-scr7"), str_lit("64bit,a,c,d,f,i,m,no-default-unroll,use-postra-scheduler,v,zaamo,zalrsc,zba,zbb,zbc,zbkb,zbkc,zbkx,zbs,zca,zicsr,zifencei,zkn,zknd,zkne,zknh,zmmul,zve32f,zve32x,zve64d,zve64f,zve64x,zvl128b,zvl32b,zvl64b") }, + { str_lit("tt-ascalon-d8"), str_lit("64bit,a,b,c,d,f,h,i,log-vrgather,m,no-default-unroll,optimized-zero-stride-load,sha,shcounterenw,shgatpa,shtvala,shvsatpa,shvstvala,shvstvecd,smaia,ssaia,ssccptr,sscofpmf,sscounterenw,ssnpm,ssstateen,ssstrict,sstc,sstvala,sstvecd,ssu64xl,supm,svade,svbare,svinval,svnapot,svpbmt,unaligned-scalar-mem,unaligned-vector-mem,use-postra-scheduler,v,za64rs,zaamo,zalrsc,zawrs,zba,zbb,zbs,zca,zcb,zcmop,zfa,zfbfmin,zfh,zfhmin,zic64b,zicbom,zicbop,zicboz,ziccamoa,ziccif,zicclsm,ziccrse,zicntr,zicond,zicsr,zifencei,zihintntl,zihintpause,zihpm,zimop,zkt,zmmul,zvbb,zvbc,zve32f,zve32x,zve64d,zve64f,zve64x,zvfbfmin,zvfbfwma,zvfh,zvfhmin,zvkb,zvkg,zvkn,zvkned,zvkng,zvknhb,zvkt,zvl128b,zvl256b,zvl32b,zvl64b") }, + { str_lit("veyron-v1"), str_lit("64bit,a,auipc-addi-fusion,c,d,f,i,ld-add-fusion,lui-addi-fusion,m,shifted-zextw-fusion,ventana-veyron,xventanacondops,zaamo,zalrsc,zba,zbb,zbc,zbs,zca,zexth-fusion,zextw-fusion,zicbom,zicbop,zicboz,zicntr,zicsr,zifencei,zihintpause,zihpm,zmmul") }, + { str_lit("xiangshan-kunminghu"), str_lit("64bit,a,b,c,d,f,h,i,m,no-default-unroll,sha,shcounterenw,shgatpa,shifted-zextw-fusion,shtvala,shvsatpa,shvstvala,shvstvecd,smaia,smcsrind,smdbltrp,smmpm,smnpm,smrnmi,smstateen,ssaia,ssccptr,sscofpmf,sscounterenw,sscsrind,ssdbltrp,ssnpm,sspm,ssstateen,ssstrict,sstc,sstvala,sstvecd,ssu64xl,supm,svade,svbare,svinval,svnapot,svpbmt,v,za64rs,zaamo,zacas,zalrsc,zawrs,zba,zbb,zbc,zbkb,zbkc,zbkx,zbs,zca,zcb,zcmop,zexth-fusion,zextw-fusion,zfa,zfh,zfhmin,zic64b,zicbom,zicbop,zicboz,ziccamoa,ziccif,zicclsm,ziccrse,zicntr,zicond,zicsr,zifencei,zihintntl,zihintpause,zihpm,zimop,zkn,zknd,zkne,zknh,zks,zksed,zksh,zkt,zmmul,zvbb,zve32f,zve32x,zve64d,zve64f,zve64x,zvfh,zvfhmin,zvkb,zvkt,zvl128b,zvl32b,zvl64b") }, + { str_lit("xiangshan-nanhu"), str_lit("64bit,a,c,d,f,i,m,no-default-unroll,shifted-zextw-fusion,svinval,zaamo,zalrsc,zba,zbb,zbc,zbkb,zbkc,zbkx,zbs,zca,zexth-fusion,zextw-fusion,zicbom,zicboz,zicsr,zifencei,zkn,zknd,zkne,zknh,zksed,zksh,zmmul") }, +}; +#elif LLVM_VERSION_MAJOR == 20 // Generated with the featuregen script in `misc/featuregen` gb_global String target_microarch_list[TargetArch_COUNT] = { // TargetArch_Invalid: diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 398797900..f8cef97ee 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -13,6 +13,7 @@ gb_global BuiltinTypeIsProc *builtin_type_is_procs[BuiltinProc__type_simple_bool nullptr, // BuiltinProc__type_simple_boolean_begin is_type_boolean, + is_type_bit_field, is_type_integer, is_type_rune, is_type_float, @@ -24,6 +25,7 @@ gb_global BuiltinTypeIsProc *builtin_type_is_procs[BuiltinProc__type_simple_bool is_type_cstring16, is_type_typeid, is_type_any, + is_type_endian_platform, is_type_endian_little, is_type_endian_big, @@ -34,8 +36,8 @@ gb_global BuiltinTypeIsProc *builtin_type_is_procs[BuiltinProc__type_simple_bool is_type_indexable, is_type_sliceable, is_type_comparable, - is_type_simple_compare, - is_type_nearly_simple_compare, + is_type_simple_compare, // easily compared using memcmp + is_type_nearly_simple_compare, // easily compared using memcmp (including floats) is_type_dereferenceable, is_type_valid_for_keys, is_type_valid_for_matrix_elems, @@ -47,14 +49,12 @@ gb_global BuiltinTypeIsProc *builtin_type_is_procs[BuiltinProc__type_simple_bool is_type_enumerated_array, is_type_slice, is_type_dynamic_array, - is_type_map, is_type_struct, is_type_union, is_type_enum, is_type_proc, is_type_bit_set, - is_type_bit_field, is_type_simd_vector, is_type_matrix, is_type_raw_union, @@ -4769,6 +4769,42 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As break; } + case BuiltinProc_constant_floor: + case BuiltinProc_constant_trunc: + case BuiltinProc_constant_ceil: + case BuiltinProc_constant_round: + { + Operand o = {}; + check_expr(c, &o, ce->args[0]); + + if (!is_type_integer_or_float(o.type) && (o.mode != Addressing_Constant)) { + error(ce->args[0], "Expected a constant number for '%.*s'", LIT(builtin_name)); + return false; + } + operand->mode = Addressing_Constant; + operand->type = o.type; + + ExactValue value = o.value; + if (value.kind == ExactValue_Integer) { + // do nothing + } else if (value.kind == ExactValue_Float) { + f64 f = value.value_float; + switch (id) { + case BuiltinProc_constant_floor: f = floor(f); break; + case BuiltinProc_constant_trunc: f = trunc(f); break; + case BuiltinProc_constant_ceil: f = ceil(f); break; + case BuiltinProc_constant_round: f = round(f); break; + default: + GB_PANIC("Unhandled built-in: %.*s", LIT(builtin_name)); + break; + } + value = exact_value_float(f); + } + + operand->value = value; + break; + } + case BuiltinProc_soa_struct: { Operand x = {}; Operand y = {}; @@ -6553,17 +6589,18 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As case BuiltinProc_type_is_boolean: + case BuiltinProc_type_is_bit_field: case BuiltinProc_type_is_integer: case BuiltinProc_type_is_rune: case BuiltinProc_type_is_float: case BuiltinProc_type_is_complex: case BuiltinProc_type_is_quaternion: - case BuiltinProc_type_is_typeid: - case BuiltinProc_type_is_any: case BuiltinProc_type_is_string: case BuiltinProc_type_is_string16: case BuiltinProc_type_is_cstring: case BuiltinProc_type_is_cstring16: + case BuiltinProc_type_is_typeid: + case BuiltinProc_type_is_any: case BuiltinProc_type_is_endian_platform: case BuiltinProc_type_is_endian_little: case BuiltinProc_type_is_endian_big: @@ -6574,8 +6611,8 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As case BuiltinProc_type_is_indexable: case BuiltinProc_type_is_sliceable: case BuiltinProc_type_is_comparable: - case BuiltinProc_type_is_simple_compare: - case BuiltinProc_type_is_nearly_simple_compare: + case BuiltinProc_type_is_simple_compare: // easily compared using memcmp + case BuiltinProc_type_is_nearly_simple_compare: // easily compared using memcmp (including floats) case BuiltinProc_type_is_dereferenceable: case BuiltinProc_type_is_valid_map_key: case BuiltinProc_type_is_valid_matrix_elements: @@ -6592,7 +6629,6 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As case BuiltinProc_type_is_enum: case BuiltinProc_type_is_proc: case BuiltinProc_type_is_bit_set: - case BuiltinProc_type_is_bit_field: case BuiltinProc_type_is_simd_vector: case BuiltinProc_type_is_matrix: case BuiltinProc_type_is_raw_union: diff --git a/src/check_expr.cpp b/src/check_expr.cpp index e22f12323..8ac277917 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -9200,6 +9200,52 @@ gb_internal ExprKind check_basic_directive_expr(CheckerContext *c, Operand *o, A return kind; } + +gb_internal void check_expr_as_value_for_ternary(CheckerContext *c, Operand *o, Ast *e, Type *type_hint) { + check_expr_base(c, o, e, type_hint); + check_not_tuple(c, o); + error_operand_no_value(o); + + switch (o->mode) { + case Addressing_Type: { + ERROR_BLOCK(); + gbString expr_str = expr_to_string(o->expr); + defer (gb_string_free(expr_str)); + + error(o->expr, "A type '%s' cannot be used as a runtime value", expr_str); + + error_line("\tSuggestion: If a runtime 'typeid' is wanted, use 'typeid_of' to convert a type\n"); + + o->mode = Addressing_Invalid; + + } break; + + case Addressing_Builtin: { + ERROR_BLOCK(); + gbString expr_str = expr_to_string(o->expr); + defer (gb_string_free(expr_str)); + + error(o->expr, "A built-in procedure '%s' cannot be used as a runtime value", expr_str); + + error_line("\tNote: Built-in procedures are implemented by the compiler and might not be actually instantiated procedures\n"); + + o->mode = Addressing_Invalid; + } break; + + case Addressing_ProcGroup: { + ERROR_BLOCK(); + gbString expr_str = expr_to_string(o->expr); + defer (gb_string_free(expr_str)); + + error(o->expr, "Cannot use overloaded procedure '%s' as a runtime value", expr_str); + + error_line("\tNote: Please specify which procedure in the procedure group to use, via cast or type inference\n"); + + o->mode = Addressing_Invalid; + } break; + } +} + gb_internal ExprKind check_ternary_if_expr(CheckerContext *c, Operand *o, Ast *node, Type *type_hint) { ExprKind kind = Expr_Expr; Operand cond = {Addressing_Invalid}; @@ -9213,7 +9259,7 @@ gb_internal ExprKind check_ternary_if_expr(CheckerContext *c, Operand *o, Ast *n Operand x = {Addressing_Invalid}; Operand y = {Addressing_Invalid}; - check_expr_or_type(c, &x, te->x, type_hint); + check_expr_as_value_for_ternary(c, &x, te->x, type_hint); node->viral_state_flags |= te->x->viral_state_flags; if (te->y != nullptr) { @@ -9221,7 +9267,7 @@ gb_internal ExprKind check_ternary_if_expr(CheckerContext *c, Operand *o, Ast *n if (type_hint == nullptr && is_type_typed(x.type)) { th = x.type; } - check_expr_or_type(c, &y, te->y, th); + check_expr_as_value_for_ternary(c, &y, te->y, th); node->viral_state_flags |= te->y->viral_state_flags; } else { error(node, "A ternary expression must have an else clause"); @@ -9248,6 +9294,20 @@ gb_internal ExprKind check_ternary_if_expr(CheckerContext *c, Operand *o, Ast *n return kind; } + if (x.mode == Addressing_Builtin && y.mode == Addressing_Builtin) { + if (type_hint == nullptr) { + error(node, "Built-in procedures cannot be used within a ternary expression since they have no well-defined signature"); + return kind; + } + } + + if (x.mode == Addressing_ProcGroup && y.mode == Addressing_ProcGroup) { + if (type_hint == nullptr) { + error(node, "Procedure groups cannot be used within a ternary expression since they have no well-defined signature that can be inferred without a context"); + return kind; + } + } + // NOTE(bill, 2023-01-30): Allow for expression like this: // x: union{f32} = f32(123) if cond else nil if (type_hint && !is_type_any(type_hint)) { diff --git a/src/check_type.cpp b/src/check_type.cpp index 0819de217..5accfbd9f 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -1611,6 +1611,12 @@ gb_internal Type *determine_type_from_polymorphic(CheckerContext *ctx, Type *pol error_line("\tSuggestion: Try slicing the value with '%s[:]'\n", os); gb_string_free(os); } + } else if (is_type_pointer(poly_type)) { + if (is_polymorphic_type_assignable(ctx, type_deref(poly_type), operand.type, /*compound*/false, /*modify_type*/false)) { + gbString os = expr_to_string(operand.expr); + error_line("\tSuggestion: Did you mean '&%s'?\n", os); + gb_string_free(os); + } } } return t_invalid; @@ -1627,6 +1633,8 @@ gb_internal bool is_expr_from_a_parameter(CheckerContext *ctx, Ast *expr) { } else if (expr->kind == Ast_Ident) { Operand x= {}; Entity *e = check_ident(ctx, &x, expr, nullptr, nullptr, true); + GB_ASSERT(e != nullptr); + if (e->flags & EntityFlag_Param) { return true; } diff --git a/src/checker.cpp b/src/checker.cpp index 8b3638c9d..1daacd9ce 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -923,6 +923,22 @@ gb_internal AstPackage *get_core_package(CheckerInfo *info, String name) { return *found; } + +gb_internal AstPackage *try_get_core_package(CheckerInfo *info, String name) { + if (name == "runtime") { + return get_runtime_package(info); + } + + gbAllocator a = heap_allocator(); + String path = get_fullpath_core_collection(a, name, nullptr); + defer (gb_free(a, path.text)); + auto found = string_map_get(&info->packages, path); + if (found == nullptr) { + return nullptr; + } + return *found; +} + gb_internal void add_package_dependency(CheckerContext *c, char const *package_name, char const *name, bool required=false) { String n = make_string_c(name); AstPackage *p = get_core_package(&c->checker->info, make_string_c(package_name)); diff --git a/src/checker_builtin_procs.hpp b/src/checker_builtin_procs.hpp index 01502128a..663274cdc 100644 --- a/src/checker_builtin_procs.hpp +++ b/src/checker_builtin_procs.hpp @@ -49,6 +49,11 @@ enum BuiltinProcId { BuiltinProc_constant_log2, + BuiltinProc_constant_floor, + BuiltinProc_constant_trunc, + BuiltinProc_constant_ceil, + BuiltinProc_constant_round, + BuiltinProc_transpose, BuiltinProc_outer_product, BuiltinProc_hadamard_product, @@ -420,7 +425,11 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT("has_target_feature"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("constant_log2"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("constant_log2"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("constant_floor"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("constant_trunc"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("constant_ceil"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("constant_round"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("transpose"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("outer_product"), 2, false, Expr_Expr, BuiltinProcPkg_intrinsics}, @@ -615,17 +624,18 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT(""), 0, false, Expr_Stmt, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_boolean"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("type_is_bit_field"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_integer"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_rune"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_float"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_complex"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_quaternion"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("type_is_typeid"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("type_is_any"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_string"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_string16"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("type_is_cstring"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("type_is_cstring16"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("type_is_cstring"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("type_is_cstring16"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("type_is_typeid"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("type_is_any"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_endian_platform"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_endian_little"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, @@ -656,7 +666,6 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT("type_is_enum"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_proc"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_bit_set"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("type_is_bit_field"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_simd_vector"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_matrix"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_is_raw_union"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, diff --git a/src/common.cpp b/src/common.cpp index 5b007bf2c..d5fc1df4b 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -59,6 +59,11 @@ template struct TypeIsPtrSizedInteger { enum {value = false}; }; template <> struct TypeIsPtrSizedInteger { enum {value = true}; }; template <> struct TypeIsPtrSizedInteger { enum {value = true}; }; +template struct TypeIs64BitInteger { enum {value = false}; }; +template <> struct TypeIs64BitInteger { enum {value = true}; }; +template <> struct TypeIs64BitInteger { enum {value = true}; }; + + #include "unicode.cpp" #include "array.cpp" diff --git a/src/linker.cpp b/src/linker.cpp index f1e0335d5..c2a3ee928 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -105,7 +105,7 @@ gb_internal i32 linker_stage(LinkerData *gen) { gb_printf_err("executing `orca sdk-path` did not produce output\n"); return 1; } - inputs = gb_string_append_fmt(inputs, " \"%s/orca-libc/lib/crt1.o\" \"%s/orca-libc/lib/libc.o\"", orca_sdk_path, orca_sdk_path); + inputs = gb_string_append_fmt(inputs, " \"%s/orca-libc/lib/crt1.o\" \"%s/orca-libc/lib/libc.a\"", orca_sdk_path, orca_sdk_path); extra_orca_flags = gb_string_append_fmt(extra_orca_flags, " -L \"%s/bin\" -lorca_wasm --export-dynamic", orca_sdk_path); } diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp index 9f2faaa08..ec7c63b1a 100644 --- a/src/llvm_abi.cpp +++ b/src/llvm_abi.cpp @@ -144,7 +144,11 @@ gb_internal void lb_add_function_type_attributes(LLVMValueRef fn, lbFunctionType LLVMContextRef c = ft->ctx; LLVMAttributeRef noalias_attr = lb_create_enum_attribute(c, "noalias"); LLVMAttributeRef nonnull_attr = lb_create_enum_attribute(c, "nonnull"); +#if LLVM_VERSION_MAJOR >= 21 + LLVMAttributeRef nocapture_attr = lb_create_string_attribute(c, make_string_c("captures"), make_string_c("none")); +#else LLVMAttributeRef nocapture_attr = lb_create_enum_attribute(c, "nocapture"); +#endif unsigned arg_index = offset; for (unsigned i = 0; i < arg_count; i++) { diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index c2decf091..d6bd7d72d 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -37,12 +37,10 @@ gb_internal String get_default_microarchitecture() { // x86-64-v2: (close to Nehalem) CMPXCHG16B, LAHF-SAHF, POPCNT, SSE3, SSE4.1, SSE4.2, SSSE3 // x86-64-v3: (close to Haswell) AVX, AVX2, BMI1, BMI2, F16C, FMA, LZCNT, MOVBE, XSAVE // x86-64-v4: AVX512F, AVX512BW, AVX512CD, AVX512DQ, AVX512VL - if (ODIN_LLVM_MINIMUM_VERSION_12) { - if (build_context.metrics.os == TargetOs_freestanding) { - default_march = str_lit("x86-64"); - } else { - default_march = str_lit("x86-64-v2"); - } + if (build_context.metrics.os == TargetOs_freestanding) { + default_march = str_lit("x86-64"); + } else { + default_march = str_lit("x86-64-v2"); } } else if (build_context.metrics.arch == TargetArch_riscv64) { default_march = str_lit("generic-rv64"); @@ -2555,6 +2553,8 @@ gb_internal WORKER_TASK_PROC(lb_generate_missing_procedures_to_check_worker_proc } gb_internal void lb_generate_missing_procedures(lbGenerator *gen, bool do_threading) { + isize retry_count = 0; +retry:; if (do_threading) { for (auto const &entry : gen->modules) { lbModule *m = entry.value; @@ -2572,6 +2572,14 @@ gb_internal void lb_generate_missing_procedures(lbGenerator *gen, bool do_thread for (auto const &entry : gen->modules) { lbModule *m = entry.value; + if (m->missing_procedures_to_check.count != 0) { + if (retry_count > gen->modules.count) { + GB_ASSERT(m->missing_procedures_to_check.count == 0); + } + + retry_count += 1; + goto retry; + } GB_ASSERT(m->missing_procedures_to_check.count == 0); GB_ASSERT(m->procedures_to_generate.count == 0); } @@ -2892,7 +2900,18 @@ gb_internal lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *star args[0] = lb_addr_load(p, all_tests_slice); lbValue result = lb_emit_call(p, runner, args); - lbValue exit_runner = lb_find_package_value(m, str_lit("os"), str_lit("exit")); + lbValue exit_runner = {}; + { + AstPackage *pkg = get_runtime_package(m->info); + + String name = str_lit("exit"); + Entity *e = scope_lookup_current(pkg->scope, name); + if (e == nullptr) { + compiler_error("Could not find type declaration for '%.*s.%.*s'\n", LIT(pkg->name), LIT(name)); + } + exit_runner = lb_find_value_from_entity(m, e); + } + auto exit_args = array_make(temporary_allocator(), 1); exit_args[0] = lb_emit_select(p, result, lb_const_int(m, t_int, 0), lb_const_int(m, t_int, 1)); lb_emit_call(p, exit_runner, exit_args, ProcInlining_none); @@ -3038,8 +3057,14 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { LLVMCodeModel code_mode = LLVMCodeModelDefault; if (is_arch_wasm()) { code_mode = LLVMCodeModelJITDefault; + debugf("LLVM code mode: LLVMCodeModelJITDefault\n"); } else if (is_arch_x86() && build_context.metrics.os == TargetOs_freestanding) { code_mode = LLVMCodeModelKernel; + debugf("LLVM code mode: LLVMCodeModelKernel\n"); + } + + if (code_mode == LLVMCodeModelDefault) { + debugf("LLVM code mode: LLVMCodeModelDefault\n"); } String llvm_cpu = get_final_microarchitecture(); @@ -3055,7 +3080,10 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { } first = false; - llvm_features = gb_string_appendc(llvm_features, "+"); + if (*str.text != '+' && *str.text != '-') { + llvm_features = gb_string_appendc(llvm_features, "+"); + } + llvm_features = gb_string_append_length(llvm_features, str.text, str.len); } diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index 9969aaa06..da5d91f2e 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -23,22 +23,8 @@ #include #endif -#if LLVM_VERSION_MAJOR < 11 -#error "LLVM Version 11 is the minimum required" -#elif LLVM_VERSION_MAJOR == 12 && !(LLVM_VERSION_MINOR > 0 || LLVM_VERSION_PATCH > 0) -#error "If LLVM Version 12.x.y is wanted, at least LLVM 12.0.1 is required" -#endif - -#if LLVM_VERSION_MAJOR > 12 || (LLVM_VERSION_MAJOR == 12 && LLVM_VERSION_MINOR >= 0 && LLVM_VERSION_PATCH > 0) -#define ODIN_LLVM_MINIMUM_VERSION_12 1 -#else -#define ODIN_LLVM_MINIMUM_VERSION_12 0 -#endif - -#if LLVM_VERSION_MAJOR > 13 || (LLVM_VERSION_MAJOR == 13 && LLVM_VERSION_MINOR >= 0 && LLVM_VERSION_PATCH > 0) -#define ODIN_LLVM_MINIMUM_VERSION_13 1 -#else -#define ODIN_LLVM_MINIMUM_VERSION_13 0 +#if LLVM_VERSION_MAJOR < 14 +#error "LLVM Version 14 is the minimum required" #endif #if LLVM_VERSION_MAJOR > 14 || (LLVM_VERSION_MAJOR == 14 && LLVM_VERSION_MINOR >= 0 && LLVM_VERSION_PATCH > 0) @@ -431,10 +417,12 @@ gb_internal bool lb_init_generator(lbGenerator *gen, Checker *c); gb_internal String lb_mangle_name(Entity *e); gb_internal String lb_get_entity_name(lbModule *m, Entity *e); +gb_internal LLVMAttributeRef lb_create_string_attribute(LLVMContextRef ctx, String const &key, String const &value); gb_internal LLVMAttributeRef lb_create_enum_attribute(LLVMContextRef ctx, char const *name, u64 value=0); gb_internal LLVMAttributeRef lb_create_enum_attribute_with_type(LLVMContextRef ctx, char const *name, LLVMTypeRef type); gb_internal void lb_add_proc_attribute_at_index(lbProcedure *p, isize index, char const *name, u64 value); gb_internal void lb_add_proc_attribute_at_index(lbProcedure *p, isize index, char const *name); +gb_internal void lb_add_nocapture_proc_attribute_at_index(lbProcedure *p, isize index); gb_internal lbProcedure *lb_create_procedure(lbModule *module, Entity *entity, bool ignore_body=false); diff --git a/src/llvm_backend_const.cpp b/src/llvm_backend_const.cpp index 4c154c85a..c014adc05 100644 --- a/src/llvm_backend_const.cpp +++ b/src/llvm_backend_const.cpp @@ -689,6 +689,22 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb if (bt->Union.variants.count == 0) { return lb_const_nil(m, original_type); } else if (bt->Union.variants.count == 1) { + if (value.kind == ExactValue_Compound) { + ast_node(cl, CompoundLit, value.value_compound); + if (cl->elems.count == 0) { + if (cl->type == nullptr) { + return lb_const_nil(m, original_type); + } + if (are_types_identical(type_of_expr(cl->type), original_type)) { + return lb_const_nil(m, original_type); + } + } + } + + if (value_type == t_untyped_nil) { + return lb_const_nil(m, original_type); + } + Type *t = bt->Union.variants[0]; lbValue cv = lb_const_value(m, t, value, cc); GB_ASSERT(LLVMIsConstant(cv.value)); @@ -729,6 +745,8 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, lb } else if (value.kind == ExactValue_Invalid) { return lb_const_nil(m, original_type); } + } else if (value_type == t_untyped_nil) { + return lb_const_nil(m, original_type); } GB_ASSERT_MSG(value_type != nullptr, "%s :: %s", type_to_string(original_type), exact_value_to_string(value)); diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 0299bdad9..a1756c87e 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -2547,29 +2547,9 @@ gb_internal LLVMAttributeRef lb_create_enum_attribute_with_type(LLVMContextRef c unsigned kind = 0; String s = make_string_c(name); - #if ODIN_LLVM_MINIMUM_VERSION_12 - kind = LLVMGetEnumAttributeKindForName(name, s.len); - GB_ASSERT_MSG(kind != 0, "unknown attribute: %s", name); - return LLVMCreateTypeAttribute(ctx, kind, type); - #else - // NOTE(2021-02-25, bill); All this attributes require a type associated with them - // and the current LLVM C API does not expose this functionality yet. - // It is better to ignore the attributes for the time being - if (s == "byval") { - // return nullptr; - } else if (s == "byref") { - return nullptr; - } else if (s == "preallocated") { - return nullptr; - } else if (s == "sret") { - // return nullptr; - } - - - kind = LLVMGetEnumAttributeKindForName(name, s.len); - GB_ASSERT_MSG(kind != 0, "unknown attribute: %s", name); - return LLVMCreateEnumAttribute(ctx, kind, 0); - #endif + kind = LLVMGetEnumAttributeKindForName(name, s.len); + GB_ASSERT_MSG(kind != 0, "unknown attribute: %s", name); + return LLVMCreateTypeAttribute(ctx, kind, type); } gb_internal LLVMAttributeRef lb_create_enum_attribute(LLVMContextRef ctx, char const *name, u64 value) { @@ -2612,6 +2592,20 @@ gb_internal void lb_add_proc_attribute_at_index(lbProcedure *p, isize index, cha lb_add_proc_attribute_at_index(p, index, name, 0); } +gb_internal void lb_add_proc_attribute_at_index_with_string(lbProcedure *p, isize index, String const &name, String const &value) { + LLVMAttributeRef attr = lb_create_string_attribute(p->module->ctx, name, value); + GB_ASSERT(attr != nullptr); + LLVMAddAttributeAtIndex(p->value, cast(unsigned)index, attr); +} + +gb_internal void lb_add_nocapture_proc_attribute_at_index(lbProcedure *p, isize index) { + #if LLVM_VERSION_MAJOR >= 21 + lb_add_proc_attribute_at_index_with_string(p, index, make_string_c("captures"), make_string_c("none")); + #else + lb_add_proc_attribute_at_index(p, index, "nocapture"); + #endif +} + gb_internal void lb_add_attribute_to_proc(lbModule *m, LLVMValueRef proc_value, char const *name, u64 value=0) { LLVMAddAttributeAtIndex(proc_value, LLVMAttributeIndex_FunctionIndex, lb_create_enum_attribute(m->ctx, name, value)); } @@ -3001,11 +2995,16 @@ gb_internal lbValue lb_find_or_add_entity_string_byte_slice_with_type(lbModule * } else { ptr = LLVMConstNull(lb_type(m, t_u8_ptr)); } + i64 align = MINIMUM_SLICE_ALIGNMENT; if (!is_type_u8_slice(slice_type)) { Type *bt = base_type(slice_type); Type *elem = bt->Slice.elem; i64 sz = type_size_of(elem); + align = gb_max(type_align_of(elem), align); GB_ASSERT(sz > 0); + GB_ASSERT(align > 0); + + LLVMSetAlignment(global_data, (u32)align); ptr = LLVMConstPointerCast(ptr, lb_type(m, alloc_type_pointer(elem))); data_len /= sz; } @@ -3056,11 +3055,16 @@ gb_internal lbValue lb_find_or_add_entity_string16_slice_with_type(lbModule *m, } else { ptr = LLVMConstNull(lb_type(m, t_u8_ptr)); } + i64 align = MINIMUM_SLICE_ALIGNMENT; if (!is_type_u16_slice(slice_type)) { Type *bt = base_type(slice_type); Type *elem = bt->Slice.elem; i64 sz = type_size_of(elem); + align = gb_max(type_align_of(elem), align); GB_ASSERT(sz > 0); + GB_ASSERT(align > 0); + + LLVMSetAlignment(global_data, (u32)align); ptr = LLVMConstPointerCast(ptr, lb_type(m, alloc_type_pointer(elem))); data_len /= sz; } diff --git a/src/llvm_backend_opt.cpp b/src/llvm_backend_opt.cpp index 8d5cfcb70..4971b1f10 100644 --- a/src/llvm_backend_opt.cpp +++ b/src/llvm_backend_opt.cpp @@ -48,13 +48,6 @@ gb_internal void lb_populate_function_pass_manager_specific(lbModule *m, LLVMPas // return LLVMIsAAllocaInst(value) != nullptr; // } - -#if LLVM_VERSION_MAJOR < 12 -#define LLVM_ADD_CONSTANT_VALUE_PASS(fpm) LLVMAddConstantPropagationPass(fpm) -#else -#define LLVM_ADD_CONSTANT_VALUE_PASS(fpm) -#endif - gb_internal bool lb_opt_ignore(i32 optimization_level) { return optimization_level < 0; } @@ -70,7 +63,6 @@ gb_internal void lb_basic_populate_function_pass_manager(LLVMPassManagerRef fpm, } else { LLVMAddPromoteMemoryToRegisterPass(fpm); LLVMAddMergedLoadStoreMotionPass(fpm); - LLVM_ADD_CONSTANT_VALUE_PASS(fpm); if (!build_context.ODIN_DEBUG) { LLVMAddEarlyCSEPass(fpm); } @@ -135,10 +127,8 @@ gb_internal void lb_populate_function_pass_manager_specific(lbModule *m, LLVMPas LLVMAddMemCpyOptPass(fpm); LLVMAddPromoteMemoryToRegisterPass(fpm); LLVMAddMergedLoadStoreMotionPass(fpm); - LLVM_ADD_CONSTANT_VALUE_PASS(fpm); LLVMAddEarlyCSEPass(fpm); - LLVM_ADD_CONSTANT_VALUE_PASS(fpm); LLVMAddMergedLoadStoreMotionPass(fpm); LLVMAddPromoteMemoryToRegisterPass(fpm); LLVMAddCFGSimplificationPass(fpm); @@ -183,7 +173,6 @@ gb_internal void lb_add_function_simplifcation_passes(LLVMPassManagerRef mpm, i3 LLVMAddBitTrackingDCEPass(mpm); LLVMAddJumpThreadingPass(mpm); - LLVM_ADD_CONSTANT_VALUE_PASS(mpm); LLVMAddLICMPass(mpm); LLVMAddLoopRerollPass(mpm); @@ -249,7 +238,6 @@ gb_internal void lb_populate_module_pass_manager(LLVMTargetMachineRef target_mac if (optimization_level >= 2) { LLVMAddEarlyCSEPass(mpm); - LLVM_ADD_CONSTANT_VALUE_PASS(mpm); LLVMAddLICMPass(mpm); LLVMAddLoopUnswitchPass(mpm); LLVMAddCFGSimplificationPass(mpm); diff --git a/src/llvm_backend_passes.cpp b/src/llvm_backend_passes.cpp index bea95ce8e..e9edbace7 100644 --- a/src/llvm_backend_passes.cpp +++ b/src/llvm_backend_passes.cpp @@ -263,7 +263,7 @@ function( ), verify )"); -#else +#else // LLVM 20 & 21 (same config) array_add(&passes, u8R"( annotation2metadata, forceattrs, @@ -656,7 +656,7 @@ function( ), verify )"); -#else +#else // LLVM 20 & 21 (same config) array_add(&passes, u8R"( annotation2metadata, forceattrs, @@ -1052,7 +1052,7 @@ function( ), verify )"); -#else +#else // LLVM 20 & 21 (same config) array_add(&passes, u8R"( annotation2metadata, forceattrs, @@ -1192,4 +1192,4 @@ verify #endif break; - } \ No newline at end of file + } diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 38609bd4e..5b7408214 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -240,8 +240,6 @@ gb_internal lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool i } } } - lb_set_linkage_from_entity_flags(p->module, p->value, entity->flags); - if (p->is_foreign) { lb_set_wasm_procedure_import_attributes(p->value, entity, p->name); @@ -272,7 +270,7 @@ gb_internal lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool i } if (e->flags&EntityFlag_NoCapture) { if (is_type_internally_pointer_like(e->type)) { - lb_add_proc_attribute_at_index(p, offset+parameter_index, "nocapture"); + lb_add_nocapture_proc_attribute_at_index(p, offset+parameter_index); } } parameter_index += 1; @@ -284,6 +282,7 @@ gb_internal lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool i LLVMSetLinkage(p->value, LLVMExternalLinkage); } + lb_set_linkage_from_entity_flags(p->module, p->value, entity->flags); if (m->debug_builder) { // Debug Information Type *bt = base_type(p->type); @@ -430,7 +429,7 @@ gb_internal lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name if (pt->Proc.calling_convention == ProcCC_Odin) { lb_add_proc_attribute_at_index(p, offset+parameter_index, "noalias"); lb_add_proc_attribute_at_index(p, offset+parameter_index, "nonnull"); - lb_add_proc_attribute_at_index(p, offset+parameter_index, "nocapture"); + lb_add_nocapture_proc_attribute_at_index(p, offset+parameter_index); } return p; } diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index 2cddd23d9..c7b4170e9 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -981,9 +981,12 @@ gb_internal lbStructFieldRemapping lb_get_struct_remapping(lbModule *m, Type *t) mutex_lock(&m->types_mutex); - auto *field_remapping = map_get(&m->struct_field_remapping, cast(void *)struct_type); + // NOTE(jakub): It's very important to check the type pointer first, + // because two disctinct but similar structs can end up with the same LLVMTypeRef after interning. + // (For example struct{u16,u8} looks identical to LLVM as struct{u16,u8,u8} once padding fields are inserted.) + auto *field_remapping = map_get(&m->struct_field_remapping, cast(void *)t); if (field_remapping == nullptr) { - field_remapping = map_get(&m->struct_field_remapping, cast(void *)t); + field_remapping = map_get(&m->struct_field_remapping, cast(void *)struct_type); } mutex_unlock(&m->types_mutex); @@ -2102,10 +2105,8 @@ gb_internal LLVMValueRef llvm_get_inline_asm(LLVMTypeRef func_type, String const cast(char *)str.text, cast(size_t)str.len, cast(char *)clobbers.text, cast(size_t)clobbers.len, has_side_effects, is_align_stack, - dialect - #if LLVM_VERSION_MAJOR >= 13 - , /*CanThrow*/false - #endif + dialect, + /*CanThrow*/false ); } @@ -3230,4 +3231,4 @@ gb_internal void lb_do_build_diagnostics(lbGenerator *gen) { lb_do_module_diagnostics(gen); gb_printf("------------------------------------------------------------------------------------------\n"); gb_printf("------------------------------------------------------------------------------------------\n\n"); -} \ No newline at end of file +} diff --git a/src/main.cpp b/src/main.cpp index 6ad20cf26..83e7d688c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -334,6 +334,7 @@ enum BuildFlagKind { BuildFlag_ShowDefineables, BuildFlag_ExportDefineables, + BuildFlag_IgnoreUnusedDefineables, BuildFlag_Vet, BuildFlag_VetShadowing, @@ -391,6 +392,7 @@ enum BuildFlagKind { BuildFlag_MinLinkLibs, BuildFlag_PrintLinkerFlags, + BuildFlag_ExportLinkedLibraries, BuildFlag_IntegerDivisionByZero, @@ -562,6 +564,7 @@ gb_internal bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_ShowDefineables, str_lit("show-defineables"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_ExportDefineables, str_lit("export-defineables"), BuildFlagParam_String, Command__does_check); + add_flag(&build_flags, BuildFlag_IgnoreUnusedDefineables, str_lit("ignore-unused-defineables"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_Vet, str_lit("vet"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_VetUnused, str_lit("vet-unused"), BuildFlagParam_None, Command__does_check); @@ -616,6 +619,7 @@ gb_internal bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_MaxErrorCount, str_lit("max-error-count"), BuildFlagParam_Integer, Command_all); add_flag(&build_flags, BuildFlag_MinLinkLibs, str_lit("min-link-libs"), BuildFlagParam_None, Command__does_build); + add_flag(&build_flags, BuildFlag_ExportLinkedLibraries, str_lit("export-linked-libs-file"), BuildFlagParam_String, Command__does_check); add_flag(&build_flags, BuildFlag_PrintLinkerFlags, str_lit("print-linker-flags"), BuildFlagParam_None, Command_build); @@ -943,6 +947,11 @@ gb_internal bool parse_build_flags(Array args) { break; } + case BuildFlag_IgnoreUnusedDefineables: { + GB_ASSERT(value.kind == ExactValue_Invalid); + build_context.ignore_unused_defineables = true; + break; + } case BuildFlag_ShowSystemCalls: { GB_ASSERT(value.kind == ExactValue_Invalid); build_context.show_system_calls = true; @@ -1547,6 +1556,14 @@ gb_internal bool parse_build_flags(Array args) { build_context.min_link_libs = true; break; + case BuildFlag_ExportLinkedLibraries: + build_context.export_linked_libs_path = string_trim_whitespace(value.value_string); + if (build_context.export_linked_libs_path.len == 0) { + gb_printf_err("-%.*s specified an empty path\n", LIT(name)); + bad_flags = true; + } + break; + case BuildFlag_PrintLinkerFlags: build_context.print_linker_flags = true; break; @@ -2262,6 +2279,63 @@ gb_internal void export_dependencies(Checker *c) { } } +gb_internal void export_linked_libraries(LinkerData *gen) { + gbFile f = {}; + char * fileName = (char *)build_context.export_linked_libs_path.text; + gbFileError err = gb_file_open_mode(&f, gbFileMode_Write, fileName); + if (err != gbFileError_None) { + gb_printf_err("Failed to export linked library list to: %s\n", fileName); + exit_with_errors(); + return; + } + defer (gb_file_close(&f)); + + StringSet min_libs_set = {}; + string_set_init(&min_libs_set, 64); + defer (string_set_destroy(&min_libs_set)); + + for (auto *e : gen->foreign_libraries) { + GB_ASSERT(e->kind == Entity_LibraryName); + ast_node(imp, ForeignImportDecl, e->LibraryName.decl); + + for (isize i = 0; i < e->LibraryName.paths.count; i++) { + String lib_path = string_trim_whitespace(e->LibraryName.paths[i]); + if (lib_path.len == 0) { + continue; + } + + if (string_set_update(&min_libs_set, lib_path)) { + continue; + } + + gb_fprintf(&f, "%.*s\t", LIT(lib_path)); + + String ext = path_extension(lib_path, false); + if (str_eq_ignore_case(ext, "a") || str_eq_ignore_case(ext, "lib") || + str_eq_ignore_case(ext, "o") || str_eq_ignore_case(ext, "obj") + ) { + gb_fprintf(&f, "static"); + } else { + gb_fprintf(&f, "dynamic"); + } + + gb_fprintf(&f, "\t"); + + Ast *file_path = imp->filepaths[i]; + GB_ASSERT(file_path->tav.mode == Addressing_Constant && file_path->tav.value.kind == ExactValue_String); + String file_path_str = file_path->tav.value.value_string; + + if (string_starts_with(file_path_str, str_lit("system:"))) { + gb_fprintf(&f, "system"); + } else { + gb_fprintf(&f, "user"); + } + + gb_fprintf(&f, "\n"); + } + } +} + gb_internal void remove_temp_files(lbGenerator *gen) { if (build_context.keep_temp_files) return; @@ -2815,6 +2889,10 @@ gb_internal int print_show_help(String const arg0, String command, String option print_usage_line(2, "Shows an overview of all the #config/#defined usages in the project."); } + if (print_flag("-ignore-unused-defineables")) { + print_usage_line(2, "Silence warning/error if a -define doesn't have at least one #config/#defined usage."); + } + if (print_flag("-show-system-calls")) { print_usage_line(2, "Prints the whole command and arguments for calls to external tools like linker and assembler."); } @@ -3719,6 +3797,11 @@ int main(int arg_count, char const **arg_ptr) { String item = string_split_iterator(&target_it, ','); if (item == "") break; + if (*item.text == '+' || *item.text == '-') { + item.text++; + item.len--; + } + String invalid; if (!check_target_feature_is_valid_for_target_arch(item, &invalid) && item != str_lit("help")) { if (item != str_lit("?")) { @@ -3768,6 +3851,7 @@ int main(int arg_count, char const **arg_ptr) { if (build_context.show_debug_messages) { debugf("Selected microarch: %.*s\n", LIT(march)); debugf("Default microarch features: %.*s\n", LIT(default_features)); + debugf("Target triplet: %.*s\n", LIT(build_context.metrics.target_triplet)); for_array(i, build_context.build_paths) { String build_path = path_to_string(heap_allocator(), build_context.build_paths[i]); debugf("build_paths[%ld]: %.*s\n", i, LIT(build_path)); @@ -3818,7 +3902,9 @@ int main(int arg_count, char const **arg_ptr) { MAIN_TIME_SECTION("type check"); check_parsed_files(checker); - check_defines(&build_context, checker); + if (!build_context.ignore_unused_defineables) { + check_defines(&build_context, checker); + } if (any_errors()) { print_all_errors(); return 1; @@ -3935,6 +4021,10 @@ int main(int arg_count, char const **arg_ptr) { export_dependencies(checker); } return result; + } else { + if (build_context.export_linked_libs_path != "") { + export_linked_libraries(gen); + } } break; } diff --git a/src/name_canonicalization.cpp b/src/name_canonicalization.cpp index 8bacfabc6..c2acf83f5 100644 --- a/src/name_canonicalization.cpp +++ b/src/name_canonicalization.cpp @@ -417,7 +417,7 @@ gb_internal gbString string_canonical_entity_name(gbAllocator allocator, Entity gb_internal void write_canonical_parent_prefix(TypeWriter *w, Entity *e) { GB_ASSERT(e != nullptr); - if (e->kind == Entity_Procedure || e->kind == Entity_TypeName) { + if (e->kind == Entity_Procedure || e->kind == Entity_TypeName || e->kind == Entity_Variable) { if (e->kind == Entity_Procedure && (e->Procedure.is_export || e->Procedure.is_foreign)) { // no prefix return; @@ -756,6 +756,14 @@ gb_internal void write_type_to_canonical_string(TypeWriter *w, Type *type) { if (i > 0) { type_writer_appendc(w, CANONICAL_FIELD_SEPARATOR); } + + if (f->flags & EntityFlags_IsSubtype) { + type_writer_appendc(w, "#subtype "); + } + + if (f->flags & EntityFlag_Using) { + type_writer_appendc(w, "using "); + } type_writer_append(w, f->token.string.text, f->token.string.len); type_writer_appendc(w, CANONICAL_TYPE_SEPARATOR); write_type_to_canonical_string(w, f->type); diff --git a/src/parser.cpp b/src/parser.cpp index 17590d240..86ba550f5 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -2739,7 +2739,7 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) { while (allow_token(f, Token_Comma)) { Ast *dummy_name = parse_ident(f); if (!err_once) { - error(dummy_name, "'bit_field' fields do not support multiple names per field"); + syntax_error(dummy_name, "'bit_field' fields do not support multiple names per field"); err_once = true; } } @@ -3299,8 +3299,16 @@ gb_internal Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) { open = expect_token(f, Token_OpenBracket); if (f->curr_token.kind == Token_CloseBracket) { - error(f->curr_token, "Expected an operand, got ]"); + ERROR_BLOCK(); + syntax_error(f->curr_token, "Expected an operand, got ]"); close = expect_token(f, Token_CloseBracket); + + if (f->allow_type) { + gbString s = expr_to_string(operand); + error_line("\tSuggestion: If a type was wanted, did you mean '[]%s'?", s); + gb_string_free(s); + } + operand = ast_index_expr(f, operand, nullptr, open, close); break; } @@ -6632,7 +6640,7 @@ gb_internal bool parse_file_tag(const String &lc, const Token &tok, AstFile *f) } else if (lc == "no-instrumentation") { f->flags |= AstFile_NoInstrumentation; } else { - error(tok, "Unknown tag '%.*s'", LIT(lc)); + syntax_error(tok, "Unknown tag '%.*s'", LIT(lc)); } return true; diff --git a/src/ptr_map.cpp b/src/ptr_map.cpp index 61f703cf1..6ee3ec16d 100644 --- a/src/ptr_map.cpp +++ b/src/ptr_map.cpp @@ -10,11 +10,31 @@ enum { enum : MapIndex { MAP_SENTINEL = ~(MapIndex)0 }; -static void *const MAP_TOMBSTONE = (void *)~(uintptr)0; + +template +struct PtrMapConstant { + static gb_inline T const TOMBSTONE() { + return (T)reinterpret_cast(~(uintptr)0); + } +}; + +template <> +struct PtrMapConstant { + static gb_inline u64 const TOMBSTONE() { + return ~(u64)0; + } +}; +template <> +struct PtrMapConstant { + static gb_inline i64 const TOMBSTONE() { + return ~(i64)0; + } +}; template struct PtrMapEntry { - static_assert(sizeof(K) == sizeof(void *), "Key size must be pointer size"); + static_assert(TypeIsPointer::value || TypeIsPtrSizedInteger::value || TypeIs64BitInteger::value, + "PtrMapEntry::K must be a pointer or 8-byte integer"); K key; V value; @@ -99,7 +119,7 @@ gb_internal void map__insert(PtrMap *h, K key, V const &value) { MapIndex original_index = index; do { auto *entry = h->entries+index; - if (!entry->key || entry->key == cast(K)MAP_TOMBSTONE) { + if (!entry->key || entry->key == PtrMapConstant::TOMBSTONE()) { entry->key = key; entry->value = value; h->count += 1; @@ -147,7 +167,7 @@ gb_internal void map_reserve(PtrMap *h, isize cap) { for (u32 i = 0; i < h->capacity; i++) { auto *entry = h->entries+i; if (entry->key && - entry->key != cast(K)MAP_TOMBSTONE) { + entry->key != PtrMapConstant::TOMBSTONE()) { map__insert(&new_h, entry->key, entry->value); } } @@ -257,7 +277,7 @@ template gb_internal void map_remove(PtrMap *h, K key) { MapIndex found_index = 0; if (map_try_get(h, key, &found_index)) { - h->entries[found_index].key = cast(K)MAP_TOMBSTONE; + h->entries[found_index].key = cast(K)PtrMapConstant::TOMBSTONE(); h->count -= 1; } } @@ -367,7 +387,7 @@ struct PtrMapIterator { return *this; } PtrMapEntry *entry = map->entries+index; - if (entry->key && entry->key != cast(K)MAP_TOMBSTONE) { + if (entry->key && entry->key != PtrMapConstant::TOMBSTONE()) { return *this; } } @@ -404,7 +424,7 @@ gb_internal PtrMapIterator begin(PtrMap &m) noexcept { MapIndex index = 0; while (index < m.capacity) { auto key = m.entries[index].key; - if (key && key != cast(K)MAP_TOMBSTONE) { + if (key && key != PtrMapConstant::TOMBSTONE()) { break; } index++; @@ -420,7 +440,7 @@ gb_internal PtrMapIterator const begin(PtrMap const &m) noexcept { MapIndex index = 0; while (index < m.capacity) { auto key = m.entries[index].key; - if (key && key != cast(K)MAP_TOMBSTONE) { + if (key && key != PtrMapConstant::TOMBSTONE()) { break; } index++; @@ -447,7 +467,8 @@ struct MapFindResult { template struct OrderedInsertPtrMapEntry { - static_assert(sizeof(K) == sizeof(void *), "Key size must be pointer size"); + static_assert(TypeIsPointer::value || TypeIsPtrSizedInteger::value || TypeIs64BitInteger::value, + "OrderedInsertPtrMapEntry::K must be a pointer or 8-byte integer"); K key; V value; diff --git a/src/threading.cpp b/src/threading.cpp index 84f09912d..02e6de14b 100644 --- a/src/threading.cpp +++ b/src/threading.cpp @@ -480,6 +480,7 @@ void rwlock_acquire_upgrade(RWSpinLock *l) { } void rwlock_release_upgrade(RWSpinLock *l) { l->bits.fetch_add(-RWLOCK_UPGRADED, std::memory_order_acq_rel); + futex_signal(&l->bits); } bool rwlock_try_release_upgrade_and_acquire_write(RWSpinLock *l) { diff --git a/src/types.cpp b/src/types.cpp index cb830d08d..a1311ba5d 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -2,6 +2,9 @@ struct Ast; struct Scope; struct Entity; +// NOTE(Jeroen): Minimum alignment for #load(file, ) slices +#define MINIMUM_SLICE_ALIGNMENT 16 + enum BasicKind { Basic_Invalid, @@ -1293,6 +1296,15 @@ gb_internal bool is_type_rune(Type *t) { } return false; } +gb_internal bool is_type_integer_or_float(Type *t) { + t = base_type(t); + if (t == nullptr) { return false; } + if (t->kind == Type_Basic) { + return (t->Basic.flags & (BasicFlag_Integer|BasicFlag_Float)) != 0; + } + return false; +} + gb_internal bool is_type_numeric(Type *t) { t = base_type(t); if (t == nullptr) { return false; } diff --git a/src/ucg/ucg.c b/src/ucg/ucg.c index c3e270e1a..119f88805 100644 --- a/src/ucg/ucg.c +++ b/src/ucg/ucg.c @@ -1,6 +1,6 @@ /* * SPDX-FileCopyrightText: (c) 2024 Feoramund - * SPDX-License-Identifier: BSD-3-Clause + * SPDX-License-Identifier: zlib */ diff --git a/src/ucg/ucg_tables.h b/src/ucg/ucg_tables.h index a33f9f898..f31e51773 100644 --- a/src/ucg/ucg_tables.h +++ b/src/ucg/ucg_tables.h @@ -1,6 +1,6 @@ /* * SPDX-FileCopyrightText: (c) 2024 Feoramund - * SPDX-License-Identifier: BSD-3-Clause + * SPDX-License-Identifier: zlib */ #ifndef _UCG_TABLES_INCLUDED #define _UCG_TABLES_INCLUDED diff --git a/tests/core/compress/test_core_compress.odin b/tests/core/compress/test_core_compress.odin index 1f3481f35..d18a03d8c 100644 --- a/tests/core/compress/test_core_compress.odin +++ b/tests/core/compress/test_core_compress.odin @@ -2,7 +2,7 @@ package test_core_compress /* Copyright 2021 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Jeroen van Rijn: Initial implementation. diff --git a/tests/core/crypto/test_core_crypto.odin b/tests/core/crypto/test_core_crypto.odin index b3eb6e041..984f61bd8 100644 --- a/tests/core/crypto/test_core_crypto.odin +++ b/tests/core/crypto/test_core_crypto.odin @@ -2,7 +2,7 @@ package test_core_crypto /* Copyright 2021 zhibog - Made available under the BSD-3 license. + Made available under Odin's license. List of contributors: zhibog, dotbmp: Initial implementation. diff --git a/tests/core/hash/test_core_hash.odin b/tests/core/hash/test_core_hash.odin index 8a951b186..30ee911a8 100644 --- a/tests/core/hash/test_core_hash.odin +++ b/tests/core/hash/test_core_hash.odin @@ -12,6 +12,7 @@ import "base:intrinsics" }; */ +V16 :: struct{s: string, h: u16} V32 :: struct{s: string, h: u32} V64 :: struct{s: string, h: u64} @@ -263,4 +264,22 @@ test_murmur64_vectors :: proc(t: ^testing.T) { testing.expect_value(t, i128(#hash(vectors[3].s, "murmur64")), i128(vectors[3].h)) testing.expect_value(t, i128(#hash(vectors[4].s, "murmur64")), i128(vectors[4].h)) testing.expect_value(t, i128(#hash(vectors[5].s, "murmur64")), i128(vectors[5].h)) +} + +@test +test_crc16_ccitt_0x1021_vectors :: proc(t: ^testing.T) { + vectors :: []V16{ + {"" , 0x0000}, + {"abc" , 0x9dd6}, + {"Hello" , 0xcbd6}, + {"world" , 0x2363}, + {"Hello, world!", 0x7ade}, + {"\x70\x6a\x77" , 0x3299}, // ECMA-167, 7.2.6 Descriptor CRC + } + + for vector in vectors { + b := transmute([]u8)vector.s + crc16 := hash.crc16_ccitt_0x1021(b) + testing.expectf(t, crc16 == vector.h, "\n\t[CCITT CRC-16({0:q})] Expected: 0x{1:4x}, got: 0x{2:4x}", vector.s, vector.h, crc16) + } } \ No newline at end of file diff --git a/tests/core/image/test_core_image.odin b/tests/core/image/test_core_image.odin index 3293b80fa..46790bc8c 100644 --- a/tests/core/image/test_core_image.odin +++ b/tests/core/image/test_core_image.odin @@ -1,6 +1,6 @@ /* Copyright 2021-2024 Jeroen van Rijn . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Jeroen van Rijn: Initial implementation. diff --git a/tests/core/math/big/generate_tests.py b/tests/core/math/big/generate_tests.py index a0c5a5b84..032d7ef38 100644 --- a/tests/core/math/big/generate_tests.py +++ b/tests/core/math/big/generate_tests.py @@ -1,6 +1,6 @@ # # Copyright 2021 Jeroen van Rijn . -# Made available under Odin's BSD-3 license. +# Made available under Odin's license. # # A BigInt implementation in Odin. # For the theoretical underpinnings, see Knuth's The Art of Computer Programming, Volume 2, section 4.3. diff --git a/tests/core/math/bits/test_core_math_bits.odin b/tests/core/math/bits/test_core_math_bits.odin new file mode 100644 index 000000000..fd9ee24c9 --- /dev/null +++ b/tests/core/math/bits/test_core_math_bits.odin @@ -0,0 +1,171 @@ +package test_core_math_bits + +import "core:math/bits" +import "core:math/rand" +import "core:testing" + +@test +test_log2 :: proc(t: ^testing.T) { + dumb_log2 :: proc(x: $T) -> (res: T) { + N :: T(size_of(T) * 8) + + if x == 0 { + return max(T) + } + + for k := N - 1; k > 0; k -= 1 { + bit_pos := T(k) + if (x >> bit_pos) & 1 == 1 { + return bit_pos + } + } + return + } + + testing.expect_value(t, bits.log2( u8(0)), max(u8)) + testing.expect_value(t, bits.log2( u16(0)), max(u16)) + testing.expect_value(t, bits.log2( u32(0)), max(u32)) + testing.expect_value(t, bits.log2( u64(0)), max(u64)) + testing.expect_value(t, bits.log2(uint(0)), max(uint)) + + for x in u8(0)... Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Jeroen van Rijn: Initial implementation. diff --git a/tests/core/net/test_core_net_freebsd.odin b/tests/core/net/test_core_net_freebsd.odin index 590db7de0..46feadc3f 100644 --- a/tests/core/net/test_core_net_freebsd.odin +++ b/tests/core/net/test_core_net_freebsd.odin @@ -1,7 +1,7 @@ /* Copyright 2021 Jeroen van Rijn . Copyright 2024 Feoramund . - Made available under Odin's BSD-3 license. + Made available under Odin's license. List of contributors: Jeroen van Rijn: Initial implementation. diff --git a/tests/core/normal.odin b/tests/core/normal.odin index a16657ea8..e8b61fee8 100644 --- a/tests/core/normal.odin +++ b/tests/core/normal.odin @@ -27,6 +27,7 @@ download_assets :: proc "contextless" () { @(require) import "io" @(require) import "math" @(require) import "math/big" +@(require) import "math/bits" @(require) import "math/linalg/glsl" @(require) import "math/noise" @(require) import "math/rand" diff --git a/tests/core/runtime/test_core_runtime.odin b/tests/core/runtime/test_core_runtime.odin index 881b5f41a..f3559954d 100644 --- a/tests/core/runtime/test_core_runtime.odin +++ b/tests/core/runtime/test_core_runtime.odin @@ -292,6 +292,65 @@ test_soa_array_allocator_resize_overlapping :: proc(t: ^testing.T) { testing.expect_value(t, array[3], [3]int{0, 0, 0}) } +@(test) +test_soa_array_inject_at_elem :: proc(t: ^testing.T) { + + V :: struct {a: u8, b: f32} + + array := make(#soa[dynamic]V, 0, 2) + defer delete(array) + + append(&array, V{1, 1.5}, V{2, 2.5}, V{3, 3.5}) + + expect_inject(t, &array, 0, {0, 0.5}, {{0, 0.5}, {1, 1.5}, {2, 2.5}, {3, 3.5}}) + expect_inject(t, &array, 2, {5, 5.5}, {{0, 0.5}, {1, 1.5}, {5, 5.5}, {2, 2.5}, {3, 3.5}}) + expect_inject(t, &array, 5, {9, 9.5}, {{0, 0.5}, {1, 1.5}, {5, 5.5}, {2, 2.5}, {3, 3.5}, {9, 9.5}}) + + expect_inject :: proc(t: ^testing.T, arr: ^#soa[dynamic]V, index: int, arg: V, expected_slice: []V) { + ok, err := inject_at_soa(arr, index, arg) + testing.expectf(t, ok == true, "Injection of %v at index %d failed", arg, index) + testing.expectf(t, err == nil, "Injection allocation of %v at index %d failed: %v", arg, index, err) + equals := len(arr) == len(expected_slice) + for e, i in expected_slice { + if arr[i] != e { + equals = false + break + } + } + testing.expectf(t, equals, "After injection of %v at index %d, expected array to be\n&%v, got\n%v", arg, index, expected_slice, arr) + } +} + +@(test) +test_soa_array_inject_at_elems :: proc(t: ^testing.T) { + + V :: struct {a: u8, b: f32} + + array := make(#soa[dynamic]V, 0, 2) + defer delete(array) + + append(&array, V{1, 1.5}, V{2, 2.5}, V{3, 3.5}) + + expect_inject(t, &array, 0, {{0, 0.5}}, {{0, 0.5}, {1, 1.5}, {2, 2.5}, {3, 3.5}}) + expect_inject(t, &array, 2, {{5, 5.5}, {6, 6.5}}, {{0, 0.5}, {1, 1.5}, {5, 5.5}, {6, 6.5}, {2, 2.5}, {3, 3.5}}) + expect_inject(t, &array, 6, {{9, 9.5}, {10, 10.5}}, {{0, 0.5}, {1, 1.5}, {5, 5.5}, {6, 6.5}, {2, 2.5}, {3, 3.5}, {9, 9.5}, {10, 10.5}}) + expect_inject(t, &array, 6, {}, {{0, 0.5}, {1, 1.5}, {5, 5.5}, {6, 6.5}, {2, 2.5}, {3, 3.5}, {9, 9.5}, {10, 10.5}}) + + expect_inject :: proc(t: ^testing.T, arr: ^#soa[dynamic]V, index: int, args: []V, expected_slice: []V) { + ok, err := inject_at_soa(arr, index, ..args) + testing.expectf(t, ok == true, "Injection of %v at index %d failed", args, index) + testing.expectf(t, err == nil, "Injection allocation of %v at index %d failed: %v", args, index, err) + equals := len(arr) == len(expected_slice) + for e, i in expected_slice { + if arr[i] != e { + equals = false + break + } + } + testing.expectf(t, equals, "After injection of %v at index %d, expected array to be\n&%v, got\n%v", args, index, expected_slice, arr) + } +} + @(test) test_memory_equal :: proc(t: ^testing.T) { data: [256]u8 diff --git a/vendor/box2d/box2d.odin b/vendor/box2d/box2d.odin index 27d3fd177..ad4670110 100644 --- a/vendor/box2d/box2d.odin +++ b/vendor/box2d/box2d.odin @@ -1562,6 +1562,12 @@ foreign lib { // Get the revolute joint spring damping ratio, non-dimensional RevoluteJoint_GetSpringDampingRatio :: proc(jointId: JointId) -> f32 --- + // Set the revolute joint spring target angle, radians + RevoluteJoint_SetTargetAngle :: proc(jointId: JointId, angle: f32) --- + + // Get the revolute joint spring target angle, radians + RevoluteJoint_GetTargetAngle :: proc(jointId: JointId) -> f32 --- + // Get the revolute joint current angle in radians relative to the reference angle // @see b2RevoluteJointDef::referenceAngle RevoluteJoint_GetAngle :: proc(jointId: JointId) -> f32 --- diff --git a/vendor/box2d/math_functions.odin b/vendor/box2d/math_functions.odin index 4394feb39..c2d197f08 100644 --- a/vendor/box2d/math_functions.odin +++ b/vendor/box2d/math_functions.odin @@ -3,7 +3,7 @@ package vendor_box2d import "core:c" import "core:math" -EPSILON :: 1e-23 +EPSILON :: math.F32_EPSILON Vec2 :: [2]f32 @@ -247,7 +247,7 @@ Normalize :: proc "c" (v: Vec2) -> Vec2 { @(require_results) IsNormalized :: proc "c" (v: Vec2) -> bool { aa := Dot(v, v) - return abs(1. - aa) < 10. * EPSILON + return abs(1. - aa) < 100. * EPSILON } @(require_results) diff --git a/vendor/box2d/types.odin b/vendor/box2d/types.odin index c4ef0cd0c..1ad7f379c 100644 --- a/vendor/box2d/types.odin +++ b/vendor/box2d/types.odin @@ -41,13 +41,13 @@ FinishTaskCallback :: #type proc "c" (userTask: rawptr, userContext: rawptr) // from a worker thread. // @warning This function should not attempt to modify Box2D state or user application state. // @ingroup world -FrictionCallback :: #type proc "c" (frictionA: f32, userMaterialIdA: i32, frictionB: f32, userMaterialIdB: i32) +FrictionCallback :: #type proc "c" (frictionA: f32, userMaterialIdA: i32, frictionB: f32, userMaterialIdB: i32) -> f32 // Optional restitution mixing callback. This intentionally provides no context objects because this is called // from a worker thread. // @warning This function should not attempt to modify Box2D state or user application state. // @ingroup world -RestitutionCallback :: #type proc "c" (restitutionA: f32, userMaterialIdA: i32, restitutuionB: f32, userMaterialIdB: i32) +RestitutionCallback :: #type proc "c" (restitutionA: f32, userMaterialIdA: i32, restitutionB: f32, userMaterialIdB: i32) -> f32 // Result from b2World_RayCastClosest // @ingroup world @@ -727,6 +727,10 @@ RevoluteJointDef :: struct { // This defines the zero angle for the joint limit. referenceAngle: f32, + // The target angle for the joint in radians. The spring-damper will drive + // to this angle. + targetAngle: f32, + // Enable a rotational spring on the revolute hinge axis enableSpring: bool, diff --git a/vendor/directx/d3d12/d3d12.odin b/vendor/directx/d3d12/d3d12.odin index 75e94c833..8f72aedb4 100644 --- a/vendor/directx/d3d12/d3d12.odin +++ b/vendor/directx/d3d12/d3d12.odin @@ -719,7 +719,7 @@ STREAM_OUTPUT_DESC :: struct { } INPUT_LAYOUT_DESC :: struct { - pInputElementDescs: [^]INPUT_ELEMENT_DESC, + pInputElementDescs: [^]INPUT_ELEMENT_DESC `fmt:"v,NumElements"`, NumElements: u32, } @@ -1649,7 +1649,7 @@ VIEW_INSTANCING_FLAG :: enum u32 { VIEW_INSTANCING_DESC :: struct { ViewInstanceCount: u32, - pViewInstanceLocations: [^]VIEW_INSTANCE_LOCATION, + pViewInstanceLocations: [^]VIEW_INSTANCE_LOCATION `fmt:"v,ViewInstanceCount"`, Flags: VIEW_INSTANCING_FLAGS, } @@ -3090,13 +3090,13 @@ EXISTING_COLLECTION_DESC :: struct { SUBOBJECT_TO_EXPORTS_ASSOCIATION :: struct { pSubobjectToAssociate: ^STATE_SUBOBJECT, NumExports: u32, - pExports: [^]^i16, + pExports: [^]cstring16 `fmt:"v,NumExports"`, } DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION :: struct { - SubobjectToAssociate: ^i16, + SubobjectToAssociate: cstring16, NumExports: u32, - pExports: [^]^i16, + pExports: [^]cstring16 `fmt:"v,NumExports"`, } HIT_GROUP_TYPE :: enum i32 { @@ -3105,11 +3105,11 @@ HIT_GROUP_TYPE :: enum i32 { } HIT_GROUP_DESC :: struct { - HitGroupExport: ^i16, + HitGroupExport: cstring16, Type: HIT_GROUP_TYPE, - AnyHitShaderImport: ^i16, - ClosestHitShaderImport: ^i16, - IntersectionShaderImport: ^i16, + AnyHitShaderImport: cstring16, + ClosestHitShaderImport: cstring16, + IntersectionShaderImport: cstring16, } RAYTRACING_SHADER_CONFIG :: struct { @@ -3506,14 +3506,14 @@ DRED_ALLOCATION_TYPE :: enum i32 { DRED_ALLOCATION_NODE :: struct { ObjectNameA: cstring, - ObjectNameW: ^i16, + ObjectNameW: cstring16, AllocationType: DRED_ALLOCATION_TYPE, pNext: ^DRED_ALLOCATION_NODE, } DRED_ALLOCATION_NODE1 :: struct { ObjectNameA: cstring, - ObjectNameW: ^i16, + ObjectNameW: cstring16, AllocationType: DRED_ALLOCATION_TYPE, pNext: ^DRED_ALLOCATION_NODE1, pObject: ^IUnknown, @@ -3539,7 +3539,7 @@ DRED_PAGE_FAULT_OUTPUT1 :: struct { pHeadRecentFreedAllocationNode: ^DRED_ALLOCATION_NODE1, } -DRED_PAGE_FAULT_FLAGS :: bit_set[DRED_PAGE_FAULT_FLAG;u32] +DRED_PAGE_FAULT_FLAGS :: distinct bit_set[DRED_PAGE_FAULT_FLAG; u32] DRED_PAGE_FAULT_FLAG :: enum u32 { } @@ -3819,7 +3819,7 @@ RENDER_PASS_ENDING_ACCESS_RESOLVE_PARAMETERS :: struct { pSrcResource: ^IResource, pDstResource: ^IResource, SubresourceCount: u32, - pSubresourceParameters: [^]RENDER_PASS_ENDING_ACCESS_RESOLVE_SUBRESOURCE_PARAMETERS, + pSubresourceParameters: [^]RENDER_PASS_ENDING_ACCESS_RESOLVE_SUBRESOURCE_PARAMETERS `fmt:"v,SubresourceCount"`, Format: dxgi.FORMAT, ResolveMode: RESOLVE_MODE, PreserveResolveSource: BOOL, @@ -3901,7 +3901,7 @@ SHADER_CACHE_MODE :: enum i32 { DISK = 1, } -SHADER_CACHE_FLAGS :: bit_set[SHADER_CACHE_FLAG;u32] +SHADER_CACHE_FLAGS :: distinct bit_set[SHADER_CACHE_FLAG; u32] SHADER_CACHE_FLAG :: enum u32 { DRIVER_VERSIONED = 0, USE_WORKING_DIR = 1, @@ -3932,7 +3932,7 @@ IShaderCacheSession_VTable :: struct { } -SHADER_CACHE_KIND_FLAGS :: bit_set[SHADER_CACHE_KIND_FLAG;u32] +SHADER_CACHE_KIND_FLAGS :: distinct bit_set[SHADER_CACHE_KIND_FLAG; u32] SHADER_CACHE_KIND_FLAG :: enum u32 { IMPLICIT_D3D_CACHE_FOR_DRIVER = 0, IMPLICIT_D3D_CONVERSIONS = 1, @@ -3940,7 +3940,7 @@ SHADER_CACHE_KIND_FLAG :: enum u32 { APPLICATION_MANAGED = 3, } -SHADER_CACHE_CONTROL_FLAGS :: bit_set[SHADER_CACHE_CONTROL_FLAG;u32] +SHADER_CACHE_CONTROL_FLAGS :: distinct bit_set[SHADER_CACHE_CONTROL_FLAG; u32] SHADER_CACHE_CONTROL_FLAG :: enum u32 { DISABLE = 0, ENABLE = 1, diff --git a/vendor/egl/egl.odin b/vendor/egl/egl.odin index fe52a7fce..744dd2a5d 100644 --- a/vendor/egl/egl.odin +++ b/vendor/egl/egl.odin @@ -26,6 +26,7 @@ OPENGL_BIT :: 0x0008 OPENGL_ES2_BIT :: 0x0004 OPENGL_ES3_BIT :: 0x00000040 +BUFFER_SIZE :: 0x3020 ALPHA_SIZE :: 0x3021 BLUE_SIZE :: 0x3022 GREEN_SIZE :: 0x3023 @@ -39,6 +40,8 @@ NONE :: 0x3038 COLOR_BUFFER_TYPE :: 0x303F RENDERABLE_TYPE :: 0x3040 CONFORMANT :: 0x3042 +VENDOR :: 0x3053 +VERSION :: 0x3054 HEIGHT :: 0x3056 WIDTH :: 0x3057 @@ -56,17 +59,38 @@ CONTEXT_OPENGL_PROFILE_MASK :: 0x30FD OPENGL_API :: 0x30A2 +CONTEXT_OPENGL_DEBUG :: 0x31B0 + +Platform :: enum u32 { + ANDROID_KHR = 0x3141, + GBM_KHR = 0x31D7, + WAYLAND_KHR = 0x31D8, + X11_KHR = 0x31D5, + X11_SCREEN_KHR = 0x31D6, + DEVICE_EXT = 0x313F, + WAYLAND_EXT = 0x31D8, + X11_EXT = 0x31D5, + X11_SCREEN_EXT = 0x31D6, + XCB_EXT = 0x31DC, + XCB_SCREEN_EXT = 0x31DE, + GBM_MESA = 0x31D7, + SURFACELESS_MESA = 0x31DD, +} + foreign import egl "system:EGL" @(default_calling_convention="c", link_prefix="egl") foreign egl { GetDisplay :: proc(display: NativeDisplayType) -> Display --- + GetPlatformDisplay :: proc(platform: Platform, native_display: rawptr, attrib_list: ^int) -> Display --- Initialize :: proc(display: Display, major: ^i32, minor: ^i32) -> Boolean --- BindAPI :: proc(api: u32) -> Boolean --- - ChooseConfig :: proc(display: Display, attrib_list: ^i32, configs: ^Config, config_size: i32, num_config: ^i32) -> Boolean --- + ChooseConfig :: proc(display: Display, attrib_list: ^i32, configs: [^]Config, config_size: i32, num_config: ^i32) -> Boolean --- CreateWindowSurface :: proc(display: Display, config: Config, native_window: NativeWindowType, attrib_list: ^i32) -> Surface --- + CreatePlatformWindowSurface :: proc(display: Display, config: Config, native_window: rawptr, attrib_list: ^int) -> Surface --- CreateContext :: proc(display: Display, config: Config, share_context: Context, attrib_list: ^i32) -> Context --- MakeCurrent :: proc(display: Display, draw: Surface, read: Surface, ctx: Context) -> Boolean --- QuerySurface :: proc(display: Display, surface: Surface, attribute: i32, value: ^i32) -> Boolean --- + QueryString :: proc(display: Display, name: i32) -> cstring --- SwapInterval :: proc(display: Display, interval: i32) -> Boolean --- SwapBuffers :: proc(display: Display, surface: Surface) -> Boolean --- GetProcAddress :: proc(name: cstring) -> rawptr --- diff --git a/vendor/raylib/raylib.odin b/vendor/raylib/raylib.odin index 7dae19f4b..37589f165 100644 --- a/vendor/raylib/raylib.odin +++ b/vendor/raylib/raylib.odin @@ -96,6 +96,7 @@ _ :: linalg MAX_TEXTFORMAT_BUFFERS :: #config(RAYLIB_MAX_TEXTFORMAT_BUFFERS, 4) MAX_TEXT_BUFFER_LENGTH :: #config(RAYLIB_MAX_TEXT_BUFFER_LENGTH, 1024) +MAX_MATERIAL_MAPS :: #config(RAYLIB_MAX_MATERIAL_MAPS, 12) #assert(size_of(rune) == size_of(c.int)) diff --git a/vendor/wgpu/doc.odin b/vendor/wgpu/doc.odin index 23f5dfc39..693062788 100644 --- a/vendor/wgpu/doc.odin +++ b/vendor/wgpu/doc.odin @@ -12,8 +12,8 @@ You can find a number of examples on [[Odin's official examples repository; http **Getting the wgpu-native libraries** For native support (not the browser), some libraries are required. Fortunately this is -extremely easy, just download them from the [[releases on GitHub; https://github.com/gfx-rs/wgpu-native/releases/tag/v25.0.2.1]]. -the bindings are for v25.0.2.1 at the moment. +extremely easy, just download them from the [[releases on GitHub; https://github.com/gfx-rs/wgpu-native/releases/tag/v27.0.2.0]]. +the bindings are for v27.0.2.0 at the moment. These are expected in the `lib` folder under the same name as they are released (just unzipped). By default it will look for a static release version (`wgpu-OS-ARCH-release.a|lib`), diff --git a/vendor/wgpu/lib/wgpu-windows-x86_64-msvc-release/lib/wgpu_native.dll b/vendor/wgpu/lib/wgpu-windows-x86_64-msvc-release/lib/wgpu_native.dll index 3c4e1b5a6..08518a94e 100644 Binary files a/vendor/wgpu/lib/wgpu-windows-x86_64-msvc-release/lib/wgpu_native.dll and b/vendor/wgpu/lib/wgpu-windows-x86_64-msvc-release/lib/wgpu_native.dll differ diff --git a/vendor/wgpu/lib/wgpu-windows-x86_64-msvc-release/lib/wgpu_native.dll.lib b/vendor/wgpu/lib/wgpu-windows-x86_64-msvc-release/lib/wgpu_native.dll.lib index 072c4b234..55589fea0 100644 Binary files a/vendor/wgpu/lib/wgpu-windows-x86_64-msvc-release/lib/wgpu_native.dll.lib and b/vendor/wgpu/lib/wgpu-windows-x86_64-msvc-release/lib/wgpu_native.dll.lib differ diff --git a/vendor/wgpu/lib/wgpu-windows-x86_64-msvc-release/lib/wgpu_native.lib b/vendor/wgpu/lib/wgpu-windows-x86_64-msvc-release/lib/wgpu_native.lib index 3ea8453f9..1948c8fca 100644 Binary files a/vendor/wgpu/lib/wgpu-windows-x86_64-msvc-release/lib/wgpu_native.lib and b/vendor/wgpu/lib/wgpu-windows-x86_64-msvc-release/lib/wgpu_native.lib differ diff --git a/vendor/wgpu/wgpu.odin b/vendor/wgpu/wgpu.odin index c44bb2cbb..3c0f76a89 100644 --- a/vendor/wgpu/wgpu.odin +++ b/vendor/wgpu/wgpu.odin @@ -13,7 +13,7 @@ when ODIN_OS == .Windows { @(private) LIB :: "lib/wgpu-windows-" + ARCH + "-msvc-" + TYPE + "/lib/wgpu_native" + EXT when !#exists(LIB) { - #panic("Could not find the compiled WGPU Native library at '" + #directory + LIB + "', these can be downloaded from https://github.com/gfx-rs/wgpu-native/releases/tag/v25.0.2.1, make sure to read the README at '" + #directory + "README.md'") + #panic("Could not find the compiled WGPU Native library at '" + #directory + LIB + "', these can be downloaded from https://github.com/gfx-rs/wgpu-native/releases/tag/v27.0.2.0, make sure to read the README at '" + #directory + "README.md'") } @(export) @@ -39,7 +39,7 @@ when ODIN_OS == .Windows { @(private) LIB :: "lib/wgpu-macos-" + ARCH + "-" + TYPE + "/lib/libwgpu_native" + EXT when !#exists(LIB) { - #panic("Could not find the compiled WGPU Native library at '" + #directory + LIB + "', these can be downloaded from https://github.com/gfx-rs/wgpu-native/releases/tag/v25.0.2.1, make sure to read the README at '" + #directory + "README.md'") + #panic("Could not find the compiled WGPU Native library at '" + #directory + LIB + "', these can be downloaded from https://github.com/gfx-rs/wgpu-native/releases/tag/v27.0.2.0, make sure to read the README at '" + #directory + "README.md'") } @(export) @@ -56,7 +56,7 @@ when ODIN_OS == .Windows { @(private) LIB :: "lib/wgpu-linux-" + ARCH + "-" + TYPE + "/lib/libwgpu_native" + EXT when !#exists(LIB) { - #panic("Could not find the compiled WGPU Native library at '" + #directory + LIB + "', these can be downloaded from https://github.com/gfx-rs/wgpu-native/releases/tag/v25.0.2.1, make sure to read the README at '" + #directory + "README.md'") + #panic("Could not find the compiled WGPU Native library at '" + #directory + LIB + "', these can be downloaded from https://github.com/gfx-rs/wgpu-native/releases/tag/v27.0.2.0, make sure to read the README at '" + #directory + "README.md'") } @(export) @@ -282,8 +282,7 @@ FeatureName :: enum i32 { // Native. PushConstants = 0x00030001, TextureAdapterSpecificFormatFeatures, - MultiDrawIndirect, - MultiDrawIndirectCount, + MultiDrawIndirectCount = 0x00030004, VertexWritableStorage, TextureBindingArray, SampledTextureAndStorageBufferArrayNonUniformIndexing, @@ -298,16 +297,15 @@ FeatureName :: enum i32 { // TODO: requires wgpu.h api change // AddressModeClampToZero, // AddressModeClampToBorder, - // PolygonModeLine, - // PolygonModePoint, - // ConservativeRasterization, + PolygonModeLine = 0x00030013, + PolygonModePoint, + ConservativeRasterization, // ClearTexture, SpirvShaderPassthrough = 0x00030017, // MultiView, VertexAttribute64bit = 0x00030019, TextureFormatNv12, - RayTracingAccelarationStructure, - RayQuery, + RayQuery = 0x0003001C, ShaderF64, ShaderI16, ShaderPrimitiveIndex, @@ -317,6 +315,7 @@ FeatureName :: enum i32 { SubgroupBarrier, TimestampQueryInsideEncoders, TimestampQueryInsidePasses, + ShaderInt64, } FilterMode :: enum i32 { @@ -446,6 +445,8 @@ SType :: enum i32 { BindGroupLayoutEntryExtras, QuerySetDescriptorExtras, SurfaceConfigurationExtras, + SurfaceSourceSwapChainPanel, + PrimitiveStateExtras, // Odin. SurfaceSourceCanvasHTMLSelector = 0x00040001, @@ -624,6 +625,7 @@ TextureFormat :: enum i32 { Rgba16Snorm, // From FeatureName.TextureFormatNv12 NV12, + P010, } TextureSampleType :: enum i32 { diff --git a/vendor/wgpu/wgpu_native_types.odin b/vendor/wgpu/wgpu_native_types.odin index a9340affe..ad6ce704e 100644 --- a/vendor/wgpu/wgpu_native_types.odin +++ b/vendor/wgpu/wgpu_native_types.odin @@ -2,8 +2,8 @@ package wgpu import "base:runtime" -BINDINGS_VERSION :: [4]u8{25, 0, 2, 1} -BINDINGS_VERSION_STRING :: "25.0.2.1" +BINDINGS_VERSION :: [4]u8{27, 0, 2, 0} +BINDINGS_VERSION_STRING :: "27.0.2.0" LogLevel :: enum i32 { Off, @@ -79,9 +79,10 @@ InstanceExtras :: struct { dx12ShaderCompiler: Dx12Compiler, gles3MinorVersion: Gles3MinorVersion, glFenceBehaviour: GLFenceBehaviour, - dxilPath: StringView, dxcPath: StringView, dcxMaxShaderModel: DxcMaxShaderModel, + budgetForDeviceCreation: ^u8, + budgetForDeviceLoss: ^u8, } DeviceExtras :: struct { @@ -191,6 +192,30 @@ SurfaceConfigurationExtras :: struct { desiredMaximumFrameLatency: u32, } +/** +* Chained in `SurfaceDescriptor` to make a `Surface` wrapping a WinUI [[ SwapChainPanel ; https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.controls.swapchainpanel ]]. +*/ +SurfaceSourceSwapChainPanel :: struct { + using chain: ChainedStruct, + /** + * A pointer to the [[ ISwapChainPanelNative ; https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/win32/microsoft.ui.xaml.media.dxinterop/nn-microsoft-ui-xaml-media-dxinterop-iswapchainpanelnative ]] + * interface of the `SwapChainPanel` that will be wrapped by the `Surface`. + */ + panelNative: rawptr, +} + +PolygonMode :: enum i32 { + Fill, + Line, + Point, +} + +PrimitiveStateExtras :: struct { + using chain: ChainedStruct, + polygonMode: PolygonMode, + conservative: b32, +} + LogCallback :: #type proc "c" (level: LogLevel, message: StringView, userdata: rawptr) // Wrappers