diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c9c453331..ca3d87b12 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,8 +32,8 @@ jobs: gmake -C vendor/stb/src gmake -C vendor/cgltf/src gmake -C vendor/miniaudio/src - ./odin check examples/all -vet -strict-style -target:netbsd_amd64 - ./odin check examples/all -vet -strict-style -target:netbsd_arm64 + ./odin check examples/all -vet -strict-style -disallow-do -target:netbsd_amd64 + ./odin check examples/all -vet -strict-style -disallow-do -target:netbsd_arm64 ./odin test tests/core/normal.odin -file -all-packages -define:ODIN_TEST_FANCY=false ./odin test tests/core/speed.odin -file -all-packages -o:speed -define:ODIN_TEST_FANCY=false ./odin test tests/vendor -all-packages -define:ODIN_TEST_FANCY=false @@ -62,7 +62,7 @@ jobs: gmake -C vendor/stb/src gmake -C vendor/cgltf/src gmake -C vendor/miniaudio/src - ./odin check examples/all -vet -strict-style -target:freebsd_amd64 + ./odin check examples/all -vet -strict-style -disallow-do -target:freebsd_amd64 ./odin test tests/core/normal.odin -file -all-packages -define:ODIN_TEST_FANCY=false ./odin test tests/core/speed.odin -file -all-packages -o:speed -define:ODIN_TEST_FANCY=false ./odin test tests/vendor -all-packages -define:ODIN_TEST_FANCY=false @@ -97,7 +97,7 @@ jobs: - name: Download LLVM (MacOS ARM) if: matrix.os == 'macos-14' run: | - brew install llvm@17 + brew install llvm@17 wasmtime echo "/opt/homebrew/opt/llvm@17/bin" >> $GITHUB_PATH - name: Build Odin @@ -135,18 +135,24 @@ jobs: ./run.sh - name: Odin check examples/all for Linux i386 - run: ./odin check examples/all -vet -strict-style -target:linux_i386 + run: ./odin check examples/all -vet -strict-style -disallow-do -target:linux_i386 if: matrix.os == 'ubuntu-latest' - name: Odin check examples/all for Linux arm64 - run: ./odin check examples/all -vet -strict-style -target:linux_arm64 + run: ./odin check examples/all -vet -strict-style -disallow-do -target:linux_arm64 if: matrix.os == 'ubuntu-latest' - name: Odin check examples/all for FreeBSD amd64 - run: ./odin check examples/all -vet -strict-style -target:freebsd_amd64 + run: ./odin check examples/all -vet -strict-style -disallow-do -target:freebsd_amd64 if: matrix.os == 'ubuntu-latest' - name: Odin check examples/all for OpenBSD amd64 - run: ./odin check examples/all -vet -strict-style -target:openbsd_amd64 + run: ./odin check examples/all -vet -strict-style -disallow-do -target:openbsd_amd64 if: matrix.os == 'ubuntu-latest' + - name: Run demo on WASI WASM32 + run: | + ./odin build examples/demo -target:wasi_wasm32 -vet -strict-style -disallow-do -out:demo.wasm + wasmtime ./demo.wasm + if: matrix.os == 'macos-14' + build_windows: name: Windows Build, Check, and Test runs-on: windows-2022 diff --git a/base/intrinsics/intrinsics.odin b/base/intrinsics/intrinsics.odin index 635c85e6f..8a16ca40e 100644 --- a/base/intrinsics/intrinsics.odin +++ b/base/intrinsics/intrinsics.odin @@ -194,7 +194,8 @@ type_proc_return_count :: proc($T: typeid) -> int where type_is_proc(T) --- type_proc_parameter_type :: proc($T: typeid, index: int) -> typeid where type_is_proc(T) --- type_proc_return_type :: proc($T: typeid, index: int) -> typeid where type_is_proc(T) --- -type_struct_field_count :: proc($T: typeid) -> int where type_is_struct(T) --- +type_struct_field_count :: proc($T: typeid) -> int where type_is_struct(T) --- +type_struct_has_implicit_padding :: proc($T: typeid) -> bool where type_is_struct(T) --- type_polymorphic_record_parameter_count :: proc($T: typeid) -> typeid --- type_polymorphic_record_parameter_value :: proc($T: typeid, index: int) -> $V --- diff --git a/base/runtime/core_builtin.odin b/base/runtime/core_builtin.odin index ff973054d..ff87316f2 100644 --- a/base/runtime/core_builtin.odin +++ b/base/runtime/core_builtin.odin @@ -65,7 +65,7 @@ copy :: proc{copy_slice, copy_from_string} // with the old value, and reducing the length of the dynamic array by 1. // // Note: This is an O(1) operation. -// Note: If you the elements to remain in their order, use `ordered_remove`. +// Note: If you want the elements to remain in their order, use `ordered_remove`. // Note: If the index is out of bounds, this procedure will panic. @builtin unordered_remove :: proc(array: ^$D/[dynamic]$T, index: int, loc := #caller_location) #no_bounds_check { @@ -79,7 +79,7 @@ unordered_remove :: proc(array: ^$D/[dynamic]$T, index: int, loc := #caller_loca // `ordered_remove` removed the element at the specified `index` whilst keeping the order of the other elements. // // Note: This is an O(N) operation. -// Note: If you the elements do not have to remain in their order, prefer `unordered_remove`. +// Note: If the elements do not have to remain in their order, prefer `unordered_remove`. // Note: If the index is out of bounds, this procedure will panic. @builtin ordered_remove :: proc(array: ^$D/[dynamic]$T, index: int, loc := #caller_location) #no_bounds_check { @@ -163,21 +163,43 @@ pop_front_safe :: proc "contextless" (array: ^$T/[dynamic]$E) -> (res: E, ok: bo // `clear` will set the length of a passed dynamic array or map to `0` @builtin -clear :: proc{clear_dynamic_array, clear_map} +clear :: proc{ + clear_dynamic_array, + clear_map, + + clear_soa_dynamic_array, +} // `reserve` will try to reserve memory of a passed dynamic array or map to the requested element count (setting the `cap`). @builtin -reserve :: proc{reserve_dynamic_array, reserve_map} +reserve :: proc{ + reserve_dynamic_array, + reserve_map, + + reserve_soa, +} @builtin -non_zero_reserve :: proc{non_zero_reserve_dynamic_array} +non_zero_reserve :: proc{ + non_zero_reserve_dynamic_array, + + non_zero_reserve_soa, +} // `resize` will try to resize memory of a passed dynamic array to the requested element count (setting the `len`, and possibly `cap`). @builtin -resize :: proc{resize_dynamic_array} +resize :: proc{ + resize_dynamic_array, + + resize_soa, +} @builtin -non_zero_resize :: proc{non_zero_resize_dynamic_array} +non_zero_resize :: proc{ + non_zero_resize_dynamic_array, + + non_zero_resize_soa, +} // Shrinks the capacity of a dynamic array or map down to the current length, or the given capacity. @builtin @@ -268,7 +290,7 @@ new_clone :: proc(data: $T, allocator := context.allocator, loc := #caller_locat return } -DEFAULT_RESERVE_CAPACITY :: 16 +DEFAULT_DYNAMIC_ARRAY_CAPACITY :: 8 @(require_results) make_aligned :: proc($T: typeid/[]$E, #any_int len: int, alignment: int, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) #optional_allocator_error { @@ -295,7 +317,7 @@ make_slice :: proc($T: typeid/[]$E, #any_int len: int, allocator := context.allo // Note: Prefer using the procedure group `make`. @(builtin, require_results) make_dynamic_array :: proc($T: typeid/[dynamic]$E, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) #optional_allocator_error { - return make_dynamic_array_len_cap(T, 0, DEFAULT_RESERVE_CAPACITY, allocator, loc) + return make_dynamic_array_len_cap(T, 0, 0, allocator, loc) } // `make_dynamic_array_len` allocates and initializes a dynamic array. Like `new`, the first argument is a type, not a value. // Unlike `new`, `make`'s return value is the same as the type of its argument, not a pointer to it. @@ -364,6 +386,11 @@ make :: proc{ make_dynamic_array_len_cap, make_map, make_multi_pointer, + + make_soa_slice, + make_soa_dynamic_array, + make_soa_dynamic_array_len, + make_soa_dynamic_array_len_cap, } @@ -423,8 +450,8 @@ _append_elem :: #force_inline proc(array: ^$T/[dynamic]$E, arg: E, should_zero: return 1, nil } else { if cap(array) < len(array)+1 { - // Same behavior as _append_elems but there's only one arg, so we always just add 8. - cap := 2 * cap(array) + 8 + // Same behavior as _append_elems but there's only one arg, so we always just add DEFAULT_DYNAMIC_ARRAY_CAPACITY. + cap := 2 * cap(array) + DEFAULT_DYNAMIC_ARRAY_CAPACITY // do not 'or_return' here as it could be a partial success if should_zero { @@ -473,7 +500,7 @@ _append_elems :: #force_inline proc(array: ^$T/[dynamic]$E, should_zero: bool, l return arg_len, nil } else { if cap(array) < len(array)+arg_len { - cap := 2 * cap(array) + max(8, arg_len) + cap := 2 * cap(array) + max(DEFAULT_DYNAMIC_ARRAY_CAPACITY, arg_len) // do not 'or_return' here as it could be a partial success if should_zero { @@ -541,8 +568,23 @@ append_string :: proc(array: ^$T/[dynamic]$E/u8, args: ..string, loc := #caller_ } // The append built-in procedure appends elements to the end of a dynamic array -@builtin append :: proc{append_elem, append_elems, append_elem_string} -@builtin non_zero_append :: proc{non_zero_append_elem, non_zero_append_elems, non_zero_append_elem_string} +@builtin append :: proc{ + append_elem, + append_elems, + append_elem_string, + + append_soa_elem, + append_soa_elems, +} + +@builtin non_zero_append :: proc{ + non_zero_append_elem, + non_zero_append_elems, + non_zero_append_elem_string, + + non_zero_append_soa_elem, + non_zero_append_soa_elems, +} @builtin diff --git a/base/runtime/core_builtin_soa.odin b/base/runtime/core_builtin_soa.odin index 547df0a2b..f1b17cbef 100644 --- a/base/runtime/core_builtin_soa.odin +++ b/base/runtime/core_builtin_soa.odin @@ -55,7 +55,7 @@ raw_soa_footer_slice :: proc(array: ^$T/#soa[]$E) -> (footer: ^Raw_SOA_Footer_Sl if array == nil { return nil } - field_count := uintptr(intrinsics.type_struct_field_count(E)) + field_count := uintptr(len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E)) footer = (^Raw_SOA_Footer_Slice)(uintptr(array) + field_count*size_of(rawptr)) return } @@ -64,12 +64,7 @@ raw_soa_footer_dynamic_array :: proc(array: ^$T/#soa[dynamic]$E) -> (footer: ^Ra if array == nil { return nil } - field_count: uintptr - when intrinsics.type_is_array(E) { - field_count = len(E) - } else { - field_count = uintptr(intrinsics.type_struct_field_count(E)) - } + field_count := uintptr(len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E)) footer = (^Raw_SOA_Footer_Dynamic_Array)(uintptr(array) + field_count*size_of(rawptr)) return } @@ -98,7 +93,7 @@ make_soa_aligned :: proc($T: typeid/#soa[]$E, length: int, alignment: int, alloc ti = type_info_base(ti) si := &ti.variant.(Type_Info_Struct) - field_count := uintptr(intrinsics.type_struct_field_count(E)) + field_count := uintptr(len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E)) total_size := 0 for i in 0.. (array: T, err: Allocator_Error) #optional_allocator_error { context.allocator = allocator - reserve_soa(&array, DEFAULT_RESERVE_CAPACITY, loc) or_return + reserve_soa(&array, 0, loc) or_return return array, nil } @@ -187,8 +182,28 @@ resize_soa :: proc(array: ^$T/#soa[dynamic]$E, length: int, loc := #caller_locat return nil } +@builtin +non_zero_resize_soa :: proc(array: ^$T/#soa[dynamic]$E, length: int, loc := #caller_location) -> Allocator_Error { + if array == nil { + return nil + } + non_zero_reserve_soa(array, length, loc) or_return + footer := raw_soa_footer(array) + footer.len = length + return nil +} + @builtin reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_location) -> Allocator_Error { + return _reserve_soa(array, capacity, true, loc) +} + +@builtin +non_zero_reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_location) -> Allocator_Error { + return _reserve_soa(array, capacity, false, loc) +} + +_reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, zero_memory: bool, loc := #caller_location) -> Allocator_Error { if array == nil { return nil } @@ -213,12 +228,7 @@ reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_lo ti = type_info_base(ti) si := &ti.variant.(Type_Info_Struct) - field_count: uintptr - when intrinsics.type_is_array(E) { - field_count = len(E) - } else { - field_count = uintptr(intrinsics.type_struct_field_count(E)) - } + field_count := uintptr(len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E)) assert(footer.cap == old_cap) old_size := 0 @@ -238,7 +248,7 @@ reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_lo old_data := (^rawptr)(array)^ new_bytes := array.allocator.procedure( - array.allocator.data, .Alloc, new_size, max_align, + array.allocator.data, .Alloc if zero_memory else .Alloc_Non_Zeroed, new_size, max_align, nil, old_size, loc, ) or_return new_data := raw_data(new_bytes) @@ -273,15 +283,26 @@ reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_lo return nil } + @builtin -append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, arg: E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { +append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, #no_broadcast arg: E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { + return _append_soa_elem(array, true, arg, loc) +} + +@builtin +non_zero_append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, #no_broadcast arg: E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { + return _append_soa_elem(array, false, arg, loc) +} + +_append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, zero_memory: bool, #no_broadcast arg: E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { if array == nil { return 0, nil } if cap(array) <= len(array) + 1 { - cap := 2 * cap(array) + 8 - err = reserve_soa(array, cap, loc) // do not 'or_return' here as it could be a partial success + // Same behavior as append_soa_elems but there's only one arg, so we always just add DEFAULT_DYNAMIC_ARRAY_CAPACITY. + cap := 2 * cap(array) + DEFAULT_DYNAMIC_ARRAY_CAPACITY + err = _reserve_soa(array, cap, zero_memory, loc) // do not 'or_return' here as it could be a partial success } footer := raw_soa_footer(array) @@ -290,12 +311,7 @@ append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, arg: E, loc := #caller_locat ti := type_info_of(T) ti = type_info_base(ti) si := &ti.variant.(Type_Info_Struct) - field_count: uintptr - when intrinsics.type_is_array(E) { - field_count = len(E) - } else { - field_count = uintptr(intrinsics.type_struct_field_count(E)) - } + field_count := uintptr(len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E)) data := (^rawptr)(array)^ @@ -326,7 +342,17 @@ append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, arg: E, loc := #caller_locat } @builtin -append_soa_elems :: proc(array: ^$T/#soa[dynamic]$E, args: ..E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { +append_soa_elems :: proc(array: ^$T/#soa[dynamic]$E, #no_broadcast args: ..E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { + return _append_soa_elems(array, true, args=args, loc=loc) +} + +@builtin +non_zero_append_soa_elems :: proc(array: ^$T/#soa[dynamic]$E, #no_broadcast args: ..E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { + return _append_soa_elems(array, false, args=args, loc=loc) +} + + +_append_soa_elems :: proc(array: ^$T/#soa[dynamic]$E, zero_memory: bool, #no_broadcast args: ..E, loc := #caller_location) -> (n: int, err: Allocator_Error) #optional_allocator_error { if array == nil { return } @@ -337,8 +363,8 @@ append_soa_elems :: proc(array: ^$T/#soa[dynamic]$E, args: ..E, loc := #caller_l } if cap(array) <= len(array)+arg_len { - cap := 2 * cap(array) + max(8, arg_len) - err = reserve_soa(array, cap, loc) // do not 'or_return' here as it could be a partial success + cap := 2 * cap(array) + max(DEFAULT_DYNAMIC_ARRAY_CAPACITY, arg_len) + err = _reserve_soa(array, cap, zero_memory, loc) // do not 'or_return' here as it could be a partial success } arg_len = min(cap(array)-len(array), arg_len) @@ -347,7 +373,7 @@ append_soa_elems :: proc(array: ^$T/#soa[dynamic]$E, args: ..E, loc := #caller_l ti := type_info_of(typeid_of(T)) ti = type_info_base(ti) si := &ti.variant.(Type_Info_Struct) - field_count := uintptr(intrinsics.type_struct_field_count(E)) + field_count := uintptr(len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E)) data := (^rawptr)(array)^ @@ -389,7 +415,8 @@ append_soa :: proc{ delete_soa_slice :: proc(array: $T/#soa[]$E, allocator := context.allocator, loc := #caller_location) -> Allocator_Error { - when intrinsics.type_struct_field_count(E) != 0 { + field_count :: len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E) + when field_count != 0 { array := array ptr := (^rawptr)(&array)^ free(ptr, allocator, loc) or_return @@ -398,7 +425,8 @@ delete_soa_slice :: proc(array: $T/#soa[]$E, allocator := context.allocator, loc } delete_soa_dynamic_array :: proc(array: $T/#soa[dynamic]$E, loc := #caller_location) -> Allocator_Error { - when intrinsics.type_struct_field_count(E) != 0 { + field_count :: len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E) + when field_count != 0 { array := array ptr := (^rawptr)(&array)^ footer := raw_soa_footer(&array) @@ -416,7 +444,8 @@ delete_soa :: proc{ clear_soa_dynamic_array :: proc(array: ^$T/#soa[dynamic]$E) { - when intrinsics.type_struct_field_count(E) != 0 { + field_count :: len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E) + when field_count != 0 { footer := raw_soa_footer(array) footer.len = 0 } @@ -438,12 +467,7 @@ into_dynamic_soa :: proc(array: $T/#soa[]$E) -> #soa[dynamic]E { allocator = nil_allocator(), } - field_count: uintptr - when intrinsics.type_is_array(E) { - field_count = len(E) - } else { - field_count = uintptr(intrinsics.type_struct_field_count(E)) - } + field_count := uintptr(len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E)) array := array dynamic_data := ([^]rawptr)(&d)[:field_count] @@ -467,12 +491,7 @@ unordered_remove_soa :: proc(array: ^$T/#soa[dynamic]$E, index: int, loc := #cal ti = type_info_base(ti) si := &ti.variant.(Type_Info_Struct) - field_count: uintptr - when intrinsics.type_is_array(E) { - field_count = len(E) - } else { - field_count = uintptr(intrinsics.type_struct_field_count(E)) - } + field_count := uintptr(len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E)) data := uintptr(array) for i in 0.. rawptr { + context = default_context() unimplemented("base:runtime 'heap_alloc' procedure is not supported on this platform") } _heap_resize :: proc "contextless" (ptr: rawptr, new_size: int) -> rawptr { + context = default_context() unimplemented("base:runtime 'heap_resize' procedure is not supported on this platform") } _heap_free :: proc "contextless" (ptr: rawptr) { + context = default_context() unimplemented("base:runtime 'heap_free' procedure is not supported on this platform") } diff --git a/base/runtime/internal.odin b/base/runtime/internal.odin index 378eea256..1a97ade09 100644 --- a/base/runtime/internal.odin +++ b/base/runtime/internal.odin @@ -1,3 +1,4 @@ +//+vet !cast package runtime import "base:intrinsics" @@ -29,7 +30,7 @@ is_power_of_two_int :: #force_inline proc "contextless" (x: int) -> bool { return (x & (x-1)) == 0 } -align_forward_int :: #force_inline proc(ptr, align: int) -> int { +align_forward_int :: #force_inline proc "odin" (ptr, align: int) -> int { assert(is_power_of_two_int(align)) p := ptr @@ -47,7 +48,7 @@ is_power_of_two_uint :: #force_inline proc "contextless" (x: uint) -> bool { return (x & (x-1)) == 0 } -align_forward_uint :: #force_inline proc(ptr, align: uint) -> uint { +align_forward_uint :: #force_inline proc "odin" (ptr, align: uint) -> uint { assert(is_power_of_two_uint(align)) p := ptr @@ -65,7 +66,7 @@ is_power_of_two_uintptr :: #force_inline proc "contextless" (x: uintptr) -> bool return (x & (x-1)) == 0 } -align_forward_uintptr :: #force_inline proc(ptr, align: uintptr) -> uintptr { +align_forward_uintptr :: #force_inline proc "odin" (ptr, align: uintptr) -> uintptr { assert(is_power_of_two_uintptr(align)) p := ptr @@ -642,21 +643,24 @@ abs_quaternion256 :: #force_inline proc "contextless" (x: quaternion256) -> f64 quo_complex32 :: proc "contextless" (n, m: complex32) -> complex32 { - e, f: f16 + nr, ni := f32(real(n)), f32(imag(n)) + mr, mi := f32(real(m)), f32(imag(m)) - if abs(real(m)) >= abs(imag(m)) { - ratio := imag(m) / real(m) - denom := real(m) + ratio*imag(m) - e = (real(n) + imag(n)*ratio) / denom - f = (imag(n) - real(n)*ratio) / denom + e, f: f32 + + if abs(mr) >= abs(mi) { + ratio := mi / mr + denom := mr + ratio*mi + e = (nr + ni*ratio) / denom + f = (ni - nr*ratio) / denom } else { - ratio := real(m) / imag(m) - denom := imag(m) + ratio*real(m) - e = (real(n)*ratio + imag(n)) / denom - f = (imag(n)*ratio - real(n)) / denom + ratio := mr / mi + denom := mi + ratio*mr + e = (nr*ratio + ni) / denom + f = (ni*ratio - nr) / denom } - return complex(e, f) + return complex(f16(e), f16(f)) } @@ -697,15 +701,15 @@ quo_complex128 :: proc "contextless" (n, m: complex128) -> complex128 { } mul_quaternion64 :: proc "contextless" (q, r: quaternion64) -> quaternion64 { - q0, q1, q2, q3 := real(q), imag(q), jmag(q), kmag(q) - r0, r1, r2, r3 := real(r), imag(r), jmag(r), kmag(r) + q0, q1, q2, q3 := f32(real(q)), f32(imag(q)), f32(jmag(q)), f32(kmag(q)) + r0, r1, r2, r3 := f32(real(r)), f32(imag(r)), f32(jmag(r)), f32(kmag(r)) t0 := r0*q0 - r1*q1 - r2*q2 - r3*q3 t1 := r0*q1 + r1*q0 - r2*q3 + r3*q2 t2 := r0*q2 + r1*q3 + r2*q0 - r3*q1 t3 := r0*q3 - r1*q2 + r2*q1 + r3*q0 - return quaternion(w=t0, x=t1, y=t2, z=t3) + return quaternion(w=f16(t0), x=f16(t1), y=f16(t2), z=f16(t3)) } mul_quaternion128 :: proc "contextless" (q, r: quaternion128) -> quaternion128 { @@ -733,8 +737,8 @@ mul_quaternion256 :: proc "contextless" (q, r: quaternion256) -> quaternion256 { } quo_quaternion64 :: proc "contextless" (q, r: quaternion64) -> quaternion64 { - q0, q1, q2, q3 := real(q), imag(q), jmag(q), kmag(q) - r0, r1, r2, r3 := real(r), imag(r), jmag(r), kmag(r) + q0, q1, q2, q3 := f32(real(q)), f32(imag(q)), f32(jmag(q)), f32(kmag(q)) + r0, r1, r2, r3 := f32(real(r)), f32(imag(r)), f32(jmag(r)), f32(kmag(r)) invmag2 := 1.0 / (r0*r0 + r1*r1 + r2*r2 + r3*r3) @@ -743,7 +747,7 @@ quo_quaternion64 :: proc "contextless" (q, r: quaternion64) -> quaternion64 { t2 := (r0*q2 - r1*q3 - r2*q0 + r3*q1) * invmag2 t3 := (r0*q3 + r1*q2 + r2*q1 - r3*q0) * invmag2 - return quaternion(w=t0, x=t1, y=t2, z=t3) + return quaternion(w=f16(t0), x=f16(t1), y=f16(t2), z=f16(t3)) } quo_quaternion128 :: proc "contextless" (q, r: quaternion128) -> quaternion128 { @@ -1012,26 +1016,26 @@ modti3 :: proc "c" (a, b: i128) -> i128 { bn := (b ~ s_b) - s_b r: u128 = --- - _ = udivmod128(transmute(u128)an, transmute(u128)bn, &r) - return (transmute(i128)r ~ s_a) - s_a + _ = udivmod128(u128(an), u128(bn), &r) + return (i128(r) ~ s_a) - s_a } @(link_name="__divmodti4", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE) divmodti4 :: proc "c" (a, b: i128, rem: ^i128) -> i128 { - u := udivmod128(transmute(u128)a, transmute(u128)b, cast(^u128)rem) - return transmute(i128)u + u := udivmod128(u128(a), u128(b), (^u128)(rem)) + return i128(u) } @(link_name="__divti3", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE) divti3 :: proc "c" (a, b: i128) -> i128 { - u := udivmodti4(transmute(u128)a, transmute(u128)b, nil) - return transmute(i128)u + u := udivmodti4(u128(a), u128(b), nil) + return i128(u) } @(link_name="__fixdfti", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE) -fixdfti :: proc(a: u64) -> i128 { +fixdfti :: proc "c" (a: u64) -> i128 { significandBits :: 52 typeWidth :: (size_of(u64)*8) exponentBits :: (typeWidth - significandBits - 1) diff --git a/base/runtime/os_specific_wasi.odin b/base/runtime/os_specific_wasi.odin index 0e229ac7e..b85d7adea 100644 --- a/base/runtime/os_specific_wasi.odin +++ b/base/runtime/os_specific_wasi.odin @@ -2,10 +2,54 @@ //+private package runtime -import "core:sys/wasm/wasi" +foreign import wasi "wasi_snapshot_preview1" + +@(default_calling_convention="contextless") +foreign wasi { + fd_write :: proc( + fd: i32, + iovs: [][]byte, + n: ^uint, + ) -> u16 --- + + @(private="file") + args_sizes_get :: proc( + num_of_args: ^uint, + size_of_args: ^uint, + ) -> u16 --- + + @(private="file") + args_get :: proc( + argv: [^]cstring, + argv_buf: [^]byte, + ) -> u16 --- +} _stderr_write :: proc "contextless" (data: []byte) -> (int, _OS_Errno) { - data_iovec := (wasi.ciovec_t)(data) - n, err := wasi.fd_write(1, {data_iovec}) + n: uint + err := fd_write(1, {data}, &n) return int(n), _OS_Errno(err) } + +_wasi_setup_args :: proc() { + num_of_args, size_of_args: uint + if errno := args_sizes_get(&num_of_args, &size_of_args); errno != 0 { + return + } + + err: Allocator_Error + if args__, err = make([]cstring, num_of_args); err != nil { + return + } + + args_buf: []byte + if args_buf, err = make([]byte, size_of_args); err != nil { + delete(args__) + return + } + + if errno := args_get(raw_data(args__), raw_data(args_buf)); errno != 0 { + delete(args__) + delete(args_buf) + } +} diff --git a/base/runtime/random_generator.odin b/base/runtime/random_generator.odin index 95ba6ece9..0c4c92bd2 100644 --- a/base/runtime/random_generator.odin +++ b/base/runtime/random_generator.odin @@ -83,13 +83,13 @@ default_random_generator_proc :: proc(data: rawptr, mode: Random_Generator_Mode, switch mode { case .Read: if r.state == 0 && r.inc == 0 { - init(r, 0) + init(r, 0) } switch len(p) { case size_of(u64): // Fast path for a 64-bit destination. - intrinsics.unaligned_store(transmute(^u64)raw_data(p), read_u64(r)) + intrinsics.unaligned_store((^u64)(raw_data(p)), read_u64(r)) case: // All other cases. pos := i8(0) @@ -108,7 +108,7 @@ default_random_generator_proc :: proc(data: rawptr, mode: Random_Generator_Mode, case .Reset: seed: u64 mem_copy_non_overlapping(&seed, raw_data(p), min(size_of(seed), len(p))) - init(r, seed) + init(r, seed) case .Query_Info: if len(p) != size_of(Random_Generator_Query_Info) { diff --git a/base/runtime/udivmod128.odin b/base/runtime/udivmod128.odin index eceb815bf..8cc70df55 100644 --- a/base/runtime/udivmod128.odin +++ b/base/runtime/udivmod128.odin @@ -58,7 +58,7 @@ udivmod128 :: proc "c" (a, b: u128, rem: ^u128) -> u128 { return u128(n[high] >> _ctz(d[high])) } - sr = transmute(u32)(i32(_clz(d[high])) - i32(_clz(n[high]))) + sr = u32(i32(_clz(d[high])) - i32(_clz(n[high]))) if sr > U64_BITS - 2 { if rem != nil { rem^ = a @@ -107,7 +107,7 @@ udivmod128 :: proc "c" (a, b: u128, rem: ^u128) -> u128 { r[low] = n[high] >> (sr - U64_BITS) } } else { - sr = transmute(u32)(i32(_clz(d[high])) - i32(_clz(n[high]))) + sr = u32(i32(_clz(d[high])) - i32(_clz(n[high]))) if sr > U64_BITS - 1 { if rem != nil { @@ -143,7 +143,7 @@ udivmod128 :: proc "c" (a, b: u128, rem: ^u128) -> u128 { r_all = transmute(u128)r s := i128(b - r_all - 1) >> (U128_BITS - 1) carry = u32(s & 1) - r_all -= b & transmute(u128)s + r_all -= b & u128(s) r = transmute([2]u64)r_all } diff --git a/base/runtime/wasm_allocator.odin b/base/runtime/wasm_allocator.odin index 6bca0b3d6..f4b399c47 100644 --- a/base/runtime/wasm_allocator.odin +++ b/base/runtime/wasm_allocator.odin @@ -495,7 +495,7 @@ claim_more_memory :: proc(a: ^WASM_Allocator, num_bytes: uint) -> bool { // we can just extend the spill. spill_end := uintptr(raw_data(a.spill)) + uintptr(len(a.spill)) if spill_end == uintptr(raw_data(allocated)) { - raw_spill := transmute(^Raw_Slice)(&a.spill) + raw_spill := (^Raw_Slice)(&a.spill) raw_spill.len += len(allocated) } else { // Otherwise, we have to "waste" the previous spill. @@ -679,7 +679,7 @@ allocate_memory :: proc(a: ^WASM_Allocator, alignment: uint, size: uint, loc := // but we just had a stale bit set to mark a populated bucket. // Reset the bit to update latest status so that we do not // redundantly look at this bucket again. - a.free_region_buckets_used &= ~(BUCKET_BITMASK_T(1) << bucket_index) + a.free_region_buckets_used &~= BUCKET_BITMASK_T(1) << bucket_index bucket_mask ~= 1 } @@ -760,7 +760,7 @@ free :: proc(a: ^WASM_Allocator, ptr: rawptr, loc := #caller_location) { defer unlock(a) size := region.size - assert(region_is_in_use(region), "double free", loc=loc) + assert(region_is_in_use(region), "double free or corrupt region", loc=loc) prev_region_size_field := ([^]uint)(region)[-1] prev_region_size := prev_region_size_field & ~uint(FREE_REGION_FLAG) diff --git a/core/c/libc/signal.odin b/core/c/libc/signal.odin index 1489779fe..c447e3cc3 100644 --- a/core/c/libc/signal.odin +++ b/core/c/libc/signal.odin @@ -34,20 +34,7 @@ when ODIN_OS == .Windows { SIGTERM :: 15 } -when ODIN_OS == .Linux || ODIN_OS == .FreeBSD || ODIN_OS == .Haiku || ODIN_OS == .OpenBSD || ODIN_OS == .NetBSD { - SIG_ERR :: rawptr(~uintptr(0)) - SIG_DFL :: rawptr(uintptr(0)) - SIG_IGN :: rawptr(uintptr(1)) - - SIGABRT :: 6 - SIGFPE :: 8 - SIGILL :: 4 - SIGINT :: 2 - SIGSEGV :: 11 - SIGTERM :: 15 -} - -when ODIN_OS == .Darwin { +when ODIN_OS == .Linux || ODIN_OS == .FreeBSD || ODIN_OS == .Haiku || ODIN_OS == .OpenBSD || ODIN_OS == .NetBSD || ODIN_OS == .Darwin { SIG_ERR :: rawptr(~uintptr(0)) SIG_DFL :: rawptr(uintptr(0)) SIG_IGN :: rawptr(uintptr(1)) diff --git a/core/compress/common.odin b/core/compress/common.odin index b22172e61..47ba45e88 100644 --- a/core/compress/common.odin +++ b/core/compress/common.odin @@ -34,13 +34,13 @@ COMPRESS_OUTPUT_ALLOCATE_MIN :: int(#config(COMPRESS_OUTPUT_ALLOCATE_MIN, 1 << 2 */ when size_of(uintptr) == 8 { - // For 64-bit platforms, we set the default max buffer size to 4 GiB, - // which is GZIP and PKZIP's max payload size. + // For 64-bit platforms, we set the default max buffer size to 4 GiB, + // which is GZIP and PKZIP's max payload size. COMPRESS_OUTPUT_ALLOCATE_MAX :: int(#config(COMPRESS_OUTPUT_ALLOCATE_MAX, 1 << 32)) } else { // For 32-bit platforms, we set the default max buffer size to 512 MiB. - COMPRESS_OUTPUT_ALLOCATE_MAX :: int(#config(COMPRESS_OUTPUT_ALLOCATE_MAX, 1 << 29)) + COMPRESS_OUTPUT_ALLOCATE_MAX :: int(#config(COMPRESS_OUTPUT_ALLOCATE_MAX, 1 << 29)) } diff --git a/core/compress/shoco/shoco.odin b/core/compress/shoco/shoco.odin index 3c1f412ba..269dd8875 100644 --- a/core/compress/shoco/shoco.odin +++ b/core/compress/shoco/shoco.odin @@ -98,7 +98,7 @@ decompress_slice_to_output_buffer :: proc(input: []u8, output: []u8, model := DE validate_model(model) or_return for inp < inp_end { - val := transmute(i8)input[inp] + val := i8(input[inp]) mark := int(-1) for val < 0 { @@ -274,12 +274,9 @@ compress_string_to_buffer :: proc(input: string, output: []u8, model := DEFAULT_ out_ptr := raw_data(output[out:]) switch pack.bytes_packed { - case 4: - intrinsics.unaligned_store(transmute(^u32)out_ptr, code) - case 2: - intrinsics.unaligned_store(transmute(^u16)out_ptr, u16(code)) - case 1: - intrinsics.unaligned_store(transmute(^u8)out_ptr, u8(code)) + case 4: intrinsics.unaligned_store((^u32)(out_ptr), code) + case 2: intrinsics.unaligned_store((^u16)(out_ptr), u16(code)) + case 1: intrinsics.unaligned_store( (^u8)(out_ptr), u8(code)) case: return out, .Unknown_Compression_Method } diff --git a/core/container/bit_array/bit_array.odin b/core/container/bit_array/bit_array.odin index a8720715c..b53bacda7 100644 --- a/core/container/bit_array/bit_array.odin +++ b/core/container/bit_array/bit_array.odin @@ -210,8 +210,11 @@ set :: proc(ba: ^Bit_Array, #any_int index: uint, set_to: bool = true, allocator ba.max_index = max(idx, ba.max_index) - if set_to{ ba.bits[leg_index] |= 1 << uint(bit_index) } - else { ba.bits[leg_index] &= ~(1 << uint(bit_index)) } + if set_to { + ba.bits[leg_index] |= 1 << uint(bit_index) + } else { + ba.bits[leg_index] &~= 1 << uint(bit_index) + } return true } @@ -253,7 +256,7 @@ Inputs: - index: Which bit in the array */ unsafe_unset :: proc(b: ^Bit_Array, bit: int) #no_bounds_check { - b.bits[bit >> INDEX_SHIFT] &= ~(1 << uint(bit & INDEX_MASK)) + b.bits[bit >> INDEX_SHIFT] &~= 1 << uint(bit & INDEX_MASK) } /* A helper function to create a Bit Array with optional bias, in case your smallest index is non-zero (including negative). diff --git a/core/container/lru/lru_cache.odin b/core/container/lru/lru_cache.odin index 23f01fac3..f8aa55dc2 100644 --- a/core/container/lru/lru_cache.odin +++ b/core/container/lru/lru_cache.odin @@ -70,8 +70,7 @@ set :: proc(c: ^$C/Cache($Key, $Value), key: Key, value: Value) -> runtime.Alloc if c.count == c.capacity { e = c.tail _remove_node(c, e) - } - else { + } else { c.count += 1 e = new(Node(Key, Value), c.node_allocator) or_return } diff --git a/core/container/queue/queue.odin b/core/container/queue/queue.odin index e46dccb33..e7a60dde0 100644 --- a/core/container/queue/queue.odin +++ b/core/container/queue/queue.odin @@ -189,7 +189,7 @@ pop_front_safe :: proc(q: ^$Q/Queue($T)) -> (elem: T, ok: bool) { return } -// Push multiple elements to the front of the queue +// Push multiple elements to the back of the queue push_back_elems :: proc(q: ^$Q/Queue($T), elems: ..T) -> (ok: bool, err: runtime.Allocator_Error) { n := uint(builtin.len(elems)) if space(q^) < int(n) { @@ -241,7 +241,7 @@ clear :: proc(q: ^$Q/Queue($T)) { } -// Internal growinh procedure +// Internal growing procedure _grow :: proc(q: ^$Q/Queue($T), min_capacity: uint = 0) -> runtime.Allocator_Error { new_capacity := max(min_capacity, uint(8), uint(builtin.len(q.data))*2) n := uint(builtin.len(q.data)) diff --git a/core/container/rbtree/rbtree.odin b/core/container/rbtree/rbtree.odin index 57a68a948..090551367 100644 --- a/core/container/rbtree/rbtree.odin +++ b/core/container/rbtree/rbtree.odin @@ -29,7 +29,7 @@ Tree :: struct($Key: typeid, $Value: typeid) { _root: ^Node(Key, Value), _node_allocator: runtime.Allocator, - _cmp_fn: proc(Key, Key) -> Ordering, + _cmp_fn: proc(Key, Key) -> Ordering, _size: int, } diff --git a/core/container/small_array/small_array.odin b/core/container/small_array/small_array.odin index ecec7b80c..b2068469d 100644 --- a/core/container/small_array/small_array.odin +++ b/core/container/small_array/small_array.odin @@ -119,20 +119,20 @@ consume :: proc "odin" (a: ^$A/Small_Array($N, $T), count: int, loc := #caller_l } ordered_remove :: proc "contextless" (a: ^$A/Small_Array($N, $T), index: int, loc := #caller_location) #no_bounds_check { - runtime.bounds_check_error_loc(loc, index, a.len) - if index+1 < a.len { + runtime.bounds_check_error_loc(loc, index, a.len) + if index+1 < a.len { copy(a.data[index:], a.data[index+1:]) } a.len -= 1 } unordered_remove :: proc "contextless" (a: ^$A/Small_Array($N, $T), index: int, loc := #caller_location) #no_bounds_check { - runtime.bounds_check_error_loc(loc, index, a.len) + runtime.bounds_check_error_loc(loc, index, a.len) n := a.len-1 if index != n { a.data[index] = a.data[n] } - a.len -= 1 + a.len -= 1 } clear :: proc "contextless" (a: ^$A/Small_Array($N, $T)) { diff --git a/core/container/topological_sort/topological_sort.odin b/core/container/topological_sort/topological_sort.odin index 0d34e8d02..10765958e 100644 --- a/core/container/topological_sort/topological_sort.odin +++ b/core/container/topological_sort/topological_sort.odin @@ -61,7 +61,7 @@ add_dependency :: proc(sorter: ^$S/Sorter($K), key, dependency: K) -> bool { } find.dependents[key] = true - find = &sorter.relations[key] + find = &sorter.relations[key] if find == nil { find = map_insert(&sorter.relations, key, make_relations(sorter)) } diff --git a/core/crypto/_edwards25519/edwards25519.odin b/core/crypto/_edwards25519/edwards25519.odin index 952bb9ef8..6495f7a3a 100644 --- a/core/crypto/_edwards25519/edwards25519.odin +++ b/core/crypto/_edwards25519/edwards25519.odin @@ -110,7 +110,7 @@ ge_set_bytes :: proc "contextless" (ge: ^Group_Element, b: []byte) -> bool { if len(b) != 32 { intrinsics.trap() } - b_ := transmute(^[32]byte)(raw_data(b)) + b_ := (^[32]byte)(raw_data(b)) // Do the work in a scratch element, so that ge is unchanged on // failure. @@ -169,7 +169,7 @@ ge_bytes :: proc "contextless" (ge: ^Group_Element, dst: []byte) { if len(dst) != 32 { intrinsics.trap() } - dst_ := transmute(^[32]byte)(raw_data(dst)) + dst_ := (^[32]byte)(raw_data(dst)) // Convert the element to affine (x, y) representation. x, y, z_inv: field.Tight_Field_Element = ---, ---, --- diff --git a/core/crypto/_edwards25519/edwards25519_scalar.odin b/core/crypto/_edwards25519/edwards25519_scalar.odin index 2644fe5f7..e21fa3755 100644 --- a/core/crypto/_edwards25519/edwards25519_scalar.odin +++ b/core/crypto/_edwards25519/edwards25519_scalar.odin @@ -28,7 +28,7 @@ sc_set_bytes :: proc "contextless" (sc: ^Scalar, b: []byte) -> bool { if len(b) != 32 { intrinsics.trap() } - b_ := transmute(^[32]byte)(raw_data(b)) + b_ := (^[32]byte)(raw_data(b)) return field.fe_from_bytes(sc, b_) } @@ -36,7 +36,7 @@ sc_set_bytes_rfc8032 :: proc "contextless" (sc: ^Scalar, b: []byte) { if len(b) != 32 { intrinsics.trap() } - b_ := transmute(^[32]byte)(raw_data(b)) + b_ := (^[32]byte)(raw_data(b)) field.fe_from_bytes_rfc8032(sc, b_) } diff --git a/core/crypto/_fiat/field_curve25519/field.odin b/core/crypto/_fiat/field_curve25519/field.odin index 8a8202ac4..04fc87659 100644 --- a/core/crypto/_fiat/field_curve25519/field.odin +++ b/core/crypto/_fiat/field_curve25519/field.odin @@ -6,13 +6,13 @@ import "core:mem" fe_relax_cast :: #force_inline proc "contextless" ( arg1: ^Tight_Field_Element, ) -> ^Loose_Field_Element { - return transmute(^Loose_Field_Element)(arg1) + return (^Loose_Field_Element)(arg1) } fe_tighten_cast :: #force_inline proc "contextless" ( arg1: ^Loose_Field_Element, ) -> ^Tight_Field_Element { - return transmute(^Tight_Field_Element)(arg1) + return (^Tight_Field_Element)(arg1) } fe_clear :: proc "contextless" ( diff --git a/core/crypto/_fiat/field_poly1305/field.odin b/core/crypto/_fiat/field_poly1305/field.odin index c50a56b0c..b12046858 100644 --- a/core/crypto/_fiat/field_poly1305/field.odin +++ b/core/crypto/_fiat/field_poly1305/field.odin @@ -7,13 +7,13 @@ import "core:mem" fe_relax_cast :: #force_inline proc "contextless" ( arg1: ^Tight_Field_Element, ) -> ^Loose_Field_Element { - return transmute(^Loose_Field_Element)(arg1) + return (^Loose_Field_Element)(arg1) } fe_tighten_cast :: #force_inline proc "contextless" ( arg1: ^Loose_Field_Element, ) -> ^Tight_Field_Element { - return transmute(^Tight_Field_Element)(arg1) + return (^Tight_Field_Element)(arg1) } fe_from_bytes :: #force_inline proc "contextless" ( diff --git a/core/crypto/kmac/kmac.odin b/core/crypto/kmac/kmac.odin index e5be6f91b..711f459b3 100644 --- a/core/crypto/kmac/kmac.odin +++ b/core/crypto/kmac/kmac.odin @@ -61,7 +61,7 @@ init_256 :: proc(ctx: ^Context, key, domain_sep: []byte) { update :: proc(ctx: ^Context, data: []byte) { assert(ctx.is_initialized) - shake.write(transmute(^shake.Context)(ctx), data) + shake.write((^shake.Context)(ctx), data) } // final finalizes the Context, writes the tag to dst, and calls reset @@ -75,7 +75,7 @@ final :: proc(ctx: ^Context, dst: []byte) { panic("crypto/kmac: invalid KMAC tag_size, too short") } - _sha3.final_cshake(transmute(^_sha3.Context)(ctx), dst) + _sha3.final_cshake((^_sha3.Context)(ctx), dst) } // clone clones the Context other into ctx. @@ -84,7 +84,7 @@ clone :: proc(ctx, other: ^Context) { return } - shake.clone(transmute(^shake.Context)(ctx), transmute(^shake.Context)(other)) + shake.clone((^shake.Context)(ctx), (^shake.Context)(other)) } // reset sanitizes the Context. The Context must be re-initialized to @@ -94,7 +94,7 @@ reset :: proc(ctx: ^Context) { return } - shake.reset(transmute(^shake.Context)(ctx)) + shake.reset((^shake.Context)(ctx)) } @(private) @@ -107,7 +107,7 @@ _init_kmac :: proc(ctx: ^Context, key, s: []byte, sec_strength: int) { panic("crypto/kmac: invalid KMAC key, too short") } - ctx_ := transmute(^_sha3.Context)(ctx) + ctx_ := (^_sha3.Context)(ctx) _sha3.init_cshake(ctx_, N_KMAC, s, sec_strength) _sha3.bytepad(ctx_, [][]byte{key}, _sha3.rate_cshake(sec_strength)) } diff --git a/core/crypto/legacy/keccak/keccak.odin b/core/crypto/legacy/keccak/keccak.odin index 7813a1ab4..6ca66b7ca 100644 --- a/core/crypto/legacy/keccak/keccak.odin +++ b/core/crypto/legacy/keccak/keccak.odin @@ -66,12 +66,12 @@ init_512 :: proc(ctx: ^Context) { @(private) _init :: proc(ctx: ^Context) { ctx.dsbyte = _sha3.DS_KECCAK - _sha3.init(transmute(^_sha3.Context)(ctx)) + _sha3.init((^_sha3.Context)(ctx)) } // update adds more data to the Context. update :: proc(ctx: ^Context, data: []byte) { - _sha3.update(transmute(^_sha3.Context)(ctx), data) + _sha3.update((^_sha3.Context)(ctx), data) } // final finalizes the Context, writes the digest to hash, and calls @@ -80,16 +80,16 @@ update :: proc(ctx: ^Context, data: []byte) { // Iff finalize_clone is set, final will work on a copy of the Context, // which is useful for for calculating rolling digests. final :: proc(ctx: ^Context, hash: []byte, finalize_clone: bool = false) { - _sha3.final(transmute(^_sha3.Context)(ctx), hash, finalize_clone) + _sha3.final((^_sha3.Context)(ctx), hash, finalize_clone) } // clone clones the Context other into ctx. clone :: proc(ctx, other: ^Context) { - _sha3.clone(transmute(^_sha3.Context)(ctx), transmute(^_sha3.Context)(other)) + _sha3.clone((^_sha3.Context)(ctx), (^_sha3.Context)(other)) } // reset sanitizes the Context. The Context must be re-initialized to // be used again. reset :: proc(ctx: ^Context) { - _sha3.reset(transmute(^_sha3.Context)(ctx)) + _sha3.reset((^_sha3.Context)(ctx)) } diff --git a/core/crypto/rand_darwin.odin b/core/crypto/rand_darwin.odin index 56acb5d22..df474bc4c 100644 --- a/core/crypto/rand_darwin.odin +++ b/core/crypto/rand_darwin.odin @@ -11,7 +11,7 @@ HAS_RAND_BYTES :: true _rand_bytes :: proc(dst: []byte) { err := Sec.RandomCopyBytes(count=len(dst), bytes=raw_data(dst)) if err != .Success { - msg := CF.StringCopyToOdinString(Sec.CopyErrorMessageString(err)) - fmt.panicf("crypto/rand_bytes: SecRandomCopyBytes returned non-zero result: %v %s", err, msg) + msg := CF.StringCopyToOdinString(Sec.CopyErrorMessageString(err)) + fmt.panicf("crypto/rand_bytes: SecRandomCopyBytes returned non-zero result: %v %s", err, msg) } } diff --git a/core/crypto/ristretto255/ristretto255.odin b/core/crypto/ristretto255/ristretto255.odin index d1f2b6ee5..3a2307da0 100644 --- a/core/crypto/ristretto255/ristretto255.odin +++ b/core/crypto/ristretto255/ristretto255.odin @@ -112,7 +112,7 @@ ge_set_bytes :: proc "contextless" (ge: ^Group_Element, b: []byte) -> bool { return false } - b_ := transmute(^[32]byte)(raw_data(b)) + b_ := (^[32]byte)(raw_data(b)) s: field.Tight_Field_Element = --- defer field.fe_clear(&s) @@ -297,7 +297,7 @@ ge_bytes :: proc(ge: ^Group_Element, dst: []byte) { // 2. Return the 32-byte little-endian encoding of s. More // specifically, this is the encoding of the canonical // representation of s as an integer between 0 and p-1, inclusive. - dst_ := transmute(^[32]byte)(raw_data(dst)) + dst_ := (^[32]byte)(raw_data(dst)) field.fe_to_bytes(dst_, &tmp) field.fe_clear_vec([]^field.Tight_Field_Element{&u1, &u2, &tmp, &z_inv, &ix0, &iy0, &x, &y}) @@ -417,7 +417,7 @@ ge_is_identity :: proc(ge: ^Group_Element) -> int { @(private) ge_map :: proc "contextless" (ge: ^Group_Element, b: []byte) { - b_ := transmute(^[32]byte)(raw_data(b)) + b_ := (^[32]byte)(raw_data(b)) // The MAP function is defined on 32-byte strings as: // diff --git a/core/crypto/ristretto255/ristretto255_scalar.odin b/core/crypto/ristretto255/ristretto255_scalar.odin index f581e5963..1ecb490e0 100644 --- a/core/crypto/ristretto255/ristretto255_scalar.odin +++ b/core/crypto/ristretto255/ristretto255_scalar.odin @@ -46,7 +46,7 @@ sc_set_bytes_wide :: proc(sc: ^Scalar, b: []byte) { panic("crypto/ristretto255: invalid wide input size") } - b_ := transmute(^[WIDE_SCALAR_SIZE]byte)(raw_data(b)) + b_ := (^[WIDE_SCALAR_SIZE]byte)(raw_data(b)) grp.sc_set_bytes_wide(sc, b_) } diff --git a/core/crypto/sha3/sha3.odin b/core/crypto/sha3/sha3.odin index bc3e6e846..78057f1ca 100644 --- a/core/crypto/sha3/sha3.odin +++ b/core/crypto/sha3/sha3.odin @@ -68,12 +68,12 @@ init_512 :: proc(ctx: ^Context) { @(private) _init :: proc(ctx: ^Context) { ctx.dsbyte = _sha3.DS_SHA3 - _sha3.init(transmute(^_sha3.Context)(ctx)) + _sha3.init((^_sha3.Context)(ctx)) } // update adds more data to the Context. update :: proc(ctx: ^Context, data: []byte) { - _sha3.update(transmute(^_sha3.Context)(ctx), data) + _sha3.update((^_sha3.Context)(ctx), data) } // final finalizes the Context, writes the digest to hash, and calls @@ -82,16 +82,16 @@ update :: proc(ctx: ^Context, data: []byte) { // Iff finalize_clone is set, final will work on a copy of the Context, // which is useful for for calculating rolling digests. final :: proc(ctx: ^Context, hash: []byte, finalize_clone: bool = false) { - _sha3.final(transmute(^_sha3.Context)(ctx), hash, finalize_clone) + _sha3.final((^_sha3.Context)(ctx), hash, finalize_clone) } // clone clones the Context other into ctx. clone :: proc(ctx, other: ^Context) { - _sha3.clone(transmute(^_sha3.Context)(ctx), transmute(^_sha3.Context)(other)) + _sha3.clone((^_sha3.Context)(ctx), (^_sha3.Context)(other)) } // reset sanitizes the Context. The Context must be re-initialized to // be used again. reset :: proc(ctx: ^Context) { - _sha3.reset(transmute(^_sha3.Context)(ctx)) + _sha3.reset((^_sha3.Context)(ctx)) } diff --git a/core/crypto/shake/shake.odin b/core/crypto/shake/shake.odin index 7da427485..4160f4cf9 100644 --- a/core/crypto/shake/shake.odin +++ b/core/crypto/shake/shake.odin @@ -24,35 +24,35 @@ Context :: distinct _sha3.Context // init_128 initializes a Context for SHAKE128. init_128 :: proc(ctx: ^Context) { - _sha3.init_cshake(transmute(^_sha3.Context)(ctx), nil, nil, 128) + _sha3.init_cshake((^_sha3.Context)(ctx), nil, nil, 128) } // init_256 initializes a Context for SHAKE256. init_256 :: proc(ctx: ^Context) { - _sha3.init_cshake(transmute(^_sha3.Context)(ctx), nil, nil, 256) + _sha3.init_cshake((^_sha3.Context)(ctx), nil, nil, 256) } // init_cshake_128 initializes a Context for cSHAKE128. init_cshake_128 :: proc(ctx: ^Context, domain_sep: []byte) { - _sha3.init_cshake(transmute(^_sha3.Context)(ctx), nil, domain_sep, 128) + _sha3.init_cshake((^_sha3.Context)(ctx), nil, domain_sep, 128) } // init_cshake_256 initializes a Context for cSHAKE256. init_cshake_256 :: proc(ctx: ^Context, domain_sep: []byte) { - _sha3.init_cshake(transmute(^_sha3.Context)(ctx), nil, domain_sep, 256) + _sha3.init_cshake((^_sha3.Context)(ctx), nil, domain_sep, 256) } // write writes more data into the SHAKE instance. This MUST not be called // after any reads have been done, and attempts to do so will panic. write :: proc(ctx: ^Context, data: []byte) { - _sha3.update(transmute(^_sha3.Context)(ctx), data) + _sha3.update((^_sha3.Context)(ctx), data) } // read reads output from the SHAKE instance. There is no practical upper // limit to the amount of data that can be read from SHAKE. After read has // been called one or more times, further calls to write will panic. read :: proc(ctx: ^Context, dst: []byte) { - ctx_ := transmute(^_sha3.Context)(ctx) + ctx_ := (^_sha3.Context)(ctx) if !ctx.is_finalized { _sha3.shake_xof(ctx_) } @@ -62,11 +62,11 @@ read :: proc(ctx: ^Context, dst: []byte) { // clone clones the Context other into ctx. clone :: proc(ctx, other: ^Context) { - _sha3.clone(transmute(^_sha3.Context)(ctx), transmute(^_sha3.Context)(other)) + _sha3.clone((^_sha3.Context)(ctx), (^_sha3.Context)(other)) } // reset sanitizes the Context. The Context must be re-initialized to // be used again. reset :: proc(ctx: ^Context) { - _sha3.reset(transmute(^_sha3.Context)(ctx)) + _sha3.reset((^_sha3.Context)(ctx)) } diff --git a/core/crypto/tuplehash/tuplehash.odin b/core/crypto/tuplehash/tuplehash.odin index baba1ce59..ed0a3aa87 100644 --- a/core/crypto/tuplehash/tuplehash.odin +++ b/core/crypto/tuplehash/tuplehash.odin @@ -13,19 +13,19 @@ Context :: distinct _sha3.Context // init_128 initializes a Context for TupleHash128 or TupleHashXOF128. init_128 :: proc(ctx: ^Context, domain_sep: []byte) { - _sha3.init_cshake(transmute(^_sha3.Context)(ctx), N_TUPLEHASH, domain_sep, 128) + _sha3.init_cshake((^_sha3.Context)(ctx), N_TUPLEHASH, domain_sep, 128) } // init_256 initializes a Context for TupleHash256 or TupleHashXOF256. init_256 :: proc(ctx: ^Context, domain_sep: []byte) { - _sha3.init_cshake(transmute(^_sha3.Context)(ctx), N_TUPLEHASH, domain_sep, 256) + _sha3.init_cshake((^_sha3.Context)(ctx), N_TUPLEHASH, domain_sep, 256) } // write_element writes a tuple element into the TupleHash or TupleHashXOF // instance. This MUST not be called after any reads have been done, and // any attempts to do so will panic. write_element :: proc(ctx: ^Context, data: []byte) { - _, _ = _sha3.encode_string(transmute(^_sha3.Context)(ctx), data) + _, _ = _sha3.encode_string((^_sha3.Context)(ctx), data) } // final finalizes the Context, writes the digest to hash, and calls @@ -34,7 +34,7 @@ write_element :: proc(ctx: ^Context, data: []byte) { // Iff finalize_clone is set, final will work on a copy of the Context, // which is useful for for calculating rolling digests. final :: proc(ctx: ^Context, hash: []byte, finalize_clone: bool = false) { - _sha3.final_cshake(transmute(^_sha3.Context)(ctx), hash, finalize_clone) + _sha3.final_cshake((^_sha3.Context)(ctx), hash, finalize_clone) } // read reads output from the TupleHashXOF instance. There is no practical @@ -42,7 +42,7 @@ final :: proc(ctx: ^Context, hash: []byte, finalize_clone: bool = false) { // After read has been called one or more times, further calls to // write_element will panic. read :: proc(ctx: ^Context, dst: []byte) { - ctx_ := transmute(^_sha3.Context)(ctx) + ctx_ := (^_sha3.Context)(ctx) if !ctx.is_finalized { _sha3.encode_byte_len(ctx_, 0, false) // right_encode _sha3.shake_xof(ctx_) @@ -53,13 +53,13 @@ read :: proc(ctx: ^Context, dst: []byte) { // clone clones the Context other into ctx. clone :: proc(ctx, other: ^Context) { - _sha3.clone(transmute(^_sha3.Context)(ctx), transmute(^_sha3.Context)(other)) + _sha3.clone((^_sha3.Context)(ctx), (^_sha3.Context)(other)) } // reset sanitizes the Context. The Context must be re-initialized to // be used again. reset :: proc(ctx: ^Context) { - _sha3.reset(transmute(^_sha3.Context)(ctx)) + _sha3.reset((^_sha3.Context)(ctx)) } @(private) diff --git a/core/debug/trace/trace_cpp.odin b/core/debug/trace/trace_cpp.odin index 894046c45..dc723184a 100644 --- a/core/debug/trace/trace_cpp.odin +++ b/core/debug/trace/trace_cpp.odin @@ -78,7 +78,7 @@ _Context :: struct { @(private="package") _init :: proc(ctx: ^Context) -> (ok: bool) { - defer if !ok do destroy(ctx) + defer if !ok { destroy(ctx) } ctx.impl.state = backtrace_create_state("odin-debug-trace", 1, nil, ctx) return ctx.impl.state != nil diff --git a/core/debug/trace/trace_nil.odin b/core/debug/trace/trace_nil.odin index 40478898b..8611d7726 100644 --- a/core/debug/trace/trace_nil.odin +++ b/core/debug/trace/trace_nil.odin @@ -1,6 +1,8 @@ //+build !windows !linux !darwin package debug_trace +import "base:runtime" + _Context :: struct { } @@ -10,9 +12,9 @@ _init :: proc(ctx: ^Context) -> (ok: bool) { _destroy :: proc(ctx: ^Context) -> bool { return true } -_frames :: proc(ctx: ^Context, skip: uint, allocator: runtime.Allocator) -> []Frame { +_frames :: proc(ctx: ^Context, skip: uint, frames_buffer: []Frame) -> []Frame { return nil } -_resolve :: proc(ctx: ^Context, frame: Frame, allocator: runtime.Allocator) -> (result: runtime.Source_Code_Location) { +_resolve :: proc(ctx: ^Context, frame: Frame, allocator: runtime.Allocator) -> (result: Frame_Location) { return } diff --git a/core/encoding/base32/base32.odin b/core/encoding/base32/base32.odin index 962a3ead4..f3320428d 100644 --- a/core/encoding/base32/base32.odin +++ b/core/encoding/base32/base32.odin @@ -8,141 +8,141 @@ package encoding_base32 // truncate it from the encoded output. ENC_TABLE := [32]byte { - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', - 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', - 'Y', 'Z', '2', '3', '4', '5', '6', '7', + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', + 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', + 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', '2', '3', '4', '5', '6', '7', } PADDING :: '=' DEC_TABLE := [?]u8 { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 26, 27, 28, 29, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, - 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 26, 27, 28, 29, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, + 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, } encode :: proc(data: []byte, ENC_TBL := ENC_TABLE, allocator := context.allocator) -> string { - out_length := (len(data) + 4) / 5 * 8 - out := make([]byte, out_length) - _encode(out, data) - return string(out) + out_length := (len(data) + 4) / 5 * 8 + out := make([]byte, out_length) + _encode(out, data) + return string(out) } @private _encode :: proc(out, data: []byte, ENC_TBL := ENC_TABLE, allocator := context.allocator) { - out := out - data := data + out := out + data := data - for len(data) > 0 { - carry: byte - switch len(data) { - case: - out[7] = ENC_TABLE[data[4] & 0x1f] - carry = data[4] >> 5 - fallthrough - case 4: - out[6] = ENC_TABLE[carry | (data[3] << 3) & 0x1f] - out[5] = ENC_TABLE[(data[3] >> 2) & 0x1f] - carry = data[3] >> 7 - fallthrough - case 3: - out[4] = ENC_TABLE[carry | (data[2] << 1) & 0x1f] - carry = (data[2] >> 4) & 0x1f - fallthrough - case 2: - out[3] = ENC_TABLE[carry | (data[1] << 4) & 0x1f] - out[2] = ENC_TABLE[(data[1] >> 1) & 0x1f] - carry = (data[1] >> 6) & 0x1f - fallthrough - case 1: - out[1] = ENC_TABLE[carry | (data[0] << 2) & 0x1f] - out[0] = ENC_TABLE[data[0] >> 3] - } + for len(data) > 0 { + carry: byte + switch len(data) { + case: + out[7] = ENC_TABLE[data[4] & 0x1f] + carry = data[4] >> 5 + fallthrough + case 4: + out[6] = ENC_TABLE[carry | (data[3] << 3) & 0x1f] + out[5] = ENC_TABLE[(data[3] >> 2) & 0x1f] + carry = data[3] >> 7 + fallthrough + case 3: + out[4] = ENC_TABLE[carry | (data[2] << 1) & 0x1f] + carry = (data[2] >> 4) & 0x1f + fallthrough + case 2: + out[3] = ENC_TABLE[carry | (data[1] << 4) & 0x1f] + out[2] = ENC_TABLE[(data[1] >> 1) & 0x1f] + carry = (data[1] >> 6) & 0x1f + fallthrough + case 1: + out[1] = ENC_TABLE[carry | (data[0] << 2) & 0x1f] + out[0] = ENC_TABLE[data[0] >> 3] + } - if len(data) < 5 { - out[7] = byte(PADDING) - if len(data) < 4 { - out[6] = byte(PADDING) - out[5] = byte(PADDING) - if len(data) < 3 { - out[4] = byte(PADDING) - if len(data) < 2 { - out[3] = byte(PADDING) - out[2] = byte(PADDING) - } - } - } - break - } - data = data[5:] - out = out[8:] - } + if len(data) < 5 { + out[7] = byte(PADDING) + if len(data) < 4 { + out[6] = byte(PADDING) + out[5] = byte(PADDING) + if len(data) < 3 { + out[4] = byte(PADDING) + if len(data) < 2 { + out[3] = byte(PADDING) + out[2] = byte(PADDING) + } + } + } + break + } + data = data[5:] + out = out[8:] + } } decode :: proc(data: string, DEC_TBL := DEC_TABLE, allocator := context.allocator) -> []byte #no_bounds_check{ - if len(data) == 0 { - return nil - } + if len(data) == 0 { + return nil + } - outi := 0 - data := data + outi := 0 + data := data - out := make([]byte, len(data) / 8 * 5, allocator) - end := false - for len(data) > 0 && !end { - dbuf : [8]byte - dlen := 8 + out := make([]byte, len(data) / 8 * 5, allocator) + end := false + for len(data) > 0 && !end { + dbuf : [8]byte + dlen := 8 - for j := 0; j < 8; { - if len(data) == 0 { - dlen, end = j, true - break - } - input := data[0] - data = data[1:] - if input == byte(PADDING) && j >= 2 && len(data) < 8 { - assert(!(len(data) + j < 8 - 1), "Corrupted input") - for k := 0; k < 8-1-j; k +=1 { - assert(len(data) < k || data[k] == byte(PADDING), "Corrupted input") - } - dlen, end = j, true - assert(dlen != 1 && dlen != 3 && dlen != 6, "Corrupted input") - break - } - dbuf[j] = DEC_TABLE[input] - assert(dbuf[j] != 0xff, "Corrupted input") - j += 1 - } + for j := 0; j < 8; { + if len(data) == 0 { + dlen, end = j, true + break + } + input := data[0] + data = data[1:] + if input == byte(PADDING) && j >= 2 && len(data) < 8 { + assert(!(len(data) + j < 8 - 1), "Corrupted input") + for k := 0; k < 8-1-j; k +=1 { + assert(len(data) < k || data[k] == byte(PADDING), "Corrupted input") + } + dlen, end = j, true + assert(dlen != 1 && dlen != 3 && dlen != 6, "Corrupted input") + break + } + dbuf[j] = DEC_TABLE[input] + assert(dbuf[j] != 0xff, "Corrupted input") + j += 1 + } - switch dlen { - case 8: - out[outi + 4] = dbuf[6] << 5 | dbuf[7] - fallthrough - case 7: - out[outi + 3] = dbuf[4] << 7 | dbuf[5] << 2 | dbuf[6] >> 3 - fallthrough - case 5: - out[outi + 2] = dbuf[3] << 4 | dbuf[4] >> 1 - fallthrough - case 4: - out[outi + 1] = dbuf[1] << 6 | dbuf[2] << 1 | dbuf[3] >> 4 - fallthrough - case 2: - out[outi + 0] = dbuf[0] << 3 | dbuf[1] >> 2 - } - outi += 5 - } - return out + switch dlen { + case 8: + out[outi + 4] = dbuf[6] << 5 | dbuf[7] + fallthrough + case 7: + out[outi + 3] = dbuf[4] << 7 | dbuf[5] << 2 | dbuf[6] >> 3 + fallthrough + case 5: + out[outi + 2] = dbuf[3] << 4 | dbuf[4] >> 1 + fallthrough + case 4: + out[outi + 1] = dbuf[1] << 6 | dbuf[2] << 1 | dbuf[3] >> 4 + fallthrough + case 2: + out[outi + 0] = dbuf[0] << 3 | dbuf[1] >> 2 + } + outi += 5 + } + return out } diff --git a/core/encoding/cbor/coding.odin b/core/encoding/cbor/coding.odin index 07f0637a6..bfeb147c4 100644 --- a/core/encoding/cbor/coding.odin +++ b/core/encoding/cbor/coding.odin @@ -233,7 +233,7 @@ encode_into_encoder :: proc(e: Encoder, v: Value, loc := #caller_location) -> En if .Self_Described_CBOR in e.flags { _encode_u64(e, TAG_SELF_DESCRIBED_CBOR, .Tag) or_return - e.flags &~= { .Self_Described_CBOR } + e.flags -= { .Self_Described_CBOR } } switch v_spec in v { @@ -423,7 +423,7 @@ _decode_bytes :: proc(d: Decoder, add: Add, type: Major = .Bytes, allocator := c _encode_bytes :: proc(e: Encoder, val: Bytes, major: Major = .Bytes) -> (err: Encode_Error) { assert(len(val) >= 0) _encode_u64(e, u64(len(val)), major) or_return - _, err = io.write_full(e.writer, val[:]) + _, err = io.write_full(e.writer, val[:]) return } @@ -440,7 +440,7 @@ _decode_text :: proc(d: Decoder, add: Add, allocator := context.allocator, loc : } _encode_text :: proc(e: Encoder, val: Text) -> Encode_Error { - return _encode_bytes(e, transmute([]byte)val, .Text) + return _encode_bytes(e, transmute([]byte)val, .Text) } _decode_array_ptr :: proc(d: Decoder, add: Add, allocator := context.allocator, loc := #caller_location) -> (v: ^Array, err: Decode_Error) { @@ -480,10 +480,10 @@ _decode_array :: proc(d: Decoder, add: Add, allocator := context.allocator, loc _encode_array :: proc(e: Encoder, arr: Array) -> Encode_Error { assert(len(arr) >= 0) _encode_u64(e, u64(len(arr)), .Array) - for val in arr { - encode(e, val) or_return - } - return nil + for val in arr { + encode(e, val) or_return + } + return nil } _decode_map_ptr :: proc(d: Decoder, add: Add, allocator := context.allocator, loc := #caller_location) -> (v: ^Map, err: Decode_Error) { @@ -576,7 +576,7 @@ _encode_map :: proc(e: Encoder, m: Map) -> (err: Encode_Error) { encode(e, entry.entry.value) or_return } - return nil + return nil } _decode_tag_ptr :: proc(d: Decoder, add: Add, allocator := context.allocator, loc := #caller_location) -> (v: Value, err: Decode_Error) { @@ -626,7 +626,7 @@ _decode_uint_as_u64 :: proc(r: io.Reader, add: Add) -> (nr: u64, err: Decode_Err _encode_tag :: proc(e: Encoder, val: Tag) -> Encode_Error { _encode_u64(e, val.number, .Tag) or_return - return encode(e, val.value) + return encode(e, val.value) } _decode_simple :: proc(r: io.Reader) -> (v: Simple, err: io.Error) { @@ -739,16 +739,16 @@ _encode_nil :: proc(w: io.Writer) -> io.Error { // Streaming encode_stream_begin :: proc(w: io.Writer, major: Major) -> (err: io.Error) { - assert(major >= Major(.Bytes) && major <= Major(.Map), "illegal stream type") + assert(major >= Major(.Bytes) && major <= Major(.Map), "illegal stream type") - header := (u8(major) << 5) | u8(Add.Length_Unknown) - _, err = io.write_full(w, {header}) + header := (u8(major) << 5) | u8(Add.Length_Unknown) + _, err = io.write_full(w, {header}) return } encode_stream_end :: proc(w: io.Writer) -> io.Error { - header := (u8(Major.Other) << 5) | u8(Add.Break) - _, err := io.write_full(w, {header}) + header := (u8(Major.Other) << 5) | u8(Add.Break) + _, err := io.write_full(w, {header}) return err } @@ -757,8 +757,8 @@ encode_stream_text :: _encode_text encode_stream_array_item :: encode encode_stream_map_entry :: proc(e: Encoder, key: Value, val: Value) -> Encode_Error { - encode(e, key) or_return - return encode(e, val) + encode(e, key) or_return + return encode(e, val) } // For `Bytes` and `Text` strings: Decodes the number of items the header says follows. diff --git a/core/encoding/cbor/marshal.odin b/core/encoding/cbor/marshal.odin index 775eafd9c..d64d22d9c 100644 --- a/core/encoding/cbor/marshal.odin +++ b/core/encoding/cbor/marshal.odin @@ -85,7 +85,7 @@ marshal_into_encoder :: proc(e: Encoder, v: any, loc := #caller_location) -> (e if .Self_Described_CBOR in e.flags { err_conv(_encode_u64(e, TAG_SELF_DESCRIBED_CBOR, .Tag)) or_return - e.flags &~= { .Self_Described_CBOR } + e.flags -= { .Self_Described_CBOR } } if v == nil { diff --git a/core/encoding/cbor/tags.odin b/core/encoding/cbor/tags.odin index 3dc79a5dd..17420af46 100644 --- a/core/encoding/cbor/tags.odin +++ b/core/encoding/cbor/tags.odin @@ -95,7 +95,6 @@ tag_register_number :: proc(impl: Tag_Implementation, nr: Tag_Number, id: string } // Controls initialization of default tag implementations. -// JS and WASI default to a panic allocator so we don't want to do it on those. INITIALIZE_DEFAULT_TAGS :: #config(CBOR_INITIALIZE_DEFAULT_TAGS, !ODIN_DEFAULT_TO_PANIC_ALLOCATOR && !ODIN_DEFAULT_TO_NIL_ALLOCATOR) @(private, init, disabled=!INITIALIZE_DEFAULT_TAGS) diff --git a/core/encoding/cbor/unmarshal.odin b/core/encoding/cbor/unmarshal.odin index c31ba1d92..289895e98 100644 --- a/core/encoding/cbor/unmarshal.odin +++ b/core/encoding/cbor/unmarshal.odin @@ -273,13 +273,13 @@ _unmarshal_value :: proc(d: Decoder, v: any, hdr: Header, allocator := context.a // NOTE: Because this is a special type and not to be treated as a general integer, // We only put the value of it in fields that are explicitly of type `Simple`. - switch &dst in v { - case Simple: - dst = decoded - return - case: - return _unsupported(v, hdr, add) - } + switch &dst in v { + case Simple: + dst = decoded + return + case: + return _unsupported(v, hdr, add) + } case .Tag: switch &dst in v { diff --git a/core/encoding/entity/generated.odin b/core/encoding/entity/generated.odin index d2acde20d..0c4742149 100644 --- a/core/encoding/entity/generated.odin +++ b/core/encoding/entity/generated.odin @@ -61,5026 +61,5026 @@ named_xml_entity_to_rune :: proc(name: string) -> (decoded: rune, ok: bool) { case 'A': switch name { - case "AElig": // LATIN CAPITAL LETTER AE - return rune(0xc6), true - case "AMP": // AMPERSAND - return rune(0x26), true - case "Aacgr": // GREEK CAPITAL LETTER ALPHA WITH TONOS - return rune(0x0386), true - case "Aacute": // LATIN CAPITAL LETTER A WITH ACUTE - return rune(0xc1), true - case "Abreve": // LATIN CAPITAL LETTER A WITH BREVE - return rune(0x0102), true - case "Acirc": // LATIN CAPITAL LETTER A WITH CIRCUMFLEX - return rune(0xc2), true - case "Acy": // CYRILLIC CAPITAL LETTER A - return rune(0x0410), true - case "Afr": // MATHEMATICAL FRAKTUR CAPITAL A - return rune(0x01d504), true - case "Agr": // GREEK CAPITAL LETTER ALPHA - return rune(0x0391), true - case "Agrave": // LATIN CAPITAL LETTER A WITH GRAVE - return rune(0xc0), true - case "Alpha": // GREEK CAPITAL LETTER ALPHA - return rune(0x0391), true - case "Amacr": // LATIN CAPITAL LETTER A WITH MACRON - return rune(0x0100), true - case "And": // DOUBLE LOGICAL AND - return rune(0x2a53), true - case "Aogon": // LATIN CAPITAL LETTER A WITH OGONEK - return rune(0x0104), true - case "Aopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL A - return rune(0x01d538), true - case "ApplyFunction": // FUNCTION APPLICATION - return rune(0x2061), true - case "Aring": // LATIN CAPITAL LETTER A WITH RING ABOVE - return rune(0xc5), true - case "Ascr": // MATHEMATICAL SCRIPT CAPITAL A - return rune(0x01d49c), true - case "Assign": // COLON EQUALS - return rune(0x2254), true - case "Ast": // TWO ASTERISKS ALIGNED VERTICALLY - return rune(0x2051), true - case "Atilde": // LATIN CAPITAL LETTER A WITH TILDE - return rune(0xc3), true - case "Auml": // LATIN CAPITAL LETTER A WITH DIAERESIS - return rune(0xc4), true + case "AElig": // LATIN CAPITAL LETTER AE + return rune(0xc6), true + case "AMP": // AMPERSAND + return rune(0x26), true + case "Aacgr": // GREEK CAPITAL LETTER ALPHA WITH TONOS + return rune(0x0386), true + case "Aacute": // LATIN CAPITAL LETTER A WITH ACUTE + return rune(0xc1), true + case "Abreve": // LATIN CAPITAL LETTER A WITH BREVE + return rune(0x0102), true + case "Acirc": // LATIN CAPITAL LETTER A WITH CIRCUMFLEX + return rune(0xc2), true + case "Acy": // CYRILLIC CAPITAL LETTER A + return rune(0x0410), true + case "Afr": // MATHEMATICAL FRAKTUR CAPITAL A + return rune(0x01d504), true + case "Agr": // GREEK CAPITAL LETTER ALPHA + return rune(0x0391), true + case "Agrave": // LATIN CAPITAL LETTER A WITH GRAVE + return rune(0xc0), true + case "Alpha": // GREEK CAPITAL LETTER ALPHA + return rune(0x0391), true + case "Amacr": // LATIN CAPITAL LETTER A WITH MACRON + return rune(0x0100), true + case "And": // DOUBLE LOGICAL AND + return rune(0x2a53), true + case "Aogon": // LATIN CAPITAL LETTER A WITH OGONEK + return rune(0x0104), true + case "Aopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL A + return rune(0x01d538), true + case "ApplyFunction": // FUNCTION APPLICATION + return rune(0x2061), true + case "Aring": // LATIN CAPITAL LETTER A WITH RING ABOVE + return rune(0xc5), true + case "Ascr": // MATHEMATICAL SCRIPT CAPITAL A + return rune(0x01d49c), true + case "Assign": // COLON EQUALS + return rune(0x2254), true + case "Ast": // TWO ASTERISKS ALIGNED VERTICALLY + return rune(0x2051), true + case "Atilde": // LATIN CAPITAL LETTER A WITH TILDE + return rune(0xc3), true + case "Auml": // LATIN CAPITAL LETTER A WITH DIAERESIS + return rune(0xc4), true } case 'B': switch name { - case "Backslash": // SET MINUS - return rune(0x2216), true - case "Barint": // INTEGRAL WITH DOUBLE STROKE - return rune(0x2a0e), true - case "Barv": // SHORT DOWN TACK WITH OVERBAR - return rune(0x2ae7), true - case "Barwed": // PERSPECTIVE - return rune(0x2306), true - case "Barwedl": // LOGICAL AND WITH DOUBLE OVERBAR - return rune(0x2a5e), true - case "Bcy": // CYRILLIC CAPITAL LETTER BE - return rune(0x0411), true - case "Because": // BECAUSE - return rune(0x2235), true - case "Bernoullis": // SCRIPT CAPITAL B - return rune(0x212c), true - case "Beta": // GREEK CAPITAL LETTER BETA - return rune(0x0392), true - case "Bfr": // MATHEMATICAL FRAKTUR CAPITAL B - return rune(0x01d505), true - case "Bgr": // GREEK CAPITAL LETTER BETA - return rune(0x0392), true - case "Bopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL B - return rune(0x01d539), true - case "Breve": // BREVE - return rune(0x02d8), true - case "Bscr": // SCRIPT CAPITAL B - return rune(0x212c), true - case "Bumpeq": // GEOMETRICALLY EQUIVALENT TO - return rune(0x224e), true - case "Bvert": // BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL - return rune(0x2506), true + case "Backslash": // SET MINUS + return rune(0x2216), true + case "Barint": // INTEGRAL WITH DOUBLE STROKE + return rune(0x2a0e), true + case "Barv": // SHORT DOWN TACK WITH OVERBAR + return rune(0x2ae7), true + case "Barwed": // PERSPECTIVE + return rune(0x2306), true + case "Barwedl": // LOGICAL AND WITH DOUBLE OVERBAR + return rune(0x2a5e), true + case "Bcy": // CYRILLIC CAPITAL LETTER BE + return rune(0x0411), true + case "Because": // BECAUSE + return rune(0x2235), true + case "Bernoullis": // SCRIPT CAPITAL B + return rune(0x212c), true + case "Beta": // GREEK CAPITAL LETTER BETA + return rune(0x0392), true + case "Bfr": // MATHEMATICAL FRAKTUR CAPITAL B + return rune(0x01d505), true + case "Bgr": // GREEK CAPITAL LETTER BETA + return rune(0x0392), true + case "Bopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL B + return rune(0x01d539), true + case "Breve": // BREVE + return rune(0x02d8), true + case "Bscr": // SCRIPT CAPITAL B + return rune(0x212c), true + case "Bumpeq": // GEOMETRICALLY EQUIVALENT TO + return rune(0x224e), true + case "Bvert": // BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL + return rune(0x2506), true } case 'C': switch name { - case "CHcy": // CYRILLIC CAPITAL LETTER CHE - return rune(0x0427), true - case "COPY": // COPYRIGHT SIGN - return rune(0xa9), true - case "Cacute": // LATIN CAPITAL LETTER C WITH ACUTE - return rune(0x0106), true - case "Cap": // DOUBLE INTERSECTION - return rune(0x22d2), true - case "CapitalDifferentialD": // DOUBLE-STRUCK ITALIC CAPITAL D - return rune(0x2145), true - case "Cayleys": // BLACK-LETTER CAPITAL C - return rune(0x212d), true - case "Ccaron": // LATIN CAPITAL LETTER C WITH CARON - return rune(0x010c), true - case "Ccedil": // LATIN CAPITAL LETTER C WITH CEDILLA - return rune(0xc7), true - case "Ccirc": // LATIN CAPITAL LETTER C WITH CIRCUMFLEX - return rune(0x0108), true - case "Cconint": // VOLUME INTEGRAL - return rune(0x2230), true - case "Cdot": // LATIN CAPITAL LETTER C WITH DOT ABOVE - return rune(0x010a), true - case "Cedilla": // CEDILLA - return rune(0xb8), true - case "CenterDot": // MIDDLE DOT - return rune(0xb7), true - case "Cfr": // BLACK-LETTER CAPITAL C - return rune(0x212d), true - case "Chi": // GREEK CAPITAL LETTER CHI - return rune(0x03a7), true - case "CircleDot": // CIRCLED DOT OPERATOR - return rune(0x2299), true - case "CircleMinus": // CIRCLED MINUS - return rune(0x2296), true - case "CirclePlus": // CIRCLED PLUS - return rune(0x2295), true - case "CircleTimes": // CIRCLED TIMES - return rune(0x2297), true - case "ClockwiseContourIntegral": // CLOCKWISE CONTOUR INTEGRAL - return rune(0x2232), true - case "CloseCurlyDoubleQuote": // RIGHT DOUBLE QUOTATION MARK - return rune(0x201d), true - case "CloseCurlyQuote": // RIGHT SINGLE QUOTATION MARK - return rune(0x2019), true - case "Colon": // PROPORTION - return rune(0x2237), true - case "Colone": // DOUBLE COLON EQUAL - return rune(0x2a74), true - case "Congruent": // IDENTICAL TO - return rune(0x2261), true - case "Conint": // SURFACE INTEGRAL - return rune(0x222f), true - case "ContourIntegral": // CONTOUR INTEGRAL - return rune(0x222e), true - case "Copf": // DOUBLE-STRUCK CAPITAL C - return rune(0x2102), true - case "Coproduct": // N-ARY COPRODUCT - return rune(0x2210), true - case "CounterClockwiseContourIntegral": // ANTICLOCKWISE CONTOUR INTEGRAL - return rune(0x2233), true - case "Cross": // VECTOR OR CROSS PRODUCT - return rune(0x2a2f), true - case "Cscr": // MATHEMATICAL SCRIPT CAPITAL C - return rune(0x01d49e), true - case "Cup": // DOUBLE UNION - return rune(0x22d3), true - case "CupCap": // EQUIVALENT TO - return rune(0x224d), true + case "CHcy": // CYRILLIC CAPITAL LETTER CHE + return rune(0x0427), true + case "COPY": // COPYRIGHT SIGN + return rune(0xa9), true + case "Cacute": // LATIN CAPITAL LETTER C WITH ACUTE + return rune(0x0106), true + case "Cap": // DOUBLE INTERSECTION + return rune(0x22d2), true + case "CapitalDifferentialD": // DOUBLE-STRUCK ITALIC CAPITAL D + return rune(0x2145), true + case "Cayleys": // BLACK-LETTER CAPITAL C + return rune(0x212d), true + case "Ccaron": // LATIN CAPITAL LETTER C WITH CARON + return rune(0x010c), true + case "Ccedil": // LATIN CAPITAL LETTER C WITH CEDILLA + return rune(0xc7), true + case "Ccirc": // LATIN CAPITAL LETTER C WITH CIRCUMFLEX + return rune(0x0108), true + case "Cconint": // VOLUME INTEGRAL + return rune(0x2230), true + case "Cdot": // LATIN CAPITAL LETTER C WITH DOT ABOVE + return rune(0x010a), true + case "Cedilla": // CEDILLA + return rune(0xb8), true + case "CenterDot": // MIDDLE DOT + return rune(0xb7), true + case "Cfr": // BLACK-LETTER CAPITAL C + return rune(0x212d), true + case "Chi": // GREEK CAPITAL LETTER CHI + return rune(0x03a7), true + case "CircleDot": // CIRCLED DOT OPERATOR + return rune(0x2299), true + case "CircleMinus": // CIRCLED MINUS + return rune(0x2296), true + case "CirclePlus": // CIRCLED PLUS + return rune(0x2295), true + case "CircleTimes": // CIRCLED TIMES + return rune(0x2297), true + case "ClockwiseContourIntegral": // CLOCKWISE CONTOUR INTEGRAL + return rune(0x2232), true + case "CloseCurlyDoubleQuote": // RIGHT DOUBLE QUOTATION MARK + return rune(0x201d), true + case "CloseCurlyQuote": // RIGHT SINGLE QUOTATION MARK + return rune(0x2019), true + case "Colon": // PROPORTION + return rune(0x2237), true + case "Colone": // DOUBLE COLON EQUAL + return rune(0x2a74), true + case "Congruent": // IDENTICAL TO + return rune(0x2261), true + case "Conint": // SURFACE INTEGRAL + return rune(0x222f), true + case "ContourIntegral": // CONTOUR INTEGRAL + return rune(0x222e), true + case "Copf": // DOUBLE-STRUCK CAPITAL C + return rune(0x2102), true + case "Coproduct": // N-ARY COPRODUCT + return rune(0x2210), true + case "CounterClockwiseContourIntegral": // ANTICLOCKWISE CONTOUR INTEGRAL + return rune(0x2233), true + case "Cross": // VECTOR OR CROSS PRODUCT + return rune(0x2a2f), true + case "Cscr": // MATHEMATICAL SCRIPT CAPITAL C + return rune(0x01d49e), true + case "Cup": // DOUBLE UNION + return rune(0x22d3), true + case "CupCap": // EQUIVALENT TO + return rune(0x224d), true } case 'D': switch name { - case "DD": // DOUBLE-STRUCK ITALIC CAPITAL D - return rune(0x2145), true - case "DDotrahd": // RIGHTWARDS ARROW WITH DOTTED STEM - return rune(0x2911), true - case "DJcy": // CYRILLIC CAPITAL LETTER DJE - return rune(0x0402), true - case "DScy": // CYRILLIC CAPITAL LETTER DZE - return rune(0x0405), true - case "DZcy": // CYRILLIC CAPITAL LETTER DZHE - return rune(0x040f), true - case "Dagger": // DOUBLE DAGGER - return rune(0x2021), true - case "Darr": // DOWNWARDS TWO HEADED ARROW - return rune(0x21a1), true - case "Dashv": // VERTICAL BAR DOUBLE LEFT TURNSTILE - return rune(0x2ae4), true - case "Dcaron": // LATIN CAPITAL LETTER D WITH CARON - return rune(0x010e), true - case "Dcy": // CYRILLIC CAPITAL LETTER DE - return rune(0x0414), true - case "Del": // NABLA - return rune(0x2207), true - case "Delta": // GREEK CAPITAL LETTER DELTA - return rune(0x0394), true - case "Dfr": // MATHEMATICAL FRAKTUR CAPITAL D - return rune(0x01d507), true - case "Dgr": // GREEK CAPITAL LETTER DELTA - return rune(0x0394), true - case "DiacriticalAcute": // ACUTE ACCENT - return rune(0xb4), true - case "DiacriticalDot": // DOT ABOVE - return rune(0x02d9), true - case "DiacriticalDoubleAcute": // DOUBLE ACUTE ACCENT - return rune(0x02dd), true - case "DiacriticalGrave": // GRAVE ACCENT - return rune(0x60), true - case "DiacriticalTilde": // SMALL TILDE - return rune(0x02dc), true - case "Diamond": // DIAMOND OPERATOR - return rune(0x22c4), true - case "DifferentialD": // DOUBLE-STRUCK ITALIC SMALL D - return rune(0x2146), true - case "Dopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL D - return rune(0x01d53b), true - case "Dot": // DIAERESIS - return rune(0xa8), true - case "DotDot": // COMBINING FOUR DOTS ABOVE - return rune(0x20dc), true - case "DotEqual": // APPROACHES THE LIMIT - return rune(0x2250), true - case "DoubleContourIntegral": // SURFACE INTEGRAL - return rune(0x222f), true - case "DoubleDot": // DIAERESIS - return rune(0xa8), true - case "DoubleDownArrow": // DOWNWARDS DOUBLE ARROW - return rune(0x21d3), true - case "DoubleLeftArrow": // LEFTWARDS DOUBLE ARROW - return rune(0x21d0), true - case "DoubleLeftRightArrow": // LEFT RIGHT DOUBLE ARROW - return rune(0x21d4), true - case "DoubleLeftTee": // VERTICAL BAR DOUBLE LEFT TURNSTILE - return rune(0x2ae4), true - case "DoubleLongLeftArrow": // LONG LEFTWARDS DOUBLE ARROW - return rune(0x27f8), true - case "DoubleLongLeftRightArrow": // LONG LEFT RIGHT DOUBLE ARROW - return rune(0x27fa), true - case "DoubleLongRightArrow": // LONG RIGHTWARDS DOUBLE ARROW - return rune(0x27f9), true - case "DoubleRightArrow": // RIGHTWARDS DOUBLE ARROW - return rune(0x21d2), true - case "DoubleRightTee": // TRUE - return rune(0x22a8), true - case "DoubleUpArrow": // UPWARDS DOUBLE ARROW - return rune(0x21d1), true - case "DoubleUpDownArrow": // UP DOWN DOUBLE ARROW - return rune(0x21d5), true - case "DoubleVerticalBar": // PARALLEL TO - return rune(0x2225), true - case "DownArrow": // DOWNWARDS ARROW - return rune(0x2193), true - case "DownArrowBar": // DOWNWARDS ARROW TO BAR - return rune(0x2913), true - case "DownArrowUpArrow": // DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW - return rune(0x21f5), true - case "DownBreve": // COMBINING INVERTED BREVE - return rune(0x0311), true - case "DownLeftRightVector": // LEFT BARB DOWN RIGHT BARB DOWN HARPOON - return rune(0x2950), true - case "DownLeftTeeVector": // LEFTWARDS HARPOON WITH BARB DOWN FROM BAR - return rune(0x295e), true - case "DownLeftVector": // LEFTWARDS HARPOON WITH BARB DOWNWARDS - return rune(0x21bd), true - case "DownLeftVectorBar": // LEFTWARDS HARPOON WITH BARB DOWN TO BAR - return rune(0x2956), true - case "DownRightTeeVector": // RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR - return rune(0x295f), true - case "DownRightVector": // RIGHTWARDS HARPOON WITH BARB DOWNWARDS - return rune(0x21c1), true - case "DownRightVectorBar": // RIGHTWARDS HARPOON WITH BARB DOWN TO BAR - return rune(0x2957), true - case "DownTee": // DOWN TACK - return rune(0x22a4), true - case "DownTeeArrow": // DOWNWARDS ARROW FROM BAR - return rune(0x21a7), true - case "Downarrow": // DOWNWARDS DOUBLE ARROW - return rune(0x21d3), true - case "Dscr": // MATHEMATICAL SCRIPT CAPITAL D - return rune(0x01d49f), true - case "Dstrok": // LATIN CAPITAL LETTER D WITH STROKE - return rune(0x0110), true + case "DD": // DOUBLE-STRUCK ITALIC CAPITAL D + return rune(0x2145), true + case "DDotrahd": // RIGHTWARDS ARROW WITH DOTTED STEM + return rune(0x2911), true + case "DJcy": // CYRILLIC CAPITAL LETTER DJE + return rune(0x0402), true + case "DScy": // CYRILLIC CAPITAL LETTER DZE + return rune(0x0405), true + case "DZcy": // CYRILLIC CAPITAL LETTER DZHE + return rune(0x040f), true + case "Dagger": // DOUBLE DAGGER + return rune(0x2021), true + case "Darr": // DOWNWARDS TWO HEADED ARROW + return rune(0x21a1), true + case "Dashv": // VERTICAL BAR DOUBLE LEFT TURNSTILE + return rune(0x2ae4), true + case "Dcaron": // LATIN CAPITAL LETTER D WITH CARON + return rune(0x010e), true + case "Dcy": // CYRILLIC CAPITAL LETTER DE + return rune(0x0414), true + case "Del": // NABLA + return rune(0x2207), true + case "Delta": // GREEK CAPITAL LETTER DELTA + return rune(0x0394), true + case "Dfr": // MATHEMATICAL FRAKTUR CAPITAL D + return rune(0x01d507), true + case "Dgr": // GREEK CAPITAL LETTER DELTA + return rune(0x0394), true + case "DiacriticalAcute": // ACUTE ACCENT + return rune(0xb4), true + case "DiacriticalDot": // DOT ABOVE + return rune(0x02d9), true + case "DiacriticalDoubleAcute": // DOUBLE ACUTE ACCENT + return rune(0x02dd), true + case "DiacriticalGrave": // GRAVE ACCENT + return rune(0x60), true + case "DiacriticalTilde": // SMALL TILDE + return rune(0x02dc), true + case "Diamond": // DIAMOND OPERATOR + return rune(0x22c4), true + case "DifferentialD": // DOUBLE-STRUCK ITALIC SMALL D + return rune(0x2146), true + case "Dopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL D + return rune(0x01d53b), true + case "Dot": // DIAERESIS + return rune(0xa8), true + case "DotDot": // COMBINING FOUR DOTS ABOVE + return rune(0x20dc), true + case "DotEqual": // APPROACHES THE LIMIT + return rune(0x2250), true + case "DoubleContourIntegral": // SURFACE INTEGRAL + return rune(0x222f), true + case "DoubleDot": // DIAERESIS + return rune(0xa8), true + case "DoubleDownArrow": // DOWNWARDS DOUBLE ARROW + return rune(0x21d3), true + case "DoubleLeftArrow": // LEFTWARDS DOUBLE ARROW + return rune(0x21d0), true + case "DoubleLeftRightArrow": // LEFT RIGHT DOUBLE ARROW + return rune(0x21d4), true + case "DoubleLeftTee": // VERTICAL BAR DOUBLE LEFT TURNSTILE + return rune(0x2ae4), true + case "DoubleLongLeftArrow": // LONG LEFTWARDS DOUBLE ARROW + return rune(0x27f8), true + case "DoubleLongLeftRightArrow": // LONG LEFT RIGHT DOUBLE ARROW + return rune(0x27fa), true + case "DoubleLongRightArrow": // LONG RIGHTWARDS DOUBLE ARROW + return rune(0x27f9), true + case "DoubleRightArrow": // RIGHTWARDS DOUBLE ARROW + return rune(0x21d2), true + case "DoubleRightTee": // TRUE + return rune(0x22a8), true + case "DoubleUpArrow": // UPWARDS DOUBLE ARROW + return rune(0x21d1), true + case "DoubleUpDownArrow": // UP DOWN DOUBLE ARROW + return rune(0x21d5), true + case "DoubleVerticalBar": // PARALLEL TO + return rune(0x2225), true + case "DownArrow": // DOWNWARDS ARROW + return rune(0x2193), true + case "DownArrowBar": // DOWNWARDS ARROW TO BAR + return rune(0x2913), true + case "DownArrowUpArrow": // DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW + return rune(0x21f5), true + case "DownBreve": // COMBINING INVERTED BREVE + return rune(0x0311), true + case "DownLeftRightVector": // LEFT BARB DOWN RIGHT BARB DOWN HARPOON + return rune(0x2950), true + case "DownLeftTeeVector": // LEFTWARDS HARPOON WITH BARB DOWN FROM BAR + return rune(0x295e), true + case "DownLeftVector": // LEFTWARDS HARPOON WITH BARB DOWNWARDS + return rune(0x21bd), true + case "DownLeftVectorBar": // LEFTWARDS HARPOON WITH BARB DOWN TO BAR + return rune(0x2956), true + case "DownRightTeeVector": // RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR + return rune(0x295f), true + case "DownRightVector": // RIGHTWARDS HARPOON WITH BARB DOWNWARDS + return rune(0x21c1), true + case "DownRightVectorBar": // RIGHTWARDS HARPOON WITH BARB DOWN TO BAR + return rune(0x2957), true + case "DownTee": // DOWN TACK + return rune(0x22a4), true + case "DownTeeArrow": // DOWNWARDS ARROW FROM BAR + return rune(0x21a7), true + case "Downarrow": // DOWNWARDS DOUBLE ARROW + return rune(0x21d3), true + case "Dscr": // MATHEMATICAL SCRIPT CAPITAL D + return rune(0x01d49f), true + case "Dstrok": // LATIN CAPITAL LETTER D WITH STROKE + return rune(0x0110), true } case 'E': switch name { - case "EEacgr": // GREEK CAPITAL LETTER ETA WITH TONOS - return rune(0x0389), true - case "EEgr": // GREEK CAPITAL LETTER ETA - return rune(0x0397), true - case "ENG": // LATIN CAPITAL LETTER ENG - return rune(0x014a), true - case "ETH": // LATIN CAPITAL LETTER ETH - return rune(0xd0), true - case "Eacgr": // GREEK CAPITAL LETTER EPSILON WITH TONOS - return rune(0x0388), true - case "Eacute": // LATIN CAPITAL LETTER E WITH ACUTE - return rune(0xc9), true - case "Ecaron": // LATIN CAPITAL LETTER E WITH CARON - return rune(0x011a), true - case "Ecirc": // LATIN CAPITAL LETTER E WITH CIRCUMFLEX - return rune(0xca), true - case "Ecy": // CYRILLIC CAPITAL LETTER E - return rune(0x042d), true - case "Edot": // LATIN CAPITAL LETTER E WITH DOT ABOVE - return rune(0x0116), true - case "Efr": // MATHEMATICAL FRAKTUR CAPITAL E - return rune(0x01d508), true - case "Egr": // GREEK CAPITAL LETTER EPSILON - return rune(0x0395), true - case "Egrave": // LATIN CAPITAL LETTER E WITH GRAVE - return rune(0xc8), true - case "Element": // ELEMENT OF - return rune(0x2208), true - case "Emacr": // LATIN CAPITAL LETTER E WITH MACRON - return rune(0x0112), true - case "EmptySmallSquare": // WHITE MEDIUM SQUARE - return rune(0x25fb), true - case "EmptyVerySmallSquare": // WHITE SMALL SQUARE - return rune(0x25ab), true - case "Eogon": // LATIN CAPITAL LETTER E WITH OGONEK - return rune(0x0118), true - case "Eopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL E - return rune(0x01d53c), true - case "Epsilon": // GREEK CAPITAL LETTER EPSILON - return rune(0x0395), true - case "Equal": // TWO CONSECUTIVE EQUALS SIGNS - return rune(0x2a75), true - case "EqualTilde": // MINUS TILDE - return rune(0x2242), true - case "Equilibrium": // RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON - return rune(0x21cc), true - case "Escr": // SCRIPT CAPITAL E - return rune(0x2130), true - case "Esim": // EQUALS SIGN ABOVE TILDE OPERATOR - return rune(0x2a73), true - case "Eta": // GREEK CAPITAL LETTER ETA - return rune(0x0397), true - case "Euml": // LATIN CAPITAL LETTER E WITH DIAERESIS - return rune(0xcb), true - case "Exists": // THERE EXISTS - return rune(0x2203), true - case "ExponentialE": // DOUBLE-STRUCK ITALIC SMALL E - return rune(0x2147), true + case "EEacgr": // GREEK CAPITAL LETTER ETA WITH TONOS + return rune(0x0389), true + case "EEgr": // GREEK CAPITAL LETTER ETA + return rune(0x0397), true + case "ENG": // LATIN CAPITAL LETTER ENG + return rune(0x014a), true + case "ETH": // LATIN CAPITAL LETTER ETH + return rune(0xd0), true + case "Eacgr": // GREEK CAPITAL LETTER EPSILON WITH TONOS + return rune(0x0388), true + case "Eacute": // LATIN CAPITAL LETTER E WITH ACUTE + return rune(0xc9), true + case "Ecaron": // LATIN CAPITAL LETTER E WITH CARON + return rune(0x011a), true + case "Ecirc": // LATIN CAPITAL LETTER E WITH CIRCUMFLEX + return rune(0xca), true + case "Ecy": // CYRILLIC CAPITAL LETTER E + return rune(0x042d), true + case "Edot": // LATIN CAPITAL LETTER E WITH DOT ABOVE + return rune(0x0116), true + case "Efr": // MATHEMATICAL FRAKTUR CAPITAL E + return rune(0x01d508), true + case "Egr": // GREEK CAPITAL LETTER EPSILON + return rune(0x0395), true + case "Egrave": // LATIN CAPITAL LETTER E WITH GRAVE + return rune(0xc8), true + case "Element": // ELEMENT OF + return rune(0x2208), true + case "Emacr": // LATIN CAPITAL LETTER E WITH MACRON + return rune(0x0112), true + case "EmptySmallSquare": // WHITE MEDIUM SQUARE + return rune(0x25fb), true + case "EmptyVerySmallSquare": // WHITE SMALL SQUARE + return rune(0x25ab), true + case "Eogon": // LATIN CAPITAL LETTER E WITH OGONEK + return rune(0x0118), true + case "Eopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL E + return rune(0x01d53c), true + case "Epsilon": // GREEK CAPITAL LETTER EPSILON + return rune(0x0395), true + case "Equal": // TWO CONSECUTIVE EQUALS SIGNS + return rune(0x2a75), true + case "EqualTilde": // MINUS TILDE + return rune(0x2242), true + case "Equilibrium": // RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON + return rune(0x21cc), true + case "Escr": // SCRIPT CAPITAL E + return rune(0x2130), true + case "Esim": // EQUALS SIGN ABOVE TILDE OPERATOR + return rune(0x2a73), true + case "Eta": // GREEK CAPITAL LETTER ETA + return rune(0x0397), true + case "Euml": // LATIN CAPITAL LETTER E WITH DIAERESIS + return rune(0xcb), true + case "Exists": // THERE EXISTS + return rune(0x2203), true + case "ExponentialE": // DOUBLE-STRUCK ITALIC SMALL E + return rune(0x2147), true } case 'F': switch name { - case "Fcy": // CYRILLIC CAPITAL LETTER EF - return rune(0x0424), true - case "Ffr": // MATHEMATICAL FRAKTUR CAPITAL F - return rune(0x01d509), true - case "FilledSmallSquare": // BLACK MEDIUM SQUARE - return rune(0x25fc), true - case "FilledVerySmallSquare": // BLACK SMALL SQUARE - return rune(0x25aa), true - case "Fopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL F - return rune(0x01d53d), true - case "ForAll": // FOR ALL - return rune(0x2200), true - case "Fouriertrf": // SCRIPT CAPITAL F - return rune(0x2131), true - case "Fscr": // SCRIPT CAPITAL F - return rune(0x2131), true + case "Fcy": // CYRILLIC CAPITAL LETTER EF + return rune(0x0424), true + case "Ffr": // MATHEMATICAL FRAKTUR CAPITAL F + return rune(0x01d509), true + case "FilledSmallSquare": // BLACK MEDIUM SQUARE + return rune(0x25fc), true + case "FilledVerySmallSquare": // BLACK SMALL SQUARE + return rune(0x25aa), true + case "Fopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL F + return rune(0x01d53d), true + case "ForAll": // FOR ALL + return rune(0x2200), true + case "Fouriertrf": // SCRIPT CAPITAL F + return rune(0x2131), true + case "Fscr": // SCRIPT CAPITAL F + return rune(0x2131), true } case 'G': switch name { - case "GJcy": // CYRILLIC CAPITAL LETTER GJE - return rune(0x0403), true - case "GT": // GREATER-THAN SIGN - return rune(0x3e), true - case "Game": // TURNED SANS-SERIF CAPITAL G - return rune(0x2141), true - case "Gamma": // GREEK CAPITAL LETTER GAMMA - return rune(0x0393), true - case "Gammad": // GREEK LETTER DIGAMMA - return rune(0x03dc), true - case "Gbreve": // LATIN CAPITAL LETTER G WITH BREVE - return rune(0x011e), true - case "Gcedil": // LATIN CAPITAL LETTER G WITH CEDILLA - return rune(0x0122), true - case "Gcirc": // LATIN CAPITAL LETTER G WITH CIRCUMFLEX - return rune(0x011c), true - case "Gcy": // CYRILLIC CAPITAL LETTER GHE - return rune(0x0413), true - case "Gdot": // LATIN CAPITAL LETTER G WITH DOT ABOVE - return rune(0x0120), true - case "Gfr": // MATHEMATICAL FRAKTUR CAPITAL G - return rune(0x01d50a), true - case "Gg": // VERY MUCH GREATER-THAN - return rune(0x22d9), true - case "Ggr": // GREEK CAPITAL LETTER GAMMA - return rune(0x0393), true - case "Gopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL G - return rune(0x01d53e), true - case "GreaterEqual": // GREATER-THAN OR EQUAL TO - return rune(0x2265), true - case "GreaterEqualLess": // GREATER-THAN EQUAL TO OR LESS-THAN - return rune(0x22db), true - case "GreaterFullEqual": // GREATER-THAN OVER EQUAL TO - return rune(0x2267), true - case "GreaterGreater": // DOUBLE NESTED GREATER-THAN - return rune(0x2aa2), true - case "GreaterLess": // GREATER-THAN OR LESS-THAN - return rune(0x2277), true - case "GreaterSlantEqual": // GREATER-THAN OR SLANTED EQUAL TO - return rune(0x2a7e), true - case "GreaterTilde": // GREATER-THAN OR EQUIVALENT TO - return rune(0x2273), true - case "Gscr": // MATHEMATICAL SCRIPT CAPITAL G - return rune(0x01d4a2), true - case "Gt": // MUCH GREATER-THAN - return rune(0x226b), true + case "GJcy": // CYRILLIC CAPITAL LETTER GJE + return rune(0x0403), true + case "GT": // GREATER-THAN SIGN + return rune(0x3e), true + case "Game": // TURNED SANS-SERIF CAPITAL G + return rune(0x2141), true + case "Gamma": // GREEK CAPITAL LETTER GAMMA + return rune(0x0393), true + case "Gammad": // GREEK LETTER DIGAMMA + return rune(0x03dc), true + case "Gbreve": // LATIN CAPITAL LETTER G WITH BREVE + return rune(0x011e), true + case "Gcedil": // LATIN CAPITAL LETTER G WITH CEDILLA + return rune(0x0122), true + case "Gcirc": // LATIN CAPITAL LETTER G WITH CIRCUMFLEX + return rune(0x011c), true + case "Gcy": // CYRILLIC CAPITAL LETTER GHE + return rune(0x0413), true + case "Gdot": // LATIN CAPITAL LETTER G WITH DOT ABOVE + return rune(0x0120), true + case "Gfr": // MATHEMATICAL FRAKTUR CAPITAL G + return rune(0x01d50a), true + case "Gg": // VERY MUCH GREATER-THAN + return rune(0x22d9), true + case "Ggr": // GREEK CAPITAL LETTER GAMMA + return rune(0x0393), true + case "Gopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL G + return rune(0x01d53e), true + case "GreaterEqual": // GREATER-THAN OR EQUAL TO + return rune(0x2265), true + case "GreaterEqualLess": // GREATER-THAN EQUAL TO OR LESS-THAN + return rune(0x22db), true + case "GreaterFullEqual": // GREATER-THAN OVER EQUAL TO + return rune(0x2267), true + case "GreaterGreater": // DOUBLE NESTED GREATER-THAN + return rune(0x2aa2), true + case "GreaterLess": // GREATER-THAN OR LESS-THAN + return rune(0x2277), true + case "GreaterSlantEqual": // GREATER-THAN OR SLANTED EQUAL TO + return rune(0x2a7e), true + case "GreaterTilde": // GREATER-THAN OR EQUIVALENT TO + return rune(0x2273), true + case "Gscr": // MATHEMATICAL SCRIPT CAPITAL G + return rune(0x01d4a2), true + case "Gt": // MUCH GREATER-THAN + return rune(0x226b), true } case 'H': switch name { - case "HARDcy": // CYRILLIC CAPITAL LETTER HARD SIGN - return rune(0x042a), true - case "Hacek": // CARON - return rune(0x02c7), true - case "Hat": // CIRCUMFLEX ACCENT - return rune(0x5e), true - case "Hcirc": // LATIN CAPITAL LETTER H WITH CIRCUMFLEX - return rune(0x0124), true - case "Hfr": // BLACK-LETTER CAPITAL H - return rune(0x210c), true - case "HilbertSpace": // SCRIPT CAPITAL H - return rune(0x210b), true - case "Hopf": // DOUBLE-STRUCK CAPITAL H - return rune(0x210d), true - case "HorizontalLine": // BOX DRAWINGS LIGHT HORIZONTAL - return rune(0x2500), true - case "Hscr": // SCRIPT CAPITAL H - return rune(0x210b), true - case "Hstrok": // LATIN CAPITAL LETTER H WITH STROKE - return rune(0x0126), true - case "HumpDownHump": // GEOMETRICALLY EQUIVALENT TO - return rune(0x224e), true - case "HumpEqual": // DIFFERENCE BETWEEN - return rune(0x224f), true + case "HARDcy": // CYRILLIC CAPITAL LETTER HARD SIGN + return rune(0x042a), true + case "Hacek": // CARON + return rune(0x02c7), true + case "Hat": // CIRCUMFLEX ACCENT + return rune(0x5e), true + case "Hcirc": // LATIN CAPITAL LETTER H WITH CIRCUMFLEX + return rune(0x0124), true + case "Hfr": // BLACK-LETTER CAPITAL H + return rune(0x210c), true + case "HilbertSpace": // SCRIPT CAPITAL H + return rune(0x210b), true + case "Hopf": // DOUBLE-STRUCK CAPITAL H + return rune(0x210d), true + case "HorizontalLine": // BOX DRAWINGS LIGHT HORIZONTAL + return rune(0x2500), true + case "Hscr": // SCRIPT CAPITAL H + return rune(0x210b), true + case "Hstrok": // LATIN CAPITAL LETTER H WITH STROKE + return rune(0x0126), true + case "HumpDownHump": // GEOMETRICALLY EQUIVALENT TO + return rune(0x224e), true + case "HumpEqual": // DIFFERENCE BETWEEN + return rune(0x224f), true } case 'I': switch name { - case "IEcy": // CYRILLIC CAPITAL LETTER IE - return rune(0x0415), true - case "IJlig": // LATIN CAPITAL LIGATURE IJ - return rune(0x0132), true - case "IOcy": // CYRILLIC CAPITAL LETTER IO - return rune(0x0401), true - case "Iacgr": // GREEK CAPITAL LETTER IOTA WITH TONOS - return rune(0x038a), true - case "Iacute": // LATIN CAPITAL LETTER I WITH ACUTE - return rune(0xcd), true - case "Icirc": // LATIN CAPITAL LETTER I WITH CIRCUMFLEX - return rune(0xce), true - case "Icy": // CYRILLIC CAPITAL LETTER I - return rune(0x0418), true - case "Idigr": // GREEK CAPITAL LETTER IOTA WITH DIALYTIKA - return rune(0x03aa), true - case "Idot": // LATIN CAPITAL LETTER I WITH DOT ABOVE - return rune(0x0130), true - case "Ifr": // BLACK-LETTER CAPITAL I - return rune(0x2111), true - case "Igr": // GREEK CAPITAL LETTER IOTA - return rune(0x0399), true - case "Igrave": // LATIN CAPITAL LETTER I WITH GRAVE - return rune(0xcc), true - case "Im": // BLACK-LETTER CAPITAL I - return rune(0x2111), true - case "Imacr": // LATIN CAPITAL LETTER I WITH MACRON - return rune(0x012a), true - case "ImaginaryI": // DOUBLE-STRUCK ITALIC SMALL I - return rune(0x2148), true - case "Implies": // RIGHTWARDS DOUBLE ARROW - return rune(0x21d2), true - case "Int": // DOUBLE INTEGRAL - return rune(0x222c), true - case "Integral": // INTEGRAL - return rune(0x222b), true - case "Intersection": // N-ARY INTERSECTION - return rune(0x22c2), true - case "InvisibleComma": // INVISIBLE SEPARATOR - return rune(0x2063), true - case "InvisibleTimes": // INVISIBLE TIMES - return rune(0x2062), true - case "Iogon": // LATIN CAPITAL LETTER I WITH OGONEK - return rune(0x012e), true - case "Iopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL I - return rune(0x01d540), true - case "Iota": // GREEK CAPITAL LETTER IOTA - return rune(0x0399), true - case "Iscr": // SCRIPT CAPITAL I - return rune(0x2110), true - case "Itilde": // LATIN CAPITAL LETTER I WITH TILDE - return rune(0x0128), true - case "Iukcy": // CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I - return rune(0x0406), true - case "Iuml": // LATIN CAPITAL LETTER I WITH DIAERESIS - return rune(0xcf), true + case "IEcy": // CYRILLIC CAPITAL LETTER IE + return rune(0x0415), true + case "IJlig": // LATIN CAPITAL LIGATURE IJ + return rune(0x0132), true + case "IOcy": // CYRILLIC CAPITAL LETTER IO + return rune(0x0401), true + case "Iacgr": // GREEK CAPITAL LETTER IOTA WITH TONOS + return rune(0x038a), true + case "Iacute": // LATIN CAPITAL LETTER I WITH ACUTE + return rune(0xcd), true + case "Icirc": // LATIN CAPITAL LETTER I WITH CIRCUMFLEX + return rune(0xce), true + case "Icy": // CYRILLIC CAPITAL LETTER I + return rune(0x0418), true + case "Idigr": // GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + return rune(0x03aa), true + case "Idot": // LATIN CAPITAL LETTER I WITH DOT ABOVE + return rune(0x0130), true + case "Ifr": // BLACK-LETTER CAPITAL I + return rune(0x2111), true + case "Igr": // GREEK CAPITAL LETTER IOTA + return rune(0x0399), true + case "Igrave": // LATIN CAPITAL LETTER I WITH GRAVE + return rune(0xcc), true + case "Im": // BLACK-LETTER CAPITAL I + return rune(0x2111), true + case "Imacr": // LATIN CAPITAL LETTER I WITH MACRON + return rune(0x012a), true + case "ImaginaryI": // DOUBLE-STRUCK ITALIC SMALL I + return rune(0x2148), true + case "Implies": // RIGHTWARDS DOUBLE ARROW + return rune(0x21d2), true + case "Int": // DOUBLE INTEGRAL + return rune(0x222c), true + case "Integral": // INTEGRAL + return rune(0x222b), true + case "Intersection": // N-ARY INTERSECTION + return rune(0x22c2), true + case "InvisibleComma": // INVISIBLE SEPARATOR + return rune(0x2063), true + case "InvisibleTimes": // INVISIBLE TIMES + return rune(0x2062), true + case "Iogon": // LATIN CAPITAL LETTER I WITH OGONEK + return rune(0x012e), true + case "Iopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL I + return rune(0x01d540), true + case "Iota": // GREEK CAPITAL LETTER IOTA + return rune(0x0399), true + case "Iscr": // SCRIPT CAPITAL I + return rune(0x2110), true + case "Itilde": // LATIN CAPITAL LETTER I WITH TILDE + return rune(0x0128), true + case "Iukcy": // CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + return rune(0x0406), true + case "Iuml": // LATIN CAPITAL LETTER I WITH DIAERESIS + return rune(0xcf), true } case 'J': switch name { - case "Jcirc": // LATIN CAPITAL LETTER J WITH CIRCUMFLEX - return rune(0x0134), true - case "Jcy": // CYRILLIC CAPITAL LETTER SHORT I - return rune(0x0419), true - case "Jfr": // MATHEMATICAL FRAKTUR CAPITAL J - return rune(0x01d50d), true - case "Jopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL J - return rune(0x01d541), true - case "Jscr": // MATHEMATICAL SCRIPT CAPITAL J - return rune(0x01d4a5), true - case "Jsercy": // CYRILLIC CAPITAL LETTER JE - return rune(0x0408), true - case "Jukcy": // CYRILLIC CAPITAL LETTER UKRAINIAN IE - return rune(0x0404), true + case "Jcirc": // LATIN CAPITAL LETTER J WITH CIRCUMFLEX + return rune(0x0134), true + case "Jcy": // CYRILLIC CAPITAL LETTER SHORT I + return rune(0x0419), true + case "Jfr": // MATHEMATICAL FRAKTUR CAPITAL J + return rune(0x01d50d), true + case "Jopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL J + return rune(0x01d541), true + case "Jscr": // MATHEMATICAL SCRIPT CAPITAL J + return rune(0x01d4a5), true + case "Jsercy": // CYRILLIC CAPITAL LETTER JE + return rune(0x0408), true + case "Jukcy": // CYRILLIC CAPITAL LETTER UKRAINIAN IE + return rune(0x0404), true } case 'K': switch name { - case "KHcy": // CYRILLIC CAPITAL LETTER HA - return rune(0x0425), true - case "KHgr": // GREEK CAPITAL LETTER CHI - return rune(0x03a7), true - case "KJcy": // CYRILLIC CAPITAL LETTER KJE - return rune(0x040c), true - case "Kappa": // GREEK CAPITAL LETTER KAPPA - return rune(0x039a), true - case "Kcedil": // LATIN CAPITAL LETTER K WITH CEDILLA - return rune(0x0136), true - case "Kcy": // CYRILLIC CAPITAL LETTER KA - return rune(0x041a), true - case "Kfr": // MATHEMATICAL FRAKTUR CAPITAL K - return rune(0x01d50e), true - case "Kgr": // GREEK CAPITAL LETTER KAPPA - return rune(0x039a), true - case "Kopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL K - return rune(0x01d542), true - case "Kscr": // MATHEMATICAL SCRIPT CAPITAL K - return rune(0x01d4a6), true + case "KHcy": // CYRILLIC CAPITAL LETTER HA + return rune(0x0425), true + case "KHgr": // GREEK CAPITAL LETTER CHI + return rune(0x03a7), true + case "KJcy": // CYRILLIC CAPITAL LETTER KJE + return rune(0x040c), true + case "Kappa": // GREEK CAPITAL LETTER KAPPA + return rune(0x039a), true + case "Kcedil": // LATIN CAPITAL LETTER K WITH CEDILLA + return rune(0x0136), true + case "Kcy": // CYRILLIC CAPITAL LETTER KA + return rune(0x041a), true + case "Kfr": // MATHEMATICAL FRAKTUR CAPITAL K + return rune(0x01d50e), true + case "Kgr": // GREEK CAPITAL LETTER KAPPA + return rune(0x039a), true + case "Kopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL K + return rune(0x01d542), true + case "Kscr": // MATHEMATICAL SCRIPT CAPITAL K + return rune(0x01d4a6), true } case 'L': switch name { - case "LJcy": // CYRILLIC CAPITAL LETTER LJE - return rune(0x0409), true - case "LT": // LESS-THAN SIGN - return rune(0x3c), true - case "Lacute": // LATIN CAPITAL LETTER L WITH ACUTE - return rune(0x0139), true - case "Lambda": // GREEK CAPITAL LETTER LAMDA - return rune(0x039b), true - case "Lang": // MATHEMATICAL LEFT DOUBLE ANGLE BRACKET - return rune(0x27ea), true - case "Laplacetrf": // SCRIPT CAPITAL L - return rune(0x2112), true - case "Larr": // LEFTWARDS TWO HEADED ARROW - return rune(0x219e), true - case "Lcaron": // LATIN CAPITAL LETTER L WITH CARON - return rune(0x013d), true - case "Lcedil": // LATIN CAPITAL LETTER L WITH CEDILLA - return rune(0x013b), true - case "Lcy": // CYRILLIC CAPITAL LETTER EL - return rune(0x041b), true - case "LeftAngleBracket": // MATHEMATICAL LEFT ANGLE BRACKET - return rune(0x27e8), true - case "LeftArrow": // LEFTWARDS ARROW - return rune(0x2190), true - case "LeftArrowBar": // LEFTWARDS ARROW TO BAR - return rune(0x21e4), true - case "LeftArrowRightArrow": // LEFTWARDS ARROW OVER RIGHTWARDS ARROW - return rune(0x21c6), true - case "LeftCeiling": // LEFT CEILING - return rune(0x2308), true - case "LeftDoubleBracket": // MATHEMATICAL LEFT WHITE SQUARE BRACKET - return rune(0x27e6), true - case "LeftDownTeeVector": // DOWNWARDS HARPOON WITH BARB LEFT FROM BAR - return rune(0x2961), true - case "LeftDownVector": // DOWNWARDS HARPOON WITH BARB LEFTWARDS - return rune(0x21c3), true - case "LeftDownVectorBar": // DOWNWARDS HARPOON WITH BARB LEFT TO BAR - return rune(0x2959), true - case "LeftFloor": // LEFT FLOOR - return rune(0x230a), true - case "LeftRightArrow": // LEFT RIGHT ARROW - return rune(0x2194), true - case "LeftRightVector": // LEFT BARB UP RIGHT BARB UP HARPOON - return rune(0x294e), true - case "LeftTee": // LEFT TACK - return rune(0x22a3), true - case "LeftTeeArrow": // LEFTWARDS ARROW FROM BAR - return rune(0x21a4), true - case "LeftTeeVector": // LEFTWARDS HARPOON WITH BARB UP FROM BAR - return rune(0x295a), true - case "LeftTriangle": // NORMAL SUBGROUP OF - return rune(0x22b2), true - case "LeftTriangleBar": // LEFT TRIANGLE BESIDE VERTICAL BAR - return rune(0x29cf), true - case "LeftTriangleEqual": // NORMAL SUBGROUP OF OR EQUAL TO - return rune(0x22b4), true - case "LeftUpDownVector": // UP BARB LEFT DOWN BARB LEFT HARPOON - return rune(0x2951), true - case "LeftUpTeeVector": // UPWARDS HARPOON WITH BARB LEFT FROM BAR - return rune(0x2960), true - case "LeftUpVector": // UPWARDS HARPOON WITH BARB LEFTWARDS - return rune(0x21bf), true - case "LeftUpVectorBar": // UPWARDS HARPOON WITH BARB LEFT TO BAR - return rune(0x2958), true - case "LeftVector": // LEFTWARDS HARPOON WITH BARB UPWARDS - return rune(0x21bc), true - case "LeftVectorBar": // LEFTWARDS HARPOON WITH BARB UP TO BAR - return rune(0x2952), true - case "Leftarrow": // LEFTWARDS DOUBLE ARROW - return rune(0x21d0), true - case "Leftrightarrow": // LEFT RIGHT DOUBLE ARROW - return rune(0x21d4), true - case "LessEqualGreater": // LESS-THAN EQUAL TO OR GREATER-THAN - return rune(0x22da), true - case "LessFullEqual": // LESS-THAN OVER EQUAL TO - return rune(0x2266), true - case "LessGreater": // LESS-THAN OR GREATER-THAN - return rune(0x2276), true - case "LessLess": // DOUBLE NESTED LESS-THAN - return rune(0x2aa1), true - case "LessSlantEqual": // LESS-THAN OR SLANTED EQUAL TO - return rune(0x2a7d), true - case "LessTilde": // LESS-THAN OR EQUIVALENT TO - return rune(0x2272), true - case "Lfr": // MATHEMATICAL FRAKTUR CAPITAL L - return rune(0x01d50f), true - case "Lgr": // GREEK CAPITAL LETTER LAMDA - return rune(0x039b), true - case "Ll": // VERY MUCH LESS-THAN - return rune(0x22d8), true - case "Lleftarrow": // LEFTWARDS TRIPLE ARROW - return rune(0x21da), true - case "Lmidot": // LATIN CAPITAL LETTER L WITH MIDDLE DOT - return rune(0x013f), true - case "LongLeftArrow": // LONG LEFTWARDS ARROW - return rune(0x27f5), true - case "LongLeftRightArrow": // LONG LEFT RIGHT ARROW - return rune(0x27f7), true - case "LongRightArrow": // LONG RIGHTWARDS ARROW - return rune(0x27f6), true - case "Longleftarrow": // LONG LEFTWARDS DOUBLE ARROW - return rune(0x27f8), true - case "Longleftrightarrow": // LONG LEFT RIGHT DOUBLE ARROW - return rune(0x27fa), true - case "Longrightarrow": // LONG RIGHTWARDS DOUBLE ARROW - return rune(0x27f9), true - case "Lopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL L - return rune(0x01d543), true - case "LowerLeftArrow": // SOUTH WEST ARROW - return rune(0x2199), true - case "LowerRightArrow": // SOUTH EAST ARROW - return rune(0x2198), true - case "Lscr": // SCRIPT CAPITAL L - return rune(0x2112), true - case "Lsh": // UPWARDS ARROW WITH TIP LEFTWARDS - return rune(0x21b0), true - case "Lstrok": // LATIN CAPITAL LETTER L WITH STROKE - return rune(0x0141), true - case "Lt": // MUCH LESS-THAN - return rune(0x226a), true - case "Ltbar": // DOUBLE NESTED LESS-THAN WITH UNDERBAR - return rune(0x2aa3), true + case "LJcy": // CYRILLIC CAPITAL LETTER LJE + return rune(0x0409), true + case "LT": // LESS-THAN SIGN + return rune(0x3c), true + case "Lacute": // LATIN CAPITAL LETTER L WITH ACUTE + return rune(0x0139), true + case "Lambda": // GREEK CAPITAL LETTER LAMDA + return rune(0x039b), true + case "Lang": // MATHEMATICAL LEFT DOUBLE ANGLE BRACKET + return rune(0x27ea), true + case "Laplacetrf": // SCRIPT CAPITAL L + return rune(0x2112), true + case "Larr": // LEFTWARDS TWO HEADED ARROW + return rune(0x219e), true + case "Lcaron": // LATIN CAPITAL LETTER L WITH CARON + return rune(0x013d), true + case "Lcedil": // LATIN CAPITAL LETTER L WITH CEDILLA + return rune(0x013b), true + case "Lcy": // CYRILLIC CAPITAL LETTER EL + return rune(0x041b), true + case "LeftAngleBracket": // MATHEMATICAL LEFT ANGLE BRACKET + return rune(0x27e8), true + case "LeftArrow": // LEFTWARDS ARROW + return rune(0x2190), true + case "LeftArrowBar": // LEFTWARDS ARROW TO BAR + return rune(0x21e4), true + case "LeftArrowRightArrow": // LEFTWARDS ARROW OVER RIGHTWARDS ARROW + return rune(0x21c6), true + case "LeftCeiling": // LEFT CEILING + return rune(0x2308), true + case "LeftDoubleBracket": // MATHEMATICAL LEFT WHITE SQUARE BRACKET + return rune(0x27e6), true + case "LeftDownTeeVector": // DOWNWARDS HARPOON WITH BARB LEFT FROM BAR + return rune(0x2961), true + case "LeftDownVector": // DOWNWARDS HARPOON WITH BARB LEFTWARDS + return rune(0x21c3), true + case "LeftDownVectorBar": // DOWNWARDS HARPOON WITH BARB LEFT TO BAR + return rune(0x2959), true + case "LeftFloor": // LEFT FLOOR + return rune(0x230a), true + case "LeftRightArrow": // LEFT RIGHT ARROW + return rune(0x2194), true + case "LeftRightVector": // LEFT BARB UP RIGHT BARB UP HARPOON + return rune(0x294e), true + case "LeftTee": // LEFT TACK + return rune(0x22a3), true + case "LeftTeeArrow": // LEFTWARDS ARROW FROM BAR + return rune(0x21a4), true + case "LeftTeeVector": // LEFTWARDS HARPOON WITH BARB UP FROM BAR + return rune(0x295a), true + case "LeftTriangle": // NORMAL SUBGROUP OF + return rune(0x22b2), true + case "LeftTriangleBar": // LEFT TRIANGLE BESIDE VERTICAL BAR + return rune(0x29cf), true + case "LeftTriangleEqual": // NORMAL SUBGROUP OF OR EQUAL TO + return rune(0x22b4), true + case "LeftUpDownVector": // UP BARB LEFT DOWN BARB LEFT HARPOON + return rune(0x2951), true + case "LeftUpTeeVector": // UPWARDS HARPOON WITH BARB LEFT FROM BAR + return rune(0x2960), true + case "LeftUpVector": // UPWARDS HARPOON WITH BARB LEFTWARDS + return rune(0x21bf), true + case "LeftUpVectorBar": // UPWARDS HARPOON WITH BARB LEFT TO BAR + return rune(0x2958), true + case "LeftVector": // LEFTWARDS HARPOON WITH BARB UPWARDS + return rune(0x21bc), true + case "LeftVectorBar": // LEFTWARDS HARPOON WITH BARB UP TO BAR + return rune(0x2952), true + case "Leftarrow": // LEFTWARDS DOUBLE ARROW + return rune(0x21d0), true + case "Leftrightarrow": // LEFT RIGHT DOUBLE ARROW + return rune(0x21d4), true + case "LessEqualGreater": // LESS-THAN EQUAL TO OR GREATER-THAN + return rune(0x22da), true + case "LessFullEqual": // LESS-THAN OVER EQUAL TO + return rune(0x2266), true + case "LessGreater": // LESS-THAN OR GREATER-THAN + return rune(0x2276), true + case "LessLess": // DOUBLE NESTED LESS-THAN + return rune(0x2aa1), true + case "LessSlantEqual": // LESS-THAN OR SLANTED EQUAL TO + return rune(0x2a7d), true + case "LessTilde": // LESS-THAN OR EQUIVALENT TO + return rune(0x2272), true + case "Lfr": // MATHEMATICAL FRAKTUR CAPITAL L + return rune(0x01d50f), true + case "Lgr": // GREEK CAPITAL LETTER LAMDA + return rune(0x039b), true + case "Ll": // VERY MUCH LESS-THAN + return rune(0x22d8), true + case "Lleftarrow": // LEFTWARDS TRIPLE ARROW + return rune(0x21da), true + case "Lmidot": // LATIN CAPITAL LETTER L WITH MIDDLE DOT + return rune(0x013f), true + case "LongLeftArrow": // LONG LEFTWARDS ARROW + return rune(0x27f5), true + case "LongLeftRightArrow": // LONG LEFT RIGHT ARROW + return rune(0x27f7), true + case "LongRightArrow": // LONG RIGHTWARDS ARROW + return rune(0x27f6), true + case "Longleftarrow": // LONG LEFTWARDS DOUBLE ARROW + return rune(0x27f8), true + case "Longleftrightarrow": // LONG LEFT RIGHT DOUBLE ARROW + return rune(0x27fa), true + case "Longrightarrow": // LONG RIGHTWARDS DOUBLE ARROW + return rune(0x27f9), true + case "Lopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL L + return rune(0x01d543), true + case "LowerLeftArrow": // SOUTH WEST ARROW + return rune(0x2199), true + case "LowerRightArrow": // SOUTH EAST ARROW + return rune(0x2198), true + case "Lscr": // SCRIPT CAPITAL L + return rune(0x2112), true + case "Lsh": // UPWARDS ARROW WITH TIP LEFTWARDS + return rune(0x21b0), true + case "Lstrok": // LATIN CAPITAL LETTER L WITH STROKE + return rune(0x0141), true + case "Lt": // MUCH LESS-THAN + return rune(0x226a), true + case "Ltbar": // DOUBLE NESTED LESS-THAN WITH UNDERBAR + return rune(0x2aa3), true } case 'M': switch name { - case "Map": // RIGHTWARDS TWO-HEADED ARROW FROM BAR - return rune(0x2905), true - case "Mapfrom": // LEFTWARDS DOUBLE ARROW FROM BAR - return rune(0x2906), true - case "Mapto": // RIGHTWARDS DOUBLE ARROW FROM BAR - return rune(0x2907), true - case "Mcy": // CYRILLIC CAPITAL LETTER EM - return rune(0x041c), true - case "MediumSpace": // MEDIUM MATHEMATICAL SPACE - return rune(0x205f), true - case "Mellintrf": // SCRIPT CAPITAL M - return rune(0x2133), true - case "Mfr": // MATHEMATICAL FRAKTUR CAPITAL M - return rune(0x01d510), true - case "Mgr": // GREEK CAPITAL LETTER MU - return rune(0x039c), true - case "MinusPlus": // MINUS-OR-PLUS SIGN - return rune(0x2213), true - case "Mopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL M - return rune(0x01d544), true - case "Mscr": // SCRIPT CAPITAL M - return rune(0x2133), true - case "Mu": // GREEK CAPITAL LETTER MU - return rune(0x039c), true + case "Map": // RIGHTWARDS TWO-HEADED ARROW FROM BAR + return rune(0x2905), true + case "Mapfrom": // LEFTWARDS DOUBLE ARROW FROM BAR + return rune(0x2906), true + case "Mapto": // RIGHTWARDS DOUBLE ARROW FROM BAR + return rune(0x2907), true + case "Mcy": // CYRILLIC CAPITAL LETTER EM + return rune(0x041c), true + case "MediumSpace": // MEDIUM MATHEMATICAL SPACE + return rune(0x205f), true + case "Mellintrf": // SCRIPT CAPITAL M + return rune(0x2133), true + case "Mfr": // MATHEMATICAL FRAKTUR CAPITAL M + return rune(0x01d510), true + case "Mgr": // GREEK CAPITAL LETTER MU + return rune(0x039c), true + case "MinusPlus": // MINUS-OR-PLUS SIGN + return rune(0x2213), true + case "Mopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL M + return rune(0x01d544), true + case "Mscr": // SCRIPT CAPITAL M + return rune(0x2133), true + case "Mu": // GREEK CAPITAL LETTER MU + return rune(0x039c), true } case 'N': switch name { - case "NJcy": // CYRILLIC CAPITAL LETTER NJE - return rune(0x040a), true - case "Nacute": // LATIN CAPITAL LETTER N WITH ACUTE - return rune(0x0143), true - case "Ncaron": // LATIN CAPITAL LETTER N WITH CARON - return rune(0x0147), true - case "Ncedil": // LATIN CAPITAL LETTER N WITH CEDILLA - return rune(0x0145), true - case "Ncy": // CYRILLIC CAPITAL LETTER EN - return rune(0x041d), true - case "NegativeMediumSpace": // ZERO WIDTH SPACE - return rune(0x200b), true - case "NegativeThickSpace": // ZERO WIDTH SPACE - return rune(0x200b), true - case "NegativeThinSpace": // ZERO WIDTH SPACE - return rune(0x200b), true - case "NegativeVeryThinSpace": // ZERO WIDTH SPACE - return rune(0x200b), true - case "NestedGreaterGreater": // MUCH GREATER-THAN - return rune(0x226b), true - case "NestedLessLess": // MUCH LESS-THAN - return rune(0x226a), true - case "NewLine": // LINE FEED (LF) - return rune(0x0a), true - case "Nfr": // MATHEMATICAL FRAKTUR CAPITAL N - return rune(0x01d511), true - case "Ngr": // GREEK CAPITAL LETTER NU - return rune(0x039d), true - case "NoBreak": // WORD JOINER - return rune(0x2060), true - case "NonBreakingSpace": // NO-BREAK SPACE - return rune(0xa0), true - case "Nopf": // DOUBLE-STRUCK CAPITAL N - return rune(0x2115), true - case "Not": // DOUBLE STROKE NOT SIGN - return rune(0x2aec), true - case "NotCongruent": // NOT IDENTICAL TO - return rune(0x2262), true - case "NotCupCap": // NOT EQUIVALENT TO - return rune(0x226d), true - case "NotDoubleVerticalBar": // NOT PARALLEL TO - return rune(0x2226), true - case "NotElement": // NOT AN ELEMENT OF - return rune(0x2209), true - case "NotEqual": // NOT EQUAL TO - return rune(0x2260), true - case "NotEqualTilde": // MINUS TILDE with slash - return rune(0x2242), true - case "NotExists": // THERE DOES NOT EXIST - return rune(0x2204), true - case "NotGreater": // NOT GREATER-THAN - return rune(0x226f), true - case "NotGreaterEqual": // NEITHER GREATER-THAN NOR EQUAL TO - return rune(0x2271), true - case "NotGreaterFullEqual": // GREATER-THAN OVER EQUAL TO with slash - return rune(0x2267), true - case "NotGreaterGreater": // MUCH GREATER THAN with slash - return rune(0x226b), true - case "NotGreaterLess": // NEITHER GREATER-THAN NOR LESS-THAN - return rune(0x2279), true - case "NotGreaterSlantEqual": // GREATER-THAN OR SLANTED EQUAL TO with slash - return rune(0x2a7e), true - case "NotGreaterTilde": // NEITHER GREATER-THAN NOR EQUIVALENT TO - return rune(0x2275), true - case "NotHumpDownHump": // GEOMETRICALLY EQUIVALENT TO with slash - return rune(0x224e), true - case "NotHumpEqual": // DIFFERENCE BETWEEN with slash - return rune(0x224f), true - case "NotLeftTriangle": // NOT NORMAL SUBGROUP OF - return rune(0x22ea), true - case "NotLeftTriangleBar": // LEFT TRIANGLE BESIDE VERTICAL BAR with slash - return rune(0x29cf), true - case "NotLeftTriangleEqual": // NOT NORMAL SUBGROUP OF OR EQUAL TO - return rune(0x22ec), true - case "NotLess": // NOT LESS-THAN - return rune(0x226e), true - case "NotLessEqual": // NEITHER LESS-THAN NOR EQUAL TO - return rune(0x2270), true - case "NotLessGreater": // NEITHER LESS-THAN NOR GREATER-THAN - return rune(0x2278), true - case "NotLessLess": // MUCH LESS THAN with slash - return rune(0x226a), true - case "NotLessSlantEqual": // LESS-THAN OR SLANTED EQUAL TO with slash - return rune(0x2a7d), true - case "NotLessTilde": // NEITHER LESS-THAN NOR EQUIVALENT TO - return rune(0x2274), true - case "NotNestedGreaterGreater": // DOUBLE NESTED GREATER-THAN with slash - return rune(0x2aa2), true - case "NotNestedLessLess": // DOUBLE NESTED LESS-THAN with slash - return rune(0x2aa1), true - case "NotPrecedes": // DOES NOT PRECEDE - return rune(0x2280), true - case "NotPrecedesEqual": // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash - return rune(0x2aaf), true - case "NotPrecedesSlantEqual": // DOES NOT PRECEDE OR EQUAL - return rune(0x22e0), true - case "NotReverseElement": // DOES NOT CONTAIN AS MEMBER - return rune(0x220c), true - case "NotRightTriangle": // DOES NOT CONTAIN AS NORMAL SUBGROUP - return rune(0x22eb), true - case "NotRightTriangleBar": // VERTICAL BAR BESIDE RIGHT TRIANGLE with slash - return rune(0x29d0), true - case "NotRightTriangleEqual": // DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL - return rune(0x22ed), true - case "NotSquareSubset": // SQUARE IMAGE OF with slash - return rune(0x228f), true - case "NotSquareSubsetEqual": // NOT SQUARE IMAGE OF OR EQUAL TO - return rune(0x22e2), true - case "NotSquareSuperset": // SQUARE ORIGINAL OF with slash - return rune(0x2290), true - case "NotSquareSupersetEqual": // NOT SQUARE ORIGINAL OF OR EQUAL TO - return rune(0x22e3), true - case "NotSubset": // SUBSET OF with vertical line - return rune(0x2282), true - case "NotSubsetEqual": // NEITHER A SUBSET OF NOR EQUAL TO - return rune(0x2288), true - case "NotSucceeds": // DOES NOT SUCCEED - return rune(0x2281), true - case "NotSucceedsEqual": // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash - return rune(0x2ab0), true - case "NotSucceedsSlantEqual": // DOES NOT SUCCEED OR EQUAL - return rune(0x22e1), true - case "NotSucceedsTilde": // SUCCEEDS OR EQUIVALENT TO with slash - return rune(0x227f), true - case "NotSuperset": // SUPERSET OF with vertical line - return rune(0x2283), true - case "NotSupersetEqual": // NEITHER A SUPERSET OF NOR EQUAL TO - return rune(0x2289), true - case "NotTilde": // NOT TILDE - return rune(0x2241), true - case "NotTildeEqual": // NOT ASYMPTOTICALLY EQUAL TO - return rune(0x2244), true - case "NotTildeFullEqual": // NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO - return rune(0x2247), true - case "NotTildeTilde": // NOT ALMOST EQUAL TO - return rune(0x2249), true - case "NotVerticalBar": // DOES NOT DIVIDE - return rune(0x2224), true - case "Nscr": // MATHEMATICAL SCRIPT CAPITAL N - return rune(0x01d4a9), true - case "Ntilde": // LATIN CAPITAL LETTER N WITH TILDE - return rune(0xd1), true - case "Nu": // GREEK CAPITAL LETTER NU - return rune(0x039d), true + case "NJcy": // CYRILLIC CAPITAL LETTER NJE + return rune(0x040a), true + case "Nacute": // LATIN CAPITAL LETTER N WITH ACUTE + return rune(0x0143), true + case "Ncaron": // LATIN CAPITAL LETTER N WITH CARON + return rune(0x0147), true + case "Ncedil": // LATIN CAPITAL LETTER N WITH CEDILLA + return rune(0x0145), true + case "Ncy": // CYRILLIC CAPITAL LETTER EN + return rune(0x041d), true + case "NegativeMediumSpace": // ZERO WIDTH SPACE + return rune(0x200b), true + case "NegativeThickSpace": // ZERO WIDTH SPACE + return rune(0x200b), true + case "NegativeThinSpace": // ZERO WIDTH SPACE + return rune(0x200b), true + case "NegativeVeryThinSpace": // ZERO WIDTH SPACE + return rune(0x200b), true + case "NestedGreaterGreater": // MUCH GREATER-THAN + return rune(0x226b), true + case "NestedLessLess": // MUCH LESS-THAN + return rune(0x226a), true + case "NewLine": // LINE FEED (LF) + return rune(0x0a), true + case "Nfr": // MATHEMATICAL FRAKTUR CAPITAL N + return rune(0x01d511), true + case "Ngr": // GREEK CAPITAL LETTER NU + return rune(0x039d), true + case "NoBreak": // WORD JOINER + return rune(0x2060), true + case "NonBreakingSpace": // NO-BREAK SPACE + return rune(0xa0), true + case "Nopf": // DOUBLE-STRUCK CAPITAL N + return rune(0x2115), true + case "Not": // DOUBLE STROKE NOT SIGN + return rune(0x2aec), true + case "NotCongruent": // NOT IDENTICAL TO + return rune(0x2262), true + case "NotCupCap": // NOT EQUIVALENT TO + return rune(0x226d), true + case "NotDoubleVerticalBar": // NOT PARALLEL TO + return rune(0x2226), true + case "NotElement": // NOT AN ELEMENT OF + return rune(0x2209), true + case "NotEqual": // NOT EQUAL TO + return rune(0x2260), true + case "NotEqualTilde": // MINUS TILDE with slash + return rune(0x2242), true + case "NotExists": // THERE DOES NOT EXIST + return rune(0x2204), true + case "NotGreater": // NOT GREATER-THAN + return rune(0x226f), true + case "NotGreaterEqual": // NEITHER GREATER-THAN NOR EQUAL TO + return rune(0x2271), true + case "NotGreaterFullEqual": // GREATER-THAN OVER EQUAL TO with slash + return rune(0x2267), true + case "NotGreaterGreater": // MUCH GREATER THAN with slash + return rune(0x226b), true + case "NotGreaterLess": // NEITHER GREATER-THAN NOR LESS-THAN + return rune(0x2279), true + case "NotGreaterSlantEqual": // GREATER-THAN OR SLANTED EQUAL TO with slash + return rune(0x2a7e), true + case "NotGreaterTilde": // NEITHER GREATER-THAN NOR EQUIVALENT TO + return rune(0x2275), true + case "NotHumpDownHump": // GEOMETRICALLY EQUIVALENT TO with slash + return rune(0x224e), true + case "NotHumpEqual": // DIFFERENCE BETWEEN with slash + return rune(0x224f), true + case "NotLeftTriangle": // NOT NORMAL SUBGROUP OF + return rune(0x22ea), true + case "NotLeftTriangleBar": // LEFT TRIANGLE BESIDE VERTICAL BAR with slash + return rune(0x29cf), true + case "NotLeftTriangleEqual": // NOT NORMAL SUBGROUP OF OR EQUAL TO + return rune(0x22ec), true + case "NotLess": // NOT LESS-THAN + return rune(0x226e), true + case "NotLessEqual": // NEITHER LESS-THAN NOR EQUAL TO + return rune(0x2270), true + case "NotLessGreater": // NEITHER LESS-THAN NOR GREATER-THAN + return rune(0x2278), true + case "NotLessLess": // MUCH LESS THAN with slash + return rune(0x226a), true + case "NotLessSlantEqual": // LESS-THAN OR SLANTED EQUAL TO with slash + return rune(0x2a7d), true + case "NotLessTilde": // NEITHER LESS-THAN NOR EQUIVALENT TO + return rune(0x2274), true + case "NotNestedGreaterGreater": // DOUBLE NESTED GREATER-THAN with slash + return rune(0x2aa2), true + case "NotNestedLessLess": // DOUBLE NESTED LESS-THAN with slash + return rune(0x2aa1), true + case "NotPrecedes": // DOES NOT PRECEDE + return rune(0x2280), true + case "NotPrecedesEqual": // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash + return rune(0x2aaf), true + case "NotPrecedesSlantEqual": // DOES NOT PRECEDE OR EQUAL + return rune(0x22e0), true + case "NotReverseElement": // DOES NOT CONTAIN AS MEMBER + return rune(0x220c), true + case "NotRightTriangle": // DOES NOT CONTAIN AS NORMAL SUBGROUP + return rune(0x22eb), true + case "NotRightTriangleBar": // VERTICAL BAR BESIDE RIGHT TRIANGLE with slash + return rune(0x29d0), true + case "NotRightTriangleEqual": // DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL + return rune(0x22ed), true + case "NotSquareSubset": // SQUARE IMAGE OF with slash + return rune(0x228f), true + case "NotSquareSubsetEqual": // NOT SQUARE IMAGE OF OR EQUAL TO + return rune(0x22e2), true + case "NotSquareSuperset": // SQUARE ORIGINAL OF with slash + return rune(0x2290), true + case "NotSquareSupersetEqual": // NOT SQUARE ORIGINAL OF OR EQUAL TO + return rune(0x22e3), true + case "NotSubset": // SUBSET OF with vertical line + return rune(0x2282), true + case "NotSubsetEqual": // NEITHER A SUBSET OF NOR EQUAL TO + return rune(0x2288), true + case "NotSucceeds": // DOES NOT SUCCEED + return rune(0x2281), true + case "NotSucceedsEqual": // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash + return rune(0x2ab0), true + case "NotSucceedsSlantEqual": // DOES NOT SUCCEED OR EQUAL + return rune(0x22e1), true + case "NotSucceedsTilde": // SUCCEEDS OR EQUIVALENT TO with slash + return rune(0x227f), true + case "NotSuperset": // SUPERSET OF with vertical line + return rune(0x2283), true + case "NotSupersetEqual": // NEITHER A SUPERSET OF NOR EQUAL TO + return rune(0x2289), true + case "NotTilde": // NOT TILDE + return rune(0x2241), true + case "NotTildeEqual": // NOT ASYMPTOTICALLY EQUAL TO + return rune(0x2244), true + case "NotTildeFullEqual": // NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO + return rune(0x2247), true + case "NotTildeTilde": // NOT ALMOST EQUAL TO + return rune(0x2249), true + case "NotVerticalBar": // DOES NOT DIVIDE + return rune(0x2224), true + case "Nscr": // MATHEMATICAL SCRIPT CAPITAL N + return rune(0x01d4a9), true + case "Ntilde": // LATIN CAPITAL LETTER N WITH TILDE + return rune(0xd1), true + case "Nu": // GREEK CAPITAL LETTER NU + return rune(0x039d), true } case 'O': switch name { - case "OElig": // LATIN CAPITAL LIGATURE OE - return rune(0x0152), true - case "OHacgr": // GREEK CAPITAL LETTER OMEGA WITH TONOS - return rune(0x038f), true - case "OHgr": // GREEK CAPITAL LETTER OMEGA - return rune(0x03a9), true - case "Oacgr": // GREEK CAPITAL LETTER OMICRON WITH TONOS - return rune(0x038c), true - case "Oacute": // LATIN CAPITAL LETTER O WITH ACUTE - return rune(0xd3), true - case "Ocirc": // LATIN CAPITAL LETTER O WITH CIRCUMFLEX - return rune(0xd4), true - case "Ocy": // CYRILLIC CAPITAL LETTER O - return rune(0x041e), true - case "Odblac": // LATIN CAPITAL LETTER O WITH DOUBLE ACUTE - return rune(0x0150), true - case "Ofr": // MATHEMATICAL FRAKTUR CAPITAL O - return rune(0x01d512), true - case "Ogr": // GREEK CAPITAL LETTER OMICRON - return rune(0x039f), true - case "Ograve": // LATIN CAPITAL LETTER O WITH GRAVE - return rune(0xd2), true - case "Omacr": // LATIN CAPITAL LETTER O WITH MACRON - return rune(0x014c), true - case "Omega": // GREEK CAPITAL LETTER OMEGA - return rune(0x03a9), true - case "Omicron": // GREEK CAPITAL LETTER OMICRON - return rune(0x039f), true - case "Oopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL O - return rune(0x01d546), true - case "OpenCurlyDoubleQuote": // LEFT DOUBLE QUOTATION MARK - return rune(0x201c), true - case "OpenCurlyQuote": // LEFT SINGLE QUOTATION MARK - return rune(0x2018), true - case "Or": // DOUBLE LOGICAL OR - return rune(0x2a54), true - case "Oscr": // MATHEMATICAL SCRIPT CAPITAL O - return rune(0x01d4aa), true - case "Oslash": // LATIN CAPITAL LETTER O WITH STROKE - return rune(0xd8), true - case "Otilde": // LATIN CAPITAL LETTER O WITH TILDE - return rune(0xd5), true - case "Otimes": // MULTIPLICATION SIGN IN DOUBLE CIRCLE - return rune(0x2a37), true - case "Ouml": // LATIN CAPITAL LETTER O WITH DIAERESIS - return rune(0xd6), true - case "OverBar": // OVERLINE - return rune(0x203e), true - case "OverBrace": // TOP CURLY BRACKET - return rune(0x23de), true - case "OverBracket": // TOP SQUARE BRACKET - return rune(0x23b4), true - case "OverParenthesis": // TOP PARENTHESIS - return rune(0x23dc), true + case "OElig": // LATIN CAPITAL LIGATURE OE + return rune(0x0152), true + case "OHacgr": // GREEK CAPITAL LETTER OMEGA WITH TONOS + return rune(0x038f), true + case "OHgr": // GREEK CAPITAL LETTER OMEGA + return rune(0x03a9), true + case "Oacgr": // GREEK CAPITAL LETTER OMICRON WITH TONOS + return rune(0x038c), true + case "Oacute": // LATIN CAPITAL LETTER O WITH ACUTE + return rune(0xd3), true + case "Ocirc": // LATIN CAPITAL LETTER O WITH CIRCUMFLEX + return rune(0xd4), true + case "Ocy": // CYRILLIC CAPITAL LETTER O + return rune(0x041e), true + case "Odblac": // LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + return rune(0x0150), true + case "Ofr": // MATHEMATICAL FRAKTUR CAPITAL O + return rune(0x01d512), true + case "Ogr": // GREEK CAPITAL LETTER OMICRON + return rune(0x039f), true + case "Ograve": // LATIN CAPITAL LETTER O WITH GRAVE + return rune(0xd2), true + case "Omacr": // LATIN CAPITAL LETTER O WITH MACRON + return rune(0x014c), true + case "Omega": // GREEK CAPITAL LETTER OMEGA + return rune(0x03a9), true + case "Omicron": // GREEK CAPITAL LETTER OMICRON + return rune(0x039f), true + case "Oopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL O + return rune(0x01d546), true + case "OpenCurlyDoubleQuote": // LEFT DOUBLE QUOTATION MARK + return rune(0x201c), true + case "OpenCurlyQuote": // LEFT SINGLE QUOTATION MARK + return rune(0x2018), true + case "Or": // DOUBLE LOGICAL OR + return rune(0x2a54), true + case "Oscr": // MATHEMATICAL SCRIPT CAPITAL O + return rune(0x01d4aa), true + case "Oslash": // LATIN CAPITAL LETTER O WITH STROKE + return rune(0xd8), true + case "Otilde": // LATIN CAPITAL LETTER O WITH TILDE + return rune(0xd5), true + case "Otimes": // MULTIPLICATION SIGN IN DOUBLE CIRCLE + return rune(0x2a37), true + case "Ouml": // LATIN CAPITAL LETTER O WITH DIAERESIS + return rune(0xd6), true + case "OverBar": // OVERLINE + return rune(0x203e), true + case "OverBrace": // TOP CURLY BRACKET + return rune(0x23de), true + case "OverBracket": // TOP SQUARE BRACKET + return rune(0x23b4), true + case "OverParenthesis": // TOP PARENTHESIS + return rune(0x23dc), true } case 'P': switch name { - case "PHgr": // GREEK CAPITAL LETTER PHI - return rune(0x03a6), true - case "PSgr": // GREEK CAPITAL LETTER PSI - return rune(0x03a8), true - case "PartialD": // PARTIAL DIFFERENTIAL - return rune(0x2202), true - case "Pcy": // CYRILLIC CAPITAL LETTER PE - return rune(0x041f), true - case "Pfr": // MATHEMATICAL FRAKTUR CAPITAL P - return rune(0x01d513), true - case "Pgr": // GREEK CAPITAL LETTER PI - return rune(0x03a0), true - case "Phi": // GREEK CAPITAL LETTER PHI - return rune(0x03a6), true - case "Pi": // GREEK CAPITAL LETTER PI - return rune(0x03a0), true - case "PlusMinus": // PLUS-MINUS SIGN - return rune(0xb1), true - case "Poincareplane": // BLACK-LETTER CAPITAL H - return rune(0x210c), true - case "Popf": // DOUBLE-STRUCK CAPITAL P - return rune(0x2119), true - case "Pr": // DOUBLE PRECEDES - return rune(0x2abb), true - case "Precedes": // PRECEDES - return rune(0x227a), true - case "PrecedesEqual": // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN - return rune(0x2aaf), true - case "PrecedesSlantEqual": // PRECEDES OR EQUAL TO - return rune(0x227c), true - case "PrecedesTilde": // PRECEDES OR EQUIVALENT TO - return rune(0x227e), true - case "Prime": // DOUBLE PRIME - return rune(0x2033), true - case "Product": // N-ARY PRODUCT - return rune(0x220f), true - case "Proportion": // PROPORTION - return rune(0x2237), true - case "Proportional": // PROPORTIONAL TO - return rune(0x221d), true - case "Pscr": // MATHEMATICAL SCRIPT CAPITAL P - return rune(0x01d4ab), true - case "Psi": // GREEK CAPITAL LETTER PSI - return rune(0x03a8), true + case "PHgr": // GREEK CAPITAL LETTER PHI + return rune(0x03a6), true + case "PSgr": // GREEK CAPITAL LETTER PSI + return rune(0x03a8), true + case "PartialD": // PARTIAL DIFFERENTIAL + return rune(0x2202), true + case "Pcy": // CYRILLIC CAPITAL LETTER PE + return rune(0x041f), true + case "Pfr": // MATHEMATICAL FRAKTUR CAPITAL P + return rune(0x01d513), true + case "Pgr": // GREEK CAPITAL LETTER PI + return rune(0x03a0), true + case "Phi": // GREEK CAPITAL LETTER PHI + return rune(0x03a6), true + case "Pi": // GREEK CAPITAL LETTER PI + return rune(0x03a0), true + case "PlusMinus": // PLUS-MINUS SIGN + return rune(0xb1), true + case "Poincareplane": // BLACK-LETTER CAPITAL H + return rune(0x210c), true + case "Popf": // DOUBLE-STRUCK CAPITAL P + return rune(0x2119), true + case "Pr": // DOUBLE PRECEDES + return rune(0x2abb), true + case "Precedes": // PRECEDES + return rune(0x227a), true + case "PrecedesEqual": // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN + return rune(0x2aaf), true + case "PrecedesSlantEqual": // PRECEDES OR EQUAL TO + return rune(0x227c), true + case "PrecedesTilde": // PRECEDES OR EQUIVALENT TO + return rune(0x227e), true + case "Prime": // DOUBLE PRIME + return rune(0x2033), true + case "Product": // N-ARY PRODUCT + return rune(0x220f), true + case "Proportion": // PROPORTION + return rune(0x2237), true + case "Proportional": // PROPORTIONAL TO + return rune(0x221d), true + case "Pscr": // MATHEMATICAL SCRIPT CAPITAL P + return rune(0x01d4ab), true + case "Psi": // GREEK CAPITAL LETTER PSI + return rune(0x03a8), true } case 'Q': switch name { - case "QUOT": // QUOTATION MARK - return rune(0x22), true - case "Qfr": // MATHEMATICAL FRAKTUR CAPITAL Q - return rune(0x01d514), true - case "Qopf": // DOUBLE-STRUCK CAPITAL Q - return rune(0x211a), true - case "Qscr": // MATHEMATICAL SCRIPT CAPITAL Q - return rune(0x01d4ac), true + case "QUOT": // QUOTATION MARK + return rune(0x22), true + case "Qfr": // MATHEMATICAL FRAKTUR CAPITAL Q + return rune(0x01d514), true + case "Qopf": // DOUBLE-STRUCK CAPITAL Q + return rune(0x211a), true + case "Qscr": // MATHEMATICAL SCRIPT CAPITAL Q + return rune(0x01d4ac), true } case 'R': switch name { - case "RBarr": // RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW - return rune(0x2910), true - case "REG": // REGISTERED SIGN - return rune(0xae), true - case "Racute": // LATIN CAPITAL LETTER R WITH ACUTE - return rune(0x0154), true - case "Rang": // MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET - return rune(0x27eb), true - case "Rarr": // RIGHTWARDS TWO HEADED ARROW - return rune(0x21a0), true - case "Rarrtl": // RIGHTWARDS TWO-HEADED ARROW WITH TAIL - return rune(0x2916), true - case "Rcaron": // LATIN CAPITAL LETTER R WITH CARON - return rune(0x0158), true - case "Rcedil": // LATIN CAPITAL LETTER R WITH CEDILLA - return rune(0x0156), true - case "Rcy": // CYRILLIC CAPITAL LETTER ER - return rune(0x0420), true - case "Re": // BLACK-LETTER CAPITAL R - return rune(0x211c), true - case "ReverseElement": // CONTAINS AS MEMBER - return rune(0x220b), true - case "ReverseEquilibrium": // LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON - return rune(0x21cb), true - case "ReverseUpEquilibrium": // DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT - return rune(0x296f), true - case "Rfr": // BLACK-LETTER CAPITAL R - return rune(0x211c), true - case "Rgr": // GREEK CAPITAL LETTER RHO - return rune(0x03a1), true - case "Rho": // GREEK CAPITAL LETTER RHO - return rune(0x03a1), true - case "RightAngleBracket": // MATHEMATICAL RIGHT ANGLE BRACKET - return rune(0x27e9), true - case "RightArrow": // RIGHTWARDS ARROW - return rune(0x2192), true - case "RightArrowBar": // RIGHTWARDS ARROW TO BAR - return rune(0x21e5), true - case "RightArrowLeftArrow": // RIGHTWARDS ARROW OVER LEFTWARDS ARROW - return rune(0x21c4), true - case "RightCeiling": // RIGHT CEILING - return rune(0x2309), true - case "RightDoubleBracket": // MATHEMATICAL RIGHT WHITE SQUARE BRACKET - return rune(0x27e7), true - case "RightDownTeeVector": // DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR - return rune(0x295d), true - case "RightDownVector": // DOWNWARDS HARPOON WITH BARB RIGHTWARDS - return rune(0x21c2), true - case "RightDownVectorBar": // DOWNWARDS HARPOON WITH BARB RIGHT TO BAR - return rune(0x2955), true - case "RightFloor": // RIGHT FLOOR - return rune(0x230b), true - case "RightTee": // RIGHT TACK - return rune(0x22a2), true - case "RightTeeArrow": // RIGHTWARDS ARROW FROM BAR - return rune(0x21a6), true - case "RightTeeVector": // RIGHTWARDS HARPOON WITH BARB UP FROM BAR - return rune(0x295b), true - case "RightTriangle": // CONTAINS AS NORMAL SUBGROUP - return rune(0x22b3), true - case "RightTriangleBar": // VERTICAL BAR BESIDE RIGHT TRIANGLE - return rune(0x29d0), true - case "RightTriangleEqual": // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO - return rune(0x22b5), true - case "RightUpDownVector": // UP BARB RIGHT DOWN BARB RIGHT HARPOON - return rune(0x294f), true - case "RightUpTeeVector": // UPWARDS HARPOON WITH BARB RIGHT FROM BAR - return rune(0x295c), true - case "RightUpVector": // UPWARDS HARPOON WITH BARB RIGHTWARDS - return rune(0x21be), true - case "RightUpVectorBar": // UPWARDS HARPOON WITH BARB RIGHT TO BAR - return rune(0x2954), true - case "RightVector": // RIGHTWARDS HARPOON WITH BARB UPWARDS - return rune(0x21c0), true - case "RightVectorBar": // RIGHTWARDS HARPOON WITH BARB UP TO BAR - return rune(0x2953), true - case "Rightarrow": // RIGHTWARDS DOUBLE ARROW - return rune(0x21d2), true - case "Ropf": // DOUBLE-STRUCK CAPITAL R - return rune(0x211d), true - case "RoundImplies": // RIGHT DOUBLE ARROW WITH ROUNDED HEAD - return rune(0x2970), true - case "Rrightarrow": // RIGHTWARDS TRIPLE ARROW - return rune(0x21db), true - case "Rscr": // SCRIPT CAPITAL R - return rune(0x211b), true - case "Rsh": // UPWARDS ARROW WITH TIP RIGHTWARDS - return rune(0x21b1), true - case "RuleDelayed": // RULE-DELAYED - return rune(0x29f4), true + case "RBarr": // RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW + return rune(0x2910), true + case "REG": // REGISTERED SIGN + return rune(0xae), true + case "Racute": // LATIN CAPITAL LETTER R WITH ACUTE + return rune(0x0154), true + case "Rang": // MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET + return rune(0x27eb), true + case "Rarr": // RIGHTWARDS TWO HEADED ARROW + return rune(0x21a0), true + case "Rarrtl": // RIGHTWARDS TWO-HEADED ARROW WITH TAIL + return rune(0x2916), true + case "Rcaron": // LATIN CAPITAL LETTER R WITH CARON + return rune(0x0158), true + case "Rcedil": // LATIN CAPITAL LETTER R WITH CEDILLA + return rune(0x0156), true + case "Rcy": // CYRILLIC CAPITAL LETTER ER + return rune(0x0420), true + case "Re": // BLACK-LETTER CAPITAL R + return rune(0x211c), true + case "ReverseElement": // CONTAINS AS MEMBER + return rune(0x220b), true + case "ReverseEquilibrium": // LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON + return rune(0x21cb), true + case "ReverseUpEquilibrium": // DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT + return rune(0x296f), true + case "Rfr": // BLACK-LETTER CAPITAL R + return rune(0x211c), true + case "Rgr": // GREEK CAPITAL LETTER RHO + return rune(0x03a1), true + case "Rho": // GREEK CAPITAL LETTER RHO + return rune(0x03a1), true + case "RightAngleBracket": // MATHEMATICAL RIGHT ANGLE BRACKET + return rune(0x27e9), true + case "RightArrow": // RIGHTWARDS ARROW + return rune(0x2192), true + case "RightArrowBar": // RIGHTWARDS ARROW TO BAR + return rune(0x21e5), true + case "RightArrowLeftArrow": // RIGHTWARDS ARROW OVER LEFTWARDS ARROW + return rune(0x21c4), true + case "RightCeiling": // RIGHT CEILING + return rune(0x2309), true + case "RightDoubleBracket": // MATHEMATICAL RIGHT WHITE SQUARE BRACKET + return rune(0x27e7), true + case "RightDownTeeVector": // DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR + return rune(0x295d), true + case "RightDownVector": // DOWNWARDS HARPOON WITH BARB RIGHTWARDS + return rune(0x21c2), true + case "RightDownVectorBar": // DOWNWARDS HARPOON WITH BARB RIGHT TO BAR + return rune(0x2955), true + case "RightFloor": // RIGHT FLOOR + return rune(0x230b), true + case "RightTee": // RIGHT TACK + return rune(0x22a2), true + case "RightTeeArrow": // RIGHTWARDS ARROW FROM BAR + return rune(0x21a6), true + case "RightTeeVector": // RIGHTWARDS HARPOON WITH BARB UP FROM BAR + return rune(0x295b), true + case "RightTriangle": // CONTAINS AS NORMAL SUBGROUP + return rune(0x22b3), true + case "RightTriangleBar": // VERTICAL BAR BESIDE RIGHT TRIANGLE + return rune(0x29d0), true + case "RightTriangleEqual": // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO + return rune(0x22b5), true + case "RightUpDownVector": // UP BARB RIGHT DOWN BARB RIGHT HARPOON + return rune(0x294f), true + case "RightUpTeeVector": // UPWARDS HARPOON WITH BARB RIGHT FROM BAR + return rune(0x295c), true + case "RightUpVector": // UPWARDS HARPOON WITH BARB RIGHTWARDS + return rune(0x21be), true + case "RightUpVectorBar": // UPWARDS HARPOON WITH BARB RIGHT TO BAR + return rune(0x2954), true + case "RightVector": // RIGHTWARDS HARPOON WITH BARB UPWARDS + return rune(0x21c0), true + case "RightVectorBar": // RIGHTWARDS HARPOON WITH BARB UP TO BAR + return rune(0x2953), true + case "Rightarrow": // RIGHTWARDS DOUBLE ARROW + return rune(0x21d2), true + case "Ropf": // DOUBLE-STRUCK CAPITAL R + return rune(0x211d), true + case "RoundImplies": // RIGHT DOUBLE ARROW WITH ROUNDED HEAD + return rune(0x2970), true + case "Rrightarrow": // RIGHTWARDS TRIPLE ARROW + return rune(0x21db), true + case "Rscr": // SCRIPT CAPITAL R + return rune(0x211b), true + case "Rsh": // UPWARDS ARROW WITH TIP RIGHTWARDS + return rune(0x21b1), true + case "RuleDelayed": // RULE-DELAYED + return rune(0x29f4), true } case 'S': switch name { - case "SHCHcy": // CYRILLIC CAPITAL LETTER SHCHA - return rune(0x0429), true - case "SHcy": // CYRILLIC CAPITAL LETTER SHA - return rune(0x0428), true - case "SOFTcy": // CYRILLIC CAPITAL LETTER SOFT SIGN - return rune(0x042c), true - case "Sacute": // LATIN CAPITAL LETTER S WITH ACUTE - return rune(0x015a), true - case "Sc": // DOUBLE SUCCEEDS - return rune(0x2abc), true - case "Scaron": // LATIN CAPITAL LETTER S WITH CARON - return rune(0x0160), true - case "Scedil": // LATIN CAPITAL LETTER S WITH CEDILLA - return rune(0x015e), true - case "Scirc": // LATIN CAPITAL LETTER S WITH CIRCUMFLEX - return rune(0x015c), true - case "Scy": // CYRILLIC CAPITAL LETTER ES - return rune(0x0421), true - case "Sfr": // MATHEMATICAL FRAKTUR CAPITAL S - return rune(0x01d516), true - case "Sgr": // GREEK CAPITAL LETTER SIGMA - return rune(0x03a3), true - case "ShortDownArrow": // DOWNWARDS ARROW - return rune(0x2193), true - case "ShortLeftArrow": // LEFTWARDS ARROW - return rune(0x2190), true - case "ShortRightArrow": // RIGHTWARDS ARROW - return rune(0x2192), true - case "ShortUpArrow": // UPWARDS ARROW - return rune(0x2191), true - case "Sigma": // GREEK CAPITAL LETTER SIGMA - return rune(0x03a3), true - case "SmallCircle": // RING OPERATOR - return rune(0x2218), true - case "Sopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL S - return rune(0x01d54a), true - case "Sqrt": // SQUARE ROOT - return rune(0x221a), true - case "Square": // WHITE SQUARE - return rune(0x25a1), true - case "SquareIntersection": // SQUARE CAP - return rune(0x2293), true - case "SquareSubset": // SQUARE IMAGE OF - return rune(0x228f), true - case "SquareSubsetEqual": // SQUARE IMAGE OF OR EQUAL TO - return rune(0x2291), true - case "SquareSuperset": // SQUARE ORIGINAL OF - return rune(0x2290), true - case "SquareSupersetEqual": // SQUARE ORIGINAL OF OR EQUAL TO - return rune(0x2292), true - case "SquareUnion": // SQUARE CUP - return rune(0x2294), true - case "Sscr": // MATHEMATICAL SCRIPT CAPITAL S - return rune(0x01d4ae), true - case "Star": // STAR OPERATOR - return rune(0x22c6), true - case "Sub": // DOUBLE SUBSET - return rune(0x22d0), true - case "Subset": // DOUBLE SUBSET - return rune(0x22d0), true - case "SubsetEqual": // SUBSET OF OR EQUAL TO - return rune(0x2286), true - case "Succeeds": // SUCCEEDS - return rune(0x227b), true - case "SucceedsEqual": // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN - return rune(0x2ab0), true - case "SucceedsSlantEqual": // SUCCEEDS OR EQUAL TO - return rune(0x227d), true - case "SucceedsTilde": // SUCCEEDS OR EQUIVALENT TO - return rune(0x227f), true - case "SuchThat": // CONTAINS AS MEMBER - return rune(0x220b), true - case "Sum": // N-ARY SUMMATION - return rune(0x2211), true - case "Sup": // DOUBLE SUPERSET - return rune(0x22d1), true - case "Superset": // SUPERSET OF - return rune(0x2283), true - case "SupersetEqual": // SUPERSET OF OR EQUAL TO - return rune(0x2287), true - case "Supset": // DOUBLE SUPERSET - return rune(0x22d1), true + case "SHCHcy": // CYRILLIC CAPITAL LETTER SHCHA + return rune(0x0429), true + case "SHcy": // CYRILLIC CAPITAL LETTER SHA + return rune(0x0428), true + case "SOFTcy": // CYRILLIC CAPITAL LETTER SOFT SIGN + return rune(0x042c), true + case "Sacute": // LATIN CAPITAL LETTER S WITH ACUTE + return rune(0x015a), true + case "Sc": // DOUBLE SUCCEEDS + return rune(0x2abc), true + case "Scaron": // LATIN CAPITAL LETTER S WITH CARON + return rune(0x0160), true + case "Scedil": // LATIN CAPITAL LETTER S WITH CEDILLA + return rune(0x015e), true + case "Scirc": // LATIN CAPITAL LETTER S WITH CIRCUMFLEX + return rune(0x015c), true + case "Scy": // CYRILLIC CAPITAL LETTER ES + return rune(0x0421), true + case "Sfr": // MATHEMATICAL FRAKTUR CAPITAL S + return rune(0x01d516), true + case "Sgr": // GREEK CAPITAL LETTER SIGMA + return rune(0x03a3), true + case "ShortDownArrow": // DOWNWARDS ARROW + return rune(0x2193), true + case "ShortLeftArrow": // LEFTWARDS ARROW + return rune(0x2190), true + case "ShortRightArrow": // RIGHTWARDS ARROW + return rune(0x2192), true + case "ShortUpArrow": // UPWARDS ARROW + return rune(0x2191), true + case "Sigma": // GREEK CAPITAL LETTER SIGMA + return rune(0x03a3), true + case "SmallCircle": // RING OPERATOR + return rune(0x2218), true + case "Sopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL S + return rune(0x01d54a), true + case "Sqrt": // SQUARE ROOT + return rune(0x221a), true + case "Square": // WHITE SQUARE + return rune(0x25a1), true + case "SquareIntersection": // SQUARE CAP + return rune(0x2293), true + case "SquareSubset": // SQUARE IMAGE OF + return rune(0x228f), true + case "SquareSubsetEqual": // SQUARE IMAGE OF OR EQUAL TO + return rune(0x2291), true + case "SquareSuperset": // SQUARE ORIGINAL OF + return rune(0x2290), true + case "SquareSupersetEqual": // SQUARE ORIGINAL OF OR EQUAL TO + return rune(0x2292), true + case "SquareUnion": // SQUARE CUP + return rune(0x2294), true + case "Sscr": // MATHEMATICAL SCRIPT CAPITAL S + return rune(0x01d4ae), true + case "Star": // STAR OPERATOR + return rune(0x22c6), true + case "Sub": // DOUBLE SUBSET + return rune(0x22d0), true + case "Subset": // DOUBLE SUBSET + return rune(0x22d0), true + case "SubsetEqual": // SUBSET OF OR EQUAL TO + return rune(0x2286), true + case "Succeeds": // SUCCEEDS + return rune(0x227b), true + case "SucceedsEqual": // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN + return rune(0x2ab0), true + case "SucceedsSlantEqual": // SUCCEEDS OR EQUAL TO + return rune(0x227d), true + case "SucceedsTilde": // SUCCEEDS OR EQUIVALENT TO + return rune(0x227f), true + case "SuchThat": // CONTAINS AS MEMBER + return rune(0x220b), true + case "Sum": // N-ARY SUMMATION + return rune(0x2211), true + case "Sup": // DOUBLE SUPERSET + return rune(0x22d1), true + case "Superset": // SUPERSET OF + return rune(0x2283), true + case "SupersetEqual": // SUPERSET OF OR EQUAL TO + return rune(0x2287), true + case "Supset": // DOUBLE SUPERSET + return rune(0x22d1), true } case 'T': switch name { - case "THORN": // LATIN CAPITAL LETTER THORN - return rune(0xde), true - case "THgr": // GREEK CAPITAL LETTER THETA - return rune(0x0398), true - case "TRADE": // TRADE MARK SIGN - return rune(0x2122), true - case "TSHcy": // CYRILLIC CAPITAL LETTER TSHE - return rune(0x040b), true - case "TScy": // CYRILLIC CAPITAL LETTER TSE - return rune(0x0426), true - case "Tab": // CHARACTER TABULATION - return rune(0x09), true - case "Tau": // GREEK CAPITAL LETTER TAU - return rune(0x03a4), true - case "Tcaron": // LATIN CAPITAL LETTER T WITH CARON - return rune(0x0164), true - case "Tcedil": // LATIN CAPITAL LETTER T WITH CEDILLA - return rune(0x0162), true - case "Tcy": // CYRILLIC CAPITAL LETTER TE - return rune(0x0422), true - case "Tfr": // MATHEMATICAL FRAKTUR CAPITAL T - return rune(0x01d517), true - case "Tgr": // GREEK CAPITAL LETTER TAU - return rune(0x03a4), true - case "Therefore": // THEREFORE - return rune(0x2234), true - case "Theta": // GREEK CAPITAL LETTER THETA - return rune(0x0398), true - case "Thetav": // GREEK CAPITAL THETA SYMBOL - return rune(0x03f4), true - case "ThickSpace": // space of width 5/18 em - return rune(0x205f), true - case "ThinSpace": // THIN SPACE - return rune(0x2009), true - case "Tilde": // TILDE OPERATOR - return rune(0x223c), true - case "TildeEqual": // ASYMPTOTICALLY EQUAL TO - return rune(0x2243), true - case "TildeFullEqual": // APPROXIMATELY EQUAL TO - return rune(0x2245), true - case "TildeTilde": // ALMOST EQUAL TO - return rune(0x2248), true - case "Topf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL T - return rune(0x01d54b), true - case "TripleDot": // COMBINING THREE DOTS ABOVE - return rune(0x20db), true - case "Tscr": // MATHEMATICAL SCRIPT CAPITAL T - return rune(0x01d4af), true - case "Tstrok": // LATIN CAPITAL LETTER T WITH STROKE - return rune(0x0166), true + case "THORN": // LATIN CAPITAL LETTER THORN + return rune(0xde), true + case "THgr": // GREEK CAPITAL LETTER THETA + return rune(0x0398), true + case "TRADE": // TRADE MARK SIGN + return rune(0x2122), true + case "TSHcy": // CYRILLIC CAPITAL LETTER TSHE + return rune(0x040b), true + case "TScy": // CYRILLIC CAPITAL LETTER TSE + return rune(0x0426), true + case "Tab": // CHARACTER TABULATION + return rune(0x09), true + case "Tau": // GREEK CAPITAL LETTER TAU + return rune(0x03a4), true + case "Tcaron": // LATIN CAPITAL LETTER T WITH CARON + return rune(0x0164), true + case "Tcedil": // LATIN CAPITAL LETTER T WITH CEDILLA + return rune(0x0162), true + case "Tcy": // CYRILLIC CAPITAL LETTER TE + return rune(0x0422), true + case "Tfr": // MATHEMATICAL FRAKTUR CAPITAL T + return rune(0x01d517), true + case "Tgr": // GREEK CAPITAL LETTER TAU + return rune(0x03a4), true + case "Therefore": // THEREFORE + return rune(0x2234), true + case "Theta": // GREEK CAPITAL LETTER THETA + return rune(0x0398), true + case "Thetav": // GREEK CAPITAL THETA SYMBOL + return rune(0x03f4), true + case "ThickSpace": // space of width 5/18 em + return rune(0x205f), true + case "ThinSpace": // THIN SPACE + return rune(0x2009), true + case "Tilde": // TILDE OPERATOR + return rune(0x223c), true + case "TildeEqual": // ASYMPTOTICALLY EQUAL TO + return rune(0x2243), true + case "TildeFullEqual": // APPROXIMATELY EQUAL TO + return rune(0x2245), true + case "TildeTilde": // ALMOST EQUAL TO + return rune(0x2248), true + case "Topf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL T + return rune(0x01d54b), true + case "TripleDot": // COMBINING THREE DOTS ABOVE + return rune(0x20db), true + case "Tscr": // MATHEMATICAL SCRIPT CAPITAL T + return rune(0x01d4af), true + case "Tstrok": // LATIN CAPITAL LETTER T WITH STROKE + return rune(0x0166), true } case 'U': switch name { - case "Uacgr": // GREEK CAPITAL LETTER UPSILON WITH TONOS - return rune(0x038e), true - case "Uacute": // LATIN CAPITAL LETTER U WITH ACUTE - return rune(0xda), true - case "Uarr": // UPWARDS TWO HEADED ARROW - return rune(0x219f), true - case "Uarrocir": // UPWARDS TWO-HEADED ARROW FROM SMALL CIRCLE - return rune(0x2949), true - case "Ubrcy": // CYRILLIC CAPITAL LETTER SHORT U - return rune(0x040e), true - case "Ubreve": // LATIN CAPITAL LETTER U WITH BREVE - return rune(0x016c), true - case "Ucirc": // LATIN CAPITAL LETTER U WITH CIRCUMFLEX - return rune(0xdb), true - case "Ucy": // CYRILLIC CAPITAL LETTER U - return rune(0x0423), true - case "Udblac": // LATIN CAPITAL LETTER U WITH DOUBLE ACUTE - return rune(0x0170), true - case "Udigr": // GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA - return rune(0x03ab), true - case "Ufr": // MATHEMATICAL FRAKTUR CAPITAL U - return rune(0x01d518), true - case "Ugr": // GREEK CAPITAL LETTER UPSILON - return rune(0x03a5), true - case "Ugrave": // LATIN CAPITAL LETTER U WITH GRAVE - return rune(0xd9), true - case "Umacr": // LATIN CAPITAL LETTER U WITH MACRON - return rune(0x016a), true - case "UnderBar": // LOW LINE - return rune(0x5f), true - case "UnderBrace": // BOTTOM CURLY BRACKET - return rune(0x23df), true - case "UnderBracket": // BOTTOM SQUARE BRACKET - return rune(0x23b5), true - case "UnderParenthesis": // BOTTOM PARENTHESIS - return rune(0x23dd), true - case "Union": // N-ARY UNION - return rune(0x22c3), true - case "UnionPlus": // MULTISET UNION - return rune(0x228e), true - case "Uogon": // LATIN CAPITAL LETTER U WITH OGONEK - return rune(0x0172), true - case "Uopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL U - return rune(0x01d54c), true - case "UpArrow": // UPWARDS ARROW - return rune(0x2191), true - case "UpArrowBar": // UPWARDS ARROW TO BAR - return rune(0x2912), true - case "UpArrowDownArrow": // UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW - return rune(0x21c5), true - case "UpDownArrow": // UP DOWN ARROW - return rune(0x2195), true - case "UpEquilibrium": // UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT - return rune(0x296e), true - case "UpTee": // UP TACK - return rune(0x22a5), true - case "UpTeeArrow": // UPWARDS ARROW FROM BAR - return rune(0x21a5), true - case "Uparrow": // UPWARDS DOUBLE ARROW - return rune(0x21d1), true - case "Updownarrow": // UP DOWN DOUBLE ARROW - return rune(0x21d5), true - case "UpperLeftArrow": // NORTH WEST ARROW - return rune(0x2196), true - case "UpperRightArrow": // NORTH EAST ARROW - return rune(0x2197), true - case "Upsi": // GREEK UPSILON WITH HOOK SYMBOL - return rune(0x03d2), true - case "Upsilon": // GREEK CAPITAL LETTER UPSILON - return rune(0x03a5), true - case "Uring": // LATIN CAPITAL LETTER U WITH RING ABOVE - return rune(0x016e), true - case "Uscr": // MATHEMATICAL SCRIPT CAPITAL U - return rune(0x01d4b0), true - case "Utilde": // LATIN CAPITAL LETTER U WITH TILDE - return rune(0x0168), true - case "Uuml": // LATIN CAPITAL LETTER U WITH DIAERESIS - return rune(0xdc), true + case "Uacgr": // GREEK CAPITAL LETTER UPSILON WITH TONOS + return rune(0x038e), true + case "Uacute": // LATIN CAPITAL LETTER U WITH ACUTE + return rune(0xda), true + case "Uarr": // UPWARDS TWO HEADED ARROW + return rune(0x219f), true + case "Uarrocir": // UPWARDS TWO-HEADED ARROW FROM SMALL CIRCLE + return rune(0x2949), true + case "Ubrcy": // CYRILLIC CAPITAL LETTER SHORT U + return rune(0x040e), true + case "Ubreve": // LATIN CAPITAL LETTER U WITH BREVE + return rune(0x016c), true + case "Ucirc": // LATIN CAPITAL LETTER U WITH CIRCUMFLEX + return rune(0xdb), true + case "Ucy": // CYRILLIC CAPITAL LETTER U + return rune(0x0423), true + case "Udblac": // LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + return rune(0x0170), true + case "Udigr": // GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + return rune(0x03ab), true + case "Ufr": // MATHEMATICAL FRAKTUR CAPITAL U + return rune(0x01d518), true + case "Ugr": // GREEK CAPITAL LETTER UPSILON + return rune(0x03a5), true + case "Ugrave": // LATIN CAPITAL LETTER U WITH GRAVE + return rune(0xd9), true + case "Umacr": // LATIN CAPITAL LETTER U WITH MACRON + return rune(0x016a), true + case "UnderBar": // LOW LINE + return rune(0x5f), true + case "UnderBrace": // BOTTOM CURLY BRACKET + return rune(0x23df), true + case "UnderBracket": // BOTTOM SQUARE BRACKET + return rune(0x23b5), true + case "UnderParenthesis": // BOTTOM PARENTHESIS + return rune(0x23dd), true + case "Union": // N-ARY UNION + return rune(0x22c3), true + case "UnionPlus": // MULTISET UNION + return rune(0x228e), true + case "Uogon": // LATIN CAPITAL LETTER U WITH OGONEK + return rune(0x0172), true + case "Uopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL U + return rune(0x01d54c), true + case "UpArrow": // UPWARDS ARROW + return rune(0x2191), true + case "UpArrowBar": // UPWARDS ARROW TO BAR + return rune(0x2912), true + case "UpArrowDownArrow": // UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW + return rune(0x21c5), true + case "UpDownArrow": // UP DOWN ARROW + return rune(0x2195), true + case "UpEquilibrium": // UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT + return rune(0x296e), true + case "UpTee": // UP TACK + return rune(0x22a5), true + case "UpTeeArrow": // UPWARDS ARROW FROM BAR + return rune(0x21a5), true + case "Uparrow": // UPWARDS DOUBLE ARROW + return rune(0x21d1), true + case "Updownarrow": // UP DOWN DOUBLE ARROW + return rune(0x21d5), true + case "UpperLeftArrow": // NORTH WEST ARROW + return rune(0x2196), true + case "UpperRightArrow": // NORTH EAST ARROW + return rune(0x2197), true + case "Upsi": // GREEK UPSILON WITH HOOK SYMBOL + return rune(0x03d2), true + case "Upsilon": // GREEK CAPITAL LETTER UPSILON + return rune(0x03a5), true + case "Uring": // LATIN CAPITAL LETTER U WITH RING ABOVE + return rune(0x016e), true + case "Uscr": // MATHEMATICAL SCRIPT CAPITAL U + return rune(0x01d4b0), true + case "Utilde": // LATIN CAPITAL LETTER U WITH TILDE + return rune(0x0168), true + case "Uuml": // LATIN CAPITAL LETTER U WITH DIAERESIS + return rune(0xdc), true } case 'V': switch name { - case "VDash": // DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE - return rune(0x22ab), true - case "Vbar": // DOUBLE UP TACK - return rune(0x2aeb), true - case "Vcy": // CYRILLIC CAPITAL LETTER VE - return rune(0x0412), true - case "Vdash": // FORCES - return rune(0x22a9), true - case "Vdashl": // LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL - return rune(0x2ae6), true - case "Vee": // N-ARY LOGICAL OR - return rune(0x22c1), true - case "Verbar": // DOUBLE VERTICAL LINE - return rune(0x2016), true - case "Vert": // DOUBLE VERTICAL LINE - return rune(0x2016), true - case "VerticalBar": // DIVIDES - return rune(0x2223), true - case "VerticalLine": // VERTICAL LINE - return rune(0x7c), true - case "VerticalSeparator": // LIGHT VERTICAL BAR - return rune(0x2758), true - case "VerticalTilde": // WREATH PRODUCT - return rune(0x2240), true - case "VeryThinSpace": // HAIR SPACE - return rune(0x200a), true - case "Vfr": // MATHEMATICAL FRAKTUR CAPITAL V - return rune(0x01d519), true - case "Vopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL V - return rune(0x01d54d), true - case "Vscr": // MATHEMATICAL SCRIPT CAPITAL V - return rune(0x01d4b1), true - case "Vvdash": // TRIPLE VERTICAL BAR RIGHT TURNSTILE - return rune(0x22aa), true + case "VDash": // DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE + return rune(0x22ab), true + case "Vbar": // DOUBLE UP TACK + return rune(0x2aeb), true + case "Vcy": // CYRILLIC CAPITAL LETTER VE + return rune(0x0412), true + case "Vdash": // FORCES + return rune(0x22a9), true + case "Vdashl": // LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL + return rune(0x2ae6), true + case "Vee": // N-ARY LOGICAL OR + return rune(0x22c1), true + case "Verbar": // DOUBLE VERTICAL LINE + return rune(0x2016), true + case "Vert": // DOUBLE VERTICAL LINE + return rune(0x2016), true + case "VerticalBar": // DIVIDES + return rune(0x2223), true + case "VerticalLine": // VERTICAL LINE + return rune(0x7c), true + case "VerticalSeparator": // LIGHT VERTICAL BAR + return rune(0x2758), true + case "VerticalTilde": // WREATH PRODUCT + return rune(0x2240), true + case "VeryThinSpace": // HAIR SPACE + return rune(0x200a), true + case "Vfr": // MATHEMATICAL FRAKTUR CAPITAL V + return rune(0x01d519), true + case "Vopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL V + return rune(0x01d54d), true + case "Vscr": // MATHEMATICAL SCRIPT CAPITAL V + return rune(0x01d4b1), true + case "Vvdash": // TRIPLE VERTICAL BAR RIGHT TURNSTILE + return rune(0x22aa), true } case 'W': switch name { - case "Wcirc": // LATIN CAPITAL LETTER W WITH CIRCUMFLEX - return rune(0x0174), true - case "Wedge": // N-ARY LOGICAL AND - return rune(0x22c0), true - case "Wfr": // MATHEMATICAL FRAKTUR CAPITAL W - return rune(0x01d51a), true - case "Wopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL W - return rune(0x01d54e), true - case "Wscr": // MATHEMATICAL SCRIPT CAPITAL W - return rune(0x01d4b2), true + case "Wcirc": // LATIN CAPITAL LETTER W WITH CIRCUMFLEX + return rune(0x0174), true + case "Wedge": // N-ARY LOGICAL AND + return rune(0x22c0), true + case "Wfr": // MATHEMATICAL FRAKTUR CAPITAL W + return rune(0x01d51a), true + case "Wopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL W + return rune(0x01d54e), true + case "Wscr": // MATHEMATICAL SCRIPT CAPITAL W + return rune(0x01d4b2), true } case 'X': switch name { - case "Xfr": // MATHEMATICAL FRAKTUR CAPITAL X - return rune(0x01d51b), true - case "Xgr": // GREEK CAPITAL LETTER XI - return rune(0x039e), true - case "Xi": // GREEK CAPITAL LETTER XI - return rune(0x039e), true - case "Xopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL X - return rune(0x01d54f), true - case "Xscr": // MATHEMATICAL SCRIPT CAPITAL X - return rune(0x01d4b3), true + case "Xfr": // MATHEMATICAL FRAKTUR CAPITAL X + return rune(0x01d51b), true + case "Xgr": // GREEK CAPITAL LETTER XI + return rune(0x039e), true + case "Xi": // GREEK CAPITAL LETTER XI + return rune(0x039e), true + case "Xopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL X + return rune(0x01d54f), true + case "Xscr": // MATHEMATICAL SCRIPT CAPITAL X + return rune(0x01d4b3), true } case 'Y': switch name { - case "YAcy": // CYRILLIC CAPITAL LETTER YA - return rune(0x042f), true - case "YIcy": // CYRILLIC CAPITAL LETTER YI - return rune(0x0407), true - case "YUcy": // CYRILLIC CAPITAL LETTER YU - return rune(0x042e), true - case "Yacute": // LATIN CAPITAL LETTER Y WITH ACUTE - return rune(0xdd), true - case "Ycirc": // LATIN CAPITAL LETTER Y WITH CIRCUMFLEX - return rune(0x0176), true - case "Ycy": // CYRILLIC CAPITAL LETTER YERU - return rune(0x042b), true - case "Yfr": // MATHEMATICAL FRAKTUR CAPITAL Y - return rune(0x01d51c), true - case "Yopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL Y - return rune(0x01d550), true - case "Yscr": // MATHEMATICAL SCRIPT CAPITAL Y - return rune(0x01d4b4), true - case "Yuml": // LATIN CAPITAL LETTER Y WITH DIAERESIS - return rune(0x0178), true + case "YAcy": // CYRILLIC CAPITAL LETTER YA + return rune(0x042f), true + case "YIcy": // CYRILLIC CAPITAL LETTER YI + return rune(0x0407), true + case "YUcy": // CYRILLIC CAPITAL LETTER YU + return rune(0x042e), true + case "Yacute": // LATIN CAPITAL LETTER Y WITH ACUTE + return rune(0xdd), true + case "Ycirc": // LATIN CAPITAL LETTER Y WITH CIRCUMFLEX + return rune(0x0176), true + case "Ycy": // CYRILLIC CAPITAL LETTER YERU + return rune(0x042b), true + case "Yfr": // MATHEMATICAL FRAKTUR CAPITAL Y + return rune(0x01d51c), true + case "Yopf": // MATHEMATICAL DOUBLE-STRUCK CAPITAL Y + return rune(0x01d550), true + case "Yscr": // MATHEMATICAL SCRIPT CAPITAL Y + return rune(0x01d4b4), true + case "Yuml": // LATIN CAPITAL LETTER Y WITH DIAERESIS + return rune(0x0178), true } case 'Z': switch name { - case "ZHcy": // CYRILLIC CAPITAL LETTER ZHE - return rune(0x0416), true - case "Zacute": // LATIN CAPITAL LETTER Z WITH ACUTE - return rune(0x0179), true - case "Zcaron": // LATIN CAPITAL LETTER Z WITH CARON - return rune(0x017d), true - case "Zcy": // CYRILLIC CAPITAL LETTER ZE - return rune(0x0417), true - case "Zdot": // LATIN CAPITAL LETTER Z WITH DOT ABOVE - return rune(0x017b), true - case "ZeroWidthSpace": // ZERO WIDTH SPACE - return rune(0x200b), true - case "Zeta": // GREEK CAPITAL LETTER ZETA - return rune(0x0396), true - case "Zfr": // BLACK-LETTER CAPITAL Z - return rune(0x2128), true - case "Zgr": // GREEK CAPITAL LETTER ZETA - return rune(0x0396), true - case "Zopf": // DOUBLE-STRUCK CAPITAL Z - return rune(0x2124), true - case "Zscr": // MATHEMATICAL SCRIPT CAPITAL Z - return rune(0x01d4b5), true + case "ZHcy": // CYRILLIC CAPITAL LETTER ZHE + return rune(0x0416), true + case "Zacute": // LATIN CAPITAL LETTER Z WITH ACUTE + return rune(0x0179), true + case "Zcaron": // LATIN CAPITAL LETTER Z WITH CARON + return rune(0x017d), true + case "Zcy": // CYRILLIC CAPITAL LETTER ZE + return rune(0x0417), true + case "Zdot": // LATIN CAPITAL LETTER Z WITH DOT ABOVE + return rune(0x017b), true + case "ZeroWidthSpace": // ZERO WIDTH SPACE + return rune(0x200b), true + case "Zeta": // GREEK CAPITAL LETTER ZETA + return rune(0x0396), true + case "Zfr": // BLACK-LETTER CAPITAL Z + return rune(0x2128), true + case "Zgr": // GREEK CAPITAL LETTER ZETA + return rune(0x0396), true + case "Zopf": // DOUBLE-STRUCK CAPITAL Z + return rune(0x2124), true + case "Zscr": // MATHEMATICAL SCRIPT CAPITAL Z + return rune(0x01d4b5), true } case 'a': switch name { - case "aacgr": // GREEK SMALL LETTER ALPHA WITH TONOS - return rune(0x03ac), true - case "aacute": // LATIN SMALL LETTER A WITH ACUTE - return rune(0xe1), true - case "abreve": // LATIN SMALL LETTER A WITH BREVE - return rune(0x0103), true - case "ac": // INVERTED LAZY S - return rune(0x223e), true - case "acE": // INVERTED LAZY S with double underline - return rune(0x223e), true - case "acd": // SINE WAVE - return rune(0x223f), true - case "acirc": // LATIN SMALL LETTER A WITH CIRCUMFLEX - return rune(0xe2), true - case "actuary": // COMBINING ANNUITY SYMBOL - return rune(0x20e7), true - case "acute": // ACUTE ACCENT - return rune(0xb4), true - case "acy": // CYRILLIC SMALL LETTER A - return rune(0x0430), true - case "aelig": // LATIN SMALL LETTER AE - return rune(0xe6), true - case "af": // FUNCTION APPLICATION - return rune(0x2061), true - case "afr": // MATHEMATICAL FRAKTUR SMALL A - return rune(0x01d51e), true - case "agr": // GREEK SMALL LETTER ALPHA - return rune(0x03b1), true - case "agrave": // LATIN SMALL LETTER A WITH GRAVE - return rune(0xe0), true - case "alefsym": // ALEF SYMBOL - return rune(0x2135), true - case "aleph": // ALEF SYMBOL - return rune(0x2135), true - case "alpha": // GREEK SMALL LETTER ALPHA - return rune(0x03b1), true - case "amacr": // LATIN SMALL LETTER A WITH MACRON - return rune(0x0101), true - case "amalg": // AMALGAMATION OR COPRODUCT - return rune(0x2a3f), true - case "amp": // AMPERSAND - return rune(0x26), true - case "and": // LOGICAL AND - return rune(0x2227), true - case "andand": // TWO INTERSECTING LOGICAL AND - return rune(0x2a55), true - case "andd": // LOGICAL AND WITH HORIZONTAL DASH - return rune(0x2a5c), true - case "andslope": // SLOPING LARGE AND - return rune(0x2a58), true - case "andv": // LOGICAL AND WITH MIDDLE STEM - return rune(0x2a5a), true - case "ang": // ANGLE - return rune(0x2220), true - case "ang90": // RIGHT ANGLE - return rune(0x221f), true - case "angdnl": // TURNED ANGLE - return rune(0x29a2), true - case "angdnr": // ACUTE ANGLE - return rune(0x299f), true - case "ange": // ANGLE WITH UNDERBAR - return rune(0x29a4), true - case "angle": // ANGLE - return rune(0x2220), true - case "angles": // ANGLE WITH S INSIDE - return rune(0x299e), true - case "angmsd": // MEASURED ANGLE - return rune(0x2221), true - case "angmsdaa": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT - return rune(0x29a8), true - case "angmsdab": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT - return rune(0x29a9), true - case "angmsdac": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT - return rune(0x29aa), true - case "angmsdad": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT - return rune(0x29ab), true - case "angmsdae": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP - return rune(0x29ac), true - case "angmsdaf": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP - return rune(0x29ad), true - case "angmsdag": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN - return rune(0x29ae), true - case "angmsdah": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN - return rune(0x29af), true - case "angrt": // RIGHT ANGLE - return rune(0x221f), true - case "angrtvb": // RIGHT ANGLE WITH ARC - return rune(0x22be), true - case "angrtvbd": // MEASURED RIGHT ANGLE WITH DOT - return rune(0x299d), true - case "angsph": // SPHERICAL ANGLE - return rune(0x2222), true - case "angst": // LATIN CAPITAL LETTER A WITH RING ABOVE - return rune(0xc5), true - case "angupl": // REVERSED ANGLE - return rune(0x29a3), true - case "angzarr": // RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW - return rune(0x237c), true - case "aogon": // LATIN SMALL LETTER A WITH OGONEK - return rune(0x0105), true - case "aopf": // MATHEMATICAL DOUBLE-STRUCK SMALL A - return rune(0x01d552), true - case "ap": // ALMOST EQUAL TO - return rune(0x2248), true - case "apE": // APPROXIMATELY EQUAL OR EQUAL TO - return rune(0x2a70), true - case "apacir": // ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT - return rune(0x2a6f), true - case "ape": // ALMOST EQUAL OR EQUAL TO - return rune(0x224a), true - case "apid": // TRIPLE TILDE - return rune(0x224b), true - case "apos": // APOSTROPHE - return rune(0x27), true - case "approx": // ALMOST EQUAL TO - return rune(0x2248), true - case "approxeq": // ALMOST EQUAL OR EQUAL TO - return rune(0x224a), true - case "aring": // LATIN SMALL LETTER A WITH RING ABOVE - return rune(0xe5), true - case "arrllsr": // LEFTWARDS ARROW ABOVE SHORT RIGHTWARDS ARROW - return rune(0x2943), true - case "arrlrsl": // RIGHTWARDS ARROW ABOVE SHORT LEFTWARDS ARROW - return rune(0x2942), true - case "arrsrll": // SHORT RIGHTWARDS ARROW ABOVE LEFTWARDS ARROW - return rune(0x2944), true - case "ascr": // MATHEMATICAL SCRIPT SMALL A - return rune(0x01d4b6), true - case "ast": // ASTERISK - return rune(0x2a), true - case "astb": // SQUARED ASTERISK - return rune(0x29c6), true - case "asymp": // ALMOST EQUAL TO - return rune(0x2248), true - case "asympeq": // EQUIVALENT TO - return rune(0x224d), true - case "atilde": // LATIN SMALL LETTER A WITH TILDE - return rune(0xe3), true - case "auml": // LATIN SMALL LETTER A WITH DIAERESIS - return rune(0xe4), true - case "awconint": // ANTICLOCKWISE CONTOUR INTEGRAL - return rune(0x2233), true - case "awint": // ANTICLOCKWISE INTEGRATION - return rune(0x2a11), true + case "aacgr": // GREEK SMALL LETTER ALPHA WITH TONOS + return rune(0x03ac), true + case "aacute": // LATIN SMALL LETTER A WITH ACUTE + return rune(0xe1), true + case "abreve": // LATIN SMALL LETTER A WITH BREVE + return rune(0x0103), true + case "ac": // INVERTED LAZY S + return rune(0x223e), true + case "acE": // INVERTED LAZY S with double underline + return rune(0x223e), true + case "acd": // SINE WAVE + return rune(0x223f), true + case "acirc": // LATIN SMALL LETTER A WITH CIRCUMFLEX + return rune(0xe2), true + case "actuary": // COMBINING ANNUITY SYMBOL + return rune(0x20e7), true + case "acute": // ACUTE ACCENT + return rune(0xb4), true + case "acy": // CYRILLIC SMALL LETTER A + return rune(0x0430), true + case "aelig": // LATIN SMALL LETTER AE + return rune(0xe6), true + case "af": // FUNCTION APPLICATION + return rune(0x2061), true + case "afr": // MATHEMATICAL FRAKTUR SMALL A + return rune(0x01d51e), true + case "agr": // GREEK SMALL LETTER ALPHA + return rune(0x03b1), true + case "agrave": // LATIN SMALL LETTER A WITH GRAVE + return rune(0xe0), true + case "alefsym": // ALEF SYMBOL + return rune(0x2135), true + case "aleph": // ALEF SYMBOL + return rune(0x2135), true + case "alpha": // GREEK SMALL LETTER ALPHA + return rune(0x03b1), true + case "amacr": // LATIN SMALL LETTER A WITH MACRON + return rune(0x0101), true + case "amalg": // AMALGAMATION OR COPRODUCT + return rune(0x2a3f), true + case "amp": // AMPERSAND + return rune(0x26), true + case "and": // LOGICAL AND + return rune(0x2227), true + case "andand": // TWO INTERSECTING LOGICAL AND + return rune(0x2a55), true + case "andd": // LOGICAL AND WITH HORIZONTAL DASH + return rune(0x2a5c), true + case "andslope": // SLOPING LARGE AND + return rune(0x2a58), true + case "andv": // LOGICAL AND WITH MIDDLE STEM + return rune(0x2a5a), true + case "ang": // ANGLE + return rune(0x2220), true + case "ang90": // RIGHT ANGLE + return rune(0x221f), true + case "angdnl": // TURNED ANGLE + return rune(0x29a2), true + case "angdnr": // ACUTE ANGLE + return rune(0x299f), true + case "ange": // ANGLE WITH UNDERBAR + return rune(0x29a4), true + case "angle": // ANGLE + return rune(0x2220), true + case "angles": // ANGLE WITH S INSIDE + return rune(0x299e), true + case "angmsd": // MEASURED ANGLE + return rune(0x2221), true + case "angmsdaa": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT + return rune(0x29a8), true + case "angmsdab": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT + return rune(0x29a9), true + case "angmsdac": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT + return rune(0x29aa), true + case "angmsdad": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT + return rune(0x29ab), true + case "angmsdae": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP + return rune(0x29ac), true + case "angmsdaf": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP + return rune(0x29ad), true + case "angmsdag": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN + return rune(0x29ae), true + case "angmsdah": // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN + return rune(0x29af), true + case "angrt": // RIGHT ANGLE + return rune(0x221f), true + case "angrtvb": // RIGHT ANGLE WITH ARC + return rune(0x22be), true + case "angrtvbd": // MEASURED RIGHT ANGLE WITH DOT + return rune(0x299d), true + case "angsph": // SPHERICAL ANGLE + return rune(0x2222), true + case "angst": // LATIN CAPITAL LETTER A WITH RING ABOVE + return rune(0xc5), true + case "angupl": // REVERSED ANGLE + return rune(0x29a3), true + case "angzarr": // RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW + return rune(0x237c), true + case "aogon": // LATIN SMALL LETTER A WITH OGONEK + return rune(0x0105), true + case "aopf": // MATHEMATICAL DOUBLE-STRUCK SMALL A + return rune(0x01d552), true + case "ap": // ALMOST EQUAL TO + return rune(0x2248), true + case "apE": // APPROXIMATELY EQUAL OR EQUAL TO + return rune(0x2a70), true + case "apacir": // ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT + return rune(0x2a6f), true + case "ape": // ALMOST EQUAL OR EQUAL TO + return rune(0x224a), true + case "apid": // TRIPLE TILDE + return rune(0x224b), true + case "apos": // APOSTROPHE + return rune(0x27), true + case "approx": // ALMOST EQUAL TO + return rune(0x2248), true + case "approxeq": // ALMOST EQUAL OR EQUAL TO + return rune(0x224a), true + case "aring": // LATIN SMALL LETTER A WITH RING ABOVE + return rune(0xe5), true + case "arrllsr": // LEFTWARDS ARROW ABOVE SHORT RIGHTWARDS ARROW + return rune(0x2943), true + case "arrlrsl": // RIGHTWARDS ARROW ABOVE SHORT LEFTWARDS ARROW + return rune(0x2942), true + case "arrsrll": // SHORT RIGHTWARDS ARROW ABOVE LEFTWARDS ARROW + return rune(0x2944), true + case "ascr": // MATHEMATICAL SCRIPT SMALL A + return rune(0x01d4b6), true + case "ast": // ASTERISK + return rune(0x2a), true + case "astb": // SQUARED ASTERISK + return rune(0x29c6), true + case "asymp": // ALMOST EQUAL TO + return rune(0x2248), true + case "asympeq": // EQUIVALENT TO + return rune(0x224d), true + case "atilde": // LATIN SMALL LETTER A WITH TILDE + return rune(0xe3), true + case "auml": // LATIN SMALL LETTER A WITH DIAERESIS + return rune(0xe4), true + case "awconint": // ANTICLOCKWISE CONTOUR INTEGRAL + return rune(0x2233), true + case "awint": // ANTICLOCKWISE INTEGRATION + return rune(0x2a11), true } case 'b': switch name { - case "b.Delta": // MATHEMATICAL BOLD CAPITAL DELTA - return rune(0x01d6ab), true - case "b.Gamma": // MATHEMATICAL BOLD CAPITAL GAMMA - return rune(0x01d6aa), true - case "b.Gammad": // MATHEMATICAL BOLD CAPITAL DIGAMMA - return rune(0x01d7ca), true - case "b.Lambda": // MATHEMATICAL BOLD CAPITAL LAMDA - return rune(0x01d6b2), true - case "b.Omega": // MATHEMATICAL BOLD CAPITAL OMEGA - return rune(0x01d6c0), true - case "b.Phi": // MATHEMATICAL BOLD CAPITAL PHI - return rune(0x01d6bd), true - case "b.Pi": // MATHEMATICAL BOLD CAPITAL PI - return rune(0x01d6b7), true - case "b.Psi": // MATHEMATICAL BOLD CAPITAL PSI - return rune(0x01d6bf), true - case "b.Sigma": // MATHEMATICAL BOLD CAPITAL SIGMA - return rune(0x01d6ba), true - case "b.Theta": // MATHEMATICAL BOLD CAPITAL THETA - return rune(0x01d6af), true - case "b.Upsi": // MATHEMATICAL BOLD CAPITAL UPSILON - return rune(0x01d6bc), true - case "b.Xi": // MATHEMATICAL BOLD CAPITAL XI - return rune(0x01d6b5), true - case "b.alpha": // MATHEMATICAL BOLD SMALL ALPHA - return rune(0x01d6c2), true - case "b.beta": // MATHEMATICAL BOLD SMALL BETA - return rune(0x01d6c3), true - case "b.chi": // MATHEMATICAL BOLD SMALL CHI - return rune(0x01d6d8), true - case "b.delta": // MATHEMATICAL BOLD SMALL DELTA - return rune(0x01d6c5), true - case "b.epsi": // MATHEMATICAL BOLD SMALL EPSILON - return rune(0x01d6c6), true - case "b.epsiv": // MATHEMATICAL BOLD EPSILON SYMBOL - return rune(0x01d6dc), true - case "b.eta": // MATHEMATICAL BOLD SMALL ETA - return rune(0x01d6c8), true - case "b.gamma": // MATHEMATICAL BOLD SMALL GAMMA - return rune(0x01d6c4), true - case "b.gammad": // MATHEMATICAL BOLD SMALL DIGAMMA - return rune(0x01d7cb), true - case "b.iota": // MATHEMATICAL BOLD SMALL IOTA - return rune(0x01d6ca), true - case "b.kappa": // MATHEMATICAL BOLD SMALL KAPPA - return rune(0x01d6cb), true - case "b.kappav": // MATHEMATICAL BOLD KAPPA SYMBOL - return rune(0x01d6de), true - case "b.lambda": // MATHEMATICAL BOLD SMALL LAMDA - return rune(0x01d6cc), true - case "b.mu": // MATHEMATICAL BOLD SMALL MU - return rune(0x01d6cd), true - case "b.nu": // MATHEMATICAL BOLD SMALL NU - return rune(0x01d6ce), true - case "b.omega": // MATHEMATICAL BOLD SMALL OMEGA - return rune(0x01d6da), true - case "b.phi": // MATHEMATICAL BOLD SMALL PHI - return rune(0x01d6d7), true - case "b.phiv": // MATHEMATICAL BOLD PHI SYMBOL - return rune(0x01d6df), true - case "b.pi": // MATHEMATICAL BOLD SMALL PI - return rune(0x01d6d1), true - case "b.piv": // MATHEMATICAL BOLD PI SYMBOL - return rune(0x01d6e1), true - case "b.psi": // MATHEMATICAL BOLD SMALL PSI - return rune(0x01d6d9), true - case "b.rho": // MATHEMATICAL BOLD SMALL RHO - return rune(0x01d6d2), true - case "b.rhov": // MATHEMATICAL BOLD RHO SYMBOL - return rune(0x01d6e0), true - case "b.sigma": // MATHEMATICAL BOLD SMALL SIGMA - return rune(0x01d6d4), true - case "b.sigmav": // MATHEMATICAL BOLD SMALL FINAL SIGMA - return rune(0x01d6d3), true - case "b.tau": // MATHEMATICAL BOLD SMALL TAU - return rune(0x01d6d5), true - case "b.thetas": // MATHEMATICAL BOLD SMALL THETA - return rune(0x01d6c9), true - case "b.thetav": // MATHEMATICAL BOLD THETA SYMBOL - return rune(0x01d6dd), true - case "b.upsi": // MATHEMATICAL BOLD SMALL UPSILON - return rune(0x01d6d6), true - case "b.xi": // MATHEMATICAL BOLD SMALL XI - return rune(0x01d6cf), true - case "b.zeta": // MATHEMATICAL BOLD SMALL ZETA - return rune(0x01d6c7), true - case "bNot": // REVERSED DOUBLE STROKE NOT SIGN - return rune(0x2aed), true - case "backcong": // ALL EQUAL TO - return rune(0x224c), true - case "backepsilon": // GREEK REVERSED LUNATE EPSILON SYMBOL - return rune(0x03f6), true - case "backprime": // REVERSED PRIME - return rune(0x2035), true - case "backsim": // REVERSED TILDE - return rune(0x223d), true - case "backsimeq": // REVERSED TILDE EQUALS - return rune(0x22cd), true - case "barV": // DOUBLE DOWN TACK - return rune(0x2aea), true - case "barvee": // NOR - return rune(0x22bd), true - case "barwed": // PROJECTIVE - return rune(0x2305), true - case "barwedge": // PROJECTIVE - return rune(0x2305), true - case "bbrk": // BOTTOM SQUARE BRACKET - return rune(0x23b5), true - case "bbrktbrk": // BOTTOM SQUARE BRACKET OVER TOP SQUARE BRACKET - return rune(0x23b6), true - case "bcong": // ALL EQUAL TO - return rune(0x224c), true - case "bcy": // CYRILLIC SMALL LETTER BE - return rune(0x0431), true - case "bdlhar": // DOWNWARDS HARPOON WITH BARB LEFT FROM BAR - return rune(0x2961), true - case "bdquo": // DOUBLE LOW-9 QUOTATION MARK - return rune(0x201e), true - case "bdrhar": // DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR - return rune(0x295d), true - case "becaus": // BECAUSE - return rune(0x2235), true - case "because": // BECAUSE - return rune(0x2235), true - case "bemptyv": // REVERSED EMPTY SET - return rune(0x29b0), true - case "bepsi": // GREEK REVERSED LUNATE EPSILON SYMBOL - return rune(0x03f6), true - case "bernou": // SCRIPT CAPITAL B - return rune(0x212c), true - case "beta": // GREEK SMALL LETTER BETA - return rune(0x03b2), true - case "beth": // BET SYMBOL - return rune(0x2136), true - case "between": // BETWEEN - return rune(0x226c), true - case "bfr": // MATHEMATICAL FRAKTUR SMALL B - return rune(0x01d51f), true - case "bgr": // GREEK SMALL LETTER BETA - return rune(0x03b2), true - case "bigcap": // N-ARY INTERSECTION - return rune(0x22c2), true - case "bigcirc": // LARGE CIRCLE - return rune(0x25ef), true - case "bigcup": // N-ARY UNION - return rune(0x22c3), true - case "bigodot": // N-ARY CIRCLED DOT OPERATOR - return rune(0x2a00), true - case "bigoplus": // N-ARY CIRCLED PLUS OPERATOR - return rune(0x2a01), true - case "bigotimes": // N-ARY CIRCLED TIMES OPERATOR - return rune(0x2a02), true - case "bigsqcup": // N-ARY SQUARE UNION OPERATOR - return rune(0x2a06), true - case "bigstar": // BLACK STAR - return rune(0x2605), true - case "bigtriangledown": // WHITE DOWN-POINTING TRIANGLE - return rune(0x25bd), true - case "bigtriangleup": // WHITE UP-POINTING TRIANGLE - return rune(0x25b3), true - case "biguplus": // N-ARY UNION OPERATOR WITH PLUS - return rune(0x2a04), true - case "bigvee": // N-ARY LOGICAL OR - return rune(0x22c1), true - case "bigwedge": // N-ARY LOGICAL AND - return rune(0x22c0), true - case "bkarow": // RIGHTWARDS DOUBLE DASH ARROW - return rune(0x290d), true - case "blacklozenge": // BLACK LOZENGE - return rune(0x29eb), true - case "blacksquare": // BLACK SMALL SQUARE - return rune(0x25aa), true - case "blacktriangle": // BLACK UP-POINTING SMALL TRIANGLE - return rune(0x25b4), true - case "blacktriangledown": // BLACK DOWN-POINTING SMALL TRIANGLE - return rune(0x25be), true - case "blacktriangleleft": // BLACK LEFT-POINTING SMALL TRIANGLE - return rune(0x25c2), true - case "blacktriangleright": // BLACK RIGHT-POINTING SMALL TRIANGLE - return rune(0x25b8), true - case "blank": // BLANK SYMBOL - return rune(0x2422), true - case "bldhar": // LEFTWARDS HARPOON WITH BARB DOWN FROM BAR - return rune(0x295e), true - case "blk12": // MEDIUM SHADE - return rune(0x2592), true - case "blk14": // LIGHT SHADE - return rune(0x2591), true - case "blk34": // DARK SHADE - return rune(0x2593), true - case "block": // FULL BLOCK - return rune(0x2588), true - case "bluhar": // LEFTWARDS HARPOON WITH BARB UP FROM BAR - return rune(0x295a), true - case "bne": // EQUALS SIGN with reverse slash - return rune(0x3d), true - case "bnequiv": // IDENTICAL TO with reverse slash - return rune(0x2261), true - case "bnot": // REVERSED NOT SIGN - return rune(0x2310), true - case "bopf": // MATHEMATICAL DOUBLE-STRUCK SMALL B - return rune(0x01d553), true - case "bot": // UP TACK - return rune(0x22a5), true - case "bottom": // UP TACK - return rune(0x22a5), true - case "bowtie": // BOWTIE - return rune(0x22c8), true - case "boxDL": // BOX DRAWINGS DOUBLE DOWN AND LEFT - return rune(0x2557), true - case "boxDR": // BOX DRAWINGS DOUBLE DOWN AND RIGHT - return rune(0x2554), true - case "boxDl": // BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE - return rune(0x2556), true - case "boxDr": // BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE - return rune(0x2553), true - case "boxH": // BOX DRAWINGS DOUBLE HORIZONTAL - return rune(0x2550), true - case "boxHD": // BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL - return rune(0x2566), true - case "boxHU": // BOX DRAWINGS DOUBLE UP AND HORIZONTAL - return rune(0x2569), true - case "boxHd": // BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE - return rune(0x2564), true - case "boxHu": // BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE - return rune(0x2567), true - case "boxUL": // BOX DRAWINGS DOUBLE UP AND LEFT - return rune(0x255d), true - case "boxUR": // BOX DRAWINGS DOUBLE UP AND RIGHT - return rune(0x255a), true - case "boxUl": // BOX DRAWINGS UP DOUBLE AND LEFT SINGLE - return rune(0x255c), true - case "boxUr": // BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE - return rune(0x2559), true - case "boxV": // BOX DRAWINGS DOUBLE VERTICAL - return rune(0x2551), true - case "boxVH": // BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL - return rune(0x256c), true - case "boxVL": // BOX DRAWINGS DOUBLE VERTICAL AND LEFT - return rune(0x2563), true - case "boxVR": // BOX DRAWINGS DOUBLE VERTICAL AND RIGHT - return rune(0x2560), true - case "boxVh": // BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE - return rune(0x256b), true - case "boxVl": // BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE - return rune(0x2562), true - case "boxVr": // BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE - return rune(0x255f), true - case "boxbox": // TWO JOINED SQUARES - return rune(0x29c9), true - case "boxdL": // BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE - return rune(0x2555), true - case "boxdR": // BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE - return rune(0x2552), true - case "boxdl": // BOX DRAWINGS LIGHT DOWN AND LEFT - return rune(0x2510), true - case "boxdr": // BOX DRAWINGS LIGHT DOWN AND RIGHT - return rune(0x250c), true - case "boxh": // BOX DRAWINGS LIGHT HORIZONTAL - return rune(0x2500), true - case "boxhD": // BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE - return rune(0x2565), true - case "boxhU": // BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE - return rune(0x2568), true - case "boxhd": // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL - return rune(0x252c), true - case "boxhu": // BOX DRAWINGS LIGHT UP AND HORIZONTAL - return rune(0x2534), true - case "boxminus": // SQUARED MINUS - return rune(0x229f), true - case "boxplus": // SQUARED PLUS - return rune(0x229e), true - case "boxtimes": // SQUARED TIMES - return rune(0x22a0), true - case "boxuL": // BOX DRAWINGS UP SINGLE AND LEFT DOUBLE - return rune(0x255b), true - case "boxuR": // BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE - return rune(0x2558), true - case "boxul": // BOX DRAWINGS LIGHT UP AND LEFT - return rune(0x2518), true - case "boxur": // BOX DRAWINGS LIGHT UP AND RIGHT - return rune(0x2514), true - case "boxv": // BOX DRAWINGS LIGHT VERTICAL - return rune(0x2502), true - case "boxvH": // BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE - return rune(0x256a), true - case "boxvL": // BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE - return rune(0x2561), true - case "boxvR": // BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE - return rune(0x255e), true - case "boxvh": // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL - return rune(0x253c), true - case "boxvl": // BOX DRAWINGS LIGHT VERTICAL AND LEFT - return rune(0x2524), true - case "boxvr": // BOX DRAWINGS LIGHT VERTICAL AND RIGHT - return rune(0x251c), true - case "bprime": // REVERSED PRIME - return rune(0x2035), true - case "brdhar": // RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR - return rune(0x295f), true - case "breve": // BREVE - return rune(0x02d8), true - case "bruhar": // RIGHTWARDS HARPOON WITH BARB UP FROM BAR - return rune(0x295b), true - case "brvbar": // BROKEN BAR - return rune(0xa6), true - case "bscr": // MATHEMATICAL SCRIPT SMALL B - return rune(0x01d4b7), true - case "bsemi": // REVERSED SEMICOLON - return rune(0x204f), true - case "bsim": // REVERSED TILDE - return rune(0x223d), true - case "bsime": // REVERSED TILDE EQUALS - return rune(0x22cd), true - case "bsol": // REVERSE SOLIDUS - return rune(0x5c), true - case "bsolb": // SQUARED FALLING DIAGONAL SLASH - return rune(0x29c5), true - case "bsolhsub": // REVERSE SOLIDUS PRECEDING SUBSET - return rune(0x27c8), true - case "btimes": // SEMIDIRECT PRODUCT WITH BOTTOM CLOSED - return rune(0x2a32), true - case "bulhar": // UPWARDS HARPOON WITH BARB LEFT FROM BAR - return rune(0x2960), true - case "bull": // BULLET - return rune(0x2022), true - case "bullet": // BULLET - return rune(0x2022), true - case "bump": // GEOMETRICALLY EQUIVALENT TO - return rune(0x224e), true - case "bumpE": // EQUALS SIGN WITH BUMPY ABOVE - return rune(0x2aae), true - case "bumpe": // DIFFERENCE BETWEEN - return rune(0x224f), true - case "bumpeq": // DIFFERENCE BETWEEN - return rune(0x224f), true - case "burhar": // UPWARDS HARPOON WITH BARB RIGHT FROM BAR - return rune(0x295c), true + case "b.Delta": // MATHEMATICAL BOLD CAPITAL DELTA + return rune(0x01d6ab), true + case "b.Gamma": // MATHEMATICAL BOLD CAPITAL GAMMA + return rune(0x01d6aa), true + case "b.Gammad": // MATHEMATICAL BOLD CAPITAL DIGAMMA + return rune(0x01d7ca), true + case "b.Lambda": // MATHEMATICAL BOLD CAPITAL LAMDA + return rune(0x01d6b2), true + case "b.Omega": // MATHEMATICAL BOLD CAPITAL OMEGA + return rune(0x01d6c0), true + case "b.Phi": // MATHEMATICAL BOLD CAPITAL PHI + return rune(0x01d6bd), true + case "b.Pi": // MATHEMATICAL BOLD CAPITAL PI + return rune(0x01d6b7), true + case "b.Psi": // MATHEMATICAL BOLD CAPITAL PSI + return rune(0x01d6bf), true + case "b.Sigma": // MATHEMATICAL BOLD CAPITAL SIGMA + return rune(0x01d6ba), true + case "b.Theta": // MATHEMATICAL BOLD CAPITAL THETA + return rune(0x01d6af), true + case "b.Upsi": // MATHEMATICAL BOLD CAPITAL UPSILON + return rune(0x01d6bc), true + case "b.Xi": // MATHEMATICAL BOLD CAPITAL XI + return rune(0x01d6b5), true + case "b.alpha": // MATHEMATICAL BOLD SMALL ALPHA + return rune(0x01d6c2), true + case "b.beta": // MATHEMATICAL BOLD SMALL BETA + return rune(0x01d6c3), true + case "b.chi": // MATHEMATICAL BOLD SMALL CHI + return rune(0x01d6d8), true + case "b.delta": // MATHEMATICAL BOLD SMALL DELTA + return rune(0x01d6c5), true + case "b.epsi": // MATHEMATICAL BOLD SMALL EPSILON + return rune(0x01d6c6), true + case "b.epsiv": // MATHEMATICAL BOLD EPSILON SYMBOL + return rune(0x01d6dc), true + case "b.eta": // MATHEMATICAL BOLD SMALL ETA + return rune(0x01d6c8), true + case "b.gamma": // MATHEMATICAL BOLD SMALL GAMMA + return rune(0x01d6c4), true + case "b.gammad": // MATHEMATICAL BOLD SMALL DIGAMMA + return rune(0x01d7cb), true + case "b.iota": // MATHEMATICAL BOLD SMALL IOTA + return rune(0x01d6ca), true + case "b.kappa": // MATHEMATICAL BOLD SMALL KAPPA + return rune(0x01d6cb), true + case "b.kappav": // MATHEMATICAL BOLD KAPPA SYMBOL + return rune(0x01d6de), true + case "b.lambda": // MATHEMATICAL BOLD SMALL LAMDA + return rune(0x01d6cc), true + case "b.mu": // MATHEMATICAL BOLD SMALL MU + return rune(0x01d6cd), true + case "b.nu": // MATHEMATICAL BOLD SMALL NU + return rune(0x01d6ce), true + case "b.omega": // MATHEMATICAL BOLD SMALL OMEGA + return rune(0x01d6da), true + case "b.phi": // MATHEMATICAL BOLD SMALL PHI + return rune(0x01d6d7), true + case "b.phiv": // MATHEMATICAL BOLD PHI SYMBOL + return rune(0x01d6df), true + case "b.pi": // MATHEMATICAL BOLD SMALL PI + return rune(0x01d6d1), true + case "b.piv": // MATHEMATICAL BOLD PI SYMBOL + return rune(0x01d6e1), true + case "b.psi": // MATHEMATICAL BOLD SMALL PSI + return rune(0x01d6d9), true + case "b.rho": // MATHEMATICAL BOLD SMALL RHO + return rune(0x01d6d2), true + case "b.rhov": // MATHEMATICAL BOLD RHO SYMBOL + return rune(0x01d6e0), true + case "b.sigma": // MATHEMATICAL BOLD SMALL SIGMA + return rune(0x01d6d4), true + case "b.sigmav": // MATHEMATICAL BOLD SMALL FINAL SIGMA + return rune(0x01d6d3), true + case "b.tau": // MATHEMATICAL BOLD SMALL TAU + return rune(0x01d6d5), true + case "b.thetas": // MATHEMATICAL BOLD SMALL THETA + return rune(0x01d6c9), true + case "b.thetav": // MATHEMATICAL BOLD THETA SYMBOL + return rune(0x01d6dd), true + case "b.upsi": // MATHEMATICAL BOLD SMALL UPSILON + return rune(0x01d6d6), true + case "b.xi": // MATHEMATICAL BOLD SMALL XI + return rune(0x01d6cf), true + case "b.zeta": // MATHEMATICAL BOLD SMALL ZETA + return rune(0x01d6c7), true + case "bNot": // REVERSED DOUBLE STROKE NOT SIGN + return rune(0x2aed), true + case "backcong": // ALL EQUAL TO + return rune(0x224c), true + case "backepsilon": // GREEK REVERSED LUNATE EPSILON SYMBOL + return rune(0x03f6), true + case "backprime": // REVERSED PRIME + return rune(0x2035), true + case "backsim": // REVERSED TILDE + return rune(0x223d), true + case "backsimeq": // REVERSED TILDE EQUALS + return rune(0x22cd), true + case "barV": // DOUBLE DOWN TACK + return rune(0x2aea), true + case "barvee": // NOR + return rune(0x22bd), true + case "barwed": // PROJECTIVE + return rune(0x2305), true + case "barwedge": // PROJECTIVE + return rune(0x2305), true + case "bbrk": // BOTTOM SQUARE BRACKET + return rune(0x23b5), true + case "bbrktbrk": // BOTTOM SQUARE BRACKET OVER TOP SQUARE BRACKET + return rune(0x23b6), true + case "bcong": // ALL EQUAL TO + return rune(0x224c), true + case "bcy": // CYRILLIC SMALL LETTER BE + return rune(0x0431), true + case "bdlhar": // DOWNWARDS HARPOON WITH BARB LEFT FROM BAR + return rune(0x2961), true + case "bdquo": // DOUBLE LOW-9 QUOTATION MARK + return rune(0x201e), true + case "bdrhar": // DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR + return rune(0x295d), true + case "becaus": // BECAUSE + return rune(0x2235), true + case "because": // BECAUSE + return rune(0x2235), true + case "bemptyv": // REVERSED EMPTY SET + return rune(0x29b0), true + case "bepsi": // GREEK REVERSED LUNATE EPSILON SYMBOL + return rune(0x03f6), true + case "bernou": // SCRIPT CAPITAL B + return rune(0x212c), true + case "beta": // GREEK SMALL LETTER BETA + return rune(0x03b2), true + case "beth": // BET SYMBOL + return rune(0x2136), true + case "between": // BETWEEN + return rune(0x226c), true + case "bfr": // MATHEMATICAL FRAKTUR SMALL B + return rune(0x01d51f), true + case "bgr": // GREEK SMALL LETTER BETA + return rune(0x03b2), true + case "bigcap": // N-ARY INTERSECTION + return rune(0x22c2), true + case "bigcirc": // LARGE CIRCLE + return rune(0x25ef), true + case "bigcup": // N-ARY UNION + return rune(0x22c3), true + case "bigodot": // N-ARY CIRCLED DOT OPERATOR + return rune(0x2a00), true + case "bigoplus": // N-ARY CIRCLED PLUS OPERATOR + return rune(0x2a01), true + case "bigotimes": // N-ARY CIRCLED TIMES OPERATOR + return rune(0x2a02), true + case "bigsqcup": // N-ARY SQUARE UNION OPERATOR + return rune(0x2a06), true + case "bigstar": // BLACK STAR + return rune(0x2605), true + case "bigtriangledown": // WHITE DOWN-POINTING TRIANGLE + return rune(0x25bd), true + case "bigtriangleup": // WHITE UP-POINTING TRIANGLE + return rune(0x25b3), true + case "biguplus": // N-ARY UNION OPERATOR WITH PLUS + return rune(0x2a04), true + case "bigvee": // N-ARY LOGICAL OR + return rune(0x22c1), true + case "bigwedge": // N-ARY LOGICAL AND + return rune(0x22c0), true + case "bkarow": // RIGHTWARDS DOUBLE DASH ARROW + return rune(0x290d), true + case "blacklozenge": // BLACK LOZENGE + return rune(0x29eb), true + case "blacksquare": // BLACK SMALL SQUARE + return rune(0x25aa), true + case "blacktriangle": // BLACK UP-POINTING SMALL TRIANGLE + return rune(0x25b4), true + case "blacktriangledown": // BLACK DOWN-POINTING SMALL TRIANGLE + return rune(0x25be), true + case "blacktriangleleft": // BLACK LEFT-POINTING SMALL TRIANGLE + return rune(0x25c2), true + case "blacktriangleright": // BLACK RIGHT-POINTING SMALL TRIANGLE + return rune(0x25b8), true + case "blank": // BLANK SYMBOL + return rune(0x2422), true + case "bldhar": // LEFTWARDS HARPOON WITH BARB DOWN FROM BAR + return rune(0x295e), true + case "blk12": // MEDIUM SHADE + return rune(0x2592), true + case "blk14": // LIGHT SHADE + return rune(0x2591), true + case "blk34": // DARK SHADE + return rune(0x2593), true + case "block": // FULL BLOCK + return rune(0x2588), true + case "bluhar": // LEFTWARDS HARPOON WITH BARB UP FROM BAR + return rune(0x295a), true + case "bne": // EQUALS SIGN with reverse slash + return rune(0x3d), true + case "bnequiv": // IDENTICAL TO with reverse slash + return rune(0x2261), true + case "bnot": // REVERSED NOT SIGN + return rune(0x2310), true + case "bopf": // MATHEMATICAL DOUBLE-STRUCK SMALL B + return rune(0x01d553), true + case "bot": // UP TACK + return rune(0x22a5), true + case "bottom": // UP TACK + return rune(0x22a5), true + case "bowtie": // BOWTIE + return rune(0x22c8), true + case "boxDL": // BOX DRAWINGS DOUBLE DOWN AND LEFT + return rune(0x2557), true + case "boxDR": // BOX DRAWINGS DOUBLE DOWN AND RIGHT + return rune(0x2554), true + case "boxDl": // BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + return rune(0x2556), true + case "boxDr": // BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + return rune(0x2553), true + case "boxH": // BOX DRAWINGS DOUBLE HORIZONTAL + return rune(0x2550), true + case "boxHD": // BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + return rune(0x2566), true + case "boxHU": // BOX DRAWINGS DOUBLE UP AND HORIZONTAL + return rune(0x2569), true + case "boxHd": // BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + return rune(0x2564), true + case "boxHu": // BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + return rune(0x2567), true + case "boxUL": // BOX DRAWINGS DOUBLE UP AND LEFT + return rune(0x255d), true + case "boxUR": // BOX DRAWINGS DOUBLE UP AND RIGHT + return rune(0x255a), true + case "boxUl": // BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + return rune(0x255c), true + case "boxUr": // BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + return rune(0x2559), true + case "boxV": // BOX DRAWINGS DOUBLE VERTICAL + return rune(0x2551), true + case "boxVH": // BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + return rune(0x256c), true + case "boxVL": // BOX DRAWINGS DOUBLE VERTICAL AND LEFT + return rune(0x2563), true + case "boxVR": // BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + return rune(0x2560), true + case "boxVh": // BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + return rune(0x256b), true + case "boxVl": // BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + return rune(0x2562), true + case "boxVr": // BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + return rune(0x255f), true + case "boxbox": // TWO JOINED SQUARES + return rune(0x29c9), true + case "boxdL": // BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + return rune(0x2555), true + case "boxdR": // BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + return rune(0x2552), true + case "boxdl": // BOX DRAWINGS LIGHT DOWN AND LEFT + return rune(0x2510), true + case "boxdr": // BOX DRAWINGS LIGHT DOWN AND RIGHT + return rune(0x250c), true + case "boxh": // BOX DRAWINGS LIGHT HORIZONTAL + return rune(0x2500), true + case "boxhD": // BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + return rune(0x2565), true + case "boxhU": // BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + return rune(0x2568), true + case "boxhd": // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + return rune(0x252c), true + case "boxhu": // BOX DRAWINGS LIGHT UP AND HORIZONTAL + return rune(0x2534), true + case "boxminus": // SQUARED MINUS + return rune(0x229f), true + case "boxplus": // SQUARED PLUS + return rune(0x229e), true + case "boxtimes": // SQUARED TIMES + return rune(0x22a0), true + case "boxuL": // BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + return rune(0x255b), true + case "boxuR": // BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + return rune(0x2558), true + case "boxul": // BOX DRAWINGS LIGHT UP AND LEFT + return rune(0x2518), true + case "boxur": // BOX DRAWINGS LIGHT UP AND RIGHT + return rune(0x2514), true + case "boxv": // BOX DRAWINGS LIGHT VERTICAL + return rune(0x2502), true + case "boxvH": // BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + return rune(0x256a), true + case "boxvL": // BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + return rune(0x2561), true + case "boxvR": // BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + return rune(0x255e), true + case "boxvh": // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + return rune(0x253c), true + case "boxvl": // BOX DRAWINGS LIGHT VERTICAL AND LEFT + return rune(0x2524), true + case "boxvr": // BOX DRAWINGS LIGHT VERTICAL AND RIGHT + return rune(0x251c), true + case "bprime": // REVERSED PRIME + return rune(0x2035), true + case "brdhar": // RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR + return rune(0x295f), true + case "breve": // BREVE + return rune(0x02d8), true + case "bruhar": // RIGHTWARDS HARPOON WITH BARB UP FROM BAR + return rune(0x295b), true + case "brvbar": // BROKEN BAR + return rune(0xa6), true + case "bscr": // MATHEMATICAL SCRIPT SMALL B + return rune(0x01d4b7), true + case "bsemi": // REVERSED SEMICOLON + return rune(0x204f), true + case "bsim": // REVERSED TILDE + return rune(0x223d), true + case "bsime": // REVERSED TILDE EQUALS + return rune(0x22cd), true + case "bsol": // REVERSE SOLIDUS + return rune(0x5c), true + case "bsolb": // SQUARED FALLING DIAGONAL SLASH + return rune(0x29c5), true + case "bsolhsub": // REVERSE SOLIDUS PRECEDING SUBSET + return rune(0x27c8), true + case "btimes": // SEMIDIRECT PRODUCT WITH BOTTOM CLOSED + return rune(0x2a32), true + case "bulhar": // UPWARDS HARPOON WITH BARB LEFT FROM BAR + return rune(0x2960), true + case "bull": // BULLET + return rune(0x2022), true + case "bullet": // BULLET + return rune(0x2022), true + case "bump": // GEOMETRICALLY EQUIVALENT TO + return rune(0x224e), true + case "bumpE": // EQUALS SIGN WITH BUMPY ABOVE + return rune(0x2aae), true + case "bumpe": // DIFFERENCE BETWEEN + return rune(0x224f), true + case "bumpeq": // DIFFERENCE BETWEEN + return rune(0x224f), true + case "burhar": // UPWARDS HARPOON WITH BARB RIGHT FROM BAR + return rune(0x295c), true } case 'c': switch name { - case "cacute": // LATIN SMALL LETTER C WITH ACUTE - return rune(0x0107), true - case "cap": // INTERSECTION - return rune(0x2229), true - case "capand": // INTERSECTION WITH LOGICAL AND - return rune(0x2a44), true - case "capbrcup": // INTERSECTION ABOVE BAR ABOVE UNION - return rune(0x2a49), true - case "capcap": // INTERSECTION BESIDE AND JOINED WITH INTERSECTION - return rune(0x2a4b), true - case "capcup": // INTERSECTION ABOVE UNION - return rune(0x2a47), true - case "capdot": // INTERSECTION WITH DOT - return rune(0x2a40), true - case "capint": // INTEGRAL WITH INTERSECTION - return rune(0x2a19), true - case "caps": // INTERSECTION with serifs - return rune(0x2229), true - case "caret": // CARET INSERTION POINT - return rune(0x2041), true - case "caron": // CARON - return rune(0x02c7), true - case "ccaps": // CLOSED INTERSECTION WITH SERIFS - return rune(0x2a4d), true - case "ccaron": // LATIN SMALL LETTER C WITH CARON - return rune(0x010d), true - case "ccedil": // LATIN SMALL LETTER C WITH CEDILLA - return rune(0xe7), true - case "ccirc": // LATIN SMALL LETTER C WITH CIRCUMFLEX - return rune(0x0109), true - case "ccups": // CLOSED UNION WITH SERIFS - return rune(0x2a4c), true - case "ccupssm": // CLOSED UNION WITH SERIFS AND SMASH PRODUCT - return rune(0x2a50), true - case "cdot": // LATIN SMALL LETTER C WITH DOT ABOVE - return rune(0x010b), true - case "cedil": // CEDILLA - return rune(0xb8), true - case "cemptyv": // EMPTY SET WITH SMALL CIRCLE ABOVE - return rune(0x29b2), true - case "cent": // CENT SIGN - return rune(0xa2), true - case "centerdot": // MIDDLE DOT - return rune(0xb7), true - case "cfr": // MATHEMATICAL FRAKTUR SMALL C - return rune(0x01d520), true - case "chcy": // CYRILLIC SMALL LETTER CHE - return rune(0x0447), true - case "check": // CHECK MARK - return rune(0x2713), true - case "checkmark": // CHECK MARK - return rune(0x2713), true - case "chi": // GREEK SMALL LETTER CHI - return rune(0x03c7), true - case "cir": // WHITE CIRCLE - return rune(0x25cb), true - case "cirE": // CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT - return rune(0x29c3), true - case "cirb": // SQUARED SMALL CIRCLE - return rune(0x29c7), true - case "circ": // MODIFIER LETTER CIRCUMFLEX ACCENT - return rune(0x02c6), true - case "circeq": // RING EQUAL TO - return rune(0x2257), true - case "circlearrowleft": // ANTICLOCKWISE OPEN CIRCLE ARROW - return rune(0x21ba), true - case "circlearrowright": // CLOCKWISE OPEN CIRCLE ARROW - return rune(0x21bb), true - case "circledR": // REGISTERED SIGN - return rune(0xae), true - case "circledS": // CIRCLED LATIN CAPITAL LETTER S - return rune(0x24c8), true - case "circledast": // CIRCLED ASTERISK OPERATOR - return rune(0x229b), true - case "circledcirc": // CIRCLED RING OPERATOR - return rune(0x229a), true - case "circleddash": // CIRCLED DASH - return rune(0x229d), true - case "cirdarr": // WHITE CIRCLE WITH DOWN ARROW - return rune(0x29ec), true - case "cire": // RING EQUAL TO - return rune(0x2257), true - case "cirerr": // ERROR-BARRED WHITE CIRCLE - return rune(0x29f2), true - case "cirfdarr": // BLACK CIRCLE WITH DOWN ARROW - return rune(0x29ed), true - case "cirferr": // ERROR-BARRED BLACK CIRCLE - return rune(0x29f3), true - case "cirfnint": // CIRCULATION FUNCTION - return rune(0x2a10), true - case "cirmid": // VERTICAL LINE WITH CIRCLE ABOVE - return rune(0x2aef), true - case "cirscir": // CIRCLE WITH SMALL CIRCLE TO THE RIGHT - return rune(0x29c2), true - case "closur": // CLOSE UP - return rune(0x2050), true - case "clubs": // BLACK CLUB SUIT - return rune(0x2663), true - case "clubsuit": // BLACK CLUB SUIT - return rune(0x2663), true - case "colon": // COLON - return rune(0x3a), true - case "colone": // COLON EQUALS - return rune(0x2254), true - case "coloneq": // COLON EQUALS - return rune(0x2254), true - case "comma": // COMMA - return rune(0x2c), true - case "commat": // COMMERCIAL AT - return rune(0x40), true - case "comp": // COMPLEMENT - return rune(0x2201), true - case "compfn": // RING OPERATOR - return rune(0x2218), true - case "complement": // COMPLEMENT - return rune(0x2201), true - case "complexes": // DOUBLE-STRUCK CAPITAL C - return rune(0x2102), true - case "cong": // APPROXIMATELY EQUAL TO - return rune(0x2245), true - case "congdot": // CONGRUENT WITH DOT ABOVE - return rune(0x2a6d), true - case "conint": // CONTOUR INTEGRAL - return rune(0x222e), true - case "copf": // MATHEMATICAL DOUBLE-STRUCK SMALL C - return rune(0x01d554), true - case "coprod": // N-ARY COPRODUCT - return rune(0x2210), true - case "copy": // COPYRIGHT SIGN - return rune(0xa9), true - case "copysr": // SOUND RECORDING COPYRIGHT - return rune(0x2117), true - case "crarr": // DOWNWARDS ARROW WITH CORNER LEFTWARDS - return rune(0x21b5), true - case "cross": // BALLOT X - return rune(0x2717), true - case "cscr": // MATHEMATICAL SCRIPT SMALL C - return rune(0x01d4b8), true - case "csub": // CLOSED SUBSET - return rune(0x2acf), true - case "csube": // CLOSED SUBSET OR EQUAL TO - return rune(0x2ad1), true - case "csup": // CLOSED SUPERSET - return rune(0x2ad0), true - case "csupe": // CLOSED SUPERSET OR EQUAL TO - return rune(0x2ad2), true - case "ctdot": // MIDLINE HORIZONTAL ELLIPSIS - return rune(0x22ef), true - case "cudarrl": // RIGHT-SIDE ARC CLOCKWISE ARROW - return rune(0x2938), true - case "cudarrr": // ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS - return rune(0x2935), true - case "cuepr": // EQUAL TO OR PRECEDES - return rune(0x22de), true - case "cuesc": // EQUAL TO OR SUCCEEDS - return rune(0x22df), true - case "cularr": // ANTICLOCKWISE TOP SEMICIRCLE ARROW - return rune(0x21b6), true - case "cularrp": // TOP ARC ANTICLOCKWISE ARROW WITH PLUS - return rune(0x293d), true - case "cup": // UNION - return rune(0x222a), true - case "cupbrcap": // UNION ABOVE BAR ABOVE INTERSECTION - return rune(0x2a48), true - case "cupcap": // UNION ABOVE INTERSECTION - return rune(0x2a46), true - case "cupcup": // UNION BESIDE AND JOINED WITH UNION - return rune(0x2a4a), true - case "cupdot": // MULTISET MULTIPLICATION - return rune(0x228d), true - case "cupint": // INTEGRAL WITH UNION - return rune(0x2a1a), true - case "cupor": // UNION WITH LOGICAL OR - return rune(0x2a45), true - case "cupre": // PRECEDES OR EQUAL TO - return rune(0x227c), true - case "cups": // UNION with serifs - return rune(0x222a), true - case "curarr": // CLOCKWISE TOP SEMICIRCLE ARROW - return rune(0x21b7), true - case "curarrm": // TOP ARC CLOCKWISE ARROW WITH MINUS - return rune(0x293c), true - case "curlyeqprec": // EQUAL TO OR PRECEDES - return rune(0x22de), true - case "curlyeqsucc": // EQUAL TO OR SUCCEEDS - return rune(0x22df), true - case "curlyvee": // CURLY LOGICAL OR - return rune(0x22ce), true - case "curlywedge": // CURLY LOGICAL AND - return rune(0x22cf), true - case "curren": // CURRENCY SIGN - return rune(0xa4), true - case "curvearrowleft": // ANTICLOCKWISE TOP SEMICIRCLE ARROW - return rune(0x21b6), true - case "curvearrowright": // CLOCKWISE TOP SEMICIRCLE ARROW - return rune(0x21b7), true - case "cuvee": // CURLY LOGICAL OR - return rune(0x22ce), true - case "cuwed": // CURLY LOGICAL AND - return rune(0x22cf), true - case "cwconint": // CLOCKWISE CONTOUR INTEGRAL - return rune(0x2232), true - case "cwint": // CLOCKWISE INTEGRAL - return rune(0x2231), true - case "cylcty": // CYLINDRICITY - return rune(0x232d), true + case "cacute": // LATIN SMALL LETTER C WITH ACUTE + return rune(0x0107), true + case "cap": // INTERSECTION + return rune(0x2229), true + case "capand": // INTERSECTION WITH LOGICAL AND + return rune(0x2a44), true + case "capbrcup": // INTERSECTION ABOVE BAR ABOVE UNION + return rune(0x2a49), true + case "capcap": // INTERSECTION BESIDE AND JOINED WITH INTERSECTION + return rune(0x2a4b), true + case "capcup": // INTERSECTION ABOVE UNION + return rune(0x2a47), true + case "capdot": // INTERSECTION WITH DOT + return rune(0x2a40), true + case "capint": // INTEGRAL WITH INTERSECTION + return rune(0x2a19), true + case "caps": // INTERSECTION with serifs + return rune(0x2229), true + case "caret": // CARET INSERTION POINT + return rune(0x2041), true + case "caron": // CARON + return rune(0x02c7), true + case "ccaps": // CLOSED INTERSECTION WITH SERIFS + return rune(0x2a4d), true + case "ccaron": // LATIN SMALL LETTER C WITH CARON + return rune(0x010d), true + case "ccedil": // LATIN SMALL LETTER C WITH CEDILLA + return rune(0xe7), true + case "ccirc": // LATIN SMALL LETTER C WITH CIRCUMFLEX + return rune(0x0109), true + case "ccups": // CLOSED UNION WITH SERIFS + return rune(0x2a4c), true + case "ccupssm": // CLOSED UNION WITH SERIFS AND SMASH PRODUCT + return rune(0x2a50), true + case "cdot": // LATIN SMALL LETTER C WITH DOT ABOVE + return rune(0x010b), true + case "cedil": // CEDILLA + return rune(0xb8), true + case "cemptyv": // EMPTY SET WITH SMALL CIRCLE ABOVE + return rune(0x29b2), true + case "cent": // CENT SIGN + return rune(0xa2), true + case "centerdot": // MIDDLE DOT + return rune(0xb7), true + case "cfr": // MATHEMATICAL FRAKTUR SMALL C + return rune(0x01d520), true + case "chcy": // CYRILLIC SMALL LETTER CHE + return rune(0x0447), true + case "check": // CHECK MARK + return rune(0x2713), true + case "checkmark": // CHECK MARK + return rune(0x2713), true + case "chi": // GREEK SMALL LETTER CHI + return rune(0x03c7), true + case "cir": // WHITE CIRCLE + return rune(0x25cb), true + case "cirE": // CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT + return rune(0x29c3), true + case "cirb": // SQUARED SMALL CIRCLE + return rune(0x29c7), true + case "circ": // MODIFIER LETTER CIRCUMFLEX ACCENT + return rune(0x02c6), true + case "circeq": // RING EQUAL TO + return rune(0x2257), true + case "circlearrowleft": // ANTICLOCKWISE OPEN CIRCLE ARROW + return rune(0x21ba), true + case "circlearrowright": // CLOCKWISE OPEN CIRCLE ARROW + return rune(0x21bb), true + case "circledR": // REGISTERED SIGN + return rune(0xae), true + case "circledS": // CIRCLED LATIN CAPITAL LETTER S + return rune(0x24c8), true + case "circledast": // CIRCLED ASTERISK OPERATOR + return rune(0x229b), true + case "circledcirc": // CIRCLED RING OPERATOR + return rune(0x229a), true + case "circleddash": // CIRCLED DASH + return rune(0x229d), true + case "cirdarr": // WHITE CIRCLE WITH DOWN ARROW + return rune(0x29ec), true + case "cire": // RING EQUAL TO + return rune(0x2257), true + case "cirerr": // ERROR-BARRED WHITE CIRCLE + return rune(0x29f2), true + case "cirfdarr": // BLACK CIRCLE WITH DOWN ARROW + return rune(0x29ed), true + case "cirferr": // ERROR-BARRED BLACK CIRCLE + return rune(0x29f3), true + case "cirfnint": // CIRCULATION FUNCTION + return rune(0x2a10), true + case "cirmid": // VERTICAL LINE WITH CIRCLE ABOVE + return rune(0x2aef), true + case "cirscir": // CIRCLE WITH SMALL CIRCLE TO THE RIGHT + return rune(0x29c2), true + case "closur": // CLOSE UP + return rune(0x2050), true + case "clubs": // BLACK CLUB SUIT + return rune(0x2663), true + case "clubsuit": // BLACK CLUB SUIT + return rune(0x2663), true + case "colon": // COLON + return rune(0x3a), true + case "colone": // COLON EQUALS + return rune(0x2254), true + case "coloneq": // COLON EQUALS + return rune(0x2254), true + case "comma": // COMMA + return rune(0x2c), true + case "commat": // COMMERCIAL AT + return rune(0x40), true + case "comp": // COMPLEMENT + return rune(0x2201), true + case "compfn": // RING OPERATOR + return rune(0x2218), true + case "complement": // COMPLEMENT + return rune(0x2201), true + case "complexes": // DOUBLE-STRUCK CAPITAL C + return rune(0x2102), true + case "cong": // APPROXIMATELY EQUAL TO + return rune(0x2245), true + case "congdot": // CONGRUENT WITH DOT ABOVE + return rune(0x2a6d), true + case "conint": // CONTOUR INTEGRAL + return rune(0x222e), true + case "copf": // MATHEMATICAL DOUBLE-STRUCK SMALL C + return rune(0x01d554), true + case "coprod": // N-ARY COPRODUCT + return rune(0x2210), true + case "copy": // COPYRIGHT SIGN + return rune(0xa9), true + case "copysr": // SOUND RECORDING COPYRIGHT + return rune(0x2117), true + case "crarr": // DOWNWARDS ARROW WITH CORNER LEFTWARDS + return rune(0x21b5), true + case "cross": // BALLOT X + return rune(0x2717), true + case "cscr": // MATHEMATICAL SCRIPT SMALL C + return rune(0x01d4b8), true + case "csub": // CLOSED SUBSET + return rune(0x2acf), true + case "csube": // CLOSED SUBSET OR EQUAL TO + return rune(0x2ad1), true + case "csup": // CLOSED SUPERSET + return rune(0x2ad0), true + case "csupe": // CLOSED SUPERSET OR EQUAL TO + return rune(0x2ad2), true + case "ctdot": // MIDLINE HORIZONTAL ELLIPSIS + return rune(0x22ef), true + case "cudarrl": // RIGHT-SIDE ARC CLOCKWISE ARROW + return rune(0x2938), true + case "cudarrr": // ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS + return rune(0x2935), true + case "cuepr": // EQUAL TO OR PRECEDES + return rune(0x22de), true + case "cuesc": // EQUAL TO OR SUCCEEDS + return rune(0x22df), true + case "cularr": // ANTICLOCKWISE TOP SEMICIRCLE ARROW + return rune(0x21b6), true + case "cularrp": // TOP ARC ANTICLOCKWISE ARROW WITH PLUS + return rune(0x293d), true + case "cup": // UNION + return rune(0x222a), true + case "cupbrcap": // UNION ABOVE BAR ABOVE INTERSECTION + return rune(0x2a48), true + case "cupcap": // UNION ABOVE INTERSECTION + return rune(0x2a46), true + case "cupcup": // UNION BESIDE AND JOINED WITH UNION + return rune(0x2a4a), true + case "cupdot": // MULTISET MULTIPLICATION + return rune(0x228d), true + case "cupint": // INTEGRAL WITH UNION + return rune(0x2a1a), true + case "cupor": // UNION WITH LOGICAL OR + return rune(0x2a45), true + case "cupre": // PRECEDES OR EQUAL TO + return rune(0x227c), true + case "cups": // UNION with serifs + return rune(0x222a), true + case "curarr": // CLOCKWISE TOP SEMICIRCLE ARROW + return rune(0x21b7), true + case "curarrm": // TOP ARC CLOCKWISE ARROW WITH MINUS + return rune(0x293c), true + case "curlyeqprec": // EQUAL TO OR PRECEDES + return rune(0x22de), true + case "curlyeqsucc": // EQUAL TO OR SUCCEEDS + return rune(0x22df), true + case "curlyvee": // CURLY LOGICAL OR + return rune(0x22ce), true + case "curlywedge": // CURLY LOGICAL AND + return rune(0x22cf), true + case "curren": // CURRENCY SIGN + return rune(0xa4), true + case "curvearrowleft": // ANTICLOCKWISE TOP SEMICIRCLE ARROW + return rune(0x21b6), true + case "curvearrowright": // CLOCKWISE TOP SEMICIRCLE ARROW + return rune(0x21b7), true + case "cuvee": // CURLY LOGICAL OR + return rune(0x22ce), true + case "cuwed": // CURLY LOGICAL AND + return rune(0x22cf), true + case "cwconint": // CLOCKWISE CONTOUR INTEGRAL + return rune(0x2232), true + case "cwint": // CLOCKWISE INTEGRAL + return rune(0x2231), true + case "cylcty": // CYLINDRICITY + return rune(0x232d), true } case 'd': switch name { - case "dAarr": // DOWNWARDS TRIPLE ARROW - return rune(0x290b), true - case "dArr": // DOWNWARDS DOUBLE ARROW - return rune(0x21d3), true - case "dHar": // DOWNWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT - return rune(0x2965), true - case "dagger": // DAGGER - return rune(0x2020), true - case "dalembrt": // SQUARE WITH CONTOURED OUTLINE - return rune(0x29e0), true - case "daleth": // DALET SYMBOL - return rune(0x2138), true - case "darr": // DOWNWARDS ARROW - return rune(0x2193), true - case "darr2": // DOWNWARDS PAIRED ARROWS - return rune(0x21ca), true - case "darrb": // DOWNWARDS ARROW TO BAR - return rune(0x2913), true - case "darrln": // DOWNWARDS ARROW WITH HORIZONTAL STROKE - return rune(0x2908), true - case "dash": // HYPHEN - return rune(0x2010), true - case "dashV": // DOUBLE VERTICAL BAR LEFT TURNSTILE - return rune(0x2ae3), true - case "dashv": // LEFT TACK - return rune(0x22a3), true - case "dbkarow": // RIGHTWARDS TRIPLE DASH ARROW - return rune(0x290f), true - case "dblac": // DOUBLE ACUTE ACCENT - return rune(0x02dd), true - case "dcaron": // LATIN SMALL LETTER D WITH CARON - return rune(0x010f), true - case "dcy": // CYRILLIC SMALL LETTER DE - return rune(0x0434), true - case "dd": // DOUBLE-STRUCK ITALIC SMALL D - return rune(0x2146), true - case "ddagger": // DOUBLE DAGGER - return rune(0x2021), true - case "ddarr": // DOWNWARDS PAIRED ARROWS - return rune(0x21ca), true - case "ddotseq": // EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW - return rune(0x2a77), true - case "deg": // DEGREE SIGN - return rune(0xb0), true - case "delta": // GREEK SMALL LETTER DELTA - return rune(0x03b4), true - case "demptyv": // EMPTY SET WITH OVERBAR - return rune(0x29b1), true - case "dfisht": // DOWN FISH TAIL - return rune(0x297f), true - case "dfr": // MATHEMATICAL FRAKTUR SMALL D - return rune(0x01d521), true - case "dgr": // GREEK SMALL LETTER DELTA - return rune(0x03b4), true - case "dharl": // DOWNWARDS HARPOON WITH BARB LEFTWARDS - return rune(0x21c3), true - case "dharr": // DOWNWARDS HARPOON WITH BARB RIGHTWARDS - return rune(0x21c2), true - case "diam": // DIAMOND OPERATOR - return rune(0x22c4), true - case "diamdarr": // BLACK DIAMOND WITH DOWN ARROW - return rune(0x29ea), true - case "diamerr": // ERROR-BARRED WHITE DIAMOND - return rune(0x29f0), true - case "diamerrf": // ERROR-BARRED BLACK DIAMOND - return rune(0x29f1), true - case "diamond": // DIAMOND OPERATOR - return rune(0x22c4), true - case "diamondsuit": // BLACK DIAMOND SUIT - return rune(0x2666), true - case "diams": // BLACK DIAMOND SUIT - return rune(0x2666), true - case "die": // DIAERESIS - return rune(0xa8), true - case "digamma": // GREEK SMALL LETTER DIGAMMA - return rune(0x03dd), true - case "disin": // ELEMENT OF WITH LONG HORIZONTAL STROKE - return rune(0x22f2), true - case "div": // DIVISION SIGN - return rune(0xf7), true - case "divide": // DIVISION SIGN - return rune(0xf7), true - case "divideontimes": // DIVISION TIMES - return rune(0x22c7), true - case "divonx": // DIVISION TIMES - return rune(0x22c7), true - case "djcy": // CYRILLIC SMALL LETTER DJE - return rune(0x0452), true - case "dlarr": // SOUTH WEST ARROW - return rune(0x2199), true - case "dlcorn": // BOTTOM LEFT CORNER - return rune(0x231e), true - case "dlcrop": // BOTTOM LEFT CROP - return rune(0x230d), true - case "dlharb": // DOWNWARDS HARPOON WITH BARB LEFT TO BAR - return rune(0x2959), true - case "dollar": // DOLLAR SIGN - return rune(0x24), true - case "dopf": // MATHEMATICAL DOUBLE-STRUCK SMALL D - return rune(0x01d555), true - case "dot": // DOT ABOVE - return rune(0x02d9), true - case "doteq": // APPROACHES THE LIMIT - return rune(0x2250), true - case "doteqdot": // GEOMETRICALLY EQUAL TO - return rune(0x2251), true - case "dotminus": // DOT MINUS - return rune(0x2238), true - case "dotplus": // DOT PLUS - return rune(0x2214), true - case "dotsquare": // SQUARED DOT OPERATOR - return rune(0x22a1), true - case "doublebarwedge": // PERSPECTIVE - return rune(0x2306), true - case "downarrow": // DOWNWARDS ARROW - return rune(0x2193), true - case "downdownarrows": // DOWNWARDS PAIRED ARROWS - return rune(0x21ca), true - case "downharpoonleft": // DOWNWARDS HARPOON WITH BARB LEFTWARDS - return rune(0x21c3), true - case "downharpoonright": // DOWNWARDS HARPOON WITH BARB RIGHTWARDS - return rune(0x21c2), true - case "drarr": // SOUTH EAST ARROW - return rune(0x2198), true - case "drbkarow": // RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW - return rune(0x2910), true - case "drcorn": // BOTTOM RIGHT CORNER - return rune(0x231f), true - case "drcrop": // BOTTOM RIGHT CROP - return rune(0x230c), true - case "drharb": // DOWNWARDS HARPOON WITH BARB RIGHT TO BAR - return rune(0x2955), true - case "dscr": // MATHEMATICAL SCRIPT SMALL D - return rune(0x01d4b9), true - case "dscy": // CYRILLIC SMALL LETTER DZE - return rune(0x0455), true - case "dsol": // SOLIDUS WITH OVERBAR - return rune(0x29f6), true - case "dstrok": // LATIN SMALL LETTER D WITH STROKE - return rune(0x0111), true - case "dtdot": // DOWN RIGHT DIAGONAL ELLIPSIS - return rune(0x22f1), true - case "dtri": // WHITE DOWN-POINTING SMALL TRIANGLE - return rune(0x25bf), true - case "dtrif": // BLACK DOWN-POINTING SMALL TRIANGLE - return rune(0x25be), true - case "dtrilf": // DOWN-POINTING TRIANGLE WITH LEFT HALF BLACK - return rune(0x29e8), true - case "dtrirf": // DOWN-POINTING TRIANGLE WITH RIGHT HALF BLACK - return rune(0x29e9), true - case "duarr": // DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW - return rune(0x21f5), true - case "duhar": // DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT - return rune(0x296f), true - case "dumap": // DOUBLE-ENDED MULTIMAP - return rune(0x29df), true - case "dwangle": // OBLIQUE ANGLE OPENING UP - return rune(0x29a6), true - case "dzcy": // CYRILLIC SMALL LETTER DZHE - return rune(0x045f), true - case "dzigrarr": // LONG RIGHTWARDS SQUIGGLE ARROW - return rune(0x27ff), true + case "dAarr": // DOWNWARDS TRIPLE ARROW + return rune(0x290b), true + case "dArr": // DOWNWARDS DOUBLE ARROW + return rune(0x21d3), true + case "dHar": // DOWNWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT + return rune(0x2965), true + case "dagger": // DAGGER + return rune(0x2020), true + case "dalembrt": // SQUARE WITH CONTOURED OUTLINE + return rune(0x29e0), true + case "daleth": // DALET SYMBOL + return rune(0x2138), true + case "darr": // DOWNWARDS ARROW + return rune(0x2193), true + case "darr2": // DOWNWARDS PAIRED ARROWS + return rune(0x21ca), true + case "darrb": // DOWNWARDS ARROW TO BAR + return rune(0x2913), true + case "darrln": // DOWNWARDS ARROW WITH HORIZONTAL STROKE + return rune(0x2908), true + case "dash": // HYPHEN + return rune(0x2010), true + case "dashV": // DOUBLE VERTICAL BAR LEFT TURNSTILE + return rune(0x2ae3), true + case "dashv": // LEFT TACK + return rune(0x22a3), true + case "dbkarow": // RIGHTWARDS TRIPLE DASH ARROW + return rune(0x290f), true + case "dblac": // DOUBLE ACUTE ACCENT + return rune(0x02dd), true + case "dcaron": // LATIN SMALL LETTER D WITH CARON + return rune(0x010f), true + case "dcy": // CYRILLIC SMALL LETTER DE + return rune(0x0434), true + case "dd": // DOUBLE-STRUCK ITALIC SMALL D + return rune(0x2146), true + case "ddagger": // DOUBLE DAGGER + return rune(0x2021), true + case "ddarr": // DOWNWARDS PAIRED ARROWS + return rune(0x21ca), true + case "ddotseq": // EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW + return rune(0x2a77), true + case "deg": // DEGREE SIGN + return rune(0xb0), true + case "delta": // GREEK SMALL LETTER DELTA + return rune(0x03b4), true + case "demptyv": // EMPTY SET WITH OVERBAR + return rune(0x29b1), true + case "dfisht": // DOWN FISH TAIL + return rune(0x297f), true + case "dfr": // MATHEMATICAL FRAKTUR SMALL D + return rune(0x01d521), true + case "dgr": // GREEK SMALL LETTER DELTA + return rune(0x03b4), true + case "dharl": // DOWNWARDS HARPOON WITH BARB LEFTWARDS + return rune(0x21c3), true + case "dharr": // DOWNWARDS HARPOON WITH BARB RIGHTWARDS + return rune(0x21c2), true + case "diam": // DIAMOND OPERATOR + return rune(0x22c4), true + case "diamdarr": // BLACK DIAMOND WITH DOWN ARROW + return rune(0x29ea), true + case "diamerr": // ERROR-BARRED WHITE DIAMOND + return rune(0x29f0), true + case "diamerrf": // ERROR-BARRED BLACK DIAMOND + return rune(0x29f1), true + case "diamond": // DIAMOND OPERATOR + return rune(0x22c4), true + case "diamondsuit": // BLACK DIAMOND SUIT + return rune(0x2666), true + case "diams": // BLACK DIAMOND SUIT + return rune(0x2666), true + case "die": // DIAERESIS + return rune(0xa8), true + case "digamma": // GREEK SMALL LETTER DIGAMMA + return rune(0x03dd), true + case "disin": // ELEMENT OF WITH LONG HORIZONTAL STROKE + return rune(0x22f2), true + case "div": // DIVISION SIGN + return rune(0xf7), true + case "divide": // DIVISION SIGN + return rune(0xf7), true + case "divideontimes": // DIVISION TIMES + return rune(0x22c7), true + case "divonx": // DIVISION TIMES + return rune(0x22c7), true + case "djcy": // CYRILLIC SMALL LETTER DJE + return rune(0x0452), true + case "dlarr": // SOUTH WEST ARROW + return rune(0x2199), true + case "dlcorn": // BOTTOM LEFT CORNER + return rune(0x231e), true + case "dlcrop": // BOTTOM LEFT CROP + return rune(0x230d), true + case "dlharb": // DOWNWARDS HARPOON WITH BARB LEFT TO BAR + return rune(0x2959), true + case "dollar": // DOLLAR SIGN + return rune(0x24), true + case "dopf": // MATHEMATICAL DOUBLE-STRUCK SMALL D + return rune(0x01d555), true + case "dot": // DOT ABOVE + return rune(0x02d9), true + case "doteq": // APPROACHES THE LIMIT + return rune(0x2250), true + case "doteqdot": // GEOMETRICALLY EQUAL TO + return rune(0x2251), true + case "dotminus": // DOT MINUS + return rune(0x2238), true + case "dotplus": // DOT PLUS + return rune(0x2214), true + case "dotsquare": // SQUARED DOT OPERATOR + return rune(0x22a1), true + case "doublebarwedge": // PERSPECTIVE + return rune(0x2306), true + case "downarrow": // DOWNWARDS ARROW + return rune(0x2193), true + case "downdownarrows": // DOWNWARDS PAIRED ARROWS + return rune(0x21ca), true + case "downharpoonleft": // DOWNWARDS HARPOON WITH BARB LEFTWARDS + return rune(0x21c3), true + case "downharpoonright": // DOWNWARDS HARPOON WITH BARB RIGHTWARDS + return rune(0x21c2), true + case "drarr": // SOUTH EAST ARROW + return rune(0x2198), true + case "drbkarow": // RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW + return rune(0x2910), true + case "drcorn": // BOTTOM RIGHT CORNER + return rune(0x231f), true + case "drcrop": // BOTTOM RIGHT CROP + return rune(0x230c), true + case "drharb": // DOWNWARDS HARPOON WITH BARB RIGHT TO BAR + return rune(0x2955), true + case "dscr": // MATHEMATICAL SCRIPT SMALL D + return rune(0x01d4b9), true + case "dscy": // CYRILLIC SMALL LETTER DZE + return rune(0x0455), true + case "dsol": // SOLIDUS WITH OVERBAR + return rune(0x29f6), true + case "dstrok": // LATIN SMALL LETTER D WITH STROKE + return rune(0x0111), true + case "dtdot": // DOWN RIGHT DIAGONAL ELLIPSIS + return rune(0x22f1), true + case "dtri": // WHITE DOWN-POINTING SMALL TRIANGLE + return rune(0x25bf), true + case "dtrif": // BLACK DOWN-POINTING SMALL TRIANGLE + return rune(0x25be), true + case "dtrilf": // DOWN-POINTING TRIANGLE WITH LEFT HALF BLACK + return rune(0x29e8), true + case "dtrirf": // DOWN-POINTING TRIANGLE WITH RIGHT HALF BLACK + return rune(0x29e9), true + case "duarr": // DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW + return rune(0x21f5), true + case "duhar": // DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT + return rune(0x296f), true + case "dumap": // DOUBLE-ENDED MULTIMAP + return rune(0x29df), true + case "dwangle": // OBLIQUE ANGLE OPENING UP + return rune(0x29a6), true + case "dzcy": // CYRILLIC SMALL LETTER DZHE + return rune(0x045f), true + case "dzigrarr": // LONG RIGHTWARDS SQUIGGLE ARROW + return rune(0x27ff), true } case 'e': switch name { - case "eDDot": // EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW - return rune(0x2a77), true - case "eDot": // GEOMETRICALLY EQUAL TO - return rune(0x2251), true - case "eacgr": // GREEK SMALL LETTER EPSILON WITH TONOS - return rune(0x03ad), true - case "eacute": // LATIN SMALL LETTER E WITH ACUTE - return rune(0xe9), true - case "easter": // EQUALS WITH ASTERISK - return rune(0x2a6e), true - case "ecaron": // LATIN SMALL LETTER E WITH CARON - return rune(0x011b), true - case "ecir": // RING IN EQUAL TO - return rune(0x2256), true - case "ecirc": // LATIN SMALL LETTER E WITH CIRCUMFLEX - return rune(0xea), true - case "ecolon": // EQUALS COLON - return rune(0x2255), true - case "ecy": // CYRILLIC SMALL LETTER E - return rune(0x044d), true - case "edot": // LATIN SMALL LETTER E WITH DOT ABOVE - return rune(0x0117), true - case "ee": // DOUBLE-STRUCK ITALIC SMALL E - return rune(0x2147), true - case "eeacgr": // GREEK SMALL LETTER ETA WITH TONOS - return rune(0x03ae), true - case "eegr": // GREEK SMALL LETTER ETA - return rune(0x03b7), true - case "efDot": // APPROXIMATELY EQUAL TO OR THE IMAGE OF - return rune(0x2252), true - case "efr": // MATHEMATICAL FRAKTUR SMALL E - return rune(0x01d522), true - case "eg": // DOUBLE-LINE EQUAL TO OR GREATER-THAN - return rune(0x2a9a), true - case "egr": // GREEK SMALL LETTER EPSILON - return rune(0x03b5), true - case "egrave": // LATIN SMALL LETTER E WITH GRAVE - return rune(0xe8), true - case "egs": // SLANTED EQUAL TO OR GREATER-THAN - return rune(0x2a96), true - case "egsdot": // SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE - return rune(0x2a98), true - case "el": // DOUBLE-LINE EQUAL TO OR LESS-THAN - return rune(0x2a99), true - case "elinters": // ELECTRICAL INTERSECTION - return rune(0x23e7), true - case "ell": // SCRIPT SMALL L - return rune(0x2113), true - case "els": // SLANTED EQUAL TO OR LESS-THAN - return rune(0x2a95), true - case "elsdot": // SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE - return rune(0x2a97), true - case "emacr": // LATIN SMALL LETTER E WITH MACRON - return rune(0x0113), true - case "empty": // EMPTY SET - return rune(0x2205), true - case "emptyset": // EMPTY SET - return rune(0x2205), true - case "emptyv": // EMPTY SET - return rune(0x2205), true - case "emsp": // EM SPACE - return rune(0x2003), true - case "emsp13": // THREE-PER-EM SPACE - return rune(0x2004), true - case "emsp14": // FOUR-PER-EM SPACE - return rune(0x2005), true - case "eng": // LATIN SMALL LETTER ENG - return rune(0x014b), true - case "ensp": // EN SPACE - return rune(0x2002), true - case "eogon": // LATIN SMALL LETTER E WITH OGONEK - return rune(0x0119), true - case "eopf": // MATHEMATICAL DOUBLE-STRUCK SMALL E - return rune(0x01d556), true - case "epar": // EQUAL AND PARALLEL TO - return rune(0x22d5), true - case "eparsl": // EQUALS SIGN AND SLANTED PARALLEL - return rune(0x29e3), true - case "eplus": // EQUALS SIGN ABOVE PLUS SIGN - return rune(0x2a71), true - case "epsi": // GREEK SMALL LETTER EPSILON - return rune(0x03b5), true - case "epsilon": // GREEK SMALL LETTER EPSILON - return rune(0x03b5), true - case "epsis": // GREEK LUNATE EPSILON SYMBOL - return rune(0x03f5), true - case "epsiv": // GREEK LUNATE EPSILON SYMBOL - return rune(0x03f5), true - case "eqcirc": // RING IN EQUAL TO - return rune(0x2256), true - case "eqcolon": // EQUALS COLON - return rune(0x2255), true - case "eqeq": // TWO CONSECUTIVE EQUALS SIGNS - return rune(0x2a75), true - case "eqsim": // MINUS TILDE - return rune(0x2242), true - case "eqslantgtr": // SLANTED EQUAL TO OR GREATER-THAN - return rune(0x2a96), true - case "eqslantless": // SLANTED EQUAL TO OR LESS-THAN - return rune(0x2a95), true - case "equals": // EQUALS SIGN - return rune(0x3d), true - case "equest": // QUESTIONED EQUAL TO - return rune(0x225f), true - case "equiv": // IDENTICAL TO - return rune(0x2261), true - case "equivDD": // EQUIVALENT WITH FOUR DOTS ABOVE - return rune(0x2a78), true - case "eqvparsl": // IDENTICAL TO AND SLANTED PARALLEL - return rune(0x29e5), true - case "erDot": // IMAGE OF OR APPROXIMATELY EQUAL TO - return rune(0x2253), true - case "erarr": // EQUALS SIGN ABOVE RIGHTWARDS ARROW - return rune(0x2971), true - case "escr": // SCRIPT SMALL E - return rune(0x212f), true - case "esdot": // APPROACHES THE LIMIT - return rune(0x2250), true - case "esim": // MINUS TILDE - return rune(0x2242), true - case "eta": // GREEK SMALL LETTER ETA - return rune(0x03b7), true - case "eth": // LATIN SMALL LETTER ETH - return rune(0xf0), true - case "euml": // LATIN SMALL LETTER E WITH DIAERESIS - return rune(0xeb), true - case "euro": // EURO SIGN - return rune(0x20ac), true - case "excl": // EXCLAMATION MARK - return rune(0x21), true - case "exist": // THERE EXISTS - return rune(0x2203), true - case "expectation": // SCRIPT CAPITAL E - return rune(0x2130), true - case "exponentiale": // DOUBLE-STRUCK ITALIC SMALL E - return rune(0x2147), true + case "eDDot": // EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW + return rune(0x2a77), true + case "eDot": // GEOMETRICALLY EQUAL TO + return rune(0x2251), true + case "eacgr": // GREEK SMALL LETTER EPSILON WITH TONOS + return rune(0x03ad), true + case "eacute": // LATIN SMALL LETTER E WITH ACUTE + return rune(0xe9), true + case "easter": // EQUALS WITH ASTERISK + return rune(0x2a6e), true + case "ecaron": // LATIN SMALL LETTER E WITH CARON + return rune(0x011b), true + case "ecir": // RING IN EQUAL TO + return rune(0x2256), true + case "ecirc": // LATIN SMALL LETTER E WITH CIRCUMFLEX + return rune(0xea), true + case "ecolon": // EQUALS COLON + return rune(0x2255), true + case "ecy": // CYRILLIC SMALL LETTER E + return rune(0x044d), true + case "edot": // LATIN SMALL LETTER E WITH DOT ABOVE + return rune(0x0117), true + case "ee": // DOUBLE-STRUCK ITALIC SMALL E + return rune(0x2147), true + case "eeacgr": // GREEK SMALL LETTER ETA WITH TONOS + return rune(0x03ae), true + case "eegr": // GREEK SMALL LETTER ETA + return rune(0x03b7), true + case "efDot": // APPROXIMATELY EQUAL TO OR THE IMAGE OF + return rune(0x2252), true + case "efr": // MATHEMATICAL FRAKTUR SMALL E + return rune(0x01d522), true + case "eg": // DOUBLE-LINE EQUAL TO OR GREATER-THAN + return rune(0x2a9a), true + case "egr": // GREEK SMALL LETTER EPSILON + return rune(0x03b5), true + case "egrave": // LATIN SMALL LETTER E WITH GRAVE + return rune(0xe8), true + case "egs": // SLANTED EQUAL TO OR GREATER-THAN + return rune(0x2a96), true + case "egsdot": // SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE + return rune(0x2a98), true + case "el": // DOUBLE-LINE EQUAL TO OR LESS-THAN + return rune(0x2a99), true + case "elinters": // ELECTRICAL INTERSECTION + return rune(0x23e7), true + case "ell": // SCRIPT SMALL L + return rune(0x2113), true + case "els": // SLANTED EQUAL TO OR LESS-THAN + return rune(0x2a95), true + case "elsdot": // SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE + return rune(0x2a97), true + case "emacr": // LATIN SMALL LETTER E WITH MACRON + return rune(0x0113), true + case "empty": // EMPTY SET + return rune(0x2205), true + case "emptyset": // EMPTY SET + return rune(0x2205), true + case "emptyv": // EMPTY SET + return rune(0x2205), true + case "emsp": // EM SPACE + return rune(0x2003), true + case "emsp13": // THREE-PER-EM SPACE + return rune(0x2004), true + case "emsp14": // FOUR-PER-EM SPACE + return rune(0x2005), true + case "eng": // LATIN SMALL LETTER ENG + return rune(0x014b), true + case "ensp": // EN SPACE + return rune(0x2002), true + case "eogon": // LATIN SMALL LETTER E WITH OGONEK + return rune(0x0119), true + case "eopf": // MATHEMATICAL DOUBLE-STRUCK SMALL E + return rune(0x01d556), true + case "epar": // EQUAL AND PARALLEL TO + return rune(0x22d5), true + case "eparsl": // EQUALS SIGN AND SLANTED PARALLEL + return rune(0x29e3), true + case "eplus": // EQUALS SIGN ABOVE PLUS SIGN + return rune(0x2a71), true + case "epsi": // GREEK SMALL LETTER EPSILON + return rune(0x03b5), true + case "epsilon": // GREEK SMALL LETTER EPSILON + return rune(0x03b5), true + case "epsis": // GREEK LUNATE EPSILON SYMBOL + return rune(0x03f5), true + case "epsiv": // GREEK LUNATE EPSILON SYMBOL + return rune(0x03f5), true + case "eqcirc": // RING IN EQUAL TO + return rune(0x2256), true + case "eqcolon": // EQUALS COLON + return rune(0x2255), true + case "eqeq": // TWO CONSECUTIVE EQUALS SIGNS + return rune(0x2a75), true + case "eqsim": // MINUS TILDE + return rune(0x2242), true + case "eqslantgtr": // SLANTED EQUAL TO OR GREATER-THAN + return rune(0x2a96), true + case "eqslantless": // SLANTED EQUAL TO OR LESS-THAN + return rune(0x2a95), true + case "equals": // EQUALS SIGN + return rune(0x3d), true + case "equest": // QUESTIONED EQUAL TO + return rune(0x225f), true + case "equiv": // IDENTICAL TO + return rune(0x2261), true + case "equivDD": // EQUIVALENT WITH FOUR DOTS ABOVE + return rune(0x2a78), true + case "eqvparsl": // IDENTICAL TO AND SLANTED PARALLEL + return rune(0x29e5), true + case "erDot": // IMAGE OF OR APPROXIMATELY EQUAL TO + return rune(0x2253), true + case "erarr": // EQUALS SIGN ABOVE RIGHTWARDS ARROW + return rune(0x2971), true + case "escr": // SCRIPT SMALL E + return rune(0x212f), true + case "esdot": // APPROACHES THE LIMIT + return rune(0x2250), true + case "esim": // MINUS TILDE + return rune(0x2242), true + case "eta": // GREEK SMALL LETTER ETA + return rune(0x03b7), true + case "eth": // LATIN SMALL LETTER ETH + return rune(0xf0), true + case "euml": // LATIN SMALL LETTER E WITH DIAERESIS + return rune(0xeb), true + case "euro": // EURO SIGN + return rune(0x20ac), true + case "excl": // EXCLAMATION MARK + return rune(0x21), true + case "exist": // THERE EXISTS + return rune(0x2203), true + case "expectation": // SCRIPT CAPITAL E + return rune(0x2130), true + case "exponentiale": // DOUBLE-STRUCK ITALIC SMALL E + return rune(0x2147), true } case 'f': switch name { - case "fallingdotseq": // APPROXIMATELY EQUAL TO OR THE IMAGE OF - return rune(0x2252), true - case "fbowtie": // BLACK BOWTIE - return rune(0x29d3), true - case "fcy": // CYRILLIC SMALL LETTER EF - return rune(0x0444), true - case "fdiag": // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT - return rune(0x2572), true - case "fdiordi": // FALLING DIAGONAL CROSSING RISING DIAGONAL - return rune(0x292c), true - case "fdonearr": // FALLING DIAGONAL CROSSING NORTH EAST ARROW - return rune(0x292f), true - case "female": // FEMALE SIGN - return rune(0x2640), true - case "ffilig": // LATIN SMALL LIGATURE FFI - return rune(0xfb03), true - case "fflig": // LATIN SMALL LIGATURE FF - return rune(0xfb00), true - case "ffllig": // LATIN SMALL LIGATURE FFL - return rune(0xfb04), true - case "ffr": // MATHEMATICAL FRAKTUR SMALL F - return rune(0x01d523), true - case "fhrglass": // BLACK HOURGLASS - return rune(0x29d7), true - case "filig": // LATIN SMALL LIGATURE FI - return rune(0xfb01), true - case "fjlig": // fj ligature - return rune(0x66), true - case "flat": // MUSIC FLAT SIGN - return rune(0x266d), true - case "fllig": // LATIN SMALL LIGATURE FL - return rune(0xfb02), true - case "fltns": // WHITE PARALLELOGRAM - return rune(0x25b1), true - case "fnof": // LATIN SMALL LETTER F WITH HOOK - return rune(0x0192), true - case "fopf": // MATHEMATICAL DOUBLE-STRUCK SMALL F - return rune(0x01d557), true - case "forall": // FOR ALL - return rune(0x2200), true - case "fork": // PITCHFORK - return rune(0x22d4), true - case "forkv": // ELEMENT OF OPENING DOWNWARDS - return rune(0x2ad9), true - case "fpartint": // FINITE PART INTEGRAL - return rune(0x2a0d), true - case "frac12": // VULGAR FRACTION ONE HALF - return rune(0xbd), true - case "frac13": // VULGAR FRACTION ONE THIRD - return rune(0x2153), true - case "frac14": // VULGAR FRACTION ONE QUARTER - return rune(0xbc), true - case "frac15": // VULGAR FRACTION ONE FIFTH - return rune(0x2155), true - case "frac16": // VULGAR FRACTION ONE SIXTH - return rune(0x2159), true - case "frac18": // VULGAR FRACTION ONE EIGHTH - return rune(0x215b), true - case "frac23": // VULGAR FRACTION TWO THIRDS - return rune(0x2154), true - case "frac25": // VULGAR FRACTION TWO FIFTHS - return rune(0x2156), true - case "frac34": // VULGAR FRACTION THREE QUARTERS - return rune(0xbe), true - case "frac35": // VULGAR FRACTION THREE FIFTHS - return rune(0x2157), true - case "frac38": // VULGAR FRACTION THREE EIGHTHS - return rune(0x215c), true - case "frac45": // VULGAR FRACTION FOUR FIFTHS - return rune(0x2158), true - case "frac56": // VULGAR FRACTION FIVE SIXTHS - return rune(0x215a), true - case "frac58": // VULGAR FRACTION FIVE EIGHTHS - return rune(0x215d), true - case "frac78": // VULGAR FRACTION SEVEN EIGHTHS - return rune(0x215e), true - case "frasl": // FRACTION SLASH - return rune(0x2044), true - case "frown": // FROWN - return rune(0x2322), true - case "fscr": // MATHEMATICAL SCRIPT SMALL F - return rune(0x01d4bb), true + case "fallingdotseq": // APPROXIMATELY EQUAL TO OR THE IMAGE OF + return rune(0x2252), true + case "fbowtie": // BLACK BOWTIE + return rune(0x29d3), true + case "fcy": // CYRILLIC SMALL LETTER EF + return rune(0x0444), true + case "fdiag": // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT + return rune(0x2572), true + case "fdiordi": // FALLING DIAGONAL CROSSING RISING DIAGONAL + return rune(0x292c), true + case "fdonearr": // FALLING DIAGONAL CROSSING NORTH EAST ARROW + return rune(0x292f), true + case "female": // FEMALE SIGN + return rune(0x2640), true + case "ffilig": // LATIN SMALL LIGATURE FFI + return rune(0xfb03), true + case "fflig": // LATIN SMALL LIGATURE FF + return rune(0xfb00), true + case "ffllig": // LATIN SMALL LIGATURE FFL + return rune(0xfb04), true + case "ffr": // MATHEMATICAL FRAKTUR SMALL F + return rune(0x01d523), true + case "fhrglass": // BLACK HOURGLASS + return rune(0x29d7), true + case "filig": // LATIN SMALL LIGATURE FI + return rune(0xfb01), true + case "fjlig": // fj ligature + return rune(0x66), true + case "flat": // MUSIC FLAT SIGN + return rune(0x266d), true + case "fllig": // LATIN SMALL LIGATURE FL + return rune(0xfb02), true + case "fltns": // WHITE PARALLELOGRAM + return rune(0x25b1), true + case "fnof": // LATIN SMALL LETTER F WITH HOOK + return rune(0x0192), true + case "fopf": // MATHEMATICAL DOUBLE-STRUCK SMALL F + return rune(0x01d557), true + case "forall": // FOR ALL + return rune(0x2200), true + case "fork": // PITCHFORK + return rune(0x22d4), true + case "forkv": // ELEMENT OF OPENING DOWNWARDS + return rune(0x2ad9), true + case "fpartint": // FINITE PART INTEGRAL + return rune(0x2a0d), true + case "frac12": // VULGAR FRACTION ONE HALF + return rune(0xbd), true + case "frac13": // VULGAR FRACTION ONE THIRD + return rune(0x2153), true + case "frac14": // VULGAR FRACTION ONE QUARTER + return rune(0xbc), true + case "frac15": // VULGAR FRACTION ONE FIFTH + return rune(0x2155), true + case "frac16": // VULGAR FRACTION ONE SIXTH + return rune(0x2159), true + case "frac18": // VULGAR FRACTION ONE EIGHTH + return rune(0x215b), true + case "frac23": // VULGAR FRACTION TWO THIRDS + return rune(0x2154), true + case "frac25": // VULGAR FRACTION TWO FIFTHS + return rune(0x2156), true + case "frac34": // VULGAR FRACTION THREE QUARTERS + return rune(0xbe), true + case "frac35": // VULGAR FRACTION THREE FIFTHS + return rune(0x2157), true + case "frac38": // VULGAR FRACTION THREE EIGHTHS + return rune(0x215c), true + case "frac45": // VULGAR FRACTION FOUR FIFTHS + return rune(0x2158), true + case "frac56": // VULGAR FRACTION FIVE SIXTHS + return rune(0x215a), true + case "frac58": // VULGAR FRACTION FIVE EIGHTHS + return rune(0x215d), true + case "frac78": // VULGAR FRACTION SEVEN EIGHTHS + return rune(0x215e), true + case "frasl": // FRACTION SLASH + return rune(0x2044), true + case "frown": // FROWN + return rune(0x2322), true + case "fscr": // MATHEMATICAL SCRIPT SMALL F + return rune(0x01d4bb), true } case 'g': switch name { - case "gE": // GREATER-THAN OVER EQUAL TO - return rune(0x2267), true - case "gEl": // GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN - return rune(0x2a8c), true - case "gacute": // LATIN SMALL LETTER G WITH ACUTE - return rune(0x01f5), true - case "gamma": // GREEK SMALL LETTER GAMMA - return rune(0x03b3), true - case "gammad": // GREEK SMALL LETTER DIGAMMA - return rune(0x03dd), true - case "gap": // GREATER-THAN OR APPROXIMATE - return rune(0x2a86), true - case "gbreve": // LATIN SMALL LETTER G WITH BREVE - return rune(0x011f), true - case "gcedil": // LATIN SMALL LETTER G WITH CEDILLA - return rune(0x0123), true - case "gcirc": // LATIN SMALL LETTER G WITH CIRCUMFLEX - return rune(0x011d), true - case "gcy": // CYRILLIC SMALL LETTER GHE - return rune(0x0433), true - case "gdot": // LATIN SMALL LETTER G WITH DOT ABOVE - return rune(0x0121), true - case "ge": // GREATER-THAN OR EQUAL TO - return rune(0x2265), true - case "gel": // GREATER-THAN EQUAL TO OR LESS-THAN - return rune(0x22db), true - case "geq": // GREATER-THAN OR EQUAL TO - return rune(0x2265), true - case "geqq": // GREATER-THAN OVER EQUAL TO - return rune(0x2267), true - case "geqslant": // GREATER-THAN OR SLANTED EQUAL TO - return rune(0x2a7e), true - case "ges": // GREATER-THAN OR SLANTED EQUAL TO - return rune(0x2a7e), true - case "gescc": // GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL - return rune(0x2aa9), true - case "gesdot": // GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE - return rune(0x2a80), true - case "gesdoto": // GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE - return rune(0x2a82), true - case "gesdotol": // GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT - return rune(0x2a84), true - case "gesl": // GREATER-THAN slanted EQUAL TO OR LESS-THAN - return rune(0x22db), true - case "gesles": // GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL - return rune(0x2a94), true - case "gfr": // MATHEMATICAL FRAKTUR SMALL G - return rune(0x01d524), true - case "gg": // MUCH GREATER-THAN - return rune(0x226b), true - case "ggg": // VERY MUCH GREATER-THAN - return rune(0x22d9), true - case "ggr": // GREEK SMALL LETTER GAMMA - return rune(0x03b3), true - case "gimel": // GIMEL SYMBOL - return rune(0x2137), true - case "gjcy": // CYRILLIC SMALL LETTER GJE - return rune(0x0453), true - case "gl": // GREATER-THAN OR LESS-THAN - return rune(0x2277), true - case "glE": // GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL - return rune(0x2a92), true - case "gla": // GREATER-THAN BESIDE LESS-THAN - return rune(0x2aa5), true - case "glj": // GREATER-THAN OVERLAPPING LESS-THAN - return rune(0x2aa4), true - case "gnE": // GREATER-THAN BUT NOT EQUAL TO - return rune(0x2269), true - case "gnap": // GREATER-THAN AND NOT APPROXIMATE - return rune(0x2a8a), true - case "gnapprox": // GREATER-THAN AND NOT APPROXIMATE - return rune(0x2a8a), true - case "gne": // GREATER-THAN AND SINGLE-LINE NOT EQUAL TO - return rune(0x2a88), true - case "gneq": // GREATER-THAN AND SINGLE-LINE NOT EQUAL TO - return rune(0x2a88), true - case "gneqq": // GREATER-THAN BUT NOT EQUAL TO - return rune(0x2269), true - case "gnsim": // GREATER-THAN BUT NOT EQUIVALENT TO - return rune(0x22e7), true - case "gopf": // MATHEMATICAL DOUBLE-STRUCK SMALL G - return rune(0x01d558), true - case "grave": // GRAVE ACCENT - return rune(0x60), true - case "gscr": // SCRIPT SMALL G - return rune(0x210a), true - case "gsdot": // GREATER-THAN WITH DOT - return rune(0x22d7), true - case "gsim": // GREATER-THAN OR EQUIVALENT TO - return rune(0x2273), true - case "gsime": // GREATER-THAN ABOVE SIMILAR OR EQUAL - return rune(0x2a8e), true - case "gsiml": // GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN - return rune(0x2a90), true - case "gt": // GREATER-THAN SIGN - return rune(0x3e), true - case "gtcc": // GREATER-THAN CLOSED BY CURVE - return rune(0x2aa7), true - case "gtcir": // GREATER-THAN WITH CIRCLE INSIDE - return rune(0x2a7a), true - case "gtdot": // GREATER-THAN WITH DOT - return rune(0x22d7), true - case "gtlPar": // DOUBLE LEFT ARC GREATER-THAN BRACKET - return rune(0x2995), true - case "gtquest": // GREATER-THAN WITH QUESTION MARK ABOVE - return rune(0x2a7c), true - case "gtrapprox": // GREATER-THAN OR APPROXIMATE - return rune(0x2a86), true - case "gtrarr": // GREATER-THAN ABOVE RIGHTWARDS ARROW - return rune(0x2978), true - case "gtrdot": // GREATER-THAN WITH DOT - return rune(0x22d7), true - case "gtreqless": // GREATER-THAN EQUAL TO OR LESS-THAN - return rune(0x22db), true - case "gtreqqless": // GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN - return rune(0x2a8c), true - case "gtrless": // GREATER-THAN OR LESS-THAN - return rune(0x2277), true - case "gtrpar": // SPHERICAL ANGLE OPENING LEFT - return rune(0x29a0), true - case "gtrsim": // GREATER-THAN OR EQUIVALENT TO - return rune(0x2273), true - case "gvertneqq": // GREATER-THAN BUT NOT EQUAL TO - with vertical stroke - return rune(0x2269), true - case "gvnE": // GREATER-THAN BUT NOT EQUAL TO - with vertical stroke - return rune(0x2269), true + case "gE": // GREATER-THAN OVER EQUAL TO + return rune(0x2267), true + case "gEl": // GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN + return rune(0x2a8c), true + case "gacute": // LATIN SMALL LETTER G WITH ACUTE + return rune(0x01f5), true + case "gamma": // GREEK SMALL LETTER GAMMA + return rune(0x03b3), true + case "gammad": // GREEK SMALL LETTER DIGAMMA + return rune(0x03dd), true + case "gap": // GREATER-THAN OR APPROXIMATE + return rune(0x2a86), true + case "gbreve": // LATIN SMALL LETTER G WITH BREVE + return rune(0x011f), true + case "gcedil": // LATIN SMALL LETTER G WITH CEDILLA + return rune(0x0123), true + case "gcirc": // LATIN SMALL LETTER G WITH CIRCUMFLEX + return rune(0x011d), true + case "gcy": // CYRILLIC SMALL LETTER GHE + return rune(0x0433), true + case "gdot": // LATIN SMALL LETTER G WITH DOT ABOVE + return rune(0x0121), true + case "ge": // GREATER-THAN OR EQUAL TO + return rune(0x2265), true + case "gel": // GREATER-THAN EQUAL TO OR LESS-THAN + return rune(0x22db), true + case "geq": // GREATER-THAN OR EQUAL TO + return rune(0x2265), true + case "geqq": // GREATER-THAN OVER EQUAL TO + return rune(0x2267), true + case "geqslant": // GREATER-THAN OR SLANTED EQUAL TO + return rune(0x2a7e), true + case "ges": // GREATER-THAN OR SLANTED EQUAL TO + return rune(0x2a7e), true + case "gescc": // GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL + return rune(0x2aa9), true + case "gesdot": // GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE + return rune(0x2a80), true + case "gesdoto": // GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE + return rune(0x2a82), true + case "gesdotol": // GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT + return rune(0x2a84), true + case "gesl": // GREATER-THAN slanted EQUAL TO OR LESS-THAN + return rune(0x22db), true + case "gesles": // GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL + return rune(0x2a94), true + case "gfr": // MATHEMATICAL FRAKTUR SMALL G + return rune(0x01d524), true + case "gg": // MUCH GREATER-THAN + return rune(0x226b), true + case "ggg": // VERY MUCH GREATER-THAN + return rune(0x22d9), true + case "ggr": // GREEK SMALL LETTER GAMMA + return rune(0x03b3), true + case "gimel": // GIMEL SYMBOL + return rune(0x2137), true + case "gjcy": // CYRILLIC SMALL LETTER GJE + return rune(0x0453), true + case "gl": // GREATER-THAN OR LESS-THAN + return rune(0x2277), true + case "glE": // GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL + return rune(0x2a92), true + case "gla": // GREATER-THAN BESIDE LESS-THAN + return rune(0x2aa5), true + case "glj": // GREATER-THAN OVERLAPPING LESS-THAN + return rune(0x2aa4), true + case "gnE": // GREATER-THAN BUT NOT EQUAL TO + return rune(0x2269), true + case "gnap": // GREATER-THAN AND NOT APPROXIMATE + return rune(0x2a8a), true + case "gnapprox": // GREATER-THAN AND NOT APPROXIMATE + return rune(0x2a8a), true + case "gne": // GREATER-THAN AND SINGLE-LINE NOT EQUAL TO + return rune(0x2a88), true + case "gneq": // GREATER-THAN AND SINGLE-LINE NOT EQUAL TO + return rune(0x2a88), true + case "gneqq": // GREATER-THAN BUT NOT EQUAL TO + return rune(0x2269), true + case "gnsim": // GREATER-THAN BUT NOT EQUIVALENT TO + return rune(0x22e7), true + case "gopf": // MATHEMATICAL DOUBLE-STRUCK SMALL G + return rune(0x01d558), true + case "grave": // GRAVE ACCENT + return rune(0x60), true + case "gscr": // SCRIPT SMALL G + return rune(0x210a), true + case "gsdot": // GREATER-THAN WITH DOT + return rune(0x22d7), true + case "gsim": // GREATER-THAN OR EQUIVALENT TO + return rune(0x2273), true + case "gsime": // GREATER-THAN ABOVE SIMILAR OR EQUAL + return rune(0x2a8e), true + case "gsiml": // GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN + return rune(0x2a90), true + case "gt": // GREATER-THAN SIGN + return rune(0x3e), true + case "gtcc": // GREATER-THAN CLOSED BY CURVE + return rune(0x2aa7), true + case "gtcir": // GREATER-THAN WITH CIRCLE INSIDE + return rune(0x2a7a), true + case "gtdot": // GREATER-THAN WITH DOT + return rune(0x22d7), true + case "gtlPar": // DOUBLE LEFT ARC GREATER-THAN BRACKET + return rune(0x2995), true + case "gtquest": // GREATER-THAN WITH QUESTION MARK ABOVE + return rune(0x2a7c), true + case "gtrapprox": // GREATER-THAN OR APPROXIMATE + return rune(0x2a86), true + case "gtrarr": // GREATER-THAN ABOVE RIGHTWARDS ARROW + return rune(0x2978), true + case "gtrdot": // GREATER-THAN WITH DOT + return rune(0x22d7), true + case "gtreqless": // GREATER-THAN EQUAL TO OR LESS-THAN + return rune(0x22db), true + case "gtreqqless": // GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN + return rune(0x2a8c), true + case "gtrless": // GREATER-THAN OR LESS-THAN + return rune(0x2277), true + case "gtrpar": // SPHERICAL ANGLE OPENING LEFT + return rune(0x29a0), true + case "gtrsim": // GREATER-THAN OR EQUIVALENT TO + return rune(0x2273), true + case "gvertneqq": // GREATER-THAN BUT NOT EQUAL TO - with vertical stroke + return rune(0x2269), true + case "gvnE": // GREATER-THAN BUT NOT EQUAL TO - with vertical stroke + return rune(0x2269), true } case 'h': switch name { - case "hArr": // LEFT RIGHT DOUBLE ARROW - return rune(0x21d4), true - case "hairsp": // HAIR SPACE - return rune(0x200a), true - case "half": // VULGAR FRACTION ONE HALF - return rune(0xbd), true - case "hamilt": // SCRIPT CAPITAL H - return rune(0x210b), true - case "hardcy": // CYRILLIC SMALL LETTER HARD SIGN - return rune(0x044a), true - case "harr": // LEFT RIGHT ARROW - return rune(0x2194), true - case "harrcir": // LEFT RIGHT ARROW THROUGH SMALL CIRCLE - return rune(0x2948), true - case "harrw": // LEFT RIGHT WAVE ARROW - return rune(0x21ad), true - case "hbar": // PLANCK CONSTANT OVER TWO PI - return rune(0x210f), true - case "hcirc": // LATIN SMALL LETTER H WITH CIRCUMFLEX - return rune(0x0125), true - case "hearts": // BLACK HEART SUIT - return rune(0x2665), true - case "heartsuit": // BLACK HEART SUIT - return rune(0x2665), true - case "hellip": // HORIZONTAL ELLIPSIS - return rune(0x2026), true - case "hercon": // HERMITIAN CONJUGATE MATRIX - return rune(0x22b9), true - case "hfr": // MATHEMATICAL FRAKTUR SMALL H - return rune(0x01d525), true - case "hksearow": // SOUTH EAST ARROW WITH HOOK - return rune(0x2925), true - case "hkswarow": // SOUTH WEST ARROW WITH HOOK - return rune(0x2926), true - case "hoarr": // LEFT RIGHT OPEN-HEADED ARROW - return rune(0x21ff), true - case "homtht": // HOMOTHETIC - return rune(0x223b), true - case "hookleftarrow": // LEFTWARDS ARROW WITH HOOK - return rune(0x21a9), true - case "hookrightarrow": // RIGHTWARDS ARROW WITH HOOK - return rune(0x21aa), true - case "hopf": // MATHEMATICAL DOUBLE-STRUCK SMALL H - return rune(0x01d559), true - case "horbar": // HORIZONTAL BAR - return rune(0x2015), true - case "hrglass": // WHITE HOURGLASS - return rune(0x29d6), true - case "hscr": // MATHEMATICAL SCRIPT SMALL H - return rune(0x01d4bd), true - case "hslash": // PLANCK CONSTANT OVER TWO PI - return rune(0x210f), true - case "hstrok": // LATIN SMALL LETTER H WITH STROKE - return rune(0x0127), true - case "htimes": // VECTOR OR CROSS PRODUCT - return rune(0x2a2f), true - case "hybull": // HYPHEN BULLET - return rune(0x2043), true - case "hyphen": // HYPHEN - return rune(0x2010), true + case "hArr": // LEFT RIGHT DOUBLE ARROW + return rune(0x21d4), true + case "hairsp": // HAIR SPACE + return rune(0x200a), true + case "half": // VULGAR FRACTION ONE HALF + return rune(0xbd), true + case "hamilt": // SCRIPT CAPITAL H + return rune(0x210b), true + case "hardcy": // CYRILLIC SMALL LETTER HARD SIGN + return rune(0x044a), true + case "harr": // LEFT RIGHT ARROW + return rune(0x2194), true + case "harrcir": // LEFT RIGHT ARROW THROUGH SMALL CIRCLE + return rune(0x2948), true + case "harrw": // LEFT RIGHT WAVE ARROW + return rune(0x21ad), true + case "hbar": // PLANCK CONSTANT OVER TWO PI + return rune(0x210f), true + case "hcirc": // LATIN SMALL LETTER H WITH CIRCUMFLEX + return rune(0x0125), true + case "hearts": // BLACK HEART SUIT + return rune(0x2665), true + case "heartsuit": // BLACK HEART SUIT + return rune(0x2665), true + case "hellip": // HORIZONTAL ELLIPSIS + return rune(0x2026), true + case "hercon": // HERMITIAN CONJUGATE MATRIX + return rune(0x22b9), true + case "hfr": // MATHEMATICAL FRAKTUR SMALL H + return rune(0x01d525), true + case "hksearow": // SOUTH EAST ARROW WITH HOOK + return rune(0x2925), true + case "hkswarow": // SOUTH WEST ARROW WITH HOOK + return rune(0x2926), true + case "hoarr": // LEFT RIGHT OPEN-HEADED ARROW + return rune(0x21ff), true + case "homtht": // HOMOTHETIC + return rune(0x223b), true + case "hookleftarrow": // LEFTWARDS ARROW WITH HOOK + return rune(0x21a9), true + case "hookrightarrow": // RIGHTWARDS ARROW WITH HOOK + return rune(0x21aa), true + case "hopf": // MATHEMATICAL DOUBLE-STRUCK SMALL H + return rune(0x01d559), true + case "horbar": // HORIZONTAL BAR + return rune(0x2015), true + case "hrglass": // WHITE HOURGLASS + return rune(0x29d6), true + case "hscr": // MATHEMATICAL SCRIPT SMALL H + return rune(0x01d4bd), true + case "hslash": // PLANCK CONSTANT OVER TWO PI + return rune(0x210f), true + case "hstrok": // LATIN SMALL LETTER H WITH STROKE + return rune(0x0127), true + case "htimes": // VECTOR OR CROSS PRODUCT + return rune(0x2a2f), true + case "hybull": // HYPHEN BULLET + return rune(0x2043), true + case "hyphen": // HYPHEN + return rune(0x2010), true } case 'i': switch name { - case "iacgr": // GREEK SMALL LETTER IOTA WITH TONOS - return rune(0x03af), true - case "iacute": // LATIN SMALL LETTER I WITH ACUTE - return rune(0xed), true - case "ic": // INVISIBLE SEPARATOR - return rune(0x2063), true - case "icirc": // LATIN SMALL LETTER I WITH CIRCUMFLEX - return rune(0xee), true - case "icy": // CYRILLIC SMALL LETTER I - return rune(0x0438), true - case "idiagr": // GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS - return rune(0x0390), true - case "idigr": // GREEK SMALL LETTER IOTA WITH DIALYTIKA - return rune(0x03ca), true - case "iecy": // CYRILLIC SMALL LETTER IE - return rune(0x0435), true - case "iexcl": // INVERTED EXCLAMATION MARK - return rune(0xa1), true - case "iff": // LEFT RIGHT DOUBLE ARROW - return rune(0x21d4), true - case "ifr": // MATHEMATICAL FRAKTUR SMALL I - return rune(0x01d526), true - case "igr": // GREEK SMALL LETTER IOTA - return rune(0x03b9), true - case "igrave": // LATIN SMALL LETTER I WITH GRAVE - return rune(0xec), true - case "ii": // DOUBLE-STRUCK ITALIC SMALL I - return rune(0x2148), true - case "iiiint": // QUADRUPLE INTEGRAL OPERATOR - return rune(0x2a0c), true - case "iiint": // TRIPLE INTEGRAL - return rune(0x222d), true - case "iinfin": // INCOMPLETE INFINITY - return rune(0x29dc), true - case "iiota": // TURNED GREEK SMALL LETTER IOTA - return rune(0x2129), true - case "ijlig": // LATIN SMALL LIGATURE IJ - return rune(0x0133), true - case "imacr": // LATIN SMALL LETTER I WITH MACRON - return rune(0x012b), true - case "image": // BLACK-LETTER CAPITAL I - return rune(0x2111), true - case "imagline": // SCRIPT CAPITAL I - return rune(0x2110), true - case "imagpart": // BLACK-LETTER CAPITAL I - return rune(0x2111), true - case "imath": // LATIN SMALL LETTER DOTLESS I - return rune(0x0131), true - case "imof": // IMAGE OF - return rune(0x22b7), true - case "imped": // LATIN CAPITAL LETTER Z WITH STROKE - return rune(0x01b5), true - case "in": // ELEMENT OF - return rune(0x2208), true - case "incare": // CARE OF - return rune(0x2105), true - case "infin": // INFINITY - return rune(0x221e), true - case "infintie": // TIE OVER INFINITY - return rune(0x29dd), true - case "inodot": // LATIN SMALL LETTER DOTLESS I - return rune(0x0131), true - case "int": // INTEGRAL - return rune(0x222b), true - case "intcal": // INTERCALATE - return rune(0x22ba), true - case "integers": // DOUBLE-STRUCK CAPITAL Z - return rune(0x2124), true - case "intercal": // INTERCALATE - return rune(0x22ba), true - case "intlarhk": // INTEGRAL WITH LEFTWARDS ARROW WITH HOOK - return rune(0x2a17), true - case "intprod": // INTERIOR PRODUCT - return rune(0x2a3c), true - case "iocy": // CYRILLIC SMALL LETTER IO - return rune(0x0451), true - case "iogon": // LATIN SMALL LETTER I WITH OGONEK - return rune(0x012f), true - case "iopf": // MATHEMATICAL DOUBLE-STRUCK SMALL I - return rune(0x01d55a), true - case "iota": // GREEK SMALL LETTER IOTA - return rune(0x03b9), true - case "iprod": // INTERIOR PRODUCT - return rune(0x2a3c), true - case "iprodr": // RIGHTHAND INTERIOR PRODUCT - return rune(0x2a3d), true - case "iquest": // INVERTED QUESTION MARK - return rune(0xbf), true - case "iscr": // MATHEMATICAL SCRIPT SMALL I - return rune(0x01d4be), true - case "isin": // ELEMENT OF - return rune(0x2208), true - case "isinE": // ELEMENT OF WITH TWO HORIZONTAL STROKES - return rune(0x22f9), true - case "isindot": // ELEMENT OF WITH DOT ABOVE - return rune(0x22f5), true - case "isins": // SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE - return rune(0x22f4), true - case "isinsv": // ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE - return rune(0x22f3), true - case "isinv": // ELEMENT OF - return rune(0x2208), true - case "isinvb": // ELEMENT OF WITH UNDERBAR - return rune(0x22f8), true - case "it": // INVISIBLE TIMES - return rune(0x2062), true - case "itilde": // LATIN SMALL LETTER I WITH TILDE - return rune(0x0129), true - case "iukcy": // CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I - return rune(0x0456), true - case "iuml": // LATIN SMALL LETTER I WITH DIAERESIS - return rune(0xef), true + case "iacgr": // GREEK SMALL LETTER IOTA WITH TONOS + return rune(0x03af), true + case "iacute": // LATIN SMALL LETTER I WITH ACUTE + return rune(0xed), true + case "ic": // INVISIBLE SEPARATOR + return rune(0x2063), true + case "icirc": // LATIN SMALL LETTER I WITH CIRCUMFLEX + return rune(0xee), true + case "icy": // CYRILLIC SMALL LETTER I + return rune(0x0438), true + case "idiagr": // GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + return rune(0x0390), true + case "idigr": // GREEK SMALL LETTER IOTA WITH DIALYTIKA + return rune(0x03ca), true + case "iecy": // CYRILLIC SMALL LETTER IE + return rune(0x0435), true + case "iexcl": // INVERTED EXCLAMATION MARK + return rune(0xa1), true + case "iff": // LEFT RIGHT DOUBLE ARROW + return rune(0x21d4), true + case "ifr": // MATHEMATICAL FRAKTUR SMALL I + return rune(0x01d526), true + case "igr": // GREEK SMALL LETTER IOTA + return rune(0x03b9), true + case "igrave": // LATIN SMALL LETTER I WITH GRAVE + return rune(0xec), true + case "ii": // DOUBLE-STRUCK ITALIC SMALL I + return rune(0x2148), true + case "iiiint": // QUADRUPLE INTEGRAL OPERATOR + return rune(0x2a0c), true + case "iiint": // TRIPLE INTEGRAL + return rune(0x222d), true + case "iinfin": // INCOMPLETE INFINITY + return rune(0x29dc), true + case "iiota": // TURNED GREEK SMALL LETTER IOTA + return rune(0x2129), true + case "ijlig": // LATIN SMALL LIGATURE IJ + return rune(0x0133), true + case "imacr": // LATIN SMALL LETTER I WITH MACRON + return rune(0x012b), true + case "image": // BLACK-LETTER CAPITAL I + return rune(0x2111), true + case "imagline": // SCRIPT CAPITAL I + return rune(0x2110), true + case "imagpart": // BLACK-LETTER CAPITAL I + return rune(0x2111), true + case "imath": // LATIN SMALL LETTER DOTLESS I + return rune(0x0131), true + case "imof": // IMAGE OF + return rune(0x22b7), true + case "imped": // LATIN CAPITAL LETTER Z WITH STROKE + return rune(0x01b5), true + case "in": // ELEMENT OF + return rune(0x2208), true + case "incare": // CARE OF + return rune(0x2105), true + case "infin": // INFINITY + return rune(0x221e), true + case "infintie": // TIE OVER INFINITY + return rune(0x29dd), true + case "inodot": // LATIN SMALL LETTER DOTLESS I + return rune(0x0131), true + case "int": // INTEGRAL + return rune(0x222b), true + case "intcal": // INTERCALATE + return rune(0x22ba), true + case "integers": // DOUBLE-STRUCK CAPITAL Z + return rune(0x2124), true + case "intercal": // INTERCALATE + return rune(0x22ba), true + case "intlarhk": // INTEGRAL WITH LEFTWARDS ARROW WITH HOOK + return rune(0x2a17), true + case "intprod": // INTERIOR PRODUCT + return rune(0x2a3c), true + case "iocy": // CYRILLIC SMALL LETTER IO + return rune(0x0451), true + case "iogon": // LATIN SMALL LETTER I WITH OGONEK + return rune(0x012f), true + case "iopf": // MATHEMATICAL DOUBLE-STRUCK SMALL I + return rune(0x01d55a), true + case "iota": // GREEK SMALL LETTER IOTA + return rune(0x03b9), true + case "iprod": // INTERIOR PRODUCT + return rune(0x2a3c), true + case "iprodr": // RIGHTHAND INTERIOR PRODUCT + return rune(0x2a3d), true + case "iquest": // INVERTED QUESTION MARK + return rune(0xbf), true + case "iscr": // MATHEMATICAL SCRIPT SMALL I + return rune(0x01d4be), true + case "isin": // ELEMENT OF + return rune(0x2208), true + case "isinE": // ELEMENT OF WITH TWO HORIZONTAL STROKES + return rune(0x22f9), true + case "isindot": // ELEMENT OF WITH DOT ABOVE + return rune(0x22f5), true + case "isins": // SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE + return rune(0x22f4), true + case "isinsv": // ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE + return rune(0x22f3), true + case "isinv": // ELEMENT OF + return rune(0x2208), true + case "isinvb": // ELEMENT OF WITH UNDERBAR + return rune(0x22f8), true + case "it": // INVISIBLE TIMES + return rune(0x2062), true + case "itilde": // LATIN SMALL LETTER I WITH TILDE + return rune(0x0129), true + case "iukcy": // CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + return rune(0x0456), true + case "iuml": // LATIN SMALL LETTER I WITH DIAERESIS + return rune(0xef), true } case 'j': switch name { - case "jcirc": // LATIN SMALL LETTER J WITH CIRCUMFLEX - return rune(0x0135), true - case "jcy": // CYRILLIC SMALL LETTER SHORT I - return rune(0x0439), true - case "jfr": // MATHEMATICAL FRAKTUR SMALL J - return rune(0x01d527), true - case "jmath": // LATIN SMALL LETTER DOTLESS J - return rune(0x0237), true - case "jnodot": // LATIN SMALL LETTER DOTLESS J - return rune(0x0237), true - case "jopf": // MATHEMATICAL DOUBLE-STRUCK SMALL J - return rune(0x01d55b), true - case "jscr": // MATHEMATICAL SCRIPT SMALL J - return rune(0x01d4bf), true - case "jsercy": // CYRILLIC SMALL LETTER JE - return rune(0x0458), true - case "jukcy": // CYRILLIC SMALL LETTER UKRAINIAN IE - return rune(0x0454), true + case "jcirc": // LATIN SMALL LETTER J WITH CIRCUMFLEX + return rune(0x0135), true + case "jcy": // CYRILLIC SMALL LETTER SHORT I + return rune(0x0439), true + case "jfr": // MATHEMATICAL FRAKTUR SMALL J + return rune(0x01d527), true + case "jmath": // LATIN SMALL LETTER DOTLESS J + return rune(0x0237), true + case "jnodot": // LATIN SMALL LETTER DOTLESS J + return rune(0x0237), true + case "jopf": // MATHEMATICAL DOUBLE-STRUCK SMALL J + return rune(0x01d55b), true + case "jscr": // MATHEMATICAL SCRIPT SMALL J + return rune(0x01d4bf), true + case "jsercy": // CYRILLIC SMALL LETTER JE + return rune(0x0458), true + case "jukcy": // CYRILLIC SMALL LETTER UKRAINIAN IE + return rune(0x0454), true } case 'k': switch name { - case "kappa": // GREEK SMALL LETTER KAPPA - return rune(0x03ba), true - case "kappav": // GREEK KAPPA SYMBOL - return rune(0x03f0), true - case "kcedil": // LATIN SMALL LETTER K WITH CEDILLA - return rune(0x0137), true - case "kcy": // CYRILLIC SMALL LETTER KA - return rune(0x043a), true - case "kfr": // MATHEMATICAL FRAKTUR SMALL K - return rune(0x01d528), true - case "kgr": // GREEK SMALL LETTER KAPPA - return rune(0x03ba), true - case "kgreen": // LATIN SMALL LETTER KRA - return rune(0x0138), true - case "khcy": // CYRILLIC SMALL LETTER HA - return rune(0x0445), true - case "khgr": // GREEK SMALL LETTER CHI - return rune(0x03c7), true - case "kjcy": // CYRILLIC SMALL LETTER KJE - return rune(0x045c), true - case "kopf": // MATHEMATICAL DOUBLE-STRUCK SMALL K - return rune(0x01d55c), true - case "koppa": // GREEK LETTER KOPPA - return rune(0x03de), true - case "kscr": // MATHEMATICAL SCRIPT SMALL K - return rune(0x01d4c0), true + case "kappa": // GREEK SMALL LETTER KAPPA + return rune(0x03ba), true + case "kappav": // GREEK KAPPA SYMBOL + return rune(0x03f0), true + case "kcedil": // LATIN SMALL LETTER K WITH CEDILLA + return rune(0x0137), true + case "kcy": // CYRILLIC SMALL LETTER KA + return rune(0x043a), true + case "kfr": // MATHEMATICAL FRAKTUR SMALL K + return rune(0x01d528), true + case "kgr": // GREEK SMALL LETTER KAPPA + return rune(0x03ba), true + case "kgreen": // LATIN SMALL LETTER KRA + return rune(0x0138), true + case "khcy": // CYRILLIC SMALL LETTER HA + return rune(0x0445), true + case "khgr": // GREEK SMALL LETTER CHI + return rune(0x03c7), true + case "kjcy": // CYRILLIC SMALL LETTER KJE + return rune(0x045c), true + case "kopf": // MATHEMATICAL DOUBLE-STRUCK SMALL K + return rune(0x01d55c), true + case "koppa": // GREEK LETTER KOPPA + return rune(0x03de), true + case "kscr": // MATHEMATICAL SCRIPT SMALL K + return rune(0x01d4c0), true } case 'l': switch name { - case "lAarr": // LEFTWARDS TRIPLE ARROW - return rune(0x21da), true - case "lArr": // LEFTWARDS DOUBLE ARROW - return rune(0x21d0), true - case "lAtail": // LEFTWARDS DOUBLE ARROW-TAIL - return rune(0x291b), true - case "lBarr": // LEFTWARDS TRIPLE DASH ARROW - return rune(0x290e), true - case "lE": // LESS-THAN OVER EQUAL TO - return rune(0x2266), true - case "lEg": // LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN - return rune(0x2a8b), true - case "lHar": // LEFTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB DOWN - return rune(0x2962), true - case "lacute": // LATIN SMALL LETTER L WITH ACUTE - return rune(0x013a), true - case "laemptyv": // EMPTY SET WITH LEFT ARROW ABOVE - return rune(0x29b4), true - case "lagran": // SCRIPT CAPITAL L - return rune(0x2112), true - case "lambda": // GREEK SMALL LETTER LAMDA - return rune(0x03bb), true - case "lang": // MATHEMATICAL LEFT ANGLE BRACKET - return rune(0x27e8), true - case "langd": // LEFT ANGLE BRACKET WITH DOT - return rune(0x2991), true - case "langle": // MATHEMATICAL LEFT ANGLE BRACKET - return rune(0x27e8), true - case "lap": // LESS-THAN OR APPROXIMATE - return rune(0x2a85), true - case "laquo": // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK - return rune(0xab), true - case "larr": // LEFTWARDS ARROW - return rune(0x2190), true - case "larr2": // LEFTWARDS PAIRED ARROWS - return rune(0x21c7), true - case "larrb": // LEFTWARDS ARROW TO BAR - return rune(0x21e4), true - case "larrbfs": // LEFTWARDS ARROW FROM BAR TO BLACK DIAMOND - return rune(0x291f), true - case "larrfs": // LEFTWARDS ARROW TO BLACK DIAMOND - return rune(0x291d), true - case "larrhk": // LEFTWARDS ARROW WITH HOOK - return rune(0x21a9), true - case "larrlp": // LEFTWARDS ARROW WITH LOOP - return rune(0x21ab), true - case "larrpl": // LEFT-SIDE ARC ANTICLOCKWISE ARROW - return rune(0x2939), true - case "larrsim": // LEFTWARDS ARROW ABOVE TILDE OPERATOR - return rune(0x2973), true - case "larrtl": // LEFTWARDS ARROW WITH TAIL - return rune(0x21a2), true - case "lat": // LARGER THAN - return rune(0x2aab), true - case "latail": // LEFTWARDS ARROW-TAIL - return rune(0x2919), true - case "late": // LARGER THAN OR EQUAL TO - return rune(0x2aad), true - case "lates": // LARGER THAN OR slanted EQUAL - return rune(0x2aad), true - case "lbarr": // LEFTWARDS DOUBLE DASH ARROW - return rune(0x290c), true - case "lbbrk": // LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT - return rune(0x2772), true - case "lbrace": // LEFT CURLY BRACKET - return rune(0x7b), true - case "lbrack": // LEFT SQUARE BRACKET - return rune(0x5b), true - case "lbrke": // LEFT SQUARE BRACKET WITH UNDERBAR - return rune(0x298b), true - case "lbrksld": // LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER - return rune(0x298f), true - case "lbrkslu": // LEFT SQUARE BRACKET WITH TICK IN TOP CORNER - return rune(0x298d), true - case "lcaron": // LATIN SMALL LETTER L WITH CARON - return rune(0x013e), true - case "lcedil": // LATIN SMALL LETTER L WITH CEDILLA - return rune(0x013c), true - case "lceil": // LEFT CEILING - return rune(0x2308), true - case "lcub": // LEFT CURLY BRACKET - return rune(0x7b), true - case "lcy": // CYRILLIC SMALL LETTER EL - return rune(0x043b), true - case "ldca": // ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS - return rune(0x2936), true - case "ldharb": // LEFTWARDS HARPOON WITH BARB DOWN TO BAR - return rune(0x2956), true - case "ldot": // LESS-THAN WITH DOT - return rune(0x22d6), true - case "ldquo": // LEFT DOUBLE QUOTATION MARK - return rune(0x201c), true - case "ldquor": // DOUBLE LOW-9 QUOTATION MARK - return rune(0x201e), true - case "ldrdhar": // LEFTWARDS HARPOON WITH BARB DOWN ABOVE RIGHTWARDS HARPOON WITH BARB DOWN - return rune(0x2967), true - case "ldrdshar": // LEFT BARB DOWN RIGHT BARB DOWN HARPOON - return rune(0x2950), true - case "ldrushar": // LEFT BARB DOWN RIGHT BARB UP HARPOON - return rune(0x294b), true - case "ldsh": // DOWNWARDS ARROW WITH TIP LEFTWARDS - return rune(0x21b2), true - case "le": // LESS-THAN OR EQUAL TO - return rune(0x2264), true - case "leftarrow": // LEFTWARDS ARROW - return rune(0x2190), true - case "leftarrowtail": // LEFTWARDS ARROW WITH TAIL - return rune(0x21a2), true - case "leftharpoondown": // LEFTWARDS HARPOON WITH BARB DOWNWARDS - return rune(0x21bd), true - case "leftharpoonup": // LEFTWARDS HARPOON WITH BARB UPWARDS - return rune(0x21bc), true - case "leftleftarrows": // LEFTWARDS PAIRED ARROWS - return rune(0x21c7), true - case "leftrightarrow": // LEFT RIGHT ARROW - return rune(0x2194), true - case "leftrightarrows": // LEFTWARDS ARROW OVER RIGHTWARDS ARROW - return rune(0x21c6), true - case "leftrightharpoons": // LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON - return rune(0x21cb), true - case "leftrightsquigarrow": // LEFT RIGHT WAVE ARROW - return rune(0x21ad), true - case "leftthreetimes": // LEFT SEMIDIRECT PRODUCT - return rune(0x22cb), true - case "leg": // LESS-THAN EQUAL TO OR GREATER-THAN - return rune(0x22da), true - case "leq": // LESS-THAN OR EQUAL TO - return rune(0x2264), true - case "leqq": // LESS-THAN OVER EQUAL TO - return rune(0x2266), true - case "leqslant": // LESS-THAN OR SLANTED EQUAL TO - return rune(0x2a7d), true - case "les": // LESS-THAN OR SLANTED EQUAL TO - return rune(0x2a7d), true - case "lescc": // LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL - return rune(0x2aa8), true - case "lesdot": // LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE - return rune(0x2a7f), true - case "lesdoto": // LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE - return rune(0x2a81), true - case "lesdotor": // LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT - return rune(0x2a83), true - case "lesg": // LESS-THAN slanted EQUAL TO OR GREATER-THAN - return rune(0x22da), true - case "lesges": // LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL - return rune(0x2a93), true - case "lessapprox": // LESS-THAN OR APPROXIMATE - return rune(0x2a85), true - case "lessdot": // LESS-THAN WITH DOT - return rune(0x22d6), true - case "lesseqgtr": // LESS-THAN EQUAL TO OR GREATER-THAN - return rune(0x22da), true - case "lesseqqgtr": // LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN - return rune(0x2a8b), true - case "lessgtr": // LESS-THAN OR GREATER-THAN - return rune(0x2276), true - case "lesssim": // LESS-THAN OR EQUIVALENT TO - return rune(0x2272), true - case "lfbowtie": // BOWTIE WITH LEFT HALF BLACK - return rune(0x29d1), true - case "lfisht": // LEFT FISH TAIL - return rune(0x297c), true - case "lfloor": // LEFT FLOOR - return rune(0x230a), true - case "lfr": // MATHEMATICAL FRAKTUR SMALL L - return rune(0x01d529), true - case "lftimes": // TIMES WITH LEFT HALF BLACK - return rune(0x29d4), true - case "lg": // LESS-THAN OR GREATER-THAN - return rune(0x2276), true - case "lgE": // LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL - return rune(0x2a91), true - case "lgr": // GREEK SMALL LETTER LAMDA - return rune(0x03bb), true - case "lhard": // LEFTWARDS HARPOON WITH BARB DOWNWARDS - return rune(0x21bd), true - case "lharu": // LEFTWARDS HARPOON WITH BARB UPWARDS - return rune(0x21bc), true - case "lharul": // LEFTWARDS HARPOON WITH BARB UP ABOVE LONG DASH - return rune(0x296a), true - case "lhblk": // LOWER HALF BLOCK - return rune(0x2584), true - case "ljcy": // CYRILLIC SMALL LETTER LJE - return rune(0x0459), true - case "ll": // MUCH LESS-THAN - return rune(0x226a), true - case "llarr": // LEFTWARDS PAIRED ARROWS - return rune(0x21c7), true - case "llcorner": // BOTTOM LEFT CORNER - return rune(0x231e), true - case "llhard": // LEFTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH - return rune(0x296b), true - case "lltri": // LOWER LEFT TRIANGLE - return rune(0x25fa), true - case "lltrif": // BLACK LOWER LEFT TRIANGLE - return rune(0x25e3), true - case "lmidot": // LATIN SMALL LETTER L WITH MIDDLE DOT - return rune(0x0140), true - case "lmoust": // UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION - return rune(0x23b0), true - case "lmoustache": // UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION - return rune(0x23b0), true - case "lnE": // LESS-THAN BUT NOT EQUAL TO - return rune(0x2268), true - case "lnap": // LESS-THAN AND NOT APPROXIMATE - return rune(0x2a89), true - case "lnapprox": // LESS-THAN AND NOT APPROXIMATE - return rune(0x2a89), true - case "lne": // LESS-THAN AND SINGLE-LINE NOT EQUAL TO - return rune(0x2a87), true - case "lneq": // LESS-THAN AND SINGLE-LINE NOT EQUAL TO - return rune(0x2a87), true - case "lneqq": // LESS-THAN BUT NOT EQUAL TO - return rune(0x2268), true - case "lnsim": // LESS-THAN BUT NOT EQUIVALENT TO - return rune(0x22e6), true - case "loang": // MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET - return rune(0x27ec), true - case "loarr": // LEFTWARDS OPEN-HEADED ARROW - return rune(0x21fd), true - case "lobrk": // MATHEMATICAL LEFT WHITE SQUARE BRACKET - return rune(0x27e6), true - case "locub": // LEFT WHITE CURLY BRACKET - return rune(0x2983), true - case "longleftarrow": // LONG LEFTWARDS ARROW - return rune(0x27f5), true - case "longleftrightarrow": // LONG LEFT RIGHT ARROW - return rune(0x27f7), true - case "longmapsto": // LONG RIGHTWARDS ARROW FROM BAR - return rune(0x27fc), true - case "longrightarrow": // LONG RIGHTWARDS ARROW - return rune(0x27f6), true - case "looparrowleft": // LEFTWARDS ARROW WITH LOOP - return rune(0x21ab), true - case "looparrowright": // RIGHTWARDS ARROW WITH LOOP - return rune(0x21ac), true - case "lopar": // LEFT WHITE PARENTHESIS - return rune(0x2985), true - case "lopf": // MATHEMATICAL DOUBLE-STRUCK SMALL L - return rune(0x01d55d), true - case "loplus": // PLUS SIGN IN LEFT HALF CIRCLE - return rune(0x2a2d), true - case "lotimes": // MULTIPLICATION SIGN IN LEFT HALF CIRCLE - return rune(0x2a34), true - case "lowast": // LOW ASTERISK - return rune(0x204e), true - case "lowbar": // LOW LINE - return rune(0x5f), true - case "lowint": // INTEGRAL WITH UNDERBAR - return rune(0x2a1c), true - case "loz": // LOZENGE - return rune(0x25ca), true - case "lozenge": // LOZENGE - return rune(0x25ca), true - case "lozf": // BLACK LOZENGE - return rune(0x29eb), true - case "lpar": // LEFT PARENTHESIS - return rune(0x28), true - case "lpargt": // SPHERICAL ANGLE OPENING LEFT - return rune(0x29a0), true - case "lparlt": // LEFT ARC LESS-THAN BRACKET - return rune(0x2993), true - case "lrarr": // LEFTWARDS ARROW OVER RIGHTWARDS ARROW - return rune(0x21c6), true - case "lrarr2": // LEFTWARDS ARROW OVER RIGHTWARDS ARROW - return rune(0x21c6), true - case "lrcorner": // BOTTOM RIGHT CORNER - return rune(0x231f), true - case "lrhar": // LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON - return rune(0x21cb), true - case "lrhar2": // LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON - return rune(0x21cb), true - case "lrhard": // RIGHTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH - return rune(0x296d), true - case "lrm": // LEFT-TO-RIGHT MARK - return rune(0x200e), true - case "lrtri": // RIGHT TRIANGLE - return rune(0x22bf), true - case "lsaquo": // SINGLE LEFT-POINTING ANGLE QUOTATION MARK - return rune(0x2039), true - case "lscr": // MATHEMATICAL SCRIPT SMALL L - return rune(0x01d4c1), true - case "lsh": // UPWARDS ARROW WITH TIP LEFTWARDS - return rune(0x21b0), true - case "lsim": // LESS-THAN OR EQUIVALENT TO - return rune(0x2272), true - case "lsime": // LESS-THAN ABOVE SIMILAR OR EQUAL - return rune(0x2a8d), true - case "lsimg": // LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN - return rune(0x2a8f), true - case "lsqb": // LEFT SQUARE BRACKET - return rune(0x5b), true - case "lsquo": // LEFT SINGLE QUOTATION MARK - return rune(0x2018), true - case "lsquor": // SINGLE LOW-9 QUOTATION MARK - return rune(0x201a), true - case "lstrok": // LATIN SMALL LETTER L WITH STROKE - return rune(0x0142), true - case "lt": // LESS-THAN SIGN - return rune(0x3c), true - case "ltcc": // LESS-THAN CLOSED BY CURVE - return rune(0x2aa6), true - case "ltcir": // LESS-THAN WITH CIRCLE INSIDE - return rune(0x2a79), true - case "ltdot": // LESS-THAN WITH DOT - return rune(0x22d6), true - case "lthree": // LEFT SEMIDIRECT PRODUCT - return rune(0x22cb), true - case "ltimes": // LEFT NORMAL FACTOR SEMIDIRECT PRODUCT - return rune(0x22c9), true - case "ltlarr": // LESS-THAN ABOVE LEFTWARDS ARROW - return rune(0x2976), true - case "ltquest": // LESS-THAN WITH QUESTION MARK ABOVE - return rune(0x2a7b), true - case "ltrPar": // DOUBLE RIGHT ARC LESS-THAN BRACKET - return rune(0x2996), true - case "ltri": // WHITE LEFT-POINTING SMALL TRIANGLE - return rune(0x25c3), true - case "ltrie": // NORMAL SUBGROUP OF OR EQUAL TO - return rune(0x22b4), true - case "ltrif": // BLACK LEFT-POINTING SMALL TRIANGLE - return rune(0x25c2), true - case "ltrivb": // LEFT TRIANGLE BESIDE VERTICAL BAR - return rune(0x29cf), true - case "luharb": // LEFTWARDS HARPOON WITH BARB UP TO BAR - return rune(0x2952), true - case "lurdshar": // LEFT BARB UP RIGHT BARB DOWN HARPOON - return rune(0x294a), true - case "luruhar": // LEFTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB UP - return rune(0x2966), true - case "lurushar": // LEFT BARB UP RIGHT BARB UP HARPOON - return rune(0x294e), true - case "lvertneqq": // LESS-THAN BUT NOT EQUAL TO - with vertical stroke - return rune(0x2268), true - case "lvnE": // LESS-THAN BUT NOT EQUAL TO - with vertical stroke - return rune(0x2268), true + case "lAarr": // LEFTWARDS TRIPLE ARROW + return rune(0x21da), true + case "lArr": // LEFTWARDS DOUBLE ARROW + return rune(0x21d0), true + case "lAtail": // LEFTWARDS DOUBLE ARROW-TAIL + return rune(0x291b), true + case "lBarr": // LEFTWARDS TRIPLE DASH ARROW + return rune(0x290e), true + case "lE": // LESS-THAN OVER EQUAL TO + return rune(0x2266), true + case "lEg": // LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN + return rune(0x2a8b), true + case "lHar": // LEFTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB DOWN + return rune(0x2962), true + case "lacute": // LATIN SMALL LETTER L WITH ACUTE + return rune(0x013a), true + case "laemptyv": // EMPTY SET WITH LEFT ARROW ABOVE + return rune(0x29b4), true + case "lagran": // SCRIPT CAPITAL L + return rune(0x2112), true + case "lambda": // GREEK SMALL LETTER LAMDA + return rune(0x03bb), true + case "lang": // MATHEMATICAL LEFT ANGLE BRACKET + return rune(0x27e8), true + case "langd": // LEFT ANGLE BRACKET WITH DOT + return rune(0x2991), true + case "langle": // MATHEMATICAL LEFT ANGLE BRACKET + return rune(0x27e8), true + case "lap": // LESS-THAN OR APPROXIMATE + return rune(0x2a85), true + case "laquo": // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + return rune(0xab), true + case "larr": // LEFTWARDS ARROW + return rune(0x2190), true + case "larr2": // LEFTWARDS PAIRED ARROWS + return rune(0x21c7), true + case "larrb": // LEFTWARDS ARROW TO BAR + return rune(0x21e4), true + case "larrbfs": // LEFTWARDS ARROW FROM BAR TO BLACK DIAMOND + return rune(0x291f), true + case "larrfs": // LEFTWARDS ARROW TO BLACK DIAMOND + return rune(0x291d), true + case "larrhk": // LEFTWARDS ARROW WITH HOOK + return rune(0x21a9), true + case "larrlp": // LEFTWARDS ARROW WITH LOOP + return rune(0x21ab), true + case "larrpl": // LEFT-SIDE ARC ANTICLOCKWISE ARROW + return rune(0x2939), true + case "larrsim": // LEFTWARDS ARROW ABOVE TILDE OPERATOR + return rune(0x2973), true + case "larrtl": // LEFTWARDS ARROW WITH TAIL + return rune(0x21a2), true + case "lat": // LARGER THAN + return rune(0x2aab), true + case "latail": // LEFTWARDS ARROW-TAIL + return rune(0x2919), true + case "late": // LARGER THAN OR EQUAL TO + return rune(0x2aad), true + case "lates": // LARGER THAN OR slanted EQUAL + return rune(0x2aad), true + case "lbarr": // LEFTWARDS DOUBLE DASH ARROW + return rune(0x290c), true + case "lbbrk": // LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT + return rune(0x2772), true + case "lbrace": // LEFT CURLY BRACKET + return rune(0x7b), true + case "lbrack": // LEFT SQUARE BRACKET + return rune(0x5b), true + case "lbrke": // LEFT SQUARE BRACKET WITH UNDERBAR + return rune(0x298b), true + case "lbrksld": // LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER + return rune(0x298f), true + case "lbrkslu": // LEFT SQUARE BRACKET WITH TICK IN TOP CORNER + return rune(0x298d), true + case "lcaron": // LATIN SMALL LETTER L WITH CARON + return rune(0x013e), true + case "lcedil": // LATIN SMALL LETTER L WITH CEDILLA + return rune(0x013c), true + case "lceil": // LEFT CEILING + return rune(0x2308), true + case "lcub": // LEFT CURLY BRACKET + return rune(0x7b), true + case "lcy": // CYRILLIC SMALL LETTER EL + return rune(0x043b), true + case "ldca": // ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS + return rune(0x2936), true + case "ldharb": // LEFTWARDS HARPOON WITH BARB DOWN TO BAR + return rune(0x2956), true + case "ldot": // LESS-THAN WITH DOT + return rune(0x22d6), true + case "ldquo": // LEFT DOUBLE QUOTATION MARK + return rune(0x201c), true + case "ldquor": // DOUBLE LOW-9 QUOTATION MARK + return rune(0x201e), true + case "ldrdhar": // LEFTWARDS HARPOON WITH BARB DOWN ABOVE RIGHTWARDS HARPOON WITH BARB DOWN + return rune(0x2967), true + case "ldrdshar": // LEFT BARB DOWN RIGHT BARB DOWN HARPOON + return rune(0x2950), true + case "ldrushar": // LEFT BARB DOWN RIGHT BARB UP HARPOON + return rune(0x294b), true + case "ldsh": // DOWNWARDS ARROW WITH TIP LEFTWARDS + return rune(0x21b2), true + case "le": // LESS-THAN OR EQUAL TO + return rune(0x2264), true + case "leftarrow": // LEFTWARDS ARROW + return rune(0x2190), true + case "leftarrowtail": // LEFTWARDS ARROW WITH TAIL + return rune(0x21a2), true + case "leftharpoondown": // LEFTWARDS HARPOON WITH BARB DOWNWARDS + return rune(0x21bd), true + case "leftharpoonup": // LEFTWARDS HARPOON WITH BARB UPWARDS + return rune(0x21bc), true + case "leftleftarrows": // LEFTWARDS PAIRED ARROWS + return rune(0x21c7), true + case "leftrightarrow": // LEFT RIGHT ARROW + return rune(0x2194), true + case "leftrightarrows": // LEFTWARDS ARROW OVER RIGHTWARDS ARROW + return rune(0x21c6), true + case "leftrightharpoons": // LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON + return rune(0x21cb), true + case "leftrightsquigarrow": // LEFT RIGHT WAVE ARROW + return rune(0x21ad), true + case "leftthreetimes": // LEFT SEMIDIRECT PRODUCT + return rune(0x22cb), true + case "leg": // LESS-THAN EQUAL TO OR GREATER-THAN + return rune(0x22da), true + case "leq": // LESS-THAN OR EQUAL TO + return rune(0x2264), true + case "leqq": // LESS-THAN OVER EQUAL TO + return rune(0x2266), true + case "leqslant": // LESS-THAN OR SLANTED EQUAL TO + return rune(0x2a7d), true + case "les": // LESS-THAN OR SLANTED EQUAL TO + return rune(0x2a7d), true + case "lescc": // LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL + return rune(0x2aa8), true + case "lesdot": // LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE + return rune(0x2a7f), true + case "lesdoto": // LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE + return rune(0x2a81), true + case "lesdotor": // LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT + return rune(0x2a83), true + case "lesg": // LESS-THAN slanted EQUAL TO OR GREATER-THAN + return rune(0x22da), true + case "lesges": // LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL + return rune(0x2a93), true + case "lessapprox": // LESS-THAN OR APPROXIMATE + return rune(0x2a85), true + case "lessdot": // LESS-THAN WITH DOT + return rune(0x22d6), true + case "lesseqgtr": // LESS-THAN EQUAL TO OR GREATER-THAN + return rune(0x22da), true + case "lesseqqgtr": // LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN + return rune(0x2a8b), true + case "lessgtr": // LESS-THAN OR GREATER-THAN + return rune(0x2276), true + case "lesssim": // LESS-THAN OR EQUIVALENT TO + return rune(0x2272), true + case "lfbowtie": // BOWTIE WITH LEFT HALF BLACK + return rune(0x29d1), true + case "lfisht": // LEFT FISH TAIL + return rune(0x297c), true + case "lfloor": // LEFT FLOOR + return rune(0x230a), true + case "lfr": // MATHEMATICAL FRAKTUR SMALL L + return rune(0x01d529), true + case "lftimes": // TIMES WITH LEFT HALF BLACK + return rune(0x29d4), true + case "lg": // LESS-THAN OR GREATER-THAN + return rune(0x2276), true + case "lgE": // LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL + return rune(0x2a91), true + case "lgr": // GREEK SMALL LETTER LAMDA + return rune(0x03bb), true + case "lhard": // LEFTWARDS HARPOON WITH BARB DOWNWARDS + return rune(0x21bd), true + case "lharu": // LEFTWARDS HARPOON WITH BARB UPWARDS + return rune(0x21bc), true + case "lharul": // LEFTWARDS HARPOON WITH BARB UP ABOVE LONG DASH + return rune(0x296a), true + case "lhblk": // LOWER HALF BLOCK + return rune(0x2584), true + case "ljcy": // CYRILLIC SMALL LETTER LJE + return rune(0x0459), true + case "ll": // MUCH LESS-THAN + return rune(0x226a), true + case "llarr": // LEFTWARDS PAIRED ARROWS + return rune(0x21c7), true + case "llcorner": // BOTTOM LEFT CORNER + return rune(0x231e), true + case "llhard": // LEFTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH + return rune(0x296b), true + case "lltri": // LOWER LEFT TRIANGLE + return rune(0x25fa), true + case "lltrif": // BLACK LOWER LEFT TRIANGLE + return rune(0x25e3), true + case "lmidot": // LATIN SMALL LETTER L WITH MIDDLE DOT + return rune(0x0140), true + case "lmoust": // UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION + return rune(0x23b0), true + case "lmoustache": // UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION + return rune(0x23b0), true + case "lnE": // LESS-THAN BUT NOT EQUAL TO + return rune(0x2268), true + case "lnap": // LESS-THAN AND NOT APPROXIMATE + return rune(0x2a89), true + case "lnapprox": // LESS-THAN AND NOT APPROXIMATE + return rune(0x2a89), true + case "lne": // LESS-THAN AND SINGLE-LINE NOT EQUAL TO + return rune(0x2a87), true + case "lneq": // LESS-THAN AND SINGLE-LINE NOT EQUAL TO + return rune(0x2a87), true + case "lneqq": // LESS-THAN BUT NOT EQUAL TO + return rune(0x2268), true + case "lnsim": // LESS-THAN BUT NOT EQUIVALENT TO + return rune(0x22e6), true + case "loang": // MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET + return rune(0x27ec), true + case "loarr": // LEFTWARDS OPEN-HEADED ARROW + return rune(0x21fd), true + case "lobrk": // MATHEMATICAL LEFT WHITE SQUARE BRACKET + return rune(0x27e6), true + case "locub": // LEFT WHITE CURLY BRACKET + return rune(0x2983), true + case "longleftarrow": // LONG LEFTWARDS ARROW + return rune(0x27f5), true + case "longleftrightarrow": // LONG LEFT RIGHT ARROW + return rune(0x27f7), true + case "longmapsto": // LONG RIGHTWARDS ARROW FROM BAR + return rune(0x27fc), true + case "longrightarrow": // LONG RIGHTWARDS ARROW + return rune(0x27f6), true + case "looparrowleft": // LEFTWARDS ARROW WITH LOOP + return rune(0x21ab), true + case "looparrowright": // RIGHTWARDS ARROW WITH LOOP + return rune(0x21ac), true + case "lopar": // LEFT WHITE PARENTHESIS + return rune(0x2985), true + case "lopf": // MATHEMATICAL DOUBLE-STRUCK SMALL L + return rune(0x01d55d), true + case "loplus": // PLUS SIGN IN LEFT HALF CIRCLE + return rune(0x2a2d), true + case "lotimes": // MULTIPLICATION SIGN IN LEFT HALF CIRCLE + return rune(0x2a34), true + case "lowast": // LOW ASTERISK + return rune(0x204e), true + case "lowbar": // LOW LINE + return rune(0x5f), true + case "lowint": // INTEGRAL WITH UNDERBAR + return rune(0x2a1c), true + case "loz": // LOZENGE + return rune(0x25ca), true + case "lozenge": // LOZENGE + return rune(0x25ca), true + case "lozf": // BLACK LOZENGE + return rune(0x29eb), true + case "lpar": // LEFT PARENTHESIS + return rune(0x28), true + case "lpargt": // SPHERICAL ANGLE OPENING LEFT + return rune(0x29a0), true + case "lparlt": // LEFT ARC LESS-THAN BRACKET + return rune(0x2993), true + case "lrarr": // LEFTWARDS ARROW OVER RIGHTWARDS ARROW + return rune(0x21c6), true + case "lrarr2": // LEFTWARDS ARROW OVER RIGHTWARDS ARROW + return rune(0x21c6), true + case "lrcorner": // BOTTOM RIGHT CORNER + return rune(0x231f), true + case "lrhar": // LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON + return rune(0x21cb), true + case "lrhar2": // LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON + return rune(0x21cb), true + case "lrhard": // RIGHTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH + return rune(0x296d), true + case "lrm": // LEFT-TO-RIGHT MARK + return rune(0x200e), true + case "lrtri": // RIGHT TRIANGLE + return rune(0x22bf), true + case "lsaquo": // SINGLE LEFT-POINTING ANGLE QUOTATION MARK + return rune(0x2039), true + case "lscr": // MATHEMATICAL SCRIPT SMALL L + return rune(0x01d4c1), true + case "lsh": // UPWARDS ARROW WITH TIP LEFTWARDS + return rune(0x21b0), true + case "lsim": // LESS-THAN OR EQUIVALENT TO + return rune(0x2272), true + case "lsime": // LESS-THAN ABOVE SIMILAR OR EQUAL + return rune(0x2a8d), true + case "lsimg": // LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN + return rune(0x2a8f), true + case "lsqb": // LEFT SQUARE BRACKET + return rune(0x5b), true + case "lsquo": // LEFT SINGLE QUOTATION MARK + return rune(0x2018), true + case "lsquor": // SINGLE LOW-9 QUOTATION MARK + return rune(0x201a), true + case "lstrok": // LATIN SMALL LETTER L WITH STROKE + return rune(0x0142), true + case "lt": // LESS-THAN SIGN + return rune(0x3c), true + case "ltcc": // LESS-THAN CLOSED BY CURVE + return rune(0x2aa6), true + case "ltcir": // LESS-THAN WITH CIRCLE INSIDE + return rune(0x2a79), true + case "ltdot": // LESS-THAN WITH DOT + return rune(0x22d6), true + case "lthree": // LEFT SEMIDIRECT PRODUCT + return rune(0x22cb), true + case "ltimes": // LEFT NORMAL FACTOR SEMIDIRECT PRODUCT + return rune(0x22c9), true + case "ltlarr": // LESS-THAN ABOVE LEFTWARDS ARROW + return rune(0x2976), true + case "ltquest": // LESS-THAN WITH QUESTION MARK ABOVE + return rune(0x2a7b), true + case "ltrPar": // DOUBLE RIGHT ARC LESS-THAN BRACKET + return rune(0x2996), true + case "ltri": // WHITE LEFT-POINTING SMALL TRIANGLE + return rune(0x25c3), true + case "ltrie": // NORMAL SUBGROUP OF OR EQUAL TO + return rune(0x22b4), true + case "ltrif": // BLACK LEFT-POINTING SMALL TRIANGLE + return rune(0x25c2), true + case "ltrivb": // LEFT TRIANGLE BESIDE VERTICAL BAR + return rune(0x29cf), true + case "luharb": // LEFTWARDS HARPOON WITH BARB UP TO BAR + return rune(0x2952), true + case "lurdshar": // LEFT BARB UP RIGHT BARB DOWN HARPOON + return rune(0x294a), true + case "luruhar": // LEFTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB UP + return rune(0x2966), true + case "lurushar": // LEFT BARB UP RIGHT BARB UP HARPOON + return rune(0x294e), true + case "lvertneqq": // LESS-THAN BUT NOT EQUAL TO - with vertical stroke + return rune(0x2268), true + case "lvnE": // LESS-THAN BUT NOT EQUAL TO - with vertical stroke + return rune(0x2268), true } case 'm': switch name { - case "mDDot": // GEOMETRIC PROPORTION - return rune(0x223a), true - case "macr": // MACRON - return rune(0xaf), true - case "male": // MALE SIGN - return rune(0x2642), true - case "malt": // MALTESE CROSS - return rune(0x2720), true - case "maltese": // MALTESE CROSS - return rune(0x2720), true - case "map": // RIGHTWARDS ARROW FROM BAR - return rune(0x21a6), true - case "mapsto": // RIGHTWARDS ARROW FROM BAR - return rune(0x21a6), true - case "mapstodown": // DOWNWARDS ARROW FROM BAR - return rune(0x21a7), true - case "mapstoleft": // LEFTWARDS ARROW FROM BAR - return rune(0x21a4), true - case "mapstoup": // UPWARDS ARROW FROM BAR - return rune(0x21a5), true - case "marker": // BLACK VERTICAL RECTANGLE - return rune(0x25ae), true - case "mcomma": // MINUS SIGN WITH COMMA ABOVE - return rune(0x2a29), true - case "mcy": // CYRILLIC SMALL LETTER EM - return rune(0x043c), true - case "mdash": // EM DASH - return rune(0x2014), true - case "measuredangle": // MEASURED ANGLE - return rune(0x2221), true - case "mfr": // MATHEMATICAL FRAKTUR SMALL M - return rune(0x01d52a), true - case "mgr": // GREEK SMALL LETTER MU - return rune(0x03bc), true - case "mho": // INVERTED OHM SIGN - return rune(0x2127), true - case "micro": // MICRO SIGN - return rune(0xb5), true - case "mid": // DIVIDES - return rune(0x2223), true - case "midast": // ASTERISK - return rune(0x2a), true - case "midcir": // VERTICAL LINE WITH CIRCLE BELOW - return rune(0x2af0), true - case "middot": // MIDDLE DOT - return rune(0xb7), true - case "minus": // MINUS SIGN - return rune(0x2212), true - case "minusb": // SQUARED MINUS - return rune(0x229f), true - case "minusd": // DOT MINUS - return rune(0x2238), true - case "minusdu": // MINUS SIGN WITH DOT BELOW - return rune(0x2a2a), true - case "mlcp": // TRANSVERSAL INTERSECTION - return rune(0x2adb), true - case "mldr": // HORIZONTAL ELLIPSIS - return rune(0x2026), true - case "mnplus": // MINUS-OR-PLUS SIGN - return rune(0x2213), true - case "models": // MODELS - return rune(0x22a7), true - case "mopf": // MATHEMATICAL DOUBLE-STRUCK SMALL M - return rune(0x01d55e), true - case "mp": // MINUS-OR-PLUS SIGN - return rune(0x2213), true - case "mscr": // MATHEMATICAL SCRIPT SMALL M - return rune(0x01d4c2), true - case "mstpos": // INVERTED LAZY S - return rune(0x223e), true - case "mu": // GREEK SMALL LETTER MU - return rune(0x03bc), true - case "multimap": // MULTIMAP - return rune(0x22b8), true - case "mumap": // MULTIMAP - return rune(0x22b8), true + case "mDDot": // GEOMETRIC PROPORTION + return rune(0x223a), true + case "macr": // MACRON + return rune(0xaf), true + case "male": // MALE SIGN + return rune(0x2642), true + case "malt": // MALTESE CROSS + return rune(0x2720), true + case "maltese": // MALTESE CROSS + return rune(0x2720), true + case "map": // RIGHTWARDS ARROW FROM BAR + return rune(0x21a6), true + case "mapsto": // RIGHTWARDS ARROW FROM BAR + return rune(0x21a6), true + case "mapstodown": // DOWNWARDS ARROW FROM BAR + return rune(0x21a7), true + case "mapstoleft": // LEFTWARDS ARROW FROM BAR + return rune(0x21a4), true + case "mapstoup": // UPWARDS ARROW FROM BAR + return rune(0x21a5), true + case "marker": // BLACK VERTICAL RECTANGLE + return rune(0x25ae), true + case "mcomma": // MINUS SIGN WITH COMMA ABOVE + return rune(0x2a29), true + case "mcy": // CYRILLIC SMALL LETTER EM + return rune(0x043c), true + case "mdash": // EM DASH + return rune(0x2014), true + case "measuredangle": // MEASURED ANGLE + return rune(0x2221), true + case "mfr": // MATHEMATICAL FRAKTUR SMALL M + return rune(0x01d52a), true + case "mgr": // GREEK SMALL LETTER MU + return rune(0x03bc), true + case "mho": // INVERTED OHM SIGN + return rune(0x2127), true + case "micro": // MICRO SIGN + return rune(0xb5), true + case "mid": // DIVIDES + return rune(0x2223), true + case "midast": // ASTERISK + return rune(0x2a), true + case "midcir": // VERTICAL LINE WITH CIRCLE BELOW + return rune(0x2af0), true + case "middot": // MIDDLE DOT + return rune(0xb7), true + case "minus": // MINUS SIGN + return rune(0x2212), true + case "minusb": // SQUARED MINUS + return rune(0x229f), true + case "minusd": // DOT MINUS + return rune(0x2238), true + case "minusdu": // MINUS SIGN WITH DOT BELOW + return rune(0x2a2a), true + case "mlcp": // TRANSVERSAL INTERSECTION + return rune(0x2adb), true + case "mldr": // HORIZONTAL ELLIPSIS + return rune(0x2026), true + case "mnplus": // MINUS-OR-PLUS SIGN + return rune(0x2213), true + case "models": // MODELS + return rune(0x22a7), true + case "mopf": // MATHEMATICAL DOUBLE-STRUCK SMALL M + return rune(0x01d55e), true + case "mp": // MINUS-OR-PLUS SIGN + return rune(0x2213), true + case "mscr": // MATHEMATICAL SCRIPT SMALL M + return rune(0x01d4c2), true + case "mstpos": // INVERTED LAZY S + return rune(0x223e), true + case "mu": // GREEK SMALL LETTER MU + return rune(0x03bc), true + case "multimap": // MULTIMAP + return rune(0x22b8), true + case "mumap": // MULTIMAP + return rune(0x22b8), true } case 'n': switch name { - case "nGg": // VERY MUCH GREATER-THAN with slash - return rune(0x22d9), true - case "nGt": // MUCH GREATER THAN with vertical line - return rune(0x226b), true - case "nGtv": // MUCH GREATER THAN with slash - return rune(0x226b), true - case "nLeftarrow": // LEFTWARDS DOUBLE ARROW WITH STROKE - return rune(0x21cd), true - case "nLeftrightarrow": // LEFT RIGHT DOUBLE ARROW WITH STROKE - return rune(0x21ce), true - case "nLl": // VERY MUCH LESS-THAN with slash - return rune(0x22d8), true - case "nLt": // MUCH LESS THAN with vertical line - return rune(0x226a), true - case "nLtv": // MUCH LESS THAN with slash - return rune(0x226a), true - case "nRightarrow": // RIGHTWARDS DOUBLE ARROW WITH STROKE - return rune(0x21cf), true - case "nVDash": // NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE - return rune(0x22af), true - case "nVdash": // DOES NOT FORCE - return rune(0x22ae), true - case "nabla": // NABLA - return rune(0x2207), true - case "nacute": // LATIN SMALL LETTER N WITH ACUTE - return rune(0x0144), true - case "nang": // ANGLE with vertical line - return rune(0x2220), true - case "nap": // NOT ALMOST EQUAL TO - return rune(0x2249), true - case "napE": // APPROXIMATELY EQUAL OR EQUAL TO with slash - return rune(0x2a70), true - case "napid": // TRIPLE TILDE with slash - return rune(0x224b), true - case "napos": // LATIN SMALL LETTER N PRECEDED BY APOSTROPHE - return rune(0x0149), true - case "napprox": // NOT ALMOST EQUAL TO - return rune(0x2249), true - case "natur": // MUSIC NATURAL SIGN - return rune(0x266e), true - case "natural": // MUSIC NATURAL SIGN - return rune(0x266e), true - case "naturals": // DOUBLE-STRUCK CAPITAL N - return rune(0x2115), true - case "nbsp": // NO-BREAK SPACE - return rune(0xa0), true - case "nbump": // GEOMETRICALLY EQUIVALENT TO with slash - return rune(0x224e), true - case "nbumpe": // DIFFERENCE BETWEEN with slash - return rune(0x224f), true - case "ncap": // INTERSECTION WITH OVERBAR - return rune(0x2a43), true - case "ncaron": // LATIN SMALL LETTER N WITH CARON - return rune(0x0148), true - case "ncedil": // LATIN SMALL LETTER N WITH CEDILLA - return rune(0x0146), true - case "ncong": // NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO - return rune(0x2247), true - case "ncongdot": // CONGRUENT WITH DOT ABOVE with slash - return rune(0x2a6d), true - case "ncup": // UNION WITH OVERBAR - return rune(0x2a42), true - case "ncy": // CYRILLIC SMALL LETTER EN - return rune(0x043d), true - case "ndash": // EN DASH - return rune(0x2013), true - case "ne": // NOT EQUAL TO - return rune(0x2260), true - case "neArr": // NORTH EAST DOUBLE ARROW - return rune(0x21d7), true - case "nearhk": // NORTH EAST ARROW WITH HOOK - return rune(0x2924), true - case "nearr": // NORTH EAST ARROW - return rune(0x2197), true - case "nearrow": // NORTH EAST ARROW - return rune(0x2197), true - case "nedot": // APPROACHES THE LIMIT with slash - return rune(0x2250), true - case "neonwarr": // NORTH EAST ARROW CROSSING NORTH WEST ARROW - return rune(0x2931), true - case "neosearr": // NORTH EAST ARROW CROSSING SOUTH EAST ARROW - return rune(0x292e), true - case "nequiv": // NOT IDENTICAL TO - return rune(0x2262), true - case "nesear": // NORTH EAST ARROW AND SOUTH EAST ARROW - return rune(0x2928), true - case "nesim": // MINUS TILDE with slash - return rune(0x2242), true - case "neswsarr": // NORTH EAST AND SOUTH WEST ARROW - return rune(0x2922), true - case "nexist": // THERE DOES NOT EXIST - return rune(0x2204), true - case "nexists": // THERE DOES NOT EXIST - return rune(0x2204), true - case "nfr": // MATHEMATICAL FRAKTUR SMALL N - return rune(0x01d52b), true - case "ngE": // GREATER-THAN OVER EQUAL TO with slash - return rune(0x2267), true - case "nge": // NEITHER GREATER-THAN NOR EQUAL TO - return rune(0x2271), true - case "ngeq": // NEITHER GREATER-THAN NOR EQUAL TO - return rune(0x2271), true - case "ngeqq": // GREATER-THAN OVER EQUAL TO with slash - return rune(0x2267), true - case "ngeqslant": // GREATER-THAN OR SLANTED EQUAL TO with slash - return rune(0x2a7e), true - case "nges": // GREATER-THAN OR SLANTED EQUAL TO with slash - return rune(0x2a7e), true - case "ngr": // GREEK SMALL LETTER NU - return rune(0x03bd), true - case "ngsim": // NEITHER GREATER-THAN NOR EQUIVALENT TO - return rune(0x2275), true - case "ngt": // NOT GREATER-THAN - return rune(0x226f), true - case "ngtr": // NOT GREATER-THAN - return rune(0x226f), true - case "nhArr": // LEFT RIGHT DOUBLE ARROW WITH STROKE - return rune(0x21ce), true - case "nharr": // LEFT RIGHT ARROW WITH STROKE - return rune(0x21ae), true - case "nhpar": // PARALLEL WITH HORIZONTAL STROKE - return rune(0x2af2), true - case "ni": // CONTAINS AS MEMBER - return rune(0x220b), true - case "nis": // SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE - return rune(0x22fc), true - case "nisd": // CONTAINS WITH LONG HORIZONTAL STROKE - return rune(0x22fa), true - case "niv": // CONTAINS AS MEMBER - return rune(0x220b), true - case "njcy": // CYRILLIC SMALL LETTER NJE - return rune(0x045a), true - case "nlArr": // LEFTWARDS DOUBLE ARROW WITH STROKE - return rune(0x21cd), true - case "nlE": // LESS-THAN OVER EQUAL TO with slash - return rune(0x2266), true - case "nlarr": // LEFTWARDS ARROW WITH STROKE - return rune(0x219a), true - case "nldr": // TWO DOT LEADER - return rune(0x2025), true - case "nle": // NEITHER LESS-THAN NOR EQUAL TO - return rune(0x2270), true - case "nleftarrow": // LEFTWARDS ARROW WITH STROKE - return rune(0x219a), true - case "nleftrightarrow": // LEFT RIGHT ARROW WITH STROKE - return rune(0x21ae), true - case "nleq": // NEITHER LESS-THAN NOR EQUAL TO - return rune(0x2270), true - case "nleqq": // LESS-THAN OVER EQUAL TO with slash - return rune(0x2266), true - case "nleqslant": // LESS-THAN OR SLANTED EQUAL TO with slash - return rune(0x2a7d), true - case "nles": // LESS-THAN OR SLANTED EQUAL TO with slash - return rune(0x2a7d), true - case "nless": // NOT LESS-THAN - return rune(0x226e), true - case "nlsim": // NEITHER LESS-THAN NOR EQUIVALENT TO - return rune(0x2274), true - case "nlt": // NOT LESS-THAN - return rune(0x226e), true - case "nltri": // NOT NORMAL SUBGROUP OF - return rune(0x22ea), true - case "nltrie": // NOT NORMAL SUBGROUP OF OR EQUAL TO - return rune(0x22ec), true - case "nltrivb": // LEFT TRIANGLE BESIDE VERTICAL BAR with slash - return rune(0x29cf), true - case "nmid": // DOES NOT DIVIDE - return rune(0x2224), true - case "nopf": // MATHEMATICAL DOUBLE-STRUCK SMALL N - return rune(0x01d55f), true - case "not": // NOT SIGN - return rune(0xac), true - case "notin": // NOT AN ELEMENT OF - return rune(0x2209), true - case "notinE": // ELEMENT OF WITH TWO HORIZONTAL STROKES with slash - return rune(0x22f9), true - case "notindot": // ELEMENT OF WITH DOT ABOVE with slash - return rune(0x22f5), true - case "notinva": // NOT AN ELEMENT OF - return rune(0x2209), true - case "notinvb": // SMALL ELEMENT OF WITH OVERBAR - return rune(0x22f7), true - case "notinvc": // ELEMENT OF WITH OVERBAR - return rune(0x22f6), true - case "notni": // DOES NOT CONTAIN AS MEMBER - return rune(0x220c), true - case "notniva": // DOES NOT CONTAIN AS MEMBER - return rune(0x220c), true - case "notnivb": // SMALL CONTAINS WITH OVERBAR - return rune(0x22fe), true - case "notnivc": // CONTAINS WITH OVERBAR - return rune(0x22fd), true - case "npar": // NOT PARALLEL TO - return rune(0x2226), true - case "nparallel": // NOT PARALLEL TO - return rune(0x2226), true - case "nparsl": // DOUBLE SOLIDUS OPERATOR with reverse slash - return rune(0x2afd), true - case "npart": // PARTIAL DIFFERENTIAL with slash - return rune(0x2202), true - case "npolint": // LINE INTEGRATION NOT INCLUDING THE POLE - return rune(0x2a14), true - case "npr": // DOES NOT PRECEDE - return rune(0x2280), true - case "nprcue": // DOES NOT PRECEDE OR EQUAL - return rune(0x22e0), true - case "npre": // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash - return rune(0x2aaf), true - case "nprec": // DOES NOT PRECEDE - return rune(0x2280), true - case "npreceq": // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash - return rune(0x2aaf), true - case "nprsim": // PRECEDES OR EQUIVALENT TO with slash - return rune(0x227e), true - case "nrArr": // RIGHTWARDS DOUBLE ARROW WITH STROKE - return rune(0x21cf), true - case "nrarr": // RIGHTWARDS ARROW WITH STROKE - return rune(0x219b), true - case "nrarrc": // WAVE ARROW POINTING DIRECTLY RIGHT with slash - return rune(0x2933), true - case "nrarrw": // RIGHTWARDS WAVE ARROW with slash - return rune(0x219d), true - case "nrightarrow": // RIGHTWARDS ARROW WITH STROKE - return rune(0x219b), true - case "nrtri": // DOES NOT CONTAIN AS NORMAL SUBGROUP - return rune(0x22eb), true - case "nrtrie": // DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL - return rune(0x22ed), true - case "nsGt": // DOUBLE NESTED GREATER-THAN with slash - return rune(0x2aa2), true - case "nsLt": // DOUBLE NESTED LESS-THAN with slash - return rune(0x2aa1), true - case "nsc": // DOES NOT SUCCEED - return rune(0x2281), true - case "nsccue": // DOES NOT SUCCEED OR EQUAL - return rune(0x22e1), true - case "nsce": // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash - return rune(0x2ab0), true - case "nscr": // MATHEMATICAL SCRIPT SMALL N - return rune(0x01d4c3), true - case "nscsim": // SUCCEEDS OR EQUIVALENT TO with slash - return rune(0x227f), true - case "nshortmid": // DOES NOT DIVIDE - return rune(0x2224), true - case "nshortparallel": // NOT PARALLEL TO - return rune(0x2226), true - case "nsim": // NOT TILDE - return rune(0x2241), true - case "nsime": // NOT ASYMPTOTICALLY EQUAL TO - return rune(0x2244), true - case "nsimeq": // NOT ASYMPTOTICALLY EQUAL TO - return rune(0x2244), true - case "nsmid": // DOES NOT DIVIDE - return rune(0x2224), true - case "nspar": // NOT PARALLEL TO - return rune(0x2226), true - case "nsqsub": // SQUARE IMAGE OF with slash - return rune(0x228f), true - case "nsqsube": // NOT SQUARE IMAGE OF OR EQUAL TO - return rune(0x22e2), true - case "nsqsup": // SQUARE ORIGINAL OF with slash - return rune(0x2290), true - case "nsqsupe": // NOT SQUARE ORIGINAL OF OR EQUAL TO - return rune(0x22e3), true - case "nsub": // NOT A SUBSET OF - return rune(0x2284), true - case "nsubE": // SUBSET OF ABOVE EQUALS SIGN with slash - return rune(0x2ac5), true - case "nsube": // NEITHER A SUBSET OF NOR EQUAL TO - return rune(0x2288), true - case "nsubset": // SUBSET OF with vertical line - return rune(0x2282), true - case "nsubseteq": // NEITHER A SUBSET OF NOR EQUAL TO - return rune(0x2288), true - case "nsubseteqq": // SUBSET OF ABOVE EQUALS SIGN with slash - return rune(0x2ac5), true - case "nsucc": // DOES NOT SUCCEED - return rune(0x2281), true - case "nsucceq": // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash - return rune(0x2ab0), true - case "nsup": // NOT A SUPERSET OF - return rune(0x2285), true - case "nsupE": // SUPERSET OF ABOVE EQUALS SIGN with slash - return rune(0x2ac6), true - case "nsupe": // NEITHER A SUPERSET OF NOR EQUAL TO - return rune(0x2289), true - case "nsupset": // SUPERSET OF with vertical line - return rune(0x2283), true - case "nsupseteq": // NEITHER A SUPERSET OF NOR EQUAL TO - return rune(0x2289), true - case "nsupseteqq": // SUPERSET OF ABOVE EQUALS SIGN with slash - return rune(0x2ac6), true - case "ntgl": // NEITHER GREATER-THAN NOR LESS-THAN - return rune(0x2279), true - case "ntilde": // LATIN SMALL LETTER N WITH TILDE - return rune(0xf1), true - case "ntlg": // NEITHER LESS-THAN NOR GREATER-THAN - return rune(0x2278), true - case "ntriangleleft": // NOT NORMAL SUBGROUP OF - return rune(0x22ea), true - case "ntrianglelefteq": // NOT NORMAL SUBGROUP OF OR EQUAL TO - return rune(0x22ec), true - case "ntriangleright": // DOES NOT CONTAIN AS NORMAL SUBGROUP - return rune(0x22eb), true - case "ntrianglerighteq": // DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL - return rune(0x22ed), true - case "nu": // GREEK SMALL LETTER NU - return rune(0x03bd), true - case "num": // NUMBER SIGN - return rune(0x23), true - case "numero": // NUMERO SIGN - return rune(0x2116), true - case "numsp": // FIGURE SPACE - return rune(0x2007), true - case "nvDash": // NOT TRUE - return rune(0x22ad), true - case "nvHarr": // LEFT RIGHT DOUBLE ARROW WITH VERTICAL STROKE - return rune(0x2904), true - case "nvap": // EQUIVALENT TO with vertical line - return rune(0x224d), true - case "nvbrtri": // VERTICAL BAR BESIDE RIGHT TRIANGLE with slash - return rune(0x29d0), true - case "nvdash": // DOES NOT PROVE - return rune(0x22ac), true - case "nvge": // GREATER-THAN OR EQUAL TO with vertical line - return rune(0x2265), true - case "nvgt": // GREATER-THAN SIGN with vertical line - return rune(0x3e), true - case "nvinfin": // INFINITY NEGATED WITH VERTICAL BAR - return rune(0x29de), true - case "nvlArr": // LEFTWARDS DOUBLE ARROW WITH VERTICAL STROKE - return rune(0x2902), true - case "nvle": // LESS-THAN OR EQUAL TO with vertical line - return rune(0x2264), true - case "nvlt": // LESS-THAN SIGN with vertical line - return rune(0x3c), true - case "nvltrie": // NORMAL SUBGROUP OF OR EQUAL TO with vertical line - return rune(0x22b4), true - case "nvrArr": // RIGHTWARDS DOUBLE ARROW WITH VERTICAL STROKE - return rune(0x2903), true - case "nvrtrie": // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO with vertical line - return rune(0x22b5), true - case "nvsim": // TILDE OPERATOR with vertical line - return rune(0x223c), true - case "nwArr": // NORTH WEST DOUBLE ARROW - return rune(0x21d6), true - case "nwarhk": // NORTH WEST ARROW WITH HOOK - return rune(0x2923), true - case "nwarr": // NORTH WEST ARROW - return rune(0x2196), true - case "nwarrow": // NORTH WEST ARROW - return rune(0x2196), true - case "nwnear": // NORTH WEST ARROW AND NORTH EAST ARROW - return rune(0x2927), true - case "nwonearr": // NORTH WEST ARROW CROSSING NORTH EAST ARROW - return rune(0x2932), true - case "nwsesarr": // NORTH WEST AND SOUTH EAST ARROW - return rune(0x2921), true + case "nGg": // VERY MUCH GREATER-THAN with slash + return rune(0x22d9), true + case "nGt": // MUCH GREATER THAN with vertical line + return rune(0x226b), true + case "nGtv": // MUCH GREATER THAN with slash + return rune(0x226b), true + case "nLeftarrow": // LEFTWARDS DOUBLE ARROW WITH STROKE + return rune(0x21cd), true + case "nLeftrightarrow": // LEFT RIGHT DOUBLE ARROW WITH STROKE + return rune(0x21ce), true + case "nLl": // VERY MUCH LESS-THAN with slash + return rune(0x22d8), true + case "nLt": // MUCH LESS THAN with vertical line + return rune(0x226a), true + case "nLtv": // MUCH LESS THAN with slash + return rune(0x226a), true + case "nRightarrow": // RIGHTWARDS DOUBLE ARROW WITH STROKE + return rune(0x21cf), true + case "nVDash": // NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE + return rune(0x22af), true + case "nVdash": // DOES NOT FORCE + return rune(0x22ae), true + case "nabla": // NABLA + return rune(0x2207), true + case "nacute": // LATIN SMALL LETTER N WITH ACUTE + return rune(0x0144), true + case "nang": // ANGLE with vertical line + return rune(0x2220), true + case "nap": // NOT ALMOST EQUAL TO + return rune(0x2249), true + case "napE": // APPROXIMATELY EQUAL OR EQUAL TO with slash + return rune(0x2a70), true + case "napid": // TRIPLE TILDE with slash + return rune(0x224b), true + case "napos": // LATIN SMALL LETTER N PRECEDED BY APOSTROPHE + return rune(0x0149), true + case "napprox": // NOT ALMOST EQUAL TO + return rune(0x2249), true + case "natur": // MUSIC NATURAL SIGN + return rune(0x266e), true + case "natural": // MUSIC NATURAL SIGN + return rune(0x266e), true + case "naturals": // DOUBLE-STRUCK CAPITAL N + return rune(0x2115), true + case "nbsp": // NO-BREAK SPACE + return rune(0xa0), true + case "nbump": // GEOMETRICALLY EQUIVALENT TO with slash + return rune(0x224e), true + case "nbumpe": // DIFFERENCE BETWEEN with slash + return rune(0x224f), true + case "ncap": // INTERSECTION WITH OVERBAR + return rune(0x2a43), true + case "ncaron": // LATIN SMALL LETTER N WITH CARON + return rune(0x0148), true + case "ncedil": // LATIN SMALL LETTER N WITH CEDILLA + return rune(0x0146), true + case "ncong": // NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO + return rune(0x2247), true + case "ncongdot": // CONGRUENT WITH DOT ABOVE with slash + return rune(0x2a6d), true + case "ncup": // UNION WITH OVERBAR + return rune(0x2a42), true + case "ncy": // CYRILLIC SMALL LETTER EN + return rune(0x043d), true + case "ndash": // EN DASH + return rune(0x2013), true + case "ne": // NOT EQUAL TO + return rune(0x2260), true + case "neArr": // NORTH EAST DOUBLE ARROW + return rune(0x21d7), true + case "nearhk": // NORTH EAST ARROW WITH HOOK + return rune(0x2924), true + case "nearr": // NORTH EAST ARROW + return rune(0x2197), true + case "nearrow": // NORTH EAST ARROW + return rune(0x2197), true + case "nedot": // APPROACHES THE LIMIT with slash + return rune(0x2250), true + case "neonwarr": // NORTH EAST ARROW CROSSING NORTH WEST ARROW + return rune(0x2931), true + case "neosearr": // NORTH EAST ARROW CROSSING SOUTH EAST ARROW + return rune(0x292e), true + case "nequiv": // NOT IDENTICAL TO + return rune(0x2262), true + case "nesear": // NORTH EAST ARROW AND SOUTH EAST ARROW + return rune(0x2928), true + case "nesim": // MINUS TILDE with slash + return rune(0x2242), true + case "neswsarr": // NORTH EAST AND SOUTH WEST ARROW + return rune(0x2922), true + case "nexist": // THERE DOES NOT EXIST + return rune(0x2204), true + case "nexists": // THERE DOES NOT EXIST + return rune(0x2204), true + case "nfr": // MATHEMATICAL FRAKTUR SMALL N + return rune(0x01d52b), true + case "ngE": // GREATER-THAN OVER EQUAL TO with slash + return rune(0x2267), true + case "nge": // NEITHER GREATER-THAN NOR EQUAL TO + return rune(0x2271), true + case "ngeq": // NEITHER GREATER-THAN NOR EQUAL TO + return rune(0x2271), true + case "ngeqq": // GREATER-THAN OVER EQUAL TO with slash + return rune(0x2267), true + case "ngeqslant": // GREATER-THAN OR SLANTED EQUAL TO with slash + return rune(0x2a7e), true + case "nges": // GREATER-THAN OR SLANTED EQUAL TO with slash + return rune(0x2a7e), true + case "ngr": // GREEK SMALL LETTER NU + return rune(0x03bd), true + case "ngsim": // NEITHER GREATER-THAN NOR EQUIVALENT TO + return rune(0x2275), true + case "ngt": // NOT GREATER-THAN + return rune(0x226f), true + case "ngtr": // NOT GREATER-THAN + return rune(0x226f), true + case "nhArr": // LEFT RIGHT DOUBLE ARROW WITH STROKE + return rune(0x21ce), true + case "nharr": // LEFT RIGHT ARROW WITH STROKE + return rune(0x21ae), true + case "nhpar": // PARALLEL WITH HORIZONTAL STROKE + return rune(0x2af2), true + case "ni": // CONTAINS AS MEMBER + return rune(0x220b), true + case "nis": // SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE + return rune(0x22fc), true + case "nisd": // CONTAINS WITH LONG HORIZONTAL STROKE + return rune(0x22fa), true + case "niv": // CONTAINS AS MEMBER + return rune(0x220b), true + case "njcy": // CYRILLIC SMALL LETTER NJE + return rune(0x045a), true + case "nlArr": // LEFTWARDS DOUBLE ARROW WITH STROKE + return rune(0x21cd), true + case "nlE": // LESS-THAN OVER EQUAL TO with slash + return rune(0x2266), true + case "nlarr": // LEFTWARDS ARROW WITH STROKE + return rune(0x219a), true + case "nldr": // TWO DOT LEADER + return rune(0x2025), true + case "nle": // NEITHER LESS-THAN NOR EQUAL TO + return rune(0x2270), true + case "nleftarrow": // LEFTWARDS ARROW WITH STROKE + return rune(0x219a), true + case "nleftrightarrow": // LEFT RIGHT ARROW WITH STROKE + return rune(0x21ae), true + case "nleq": // NEITHER LESS-THAN NOR EQUAL TO + return rune(0x2270), true + case "nleqq": // LESS-THAN OVER EQUAL TO with slash + return rune(0x2266), true + case "nleqslant": // LESS-THAN OR SLANTED EQUAL TO with slash + return rune(0x2a7d), true + case "nles": // LESS-THAN OR SLANTED EQUAL TO with slash + return rune(0x2a7d), true + case "nless": // NOT LESS-THAN + return rune(0x226e), true + case "nlsim": // NEITHER LESS-THAN NOR EQUIVALENT TO + return rune(0x2274), true + case "nlt": // NOT LESS-THAN + return rune(0x226e), true + case "nltri": // NOT NORMAL SUBGROUP OF + return rune(0x22ea), true + case "nltrie": // NOT NORMAL SUBGROUP OF OR EQUAL TO + return rune(0x22ec), true + case "nltrivb": // LEFT TRIANGLE BESIDE VERTICAL BAR with slash + return rune(0x29cf), true + case "nmid": // DOES NOT DIVIDE + return rune(0x2224), true + case "nopf": // MATHEMATICAL DOUBLE-STRUCK SMALL N + return rune(0x01d55f), true + case "not": // NOT SIGN + return rune(0xac), true + case "notin": // NOT AN ELEMENT OF + return rune(0x2209), true + case "notinE": // ELEMENT OF WITH TWO HORIZONTAL STROKES with slash + return rune(0x22f9), true + case "notindot": // ELEMENT OF WITH DOT ABOVE with slash + return rune(0x22f5), true + case "notinva": // NOT AN ELEMENT OF + return rune(0x2209), true + case "notinvb": // SMALL ELEMENT OF WITH OVERBAR + return rune(0x22f7), true + case "notinvc": // ELEMENT OF WITH OVERBAR + return rune(0x22f6), true + case "notni": // DOES NOT CONTAIN AS MEMBER + return rune(0x220c), true + case "notniva": // DOES NOT CONTAIN AS MEMBER + return rune(0x220c), true + case "notnivb": // SMALL CONTAINS WITH OVERBAR + return rune(0x22fe), true + case "notnivc": // CONTAINS WITH OVERBAR + return rune(0x22fd), true + case "npar": // NOT PARALLEL TO + return rune(0x2226), true + case "nparallel": // NOT PARALLEL TO + return rune(0x2226), true + case "nparsl": // DOUBLE SOLIDUS OPERATOR with reverse slash + return rune(0x2afd), true + case "npart": // PARTIAL DIFFERENTIAL with slash + return rune(0x2202), true + case "npolint": // LINE INTEGRATION NOT INCLUDING THE POLE + return rune(0x2a14), true + case "npr": // DOES NOT PRECEDE + return rune(0x2280), true + case "nprcue": // DOES NOT PRECEDE OR EQUAL + return rune(0x22e0), true + case "npre": // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash + return rune(0x2aaf), true + case "nprec": // DOES NOT PRECEDE + return rune(0x2280), true + case "npreceq": // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN with slash + return rune(0x2aaf), true + case "nprsim": // PRECEDES OR EQUIVALENT TO with slash + return rune(0x227e), true + case "nrArr": // RIGHTWARDS DOUBLE ARROW WITH STROKE + return rune(0x21cf), true + case "nrarr": // RIGHTWARDS ARROW WITH STROKE + return rune(0x219b), true + case "nrarrc": // WAVE ARROW POINTING DIRECTLY RIGHT with slash + return rune(0x2933), true + case "nrarrw": // RIGHTWARDS WAVE ARROW with slash + return rune(0x219d), true + case "nrightarrow": // RIGHTWARDS ARROW WITH STROKE + return rune(0x219b), true + case "nrtri": // DOES NOT CONTAIN AS NORMAL SUBGROUP + return rune(0x22eb), true + case "nrtrie": // DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL + return rune(0x22ed), true + case "nsGt": // DOUBLE NESTED GREATER-THAN with slash + return rune(0x2aa2), true + case "nsLt": // DOUBLE NESTED LESS-THAN with slash + return rune(0x2aa1), true + case "nsc": // DOES NOT SUCCEED + return rune(0x2281), true + case "nsccue": // DOES NOT SUCCEED OR EQUAL + return rune(0x22e1), true + case "nsce": // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash + return rune(0x2ab0), true + case "nscr": // MATHEMATICAL SCRIPT SMALL N + return rune(0x01d4c3), true + case "nscsim": // SUCCEEDS OR EQUIVALENT TO with slash + return rune(0x227f), true + case "nshortmid": // DOES NOT DIVIDE + return rune(0x2224), true + case "nshortparallel": // NOT PARALLEL TO + return rune(0x2226), true + case "nsim": // NOT TILDE + return rune(0x2241), true + case "nsime": // NOT ASYMPTOTICALLY EQUAL TO + return rune(0x2244), true + case "nsimeq": // NOT ASYMPTOTICALLY EQUAL TO + return rune(0x2244), true + case "nsmid": // DOES NOT DIVIDE + return rune(0x2224), true + case "nspar": // NOT PARALLEL TO + return rune(0x2226), true + case "nsqsub": // SQUARE IMAGE OF with slash + return rune(0x228f), true + case "nsqsube": // NOT SQUARE IMAGE OF OR EQUAL TO + return rune(0x22e2), true + case "nsqsup": // SQUARE ORIGINAL OF with slash + return rune(0x2290), true + case "nsqsupe": // NOT SQUARE ORIGINAL OF OR EQUAL TO + return rune(0x22e3), true + case "nsub": // NOT A SUBSET OF + return rune(0x2284), true + case "nsubE": // SUBSET OF ABOVE EQUALS SIGN with slash + return rune(0x2ac5), true + case "nsube": // NEITHER A SUBSET OF NOR EQUAL TO + return rune(0x2288), true + case "nsubset": // SUBSET OF with vertical line + return rune(0x2282), true + case "nsubseteq": // NEITHER A SUBSET OF NOR EQUAL TO + return rune(0x2288), true + case "nsubseteqq": // SUBSET OF ABOVE EQUALS SIGN with slash + return rune(0x2ac5), true + case "nsucc": // DOES NOT SUCCEED + return rune(0x2281), true + case "nsucceq": // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN with slash + return rune(0x2ab0), true + case "nsup": // NOT A SUPERSET OF + return rune(0x2285), true + case "nsupE": // SUPERSET OF ABOVE EQUALS SIGN with slash + return rune(0x2ac6), true + case "nsupe": // NEITHER A SUPERSET OF NOR EQUAL TO + return rune(0x2289), true + case "nsupset": // SUPERSET OF with vertical line + return rune(0x2283), true + case "nsupseteq": // NEITHER A SUPERSET OF NOR EQUAL TO + return rune(0x2289), true + case "nsupseteqq": // SUPERSET OF ABOVE EQUALS SIGN with slash + return rune(0x2ac6), true + case "ntgl": // NEITHER GREATER-THAN NOR LESS-THAN + return rune(0x2279), true + case "ntilde": // LATIN SMALL LETTER N WITH TILDE + return rune(0xf1), true + case "ntlg": // NEITHER LESS-THAN NOR GREATER-THAN + return rune(0x2278), true + case "ntriangleleft": // NOT NORMAL SUBGROUP OF + return rune(0x22ea), true + case "ntrianglelefteq": // NOT NORMAL SUBGROUP OF OR EQUAL TO + return rune(0x22ec), true + case "ntriangleright": // DOES NOT CONTAIN AS NORMAL SUBGROUP + return rune(0x22eb), true + case "ntrianglerighteq": // DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL + return rune(0x22ed), true + case "nu": // GREEK SMALL LETTER NU + return rune(0x03bd), true + case "num": // NUMBER SIGN + return rune(0x23), true + case "numero": // NUMERO SIGN + return rune(0x2116), true + case "numsp": // FIGURE SPACE + return rune(0x2007), true + case "nvDash": // NOT TRUE + return rune(0x22ad), true + case "nvHarr": // LEFT RIGHT DOUBLE ARROW WITH VERTICAL STROKE + return rune(0x2904), true + case "nvap": // EQUIVALENT TO with vertical line + return rune(0x224d), true + case "nvbrtri": // VERTICAL BAR BESIDE RIGHT TRIANGLE with slash + return rune(0x29d0), true + case "nvdash": // DOES NOT PROVE + return rune(0x22ac), true + case "nvge": // GREATER-THAN OR EQUAL TO with vertical line + return rune(0x2265), true + case "nvgt": // GREATER-THAN SIGN with vertical line + return rune(0x3e), true + case "nvinfin": // INFINITY NEGATED WITH VERTICAL BAR + return rune(0x29de), true + case "nvlArr": // LEFTWARDS DOUBLE ARROW WITH VERTICAL STROKE + return rune(0x2902), true + case "nvle": // LESS-THAN OR EQUAL TO with vertical line + return rune(0x2264), true + case "nvlt": // LESS-THAN SIGN with vertical line + return rune(0x3c), true + case "nvltrie": // NORMAL SUBGROUP OF OR EQUAL TO with vertical line + return rune(0x22b4), true + case "nvrArr": // RIGHTWARDS DOUBLE ARROW WITH VERTICAL STROKE + return rune(0x2903), true + case "nvrtrie": // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO with vertical line + return rune(0x22b5), true + case "nvsim": // TILDE OPERATOR with vertical line + return rune(0x223c), true + case "nwArr": // NORTH WEST DOUBLE ARROW + return rune(0x21d6), true + case "nwarhk": // NORTH WEST ARROW WITH HOOK + return rune(0x2923), true + case "nwarr": // NORTH WEST ARROW + return rune(0x2196), true + case "nwarrow": // NORTH WEST ARROW + return rune(0x2196), true + case "nwnear": // NORTH WEST ARROW AND NORTH EAST ARROW + return rune(0x2927), true + case "nwonearr": // NORTH WEST ARROW CROSSING NORTH EAST ARROW + return rune(0x2932), true + case "nwsesarr": // NORTH WEST AND SOUTH EAST ARROW + return rune(0x2921), true } case 'o': switch name { - case "oS": // CIRCLED LATIN CAPITAL LETTER S - return rune(0x24c8), true - case "oacgr": // GREEK SMALL LETTER OMICRON WITH TONOS - return rune(0x03cc), true - case "oacute": // LATIN SMALL LETTER O WITH ACUTE - return rune(0xf3), true - case "oast": // CIRCLED ASTERISK OPERATOR - return rune(0x229b), true - case "obsol": // CIRCLED REVERSE SOLIDUS - return rune(0x29b8), true - case "ocir": // CIRCLED RING OPERATOR - return rune(0x229a), true - case "ocirc": // LATIN SMALL LETTER O WITH CIRCUMFLEX - return rune(0xf4), true - case "ocy": // CYRILLIC SMALL LETTER O - return rune(0x043e), true - case "odash": // CIRCLED DASH - return rune(0x229d), true - case "odblac": // LATIN SMALL LETTER O WITH DOUBLE ACUTE - return rune(0x0151), true - case "odiv": // CIRCLED DIVISION SIGN - return rune(0x2a38), true - case "odot": // CIRCLED DOT OPERATOR - return rune(0x2299), true - case "odsold": // CIRCLED ANTICLOCKWISE-ROTATED DIVISION SIGN - return rune(0x29bc), true - case "oelig": // LATIN SMALL LIGATURE OE - return rune(0x0153), true - case "ofcir": // CIRCLED BULLET - return rune(0x29bf), true - case "ofr": // MATHEMATICAL FRAKTUR SMALL O - return rune(0x01d52c), true - case "ogon": // OGONEK - return rune(0x02db), true - case "ogr": // GREEK SMALL LETTER OMICRON - return rune(0x03bf), true - case "ograve": // LATIN SMALL LETTER O WITH GRAVE - return rune(0xf2), true - case "ogt": // CIRCLED GREATER-THAN - return rune(0x29c1), true - case "ohacgr": // GREEK SMALL LETTER OMEGA WITH TONOS - return rune(0x03ce), true - case "ohbar": // CIRCLE WITH HORIZONTAL BAR - return rune(0x29b5), true - case "ohgr": // GREEK SMALL LETTER OMEGA - return rune(0x03c9), true - case "ohm": // GREEK CAPITAL LETTER OMEGA - return rune(0x03a9), true - case "oint": // CONTOUR INTEGRAL - return rune(0x222e), true - case "olarr": // ANTICLOCKWISE OPEN CIRCLE ARROW - return rune(0x21ba), true - case "olcir": // CIRCLED WHITE BULLET - return rune(0x29be), true - case "olcross": // CIRCLE WITH SUPERIMPOSED X - return rune(0x29bb), true - case "oline": // OVERLINE - return rune(0x203e), true - case "olt": // CIRCLED LESS-THAN - return rune(0x29c0), true - case "omacr": // LATIN SMALL LETTER O WITH MACRON - return rune(0x014d), true - case "omega": // GREEK SMALL LETTER OMEGA - return rune(0x03c9), true - case "omicron": // GREEK SMALL LETTER OMICRON - return rune(0x03bf), true - case "omid": // CIRCLED VERTICAL BAR - return rune(0x29b6), true - case "ominus": // CIRCLED MINUS - return rune(0x2296), true - case "oopf": // MATHEMATICAL DOUBLE-STRUCK SMALL O - return rune(0x01d560), true - case "opar": // CIRCLED PARALLEL - return rune(0x29b7), true - case "operp": // CIRCLED PERPENDICULAR - return rune(0x29b9), true - case "opfgamma": // DOUBLE-STRUCK SMALL GAMMA - return rune(0x213d), true - case "opfpi": // DOUBLE-STRUCK CAPITAL PI - return rune(0x213f), true - case "opfsum": // DOUBLE-STRUCK N-ARY SUMMATION - return rune(0x2140), true - case "oplus": // CIRCLED PLUS - return rune(0x2295), true - case "or": // LOGICAL OR - return rune(0x2228), true - case "orarr": // CLOCKWISE OPEN CIRCLE ARROW - return rune(0x21bb), true - case "ord": // LOGICAL OR WITH HORIZONTAL DASH - return rune(0x2a5d), true - case "order": // SCRIPT SMALL O - return rune(0x2134), true - case "orderof": // SCRIPT SMALL O - return rune(0x2134), true - case "ordf": // FEMININE ORDINAL INDICATOR - return rune(0xaa), true - case "ordm": // MASCULINE ORDINAL INDICATOR - return rune(0xba), true - case "origof": // ORIGINAL OF - return rune(0x22b6), true - case "oror": // TWO INTERSECTING LOGICAL OR - return rune(0x2a56), true - case "orslope": // SLOPING LARGE OR - return rune(0x2a57), true - case "orv": // LOGICAL OR WITH MIDDLE STEM - return rune(0x2a5b), true - case "oscr": // SCRIPT SMALL O - return rune(0x2134), true - case "oslash": // LATIN SMALL LETTER O WITH STROKE - return rune(0xf8), true - case "osol": // CIRCLED DIVISION SLASH - return rune(0x2298), true - case "otilde": // LATIN SMALL LETTER O WITH TILDE - return rune(0xf5), true - case "otimes": // CIRCLED TIMES - return rune(0x2297), true - case "otimesas": // CIRCLED MULTIPLICATION SIGN WITH CIRCUMFLEX ACCENT - return rune(0x2a36), true - case "ouml": // LATIN SMALL LETTER O WITH DIAERESIS - return rune(0xf6), true - case "ovbar": // APL FUNCTIONAL SYMBOL CIRCLE STILE - return rune(0x233d), true - case "ovrbrk": // TOP SQUARE BRACKET - return rune(0x23b4), true - case "ovrcub": // TOP CURLY BRACKET - return rune(0x23de), true - case "ovrpar": // TOP PARENTHESIS - return rune(0x23dc), true - case "oxuarr": // UP ARROW THROUGH CIRCLE - return rune(0x29bd), true + case "oS": // CIRCLED LATIN CAPITAL LETTER S + return rune(0x24c8), true + case "oacgr": // GREEK SMALL LETTER OMICRON WITH TONOS + return rune(0x03cc), true + case "oacute": // LATIN SMALL LETTER O WITH ACUTE + return rune(0xf3), true + case "oast": // CIRCLED ASTERISK OPERATOR + return rune(0x229b), true + case "obsol": // CIRCLED REVERSE SOLIDUS + return rune(0x29b8), true + case "ocir": // CIRCLED RING OPERATOR + return rune(0x229a), true + case "ocirc": // LATIN SMALL LETTER O WITH CIRCUMFLEX + return rune(0xf4), true + case "ocy": // CYRILLIC SMALL LETTER O + return rune(0x043e), true + case "odash": // CIRCLED DASH + return rune(0x229d), true + case "odblac": // LATIN SMALL LETTER O WITH DOUBLE ACUTE + return rune(0x0151), true + case "odiv": // CIRCLED DIVISION SIGN + return rune(0x2a38), true + case "odot": // CIRCLED DOT OPERATOR + return rune(0x2299), true + case "odsold": // CIRCLED ANTICLOCKWISE-ROTATED DIVISION SIGN + return rune(0x29bc), true + case "oelig": // LATIN SMALL LIGATURE OE + return rune(0x0153), true + case "ofcir": // CIRCLED BULLET + return rune(0x29bf), true + case "ofr": // MATHEMATICAL FRAKTUR SMALL O + return rune(0x01d52c), true + case "ogon": // OGONEK + return rune(0x02db), true + case "ogr": // GREEK SMALL LETTER OMICRON + return rune(0x03bf), true + case "ograve": // LATIN SMALL LETTER O WITH GRAVE + return rune(0xf2), true + case "ogt": // CIRCLED GREATER-THAN + return rune(0x29c1), true + case "ohacgr": // GREEK SMALL LETTER OMEGA WITH TONOS + return rune(0x03ce), true + case "ohbar": // CIRCLE WITH HORIZONTAL BAR + return rune(0x29b5), true + case "ohgr": // GREEK SMALL LETTER OMEGA + return rune(0x03c9), true + case "ohm": // GREEK CAPITAL LETTER OMEGA + return rune(0x03a9), true + case "oint": // CONTOUR INTEGRAL + return rune(0x222e), true + case "olarr": // ANTICLOCKWISE OPEN CIRCLE ARROW + return rune(0x21ba), true + case "olcir": // CIRCLED WHITE BULLET + return rune(0x29be), true + case "olcross": // CIRCLE WITH SUPERIMPOSED X + return rune(0x29bb), true + case "oline": // OVERLINE + return rune(0x203e), true + case "olt": // CIRCLED LESS-THAN + return rune(0x29c0), true + case "omacr": // LATIN SMALL LETTER O WITH MACRON + return rune(0x014d), true + case "omega": // GREEK SMALL LETTER OMEGA + return rune(0x03c9), true + case "omicron": // GREEK SMALL LETTER OMICRON + return rune(0x03bf), true + case "omid": // CIRCLED VERTICAL BAR + return rune(0x29b6), true + case "ominus": // CIRCLED MINUS + return rune(0x2296), true + case "oopf": // MATHEMATICAL DOUBLE-STRUCK SMALL O + return rune(0x01d560), true + case "opar": // CIRCLED PARALLEL + return rune(0x29b7), true + case "operp": // CIRCLED PERPENDICULAR + return rune(0x29b9), true + case "opfgamma": // DOUBLE-STRUCK SMALL GAMMA + return rune(0x213d), true + case "opfpi": // DOUBLE-STRUCK CAPITAL PI + return rune(0x213f), true + case "opfsum": // DOUBLE-STRUCK N-ARY SUMMATION + return rune(0x2140), true + case "oplus": // CIRCLED PLUS + return rune(0x2295), true + case "or": // LOGICAL OR + return rune(0x2228), true + case "orarr": // CLOCKWISE OPEN CIRCLE ARROW + return rune(0x21bb), true + case "ord": // LOGICAL OR WITH HORIZONTAL DASH + return rune(0x2a5d), true + case "order": // SCRIPT SMALL O + return rune(0x2134), true + case "orderof": // SCRIPT SMALL O + return rune(0x2134), true + case "ordf": // FEMININE ORDINAL INDICATOR + return rune(0xaa), true + case "ordm": // MASCULINE ORDINAL INDICATOR + return rune(0xba), true + case "origof": // ORIGINAL OF + return rune(0x22b6), true + case "oror": // TWO INTERSECTING LOGICAL OR + return rune(0x2a56), true + case "orslope": // SLOPING LARGE OR + return rune(0x2a57), true + case "orv": // LOGICAL OR WITH MIDDLE STEM + return rune(0x2a5b), true + case "oscr": // SCRIPT SMALL O + return rune(0x2134), true + case "oslash": // LATIN SMALL LETTER O WITH STROKE + return rune(0xf8), true + case "osol": // CIRCLED DIVISION SLASH + return rune(0x2298), true + case "otilde": // LATIN SMALL LETTER O WITH TILDE + return rune(0xf5), true + case "otimes": // CIRCLED TIMES + return rune(0x2297), true + case "otimesas": // CIRCLED MULTIPLICATION SIGN WITH CIRCUMFLEX ACCENT + return rune(0x2a36), true + case "ouml": // LATIN SMALL LETTER O WITH DIAERESIS + return rune(0xf6), true + case "ovbar": // APL FUNCTIONAL SYMBOL CIRCLE STILE + return rune(0x233d), true + case "ovrbrk": // TOP SQUARE BRACKET + return rune(0x23b4), true + case "ovrcub": // TOP CURLY BRACKET + return rune(0x23de), true + case "ovrpar": // TOP PARENTHESIS + return rune(0x23dc), true + case "oxuarr": // UP ARROW THROUGH CIRCLE + return rune(0x29bd), true } case 'p': switch name { - case "par": // PARALLEL TO - return rune(0x2225), true - case "para": // PILCROW SIGN - return rune(0xb6), true - case "parallel": // PARALLEL TO - return rune(0x2225), true - case "parsim": // PARALLEL WITH TILDE OPERATOR - return rune(0x2af3), true - case "parsl": // DOUBLE SOLIDUS OPERATOR - return rune(0x2afd), true - case "part": // PARTIAL DIFFERENTIAL - return rune(0x2202), true - case "pcy": // CYRILLIC SMALL LETTER PE - return rune(0x043f), true - case "percnt": // PERCENT SIGN - return rune(0x25), true - case "period": // FULL STOP - return rune(0x2e), true - case "permil": // PER MILLE SIGN - return rune(0x2030), true - case "perp": // UP TACK - return rune(0x22a5), true - case "pertenk": // PER TEN THOUSAND SIGN - return rune(0x2031), true - case "pfr": // MATHEMATICAL FRAKTUR SMALL P - return rune(0x01d52d), true - case "pgr": // GREEK SMALL LETTER PI - return rune(0x03c0), true - case "phgr": // GREEK SMALL LETTER PHI - return rune(0x03c6), true - case "phi": // GREEK SMALL LETTER PHI - return rune(0x03c6), true - case "phis": // GREEK PHI SYMBOL - return rune(0x03d5), true - case "phiv": // GREEK PHI SYMBOL - return rune(0x03d5), true - case "phmmat": // SCRIPT CAPITAL M - return rune(0x2133), true - case "phone": // BLACK TELEPHONE - return rune(0x260e), true - case "pi": // GREEK SMALL LETTER PI - return rune(0x03c0), true - case "pitchfork": // PITCHFORK - return rune(0x22d4), true - case "piv": // GREEK PI SYMBOL - return rune(0x03d6), true - case "planck": // PLANCK CONSTANT OVER TWO PI - return rune(0x210f), true - case "planckh": // PLANCK CONSTANT - return rune(0x210e), true - case "plankv": // PLANCK CONSTANT OVER TWO PI - return rune(0x210f), true - case "plus": // PLUS SIGN - return rune(0x2b), true - case "plusacir": // PLUS SIGN WITH CIRCUMFLEX ACCENT ABOVE - return rune(0x2a23), true - case "plusb": // SQUARED PLUS - return rune(0x229e), true - case "pluscir": // PLUS SIGN WITH SMALL CIRCLE ABOVE - return rune(0x2a22), true - case "plusdo": // DOT PLUS - return rune(0x2214), true - case "plusdu": // PLUS SIGN WITH DOT BELOW - return rune(0x2a25), true - case "pluse": // PLUS SIGN ABOVE EQUALS SIGN - return rune(0x2a72), true - case "plusmn": // PLUS-MINUS SIGN - return rune(0xb1), true - case "plussim": // PLUS SIGN WITH TILDE BELOW - return rune(0x2a26), true - case "plustrif": // PLUS SIGN WITH BLACK TRIANGLE - return rune(0x2a28), true - case "plustwo": // PLUS SIGN WITH SUBSCRIPT TWO - return rune(0x2a27), true - case "pm": // PLUS-MINUS SIGN - return rune(0xb1), true - case "pointint": // INTEGRAL AROUND A POINT OPERATOR - return rune(0x2a15), true - case "popf": // MATHEMATICAL DOUBLE-STRUCK SMALL P - return rune(0x01d561), true - case "pound": // POUND SIGN - return rune(0xa3), true - case "pr": // PRECEDES - return rune(0x227a), true - case "prE": // PRECEDES ABOVE EQUALS SIGN - return rune(0x2ab3), true - case "prap": // PRECEDES ABOVE ALMOST EQUAL TO - return rune(0x2ab7), true - case "prcue": // PRECEDES OR EQUAL TO - return rune(0x227c), true - case "pre": // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN - return rune(0x2aaf), true - case "prec": // PRECEDES - return rune(0x227a), true - case "precapprox": // PRECEDES ABOVE ALMOST EQUAL TO - return rune(0x2ab7), true - case "preccurlyeq": // PRECEDES OR EQUAL TO - return rune(0x227c), true - case "preceq": // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN - return rune(0x2aaf), true - case "precnapprox": // PRECEDES ABOVE NOT ALMOST EQUAL TO - return rune(0x2ab9), true - case "precneqq": // PRECEDES ABOVE NOT EQUAL TO - return rune(0x2ab5), true - case "precnsim": // PRECEDES BUT NOT EQUIVALENT TO - return rune(0x22e8), true - case "precsim": // PRECEDES OR EQUIVALENT TO - return rune(0x227e), true - case "prime": // PRIME - return rune(0x2032), true - case "primes": // DOUBLE-STRUCK CAPITAL P - return rune(0x2119), true - case "prnE": // PRECEDES ABOVE NOT EQUAL TO - return rune(0x2ab5), true - case "prnap": // PRECEDES ABOVE NOT ALMOST EQUAL TO - return rune(0x2ab9), true - case "prnsim": // PRECEDES BUT NOT EQUIVALENT TO - return rune(0x22e8), true - case "prod": // N-ARY PRODUCT - return rune(0x220f), true - case "profalar": // ALL AROUND-PROFILE - return rune(0x232e), true - case "profline": // ARC - return rune(0x2312), true - case "profsurf": // SEGMENT - return rune(0x2313), true - case "prop": // PROPORTIONAL TO - return rune(0x221d), true - case "propto": // PROPORTIONAL TO - return rune(0x221d), true - case "prsim": // PRECEDES OR EQUIVALENT TO - return rune(0x227e), true - case "prurel": // PRECEDES UNDER RELATION - return rune(0x22b0), true - case "pscr": // MATHEMATICAL SCRIPT SMALL P - return rune(0x01d4c5), true - case "psgr": // GREEK SMALL LETTER PSI - return rune(0x03c8), true - case "psi": // GREEK SMALL LETTER PSI - return rune(0x03c8), true - case "puncsp": // PUNCTUATION SPACE - return rune(0x2008), true + case "par": // PARALLEL TO + return rune(0x2225), true + case "para": // PILCROW SIGN + return rune(0xb6), true + case "parallel": // PARALLEL TO + return rune(0x2225), true + case "parsim": // PARALLEL WITH TILDE OPERATOR + return rune(0x2af3), true + case "parsl": // DOUBLE SOLIDUS OPERATOR + return rune(0x2afd), true + case "part": // PARTIAL DIFFERENTIAL + return rune(0x2202), true + case "pcy": // CYRILLIC SMALL LETTER PE + return rune(0x043f), true + case "percnt": // PERCENT SIGN + return rune(0x25), true + case "period": // FULL STOP + return rune(0x2e), true + case "permil": // PER MILLE SIGN + return rune(0x2030), true + case "perp": // UP TACK + return rune(0x22a5), true + case "pertenk": // PER TEN THOUSAND SIGN + return rune(0x2031), true + case "pfr": // MATHEMATICAL FRAKTUR SMALL P + return rune(0x01d52d), true + case "pgr": // GREEK SMALL LETTER PI + return rune(0x03c0), true + case "phgr": // GREEK SMALL LETTER PHI + return rune(0x03c6), true + case "phi": // GREEK SMALL LETTER PHI + return rune(0x03c6), true + case "phis": // GREEK PHI SYMBOL + return rune(0x03d5), true + case "phiv": // GREEK PHI SYMBOL + return rune(0x03d5), true + case "phmmat": // SCRIPT CAPITAL M + return rune(0x2133), true + case "phone": // BLACK TELEPHONE + return rune(0x260e), true + case "pi": // GREEK SMALL LETTER PI + return rune(0x03c0), true + case "pitchfork": // PITCHFORK + return rune(0x22d4), true + case "piv": // GREEK PI SYMBOL + return rune(0x03d6), true + case "planck": // PLANCK CONSTANT OVER TWO PI + return rune(0x210f), true + case "planckh": // PLANCK CONSTANT + return rune(0x210e), true + case "plankv": // PLANCK CONSTANT OVER TWO PI + return rune(0x210f), true + case "plus": // PLUS SIGN + return rune(0x2b), true + case "plusacir": // PLUS SIGN WITH CIRCUMFLEX ACCENT ABOVE + return rune(0x2a23), true + case "plusb": // SQUARED PLUS + return rune(0x229e), true + case "pluscir": // PLUS SIGN WITH SMALL CIRCLE ABOVE + return rune(0x2a22), true + case "plusdo": // DOT PLUS + return rune(0x2214), true + case "plusdu": // PLUS SIGN WITH DOT BELOW + return rune(0x2a25), true + case "pluse": // PLUS SIGN ABOVE EQUALS SIGN + return rune(0x2a72), true + case "plusmn": // PLUS-MINUS SIGN + return rune(0xb1), true + case "plussim": // PLUS SIGN WITH TILDE BELOW + return rune(0x2a26), true + case "plustrif": // PLUS SIGN WITH BLACK TRIANGLE + return rune(0x2a28), true + case "plustwo": // PLUS SIGN WITH SUBSCRIPT TWO + return rune(0x2a27), true + case "pm": // PLUS-MINUS SIGN + return rune(0xb1), true + case "pointint": // INTEGRAL AROUND A POINT OPERATOR + return rune(0x2a15), true + case "popf": // MATHEMATICAL DOUBLE-STRUCK SMALL P + return rune(0x01d561), true + case "pound": // POUND SIGN + return rune(0xa3), true + case "pr": // PRECEDES + return rune(0x227a), true + case "prE": // PRECEDES ABOVE EQUALS SIGN + return rune(0x2ab3), true + case "prap": // PRECEDES ABOVE ALMOST EQUAL TO + return rune(0x2ab7), true + case "prcue": // PRECEDES OR EQUAL TO + return rune(0x227c), true + case "pre": // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN + return rune(0x2aaf), true + case "prec": // PRECEDES + return rune(0x227a), true + case "precapprox": // PRECEDES ABOVE ALMOST EQUAL TO + return rune(0x2ab7), true + case "preccurlyeq": // PRECEDES OR EQUAL TO + return rune(0x227c), true + case "preceq": // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN + return rune(0x2aaf), true + case "precnapprox": // PRECEDES ABOVE NOT ALMOST EQUAL TO + return rune(0x2ab9), true + case "precneqq": // PRECEDES ABOVE NOT EQUAL TO + return rune(0x2ab5), true + case "precnsim": // PRECEDES BUT NOT EQUIVALENT TO + return rune(0x22e8), true + case "precsim": // PRECEDES OR EQUIVALENT TO + return rune(0x227e), true + case "prime": // PRIME + return rune(0x2032), true + case "primes": // DOUBLE-STRUCK CAPITAL P + return rune(0x2119), true + case "prnE": // PRECEDES ABOVE NOT EQUAL TO + return rune(0x2ab5), true + case "prnap": // PRECEDES ABOVE NOT ALMOST EQUAL TO + return rune(0x2ab9), true + case "prnsim": // PRECEDES BUT NOT EQUIVALENT TO + return rune(0x22e8), true + case "prod": // N-ARY PRODUCT + return rune(0x220f), true + case "profalar": // ALL AROUND-PROFILE + return rune(0x232e), true + case "profline": // ARC + return rune(0x2312), true + case "profsurf": // SEGMENT + return rune(0x2313), true + case "prop": // PROPORTIONAL TO + return rune(0x221d), true + case "propto": // PROPORTIONAL TO + return rune(0x221d), true + case "prsim": // PRECEDES OR EQUIVALENT TO + return rune(0x227e), true + case "prurel": // PRECEDES UNDER RELATION + return rune(0x22b0), true + case "pscr": // MATHEMATICAL SCRIPT SMALL P + return rune(0x01d4c5), true + case "psgr": // GREEK SMALL LETTER PSI + return rune(0x03c8), true + case "psi": // GREEK SMALL LETTER PSI + return rune(0x03c8), true + case "puncsp": // PUNCTUATION SPACE + return rune(0x2008), true } case 'q': switch name { - case "qfr": // MATHEMATICAL FRAKTUR SMALL Q - return rune(0x01d52e), true - case "qint": // QUADRUPLE INTEGRAL OPERATOR - return rune(0x2a0c), true - case "qopf": // MATHEMATICAL DOUBLE-STRUCK SMALL Q - return rune(0x01d562), true - case "qprime": // QUADRUPLE PRIME - return rune(0x2057), true - case "qscr": // MATHEMATICAL SCRIPT SMALL Q - return rune(0x01d4c6), true - case "quaternions": // DOUBLE-STRUCK CAPITAL H - return rune(0x210d), true - case "quatint": // QUATERNION INTEGRAL OPERATOR - return rune(0x2a16), true - case "quest": // QUESTION MARK - return rune(0x3f), true - case "questeq": // QUESTIONED EQUAL TO - return rune(0x225f), true - case "quot": // QUOTATION MARK - return rune(0x22), true + case "qfr": // MATHEMATICAL FRAKTUR SMALL Q + return rune(0x01d52e), true + case "qint": // QUADRUPLE INTEGRAL OPERATOR + return rune(0x2a0c), true + case "qopf": // MATHEMATICAL DOUBLE-STRUCK SMALL Q + return rune(0x01d562), true + case "qprime": // QUADRUPLE PRIME + return rune(0x2057), true + case "qscr": // MATHEMATICAL SCRIPT SMALL Q + return rune(0x01d4c6), true + case "quaternions": // DOUBLE-STRUCK CAPITAL H + return rune(0x210d), true + case "quatint": // QUATERNION INTEGRAL OPERATOR + return rune(0x2a16), true + case "quest": // QUESTION MARK + return rune(0x3f), true + case "questeq": // QUESTIONED EQUAL TO + return rune(0x225f), true + case "quot": // QUOTATION MARK + return rune(0x22), true } case 'r': switch name { - case "rAarr": // RIGHTWARDS TRIPLE ARROW - return rune(0x21db), true - case "rArr": // RIGHTWARDS DOUBLE ARROW - return rune(0x21d2), true - case "rAtail": // RIGHTWARDS DOUBLE ARROW-TAIL - return rune(0x291c), true - case "rBarr": // RIGHTWARDS TRIPLE DASH ARROW - return rune(0x290f), true - case "rHar": // RIGHTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB DOWN - return rune(0x2964), true - case "race": // REVERSED TILDE with underline - return rune(0x223d), true - case "racute": // LATIN SMALL LETTER R WITH ACUTE - return rune(0x0155), true - case "radic": // SQUARE ROOT - return rune(0x221a), true - case "raemptyv": // EMPTY SET WITH RIGHT ARROW ABOVE - return rune(0x29b3), true - case "rang": // MATHEMATICAL RIGHT ANGLE BRACKET - return rune(0x27e9), true - case "rangd": // RIGHT ANGLE BRACKET WITH DOT - return rune(0x2992), true - case "range": // REVERSED ANGLE WITH UNDERBAR - return rune(0x29a5), true - case "rangle": // MATHEMATICAL RIGHT ANGLE BRACKET - return rune(0x27e9), true - case "raquo": // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK - return rune(0xbb), true - case "rarr": // RIGHTWARDS ARROW - return rune(0x2192), true - case "rarr2": // RIGHTWARDS PAIRED ARROWS - return rune(0x21c9), true - case "rarr3": // THREE RIGHTWARDS ARROWS - return rune(0x21f6), true - case "rarrap": // RIGHTWARDS ARROW ABOVE ALMOST EQUAL TO - return rune(0x2975), true - case "rarrb": // RIGHTWARDS ARROW TO BAR - return rune(0x21e5), true - case "rarrbfs": // RIGHTWARDS ARROW FROM BAR TO BLACK DIAMOND - return rune(0x2920), true - case "rarrc": // WAVE ARROW POINTING DIRECTLY RIGHT - return rune(0x2933), true - case "rarrfs": // RIGHTWARDS ARROW TO BLACK DIAMOND - return rune(0x291e), true - case "rarrhk": // RIGHTWARDS ARROW WITH HOOK - return rune(0x21aa), true - case "rarrlp": // RIGHTWARDS ARROW WITH LOOP - return rune(0x21ac), true - case "rarrpl": // RIGHTWARDS ARROW WITH PLUS BELOW - return rune(0x2945), true - case "rarrsim": // RIGHTWARDS ARROW ABOVE TILDE OPERATOR - return rune(0x2974), true - case "rarrtl": // RIGHTWARDS ARROW WITH TAIL - return rune(0x21a3), true - case "rarrw": // RIGHTWARDS WAVE ARROW - return rune(0x219d), true - case "rarrx": // RIGHTWARDS ARROW THROUGH X - return rune(0x2947), true - case "ratail": // RIGHTWARDS ARROW-TAIL - return rune(0x291a), true - case "ratio": // RATIO - return rune(0x2236), true - case "rationals": // DOUBLE-STRUCK CAPITAL Q - return rune(0x211a), true - case "rbarr": // RIGHTWARDS DOUBLE DASH ARROW - return rune(0x290d), true - case "rbbrk": // LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT - return rune(0x2773), true - case "rbrace": // RIGHT CURLY BRACKET - return rune(0x7d), true - case "rbrack": // RIGHT SQUARE BRACKET - return rune(0x5d), true - case "rbrke": // RIGHT SQUARE BRACKET WITH UNDERBAR - return rune(0x298c), true - case "rbrksld": // RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER - return rune(0x298e), true - case "rbrkslu": // RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER - return rune(0x2990), true - case "rcaron": // LATIN SMALL LETTER R WITH CARON - return rune(0x0159), true - case "rcedil": // LATIN SMALL LETTER R WITH CEDILLA - return rune(0x0157), true - case "rceil": // RIGHT CEILING - return rune(0x2309), true - case "rcub": // RIGHT CURLY BRACKET - return rune(0x7d), true - case "rcy": // CYRILLIC SMALL LETTER ER - return rune(0x0440), true - case "rdca": // ARROW POINTING DOWNWARDS THEN CURVING RIGHTWARDS - return rune(0x2937), true - case "rdharb": // RIGHTWARDS HARPOON WITH BARB DOWN TO BAR - return rune(0x2957), true - case "rdiag": // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT - return rune(0x2571), true - case "rdiofdi": // RISING DIAGONAL CROSSING FALLING DIAGONAL - return rune(0x292b), true - case "rdldhar": // RIGHTWARDS HARPOON WITH BARB DOWN ABOVE LEFTWARDS HARPOON WITH BARB DOWN - return rune(0x2969), true - case "rdosearr": // RISING DIAGONAL CROSSING SOUTH EAST ARROW - return rune(0x2930), true - case "rdquo": // RIGHT DOUBLE QUOTATION MARK - return rune(0x201d), true - case "rdquor": // RIGHT DOUBLE QUOTATION MARK - return rune(0x201d), true - case "rdsh": // DOWNWARDS ARROW WITH TIP RIGHTWARDS - return rune(0x21b3), true - case "real": // BLACK-LETTER CAPITAL R - return rune(0x211c), true - case "realine": // SCRIPT CAPITAL R - return rune(0x211b), true - case "realpart": // BLACK-LETTER CAPITAL R - return rune(0x211c), true - case "reals": // DOUBLE-STRUCK CAPITAL R - return rune(0x211d), true - case "rect": // WHITE RECTANGLE - return rune(0x25ad), true - case "reg": // REGISTERED SIGN - return rune(0xae), true - case "rfbowtie": // BOWTIE WITH RIGHT HALF BLACK - return rune(0x29d2), true - case "rfisht": // RIGHT FISH TAIL - return rune(0x297d), true - case "rfloor": // RIGHT FLOOR - return rune(0x230b), true - case "rfr": // MATHEMATICAL FRAKTUR SMALL R - return rune(0x01d52f), true - case "rftimes": // TIMES WITH RIGHT HALF BLACK - return rune(0x29d5), true - case "rgr": // GREEK SMALL LETTER RHO - return rune(0x03c1), true - case "rhard": // RIGHTWARDS HARPOON WITH BARB DOWNWARDS - return rune(0x21c1), true - case "rharu": // RIGHTWARDS HARPOON WITH BARB UPWARDS - return rune(0x21c0), true - case "rharul": // RIGHTWARDS HARPOON WITH BARB UP ABOVE LONG DASH - return rune(0x296c), true - case "rho": // GREEK SMALL LETTER RHO - return rune(0x03c1), true - case "rhov": // GREEK RHO SYMBOL - return rune(0x03f1), true - case "rightarrow": // RIGHTWARDS ARROW - return rune(0x2192), true - case "rightarrowtail": // RIGHTWARDS ARROW WITH TAIL - return rune(0x21a3), true - case "rightharpoondown": // RIGHTWARDS HARPOON WITH BARB DOWNWARDS - return rune(0x21c1), true - case "rightharpoonup": // RIGHTWARDS HARPOON WITH BARB UPWARDS - return rune(0x21c0), true - case "rightleftarrows": // RIGHTWARDS ARROW OVER LEFTWARDS ARROW - return rune(0x21c4), true - case "rightleftharpoons": // RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON - return rune(0x21cc), true - case "rightrightarrows": // RIGHTWARDS PAIRED ARROWS - return rune(0x21c9), true - case "rightsquigarrow": // RIGHTWARDS WAVE ARROW - return rune(0x219d), true - case "rightthreetimes": // RIGHT SEMIDIRECT PRODUCT - return rune(0x22cc), true - case "rimply": // RIGHT DOUBLE ARROW WITH ROUNDED HEAD - return rune(0x2970), true - case "ring": // RING ABOVE - return rune(0x02da), true - case "risingdotseq": // IMAGE OF OR APPROXIMATELY EQUAL TO - return rune(0x2253), true - case "rlarr": // RIGHTWARDS ARROW OVER LEFTWARDS ARROW - return rune(0x21c4), true - case "rlarr2": // RIGHTWARDS ARROW OVER LEFTWARDS ARROW - return rune(0x21c4), true - case "rlhar": // RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON - return rune(0x21cc), true - case "rlhar2": // RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON - return rune(0x21cc), true - case "rlm": // RIGHT-TO-LEFT MARK - return rune(0x200f), true - case "rmoust": // UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION - return rune(0x23b1), true - case "rmoustache": // UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION - return rune(0x23b1), true - case "rnmid": // DOES NOT DIVIDE WITH REVERSED NEGATION SLASH - return rune(0x2aee), true - case "roang": // MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET - return rune(0x27ed), true - case "roarr": // RIGHTWARDS OPEN-HEADED ARROW - return rune(0x21fe), true - case "robrk": // MATHEMATICAL RIGHT WHITE SQUARE BRACKET - return rune(0x27e7), true - case "rocub": // RIGHT WHITE CURLY BRACKET - return rune(0x2984), true - case "ropar": // RIGHT WHITE PARENTHESIS - return rune(0x2986), true - case "ropf": // MATHEMATICAL DOUBLE-STRUCK SMALL R - return rune(0x01d563), true - case "roplus": // PLUS SIGN IN RIGHT HALF CIRCLE - return rune(0x2a2e), true - case "rotimes": // MULTIPLICATION SIGN IN RIGHT HALF CIRCLE - return rune(0x2a35), true - case "rpar": // RIGHT PARENTHESIS - return rune(0x29), true - case "rpargt": // RIGHT ARC GREATER-THAN BRACKET - return rune(0x2994), true - case "rppolint": // LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE - return rune(0x2a12), true - case "rrarr": // RIGHTWARDS PAIRED ARROWS - return rune(0x21c9), true - case "rsaquo": // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK - return rune(0x203a), true - case "rscr": // MATHEMATICAL SCRIPT SMALL R - return rune(0x01d4c7), true - case "rsh": // UPWARDS ARROW WITH TIP RIGHTWARDS - return rune(0x21b1), true - case "rsolbar": // REVERSE SOLIDUS WITH HORIZONTAL STROKE - return rune(0x29f7), true - case "rsqb": // RIGHT SQUARE BRACKET - return rune(0x5d), true - case "rsquo": // RIGHT SINGLE QUOTATION MARK - return rune(0x2019), true - case "rsquor": // RIGHT SINGLE QUOTATION MARK - return rune(0x2019), true - case "rthree": // RIGHT SEMIDIRECT PRODUCT - return rune(0x22cc), true - case "rtimes": // RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT - return rune(0x22ca), true - case "rtri": // WHITE RIGHT-POINTING SMALL TRIANGLE - return rune(0x25b9), true - case "rtrie": // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO - return rune(0x22b5), true - case "rtrif": // BLACK RIGHT-POINTING SMALL TRIANGLE - return rune(0x25b8), true - case "rtriltri": // RIGHT TRIANGLE ABOVE LEFT TRIANGLE - return rune(0x29ce), true - case "ruharb": // RIGHTWARDS HARPOON WITH BARB UP TO BAR - return rune(0x2953), true - case "ruluhar": // RIGHTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB UP - return rune(0x2968), true - case "rx": // PRESCRIPTION TAKE - return rune(0x211e), true + case "rAarr": // RIGHTWARDS TRIPLE ARROW + return rune(0x21db), true + case "rArr": // RIGHTWARDS DOUBLE ARROW + return rune(0x21d2), true + case "rAtail": // RIGHTWARDS DOUBLE ARROW-TAIL + return rune(0x291c), true + case "rBarr": // RIGHTWARDS TRIPLE DASH ARROW + return rune(0x290f), true + case "rHar": // RIGHTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB DOWN + return rune(0x2964), true + case "race": // REVERSED TILDE with underline + return rune(0x223d), true + case "racute": // LATIN SMALL LETTER R WITH ACUTE + return rune(0x0155), true + case "radic": // SQUARE ROOT + return rune(0x221a), true + case "raemptyv": // EMPTY SET WITH RIGHT ARROW ABOVE + return rune(0x29b3), true + case "rang": // MATHEMATICAL RIGHT ANGLE BRACKET + return rune(0x27e9), true + case "rangd": // RIGHT ANGLE BRACKET WITH DOT + return rune(0x2992), true + case "range": // REVERSED ANGLE WITH UNDERBAR + return rune(0x29a5), true + case "rangle": // MATHEMATICAL RIGHT ANGLE BRACKET + return rune(0x27e9), true + case "raquo": // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + return rune(0xbb), true + case "rarr": // RIGHTWARDS ARROW + return rune(0x2192), true + case "rarr2": // RIGHTWARDS PAIRED ARROWS + return rune(0x21c9), true + case "rarr3": // THREE RIGHTWARDS ARROWS + return rune(0x21f6), true + case "rarrap": // RIGHTWARDS ARROW ABOVE ALMOST EQUAL TO + return rune(0x2975), true + case "rarrb": // RIGHTWARDS ARROW TO BAR + return rune(0x21e5), true + case "rarrbfs": // RIGHTWARDS ARROW FROM BAR TO BLACK DIAMOND + return rune(0x2920), true + case "rarrc": // WAVE ARROW POINTING DIRECTLY RIGHT + return rune(0x2933), true + case "rarrfs": // RIGHTWARDS ARROW TO BLACK DIAMOND + return rune(0x291e), true + case "rarrhk": // RIGHTWARDS ARROW WITH HOOK + return rune(0x21aa), true + case "rarrlp": // RIGHTWARDS ARROW WITH LOOP + return rune(0x21ac), true + case "rarrpl": // RIGHTWARDS ARROW WITH PLUS BELOW + return rune(0x2945), true + case "rarrsim": // RIGHTWARDS ARROW ABOVE TILDE OPERATOR + return rune(0x2974), true + case "rarrtl": // RIGHTWARDS ARROW WITH TAIL + return rune(0x21a3), true + case "rarrw": // RIGHTWARDS WAVE ARROW + return rune(0x219d), true + case "rarrx": // RIGHTWARDS ARROW THROUGH X + return rune(0x2947), true + case "ratail": // RIGHTWARDS ARROW-TAIL + return rune(0x291a), true + case "ratio": // RATIO + return rune(0x2236), true + case "rationals": // DOUBLE-STRUCK CAPITAL Q + return rune(0x211a), true + case "rbarr": // RIGHTWARDS DOUBLE DASH ARROW + return rune(0x290d), true + case "rbbrk": // LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT + return rune(0x2773), true + case "rbrace": // RIGHT CURLY BRACKET + return rune(0x7d), true + case "rbrack": // RIGHT SQUARE BRACKET + return rune(0x5d), true + case "rbrke": // RIGHT SQUARE BRACKET WITH UNDERBAR + return rune(0x298c), true + case "rbrksld": // RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER + return rune(0x298e), true + case "rbrkslu": // RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER + return rune(0x2990), true + case "rcaron": // LATIN SMALL LETTER R WITH CARON + return rune(0x0159), true + case "rcedil": // LATIN SMALL LETTER R WITH CEDILLA + return rune(0x0157), true + case "rceil": // RIGHT CEILING + return rune(0x2309), true + case "rcub": // RIGHT CURLY BRACKET + return rune(0x7d), true + case "rcy": // CYRILLIC SMALL LETTER ER + return rune(0x0440), true + case "rdca": // ARROW POINTING DOWNWARDS THEN CURVING RIGHTWARDS + return rune(0x2937), true + case "rdharb": // RIGHTWARDS HARPOON WITH BARB DOWN TO BAR + return rune(0x2957), true + case "rdiag": // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT + return rune(0x2571), true + case "rdiofdi": // RISING DIAGONAL CROSSING FALLING DIAGONAL + return rune(0x292b), true + case "rdldhar": // RIGHTWARDS HARPOON WITH BARB DOWN ABOVE LEFTWARDS HARPOON WITH BARB DOWN + return rune(0x2969), true + case "rdosearr": // RISING DIAGONAL CROSSING SOUTH EAST ARROW + return rune(0x2930), true + case "rdquo": // RIGHT DOUBLE QUOTATION MARK + return rune(0x201d), true + case "rdquor": // RIGHT DOUBLE QUOTATION MARK + return rune(0x201d), true + case "rdsh": // DOWNWARDS ARROW WITH TIP RIGHTWARDS + return rune(0x21b3), true + case "real": // BLACK-LETTER CAPITAL R + return rune(0x211c), true + case "realine": // SCRIPT CAPITAL R + return rune(0x211b), true + case "realpart": // BLACK-LETTER CAPITAL R + return rune(0x211c), true + case "reals": // DOUBLE-STRUCK CAPITAL R + return rune(0x211d), true + case "rect": // WHITE RECTANGLE + return rune(0x25ad), true + case "reg": // REGISTERED SIGN + return rune(0xae), true + case "rfbowtie": // BOWTIE WITH RIGHT HALF BLACK + return rune(0x29d2), true + case "rfisht": // RIGHT FISH TAIL + return rune(0x297d), true + case "rfloor": // RIGHT FLOOR + return rune(0x230b), true + case "rfr": // MATHEMATICAL FRAKTUR SMALL R + return rune(0x01d52f), true + case "rftimes": // TIMES WITH RIGHT HALF BLACK + return rune(0x29d5), true + case "rgr": // GREEK SMALL LETTER RHO + return rune(0x03c1), true + case "rhard": // RIGHTWARDS HARPOON WITH BARB DOWNWARDS + return rune(0x21c1), true + case "rharu": // RIGHTWARDS HARPOON WITH BARB UPWARDS + return rune(0x21c0), true + case "rharul": // RIGHTWARDS HARPOON WITH BARB UP ABOVE LONG DASH + return rune(0x296c), true + case "rho": // GREEK SMALL LETTER RHO + return rune(0x03c1), true + case "rhov": // GREEK RHO SYMBOL + return rune(0x03f1), true + case "rightarrow": // RIGHTWARDS ARROW + return rune(0x2192), true + case "rightarrowtail": // RIGHTWARDS ARROW WITH TAIL + return rune(0x21a3), true + case "rightharpoondown": // RIGHTWARDS HARPOON WITH BARB DOWNWARDS + return rune(0x21c1), true + case "rightharpoonup": // RIGHTWARDS HARPOON WITH BARB UPWARDS + return rune(0x21c0), true + case "rightleftarrows": // RIGHTWARDS ARROW OVER LEFTWARDS ARROW + return rune(0x21c4), true + case "rightleftharpoons": // RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON + return rune(0x21cc), true + case "rightrightarrows": // RIGHTWARDS PAIRED ARROWS + return rune(0x21c9), true + case "rightsquigarrow": // RIGHTWARDS WAVE ARROW + return rune(0x219d), true + case "rightthreetimes": // RIGHT SEMIDIRECT PRODUCT + return rune(0x22cc), true + case "rimply": // RIGHT DOUBLE ARROW WITH ROUNDED HEAD + return rune(0x2970), true + case "ring": // RING ABOVE + return rune(0x02da), true + case "risingdotseq": // IMAGE OF OR APPROXIMATELY EQUAL TO + return rune(0x2253), true + case "rlarr": // RIGHTWARDS ARROW OVER LEFTWARDS ARROW + return rune(0x21c4), true + case "rlarr2": // RIGHTWARDS ARROW OVER LEFTWARDS ARROW + return rune(0x21c4), true + case "rlhar": // RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON + return rune(0x21cc), true + case "rlhar2": // RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON + return rune(0x21cc), true + case "rlm": // RIGHT-TO-LEFT MARK + return rune(0x200f), true + case "rmoust": // UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION + return rune(0x23b1), true + case "rmoustache": // UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION + return rune(0x23b1), true + case "rnmid": // DOES NOT DIVIDE WITH REVERSED NEGATION SLASH + return rune(0x2aee), true + case "roang": // MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET + return rune(0x27ed), true + case "roarr": // RIGHTWARDS OPEN-HEADED ARROW + return rune(0x21fe), true + case "robrk": // MATHEMATICAL RIGHT WHITE SQUARE BRACKET + return rune(0x27e7), true + case "rocub": // RIGHT WHITE CURLY BRACKET + return rune(0x2984), true + case "ropar": // RIGHT WHITE PARENTHESIS + return rune(0x2986), true + case "ropf": // MATHEMATICAL DOUBLE-STRUCK SMALL R + return rune(0x01d563), true + case "roplus": // PLUS SIGN IN RIGHT HALF CIRCLE + return rune(0x2a2e), true + case "rotimes": // MULTIPLICATION SIGN IN RIGHT HALF CIRCLE + return rune(0x2a35), true + case "rpar": // RIGHT PARENTHESIS + return rune(0x29), true + case "rpargt": // RIGHT ARC GREATER-THAN BRACKET + return rune(0x2994), true + case "rppolint": // LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE + return rune(0x2a12), true + case "rrarr": // RIGHTWARDS PAIRED ARROWS + return rune(0x21c9), true + case "rsaquo": // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + return rune(0x203a), true + case "rscr": // MATHEMATICAL SCRIPT SMALL R + return rune(0x01d4c7), true + case "rsh": // UPWARDS ARROW WITH TIP RIGHTWARDS + return rune(0x21b1), true + case "rsolbar": // REVERSE SOLIDUS WITH HORIZONTAL STROKE + return rune(0x29f7), true + case "rsqb": // RIGHT SQUARE BRACKET + return rune(0x5d), true + case "rsquo": // RIGHT SINGLE QUOTATION MARK + return rune(0x2019), true + case "rsquor": // RIGHT SINGLE QUOTATION MARK + return rune(0x2019), true + case "rthree": // RIGHT SEMIDIRECT PRODUCT + return rune(0x22cc), true + case "rtimes": // RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT + return rune(0x22ca), true + case "rtri": // WHITE RIGHT-POINTING SMALL TRIANGLE + return rune(0x25b9), true + case "rtrie": // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO + return rune(0x22b5), true + case "rtrif": // BLACK RIGHT-POINTING SMALL TRIANGLE + return rune(0x25b8), true + case "rtriltri": // RIGHT TRIANGLE ABOVE LEFT TRIANGLE + return rune(0x29ce), true + case "ruharb": // RIGHTWARDS HARPOON WITH BARB UP TO BAR + return rune(0x2953), true + case "ruluhar": // RIGHTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB UP + return rune(0x2968), true + case "rx": // PRESCRIPTION TAKE + return rune(0x211e), true } case 's': switch name { - case "sacute": // LATIN SMALL LETTER S WITH ACUTE - return rune(0x015b), true - case "samalg": // N-ARY COPRODUCT - return rune(0x2210), true - case "sampi": // GREEK LETTER SAMPI - return rune(0x03e0), true - case "sbquo": // SINGLE LOW-9 QUOTATION MARK - return rune(0x201a), true - case "sbsol": // SMALL REVERSE SOLIDUS - return rune(0xfe68), true - case "sc": // SUCCEEDS - return rune(0x227b), true - case "scE": // SUCCEEDS ABOVE EQUALS SIGN - return rune(0x2ab4), true - case "scap": // SUCCEEDS ABOVE ALMOST EQUAL TO - return rune(0x2ab8), true - case "scaron": // LATIN SMALL LETTER S WITH CARON - return rune(0x0161), true - case "sccue": // SUCCEEDS OR EQUAL TO - return rune(0x227d), true - case "sce": // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN - return rune(0x2ab0), true - case "scedil": // LATIN SMALL LETTER S WITH CEDILLA - return rune(0x015f), true - case "scirc": // LATIN SMALL LETTER S WITH CIRCUMFLEX - return rune(0x015d), true - case "scnE": // SUCCEEDS ABOVE NOT EQUAL TO - return rune(0x2ab6), true - case "scnap": // SUCCEEDS ABOVE NOT ALMOST EQUAL TO - return rune(0x2aba), true - case "scnsim": // SUCCEEDS BUT NOT EQUIVALENT TO - return rune(0x22e9), true - case "scpolint": // LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE - return rune(0x2a13), true - case "scsim": // SUCCEEDS OR EQUIVALENT TO - return rune(0x227f), true - case "scy": // CYRILLIC SMALL LETTER ES - return rune(0x0441), true - case "sdot": // DOT OPERATOR - return rune(0x22c5), true - case "sdotb": // SQUARED DOT OPERATOR - return rune(0x22a1), true - case "sdote": // EQUALS SIGN WITH DOT BELOW - return rune(0x2a66), true - case "seArr": // SOUTH EAST DOUBLE ARROW - return rune(0x21d8), true - case "searhk": // SOUTH EAST ARROW WITH HOOK - return rune(0x2925), true - case "searr": // SOUTH EAST ARROW - return rune(0x2198), true - case "searrow": // SOUTH EAST ARROW - return rune(0x2198), true - case "sect": // SECTION SIGN - return rune(0xa7), true - case "semi": // SEMICOLON - return rune(0x3b), true - case "seonearr": // SOUTH EAST ARROW CROSSING NORTH EAST ARROW - return rune(0x292d), true - case "seswar": // SOUTH EAST ARROW AND SOUTH WEST ARROW - return rune(0x2929), true - case "setminus": // SET MINUS - return rune(0x2216), true - case "setmn": // SET MINUS - return rune(0x2216), true - case "sext": // SIX POINTED BLACK STAR - return rune(0x2736), true - case "sfgr": // GREEK SMALL LETTER FINAL SIGMA - return rune(0x03c2), true - case "sfr": // MATHEMATICAL FRAKTUR SMALL S - return rune(0x01d530), true - case "sfrown": // FROWN - return rune(0x2322), true - case "sgr": // GREEK SMALL LETTER SIGMA - return rune(0x03c3), true - case "sharp": // MUSIC SHARP SIGN - return rune(0x266f), true - case "shchcy": // CYRILLIC SMALL LETTER SHCHA - return rune(0x0449), true - case "shcy": // CYRILLIC SMALL LETTER SHA - return rune(0x0448), true - case "shortmid": // DIVIDES - return rune(0x2223), true - case "shortparallel": // PARALLEL TO - return rune(0x2225), true - case "shuffle": // SHUFFLE PRODUCT - return rune(0x29e2), true - case "shy": // SOFT HYPHEN - return rune(0xad), true - case "sigma": // GREEK SMALL LETTER SIGMA - return rune(0x03c3), true - case "sigmaf": // GREEK SMALL LETTER FINAL SIGMA - return rune(0x03c2), true - case "sigmav": // GREEK SMALL LETTER FINAL SIGMA - return rune(0x03c2), true - case "sim": // TILDE OPERATOR - return rune(0x223c), true - case "simdot": // TILDE OPERATOR WITH DOT ABOVE - return rune(0x2a6a), true - case "sime": // ASYMPTOTICALLY EQUAL TO - return rune(0x2243), true - case "simeq": // ASYMPTOTICALLY EQUAL TO - return rune(0x2243), true - case "simg": // SIMILAR OR GREATER-THAN - return rune(0x2a9e), true - case "simgE": // SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN - return rune(0x2aa0), true - case "siml": // SIMILAR OR LESS-THAN - return rune(0x2a9d), true - case "simlE": // SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN - return rune(0x2a9f), true - case "simne": // APPROXIMATELY BUT NOT ACTUALLY EQUAL TO - return rune(0x2246), true - case "simplus": // PLUS SIGN WITH TILDE ABOVE - return rune(0x2a24), true - case "simrarr": // TILDE OPERATOR ABOVE RIGHTWARDS ARROW - return rune(0x2972), true - case "slarr": // LEFTWARDS ARROW - return rune(0x2190), true - case "slint": // INTEGRAL AVERAGE WITH SLASH - return rune(0x2a0f), true - case "smallsetminus": // SET MINUS - return rune(0x2216), true - case "smashp": // SMASH PRODUCT - return rune(0x2a33), true - case "smeparsl": // EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE - return rune(0x29e4), true - case "smid": // DIVIDES - return rune(0x2223), true - case "smile": // SMILE - return rune(0x2323), true - case "smt": // SMALLER THAN - return rune(0x2aaa), true - case "smte": // SMALLER THAN OR EQUAL TO - return rune(0x2aac), true - case "smtes": // SMALLER THAN OR slanted EQUAL - return rune(0x2aac), true - case "softcy": // CYRILLIC SMALL LETTER SOFT SIGN - return rune(0x044c), true - case "sol": // SOLIDUS - return rune(0x2f), true - case "solb": // SQUARED RISING DIAGONAL SLASH - return rune(0x29c4), true - case "solbar": // APL FUNCTIONAL SYMBOL SLASH BAR - return rune(0x233f), true - case "sopf": // MATHEMATICAL DOUBLE-STRUCK SMALL S - return rune(0x01d564), true - case "spades": // BLACK SPADE SUIT - return rune(0x2660), true - case "spadesuit": // BLACK SPADE SUIT - return rune(0x2660), true - case "spar": // PARALLEL TO - return rune(0x2225), true - case "sqcap": // SQUARE CAP - return rune(0x2293), true - case "sqcaps": // SQUARE CAP with serifs - return rune(0x2293), true - case "sqcup": // SQUARE CUP - return rune(0x2294), true - case "sqcups": // SQUARE CUP with serifs - return rune(0x2294), true - case "sqsub": // SQUARE IMAGE OF - return rune(0x228f), true - case "sqsube": // SQUARE IMAGE OF OR EQUAL TO - return rune(0x2291), true - case "sqsubset": // SQUARE IMAGE OF - return rune(0x228f), true - case "sqsubseteq": // SQUARE IMAGE OF OR EQUAL TO - return rune(0x2291), true - case "sqsup": // SQUARE ORIGINAL OF - return rune(0x2290), true - case "sqsupe": // SQUARE ORIGINAL OF OR EQUAL TO - return rune(0x2292), true - case "sqsupset": // SQUARE ORIGINAL OF - return rune(0x2290), true - case "sqsupseteq": // SQUARE ORIGINAL OF OR EQUAL TO - return rune(0x2292), true - case "squ": // WHITE SQUARE - return rune(0x25a1), true - case "square": // WHITE SQUARE - return rune(0x25a1), true - case "squarf": // BLACK SMALL SQUARE - return rune(0x25aa), true - case "squb": // SQUARED SQUARE - return rune(0x29c8), true - case "squerr": // ERROR-BARRED WHITE SQUARE - return rune(0x29ee), true - case "squf": // BLACK SMALL SQUARE - return rune(0x25aa), true - case "squferr": // ERROR-BARRED BLACK SQUARE - return rune(0x29ef), true - case "srarr": // RIGHTWARDS ARROW - return rune(0x2192), true - case "sscr": // MATHEMATICAL SCRIPT SMALL S - return rune(0x01d4c8), true - case "ssetmn": // SET MINUS - return rune(0x2216), true - case "ssmile": // SMILE - return rune(0x2323), true - case "sstarf": // STAR OPERATOR - return rune(0x22c6), true - case "star": // WHITE STAR - return rune(0x2606), true - case "starf": // BLACK STAR - return rune(0x2605), true - case "stigma": // GREEK LETTER STIGMA - return rune(0x03da), true - case "straightepsilon": // GREEK LUNATE EPSILON SYMBOL - return rune(0x03f5), true - case "straightphi": // GREEK PHI SYMBOL - return rune(0x03d5), true - case "strns": // MACRON - return rune(0xaf), true - case "sub": // SUBSET OF - return rune(0x2282), true - case "subE": // SUBSET OF ABOVE EQUALS SIGN - return rune(0x2ac5), true - case "subdot": // SUBSET WITH DOT - return rune(0x2abd), true - case "sube": // SUBSET OF OR EQUAL TO - return rune(0x2286), true - case "subedot": // SUBSET OF OR EQUAL TO WITH DOT ABOVE - return rune(0x2ac3), true - case "submult": // SUBSET WITH MULTIPLICATION SIGN BELOW - return rune(0x2ac1), true - case "subnE": // SUBSET OF ABOVE NOT EQUAL TO - return rune(0x2acb), true - case "subne": // SUBSET OF WITH NOT EQUAL TO - return rune(0x228a), true - case "subplus": // SUBSET WITH PLUS SIGN BELOW - return rune(0x2abf), true - case "subrarr": // SUBSET ABOVE RIGHTWARDS ARROW - return rune(0x2979), true - case "subset": // SUBSET OF - return rune(0x2282), true - case "subseteq": // SUBSET OF OR EQUAL TO - return rune(0x2286), true - case "subseteqq": // SUBSET OF ABOVE EQUALS SIGN - return rune(0x2ac5), true - case "subsetneq": // SUBSET OF WITH NOT EQUAL TO - return rune(0x228a), true - case "subsetneqq": // SUBSET OF ABOVE NOT EQUAL TO - return rune(0x2acb), true - case "subsim": // SUBSET OF ABOVE TILDE OPERATOR - return rune(0x2ac7), true - case "subsub": // SUBSET ABOVE SUBSET - return rune(0x2ad5), true - case "subsup": // SUBSET ABOVE SUPERSET - return rune(0x2ad3), true - case "succ": // SUCCEEDS - return rune(0x227b), true - case "succapprox": // SUCCEEDS ABOVE ALMOST EQUAL TO - return rune(0x2ab8), true - case "succcurlyeq": // SUCCEEDS OR EQUAL TO - return rune(0x227d), true - case "succeq": // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN - return rune(0x2ab0), true - case "succnapprox": // SUCCEEDS ABOVE NOT ALMOST EQUAL TO - return rune(0x2aba), true - case "succneqq": // SUCCEEDS ABOVE NOT EQUAL TO - return rune(0x2ab6), true - case "succnsim": // SUCCEEDS BUT NOT EQUIVALENT TO - return rune(0x22e9), true - case "succsim": // SUCCEEDS OR EQUIVALENT TO - return rune(0x227f), true - case "sum": // N-ARY SUMMATION - return rune(0x2211), true - case "sumint": // SUMMATION WITH INTEGRAL - return rune(0x2a0b), true - case "sung": // EIGHTH NOTE - return rune(0x266a), true - case "sup": // SUPERSET OF - return rune(0x2283), true - case "sup1": // SUPERSCRIPT ONE - return rune(0xb9), true - case "sup2": // SUPERSCRIPT TWO - return rune(0xb2), true - case "sup3": // SUPERSCRIPT THREE - return rune(0xb3), true - case "supE": // SUPERSET OF ABOVE EQUALS SIGN - return rune(0x2ac6), true - case "supdot": // SUPERSET WITH DOT - return rune(0x2abe), true - case "supdsub": // SUPERSET BESIDE AND JOINED BY DASH WITH SUBSET - return rune(0x2ad8), true - case "supe": // SUPERSET OF OR EQUAL TO - return rune(0x2287), true - case "supedot": // SUPERSET OF OR EQUAL TO WITH DOT ABOVE - return rune(0x2ac4), true - case "suphsol": // SUPERSET PRECEDING SOLIDUS - return rune(0x27c9), true - case "suphsub": // SUPERSET BESIDE SUBSET - return rune(0x2ad7), true - case "suplarr": // SUPERSET ABOVE LEFTWARDS ARROW - return rune(0x297b), true - case "supmult": // SUPERSET WITH MULTIPLICATION SIGN BELOW - return rune(0x2ac2), true - case "supnE": // SUPERSET OF ABOVE NOT EQUAL TO - return rune(0x2acc), true - case "supne": // SUPERSET OF WITH NOT EQUAL TO - return rune(0x228b), true - case "supplus": // SUPERSET WITH PLUS SIGN BELOW - return rune(0x2ac0), true - case "supset": // SUPERSET OF - return rune(0x2283), true - case "supseteq": // SUPERSET OF OR EQUAL TO - return rune(0x2287), true - case "supseteqq": // SUPERSET OF ABOVE EQUALS SIGN - return rune(0x2ac6), true - case "supsetneq": // SUPERSET OF WITH NOT EQUAL TO - return rune(0x228b), true - case "supsetneqq": // SUPERSET OF ABOVE NOT EQUAL TO - return rune(0x2acc), true - case "supsim": // SUPERSET OF ABOVE TILDE OPERATOR - return rune(0x2ac8), true - case "supsub": // SUPERSET ABOVE SUBSET - return rune(0x2ad4), true - case "supsup": // SUPERSET ABOVE SUPERSET - return rune(0x2ad6), true - case "swArr": // SOUTH WEST DOUBLE ARROW - return rune(0x21d9), true - case "swarhk": // SOUTH WEST ARROW WITH HOOK - return rune(0x2926), true - case "swarr": // SOUTH WEST ARROW - return rune(0x2199), true - case "swarrow": // SOUTH WEST ARROW - return rune(0x2199), true - case "swnwar": // SOUTH WEST ARROW AND NORTH WEST ARROW - return rune(0x292a), true - case "szlig": // LATIN SMALL LETTER SHARP S - return rune(0xdf), true + case "sacute": // LATIN SMALL LETTER S WITH ACUTE + return rune(0x015b), true + case "samalg": // N-ARY COPRODUCT + return rune(0x2210), true + case "sampi": // GREEK LETTER SAMPI + return rune(0x03e0), true + case "sbquo": // SINGLE LOW-9 QUOTATION MARK + return rune(0x201a), true + case "sbsol": // SMALL REVERSE SOLIDUS + return rune(0xfe68), true + case "sc": // SUCCEEDS + return rune(0x227b), true + case "scE": // SUCCEEDS ABOVE EQUALS SIGN + return rune(0x2ab4), true + case "scap": // SUCCEEDS ABOVE ALMOST EQUAL TO + return rune(0x2ab8), true + case "scaron": // LATIN SMALL LETTER S WITH CARON + return rune(0x0161), true + case "sccue": // SUCCEEDS OR EQUAL TO + return rune(0x227d), true + case "sce": // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN + return rune(0x2ab0), true + case "scedil": // LATIN SMALL LETTER S WITH CEDILLA + return rune(0x015f), true + case "scirc": // LATIN SMALL LETTER S WITH CIRCUMFLEX + return rune(0x015d), true + case "scnE": // SUCCEEDS ABOVE NOT EQUAL TO + return rune(0x2ab6), true + case "scnap": // SUCCEEDS ABOVE NOT ALMOST EQUAL TO + return rune(0x2aba), true + case "scnsim": // SUCCEEDS BUT NOT EQUIVALENT TO + return rune(0x22e9), true + case "scpolint": // LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE + return rune(0x2a13), true + case "scsim": // SUCCEEDS OR EQUIVALENT TO + return rune(0x227f), true + case "scy": // CYRILLIC SMALL LETTER ES + return rune(0x0441), true + case "sdot": // DOT OPERATOR + return rune(0x22c5), true + case "sdotb": // SQUARED DOT OPERATOR + return rune(0x22a1), true + case "sdote": // EQUALS SIGN WITH DOT BELOW + return rune(0x2a66), true + case "seArr": // SOUTH EAST DOUBLE ARROW + return rune(0x21d8), true + case "searhk": // SOUTH EAST ARROW WITH HOOK + return rune(0x2925), true + case "searr": // SOUTH EAST ARROW + return rune(0x2198), true + case "searrow": // SOUTH EAST ARROW + return rune(0x2198), true + case "sect": // SECTION SIGN + return rune(0xa7), true + case "semi": // SEMICOLON + return rune(0x3b), true + case "seonearr": // SOUTH EAST ARROW CROSSING NORTH EAST ARROW + return rune(0x292d), true + case "seswar": // SOUTH EAST ARROW AND SOUTH WEST ARROW + return rune(0x2929), true + case "setminus": // SET MINUS + return rune(0x2216), true + case "setmn": // SET MINUS + return rune(0x2216), true + case "sext": // SIX POINTED BLACK STAR + return rune(0x2736), true + case "sfgr": // GREEK SMALL LETTER FINAL SIGMA + return rune(0x03c2), true + case "sfr": // MATHEMATICAL FRAKTUR SMALL S + return rune(0x01d530), true + case "sfrown": // FROWN + return rune(0x2322), true + case "sgr": // GREEK SMALL LETTER SIGMA + return rune(0x03c3), true + case "sharp": // MUSIC SHARP SIGN + return rune(0x266f), true + case "shchcy": // CYRILLIC SMALL LETTER SHCHA + return rune(0x0449), true + case "shcy": // CYRILLIC SMALL LETTER SHA + return rune(0x0448), true + case "shortmid": // DIVIDES + return rune(0x2223), true + case "shortparallel": // PARALLEL TO + return rune(0x2225), true + case "shuffle": // SHUFFLE PRODUCT + return rune(0x29e2), true + case "shy": // SOFT HYPHEN + return rune(0xad), true + case "sigma": // GREEK SMALL LETTER SIGMA + return rune(0x03c3), true + case "sigmaf": // GREEK SMALL LETTER FINAL SIGMA + return rune(0x03c2), true + case "sigmav": // GREEK SMALL LETTER FINAL SIGMA + return rune(0x03c2), true + case "sim": // TILDE OPERATOR + return rune(0x223c), true + case "simdot": // TILDE OPERATOR WITH DOT ABOVE + return rune(0x2a6a), true + case "sime": // ASYMPTOTICALLY EQUAL TO + return rune(0x2243), true + case "simeq": // ASYMPTOTICALLY EQUAL TO + return rune(0x2243), true + case "simg": // SIMILAR OR GREATER-THAN + return rune(0x2a9e), true + case "simgE": // SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN + return rune(0x2aa0), true + case "siml": // SIMILAR OR LESS-THAN + return rune(0x2a9d), true + case "simlE": // SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN + return rune(0x2a9f), true + case "simne": // APPROXIMATELY BUT NOT ACTUALLY EQUAL TO + return rune(0x2246), true + case "simplus": // PLUS SIGN WITH TILDE ABOVE + return rune(0x2a24), true + case "simrarr": // TILDE OPERATOR ABOVE RIGHTWARDS ARROW + return rune(0x2972), true + case "slarr": // LEFTWARDS ARROW + return rune(0x2190), true + case "slint": // INTEGRAL AVERAGE WITH SLASH + return rune(0x2a0f), true + case "smallsetminus": // SET MINUS + return rune(0x2216), true + case "smashp": // SMASH PRODUCT + return rune(0x2a33), true + case "smeparsl": // EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE + return rune(0x29e4), true + case "smid": // DIVIDES + return rune(0x2223), true + case "smile": // SMILE + return rune(0x2323), true + case "smt": // SMALLER THAN + return rune(0x2aaa), true + case "smte": // SMALLER THAN OR EQUAL TO + return rune(0x2aac), true + case "smtes": // SMALLER THAN OR slanted EQUAL + return rune(0x2aac), true + case "softcy": // CYRILLIC SMALL LETTER SOFT SIGN + return rune(0x044c), true + case "sol": // SOLIDUS + return rune(0x2f), true + case "solb": // SQUARED RISING DIAGONAL SLASH + return rune(0x29c4), true + case "solbar": // APL FUNCTIONAL SYMBOL SLASH BAR + return rune(0x233f), true + case "sopf": // MATHEMATICAL DOUBLE-STRUCK SMALL S + return rune(0x01d564), true + case "spades": // BLACK SPADE SUIT + return rune(0x2660), true + case "spadesuit": // BLACK SPADE SUIT + return rune(0x2660), true + case "spar": // PARALLEL TO + return rune(0x2225), true + case "sqcap": // SQUARE CAP + return rune(0x2293), true + case "sqcaps": // SQUARE CAP with serifs + return rune(0x2293), true + case "sqcup": // SQUARE CUP + return rune(0x2294), true + case "sqcups": // SQUARE CUP with serifs + return rune(0x2294), true + case "sqsub": // SQUARE IMAGE OF + return rune(0x228f), true + case "sqsube": // SQUARE IMAGE OF OR EQUAL TO + return rune(0x2291), true + case "sqsubset": // SQUARE IMAGE OF + return rune(0x228f), true + case "sqsubseteq": // SQUARE IMAGE OF OR EQUAL TO + return rune(0x2291), true + case "sqsup": // SQUARE ORIGINAL OF + return rune(0x2290), true + case "sqsupe": // SQUARE ORIGINAL OF OR EQUAL TO + return rune(0x2292), true + case "sqsupset": // SQUARE ORIGINAL OF + return rune(0x2290), true + case "sqsupseteq": // SQUARE ORIGINAL OF OR EQUAL TO + return rune(0x2292), true + case "squ": // WHITE SQUARE + return rune(0x25a1), true + case "square": // WHITE SQUARE + return rune(0x25a1), true + case "squarf": // BLACK SMALL SQUARE + return rune(0x25aa), true + case "squb": // SQUARED SQUARE + return rune(0x29c8), true + case "squerr": // ERROR-BARRED WHITE SQUARE + return rune(0x29ee), true + case "squf": // BLACK SMALL SQUARE + return rune(0x25aa), true + case "squferr": // ERROR-BARRED BLACK SQUARE + return rune(0x29ef), true + case "srarr": // RIGHTWARDS ARROW + return rune(0x2192), true + case "sscr": // MATHEMATICAL SCRIPT SMALL S + return rune(0x01d4c8), true + case "ssetmn": // SET MINUS + return rune(0x2216), true + case "ssmile": // SMILE + return rune(0x2323), true + case "sstarf": // STAR OPERATOR + return rune(0x22c6), true + case "star": // WHITE STAR + return rune(0x2606), true + case "starf": // BLACK STAR + return rune(0x2605), true + case "stigma": // GREEK LETTER STIGMA + return rune(0x03da), true + case "straightepsilon": // GREEK LUNATE EPSILON SYMBOL + return rune(0x03f5), true + case "straightphi": // GREEK PHI SYMBOL + return rune(0x03d5), true + case "strns": // MACRON + return rune(0xaf), true + case "sub": // SUBSET OF + return rune(0x2282), true + case "subE": // SUBSET OF ABOVE EQUALS SIGN + return rune(0x2ac5), true + case "subdot": // SUBSET WITH DOT + return rune(0x2abd), true + case "sube": // SUBSET OF OR EQUAL TO + return rune(0x2286), true + case "subedot": // SUBSET OF OR EQUAL TO WITH DOT ABOVE + return rune(0x2ac3), true + case "submult": // SUBSET WITH MULTIPLICATION SIGN BELOW + return rune(0x2ac1), true + case "subnE": // SUBSET OF ABOVE NOT EQUAL TO + return rune(0x2acb), true + case "subne": // SUBSET OF WITH NOT EQUAL TO + return rune(0x228a), true + case "subplus": // SUBSET WITH PLUS SIGN BELOW + return rune(0x2abf), true + case "subrarr": // SUBSET ABOVE RIGHTWARDS ARROW + return rune(0x2979), true + case "subset": // SUBSET OF + return rune(0x2282), true + case "subseteq": // SUBSET OF OR EQUAL TO + return rune(0x2286), true + case "subseteqq": // SUBSET OF ABOVE EQUALS SIGN + return rune(0x2ac5), true + case "subsetneq": // SUBSET OF WITH NOT EQUAL TO + return rune(0x228a), true + case "subsetneqq": // SUBSET OF ABOVE NOT EQUAL TO + return rune(0x2acb), true + case "subsim": // SUBSET OF ABOVE TILDE OPERATOR + return rune(0x2ac7), true + case "subsub": // SUBSET ABOVE SUBSET + return rune(0x2ad5), true + case "subsup": // SUBSET ABOVE SUPERSET + return rune(0x2ad3), true + case "succ": // SUCCEEDS + return rune(0x227b), true + case "succapprox": // SUCCEEDS ABOVE ALMOST EQUAL TO + return rune(0x2ab8), true + case "succcurlyeq": // SUCCEEDS OR EQUAL TO + return rune(0x227d), true + case "succeq": // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN + return rune(0x2ab0), true + case "succnapprox": // SUCCEEDS ABOVE NOT ALMOST EQUAL TO + return rune(0x2aba), true + case "succneqq": // SUCCEEDS ABOVE NOT EQUAL TO + return rune(0x2ab6), true + case "succnsim": // SUCCEEDS BUT NOT EQUIVALENT TO + return rune(0x22e9), true + case "succsim": // SUCCEEDS OR EQUIVALENT TO + return rune(0x227f), true + case "sum": // N-ARY SUMMATION + return rune(0x2211), true + case "sumint": // SUMMATION WITH INTEGRAL + return rune(0x2a0b), true + case "sung": // EIGHTH NOTE + return rune(0x266a), true + case "sup": // SUPERSET OF + return rune(0x2283), true + case "sup1": // SUPERSCRIPT ONE + return rune(0xb9), true + case "sup2": // SUPERSCRIPT TWO + return rune(0xb2), true + case "sup3": // SUPERSCRIPT THREE + return rune(0xb3), true + case "supE": // SUPERSET OF ABOVE EQUALS SIGN + return rune(0x2ac6), true + case "supdot": // SUPERSET WITH DOT + return rune(0x2abe), true + case "supdsub": // SUPERSET BESIDE AND JOINED BY DASH WITH SUBSET + return rune(0x2ad8), true + case "supe": // SUPERSET OF OR EQUAL TO + return rune(0x2287), true + case "supedot": // SUPERSET OF OR EQUAL TO WITH DOT ABOVE + return rune(0x2ac4), true + case "suphsol": // SUPERSET PRECEDING SOLIDUS + return rune(0x27c9), true + case "suphsub": // SUPERSET BESIDE SUBSET + return rune(0x2ad7), true + case "suplarr": // SUPERSET ABOVE LEFTWARDS ARROW + return rune(0x297b), true + case "supmult": // SUPERSET WITH MULTIPLICATION SIGN BELOW + return rune(0x2ac2), true + case "supnE": // SUPERSET OF ABOVE NOT EQUAL TO + return rune(0x2acc), true + case "supne": // SUPERSET OF WITH NOT EQUAL TO + return rune(0x228b), true + case "supplus": // SUPERSET WITH PLUS SIGN BELOW + return rune(0x2ac0), true + case "supset": // SUPERSET OF + return rune(0x2283), true + case "supseteq": // SUPERSET OF OR EQUAL TO + return rune(0x2287), true + case "supseteqq": // SUPERSET OF ABOVE EQUALS SIGN + return rune(0x2ac6), true + case "supsetneq": // SUPERSET OF WITH NOT EQUAL TO + return rune(0x228b), true + case "supsetneqq": // SUPERSET OF ABOVE NOT EQUAL TO + return rune(0x2acc), true + case "supsim": // SUPERSET OF ABOVE TILDE OPERATOR + return rune(0x2ac8), true + case "supsub": // SUPERSET ABOVE SUBSET + return rune(0x2ad4), true + case "supsup": // SUPERSET ABOVE SUPERSET + return rune(0x2ad6), true + case "swArr": // SOUTH WEST DOUBLE ARROW + return rune(0x21d9), true + case "swarhk": // SOUTH WEST ARROW WITH HOOK + return rune(0x2926), true + case "swarr": // SOUTH WEST ARROW + return rune(0x2199), true + case "swarrow": // SOUTH WEST ARROW + return rune(0x2199), true + case "swnwar": // SOUTH WEST ARROW AND NORTH WEST ARROW + return rune(0x292a), true + case "szlig": // LATIN SMALL LETTER SHARP S + return rune(0xdf), true } case 't': switch name { - case "target": // POSITION INDICATOR - return rune(0x2316), true - case "tau": // GREEK SMALL LETTER TAU - return rune(0x03c4), true - case "tbrk": // TOP SQUARE BRACKET - return rune(0x23b4), true - case "tcaron": // LATIN SMALL LETTER T WITH CARON - return rune(0x0165), true - case "tcedil": // LATIN SMALL LETTER T WITH CEDILLA - return rune(0x0163), true - case "tcy": // CYRILLIC SMALL LETTER TE - return rune(0x0442), true - case "tdot": // COMBINING THREE DOTS ABOVE - return rune(0x20db), true - case "telrec": // TELEPHONE RECORDER - return rune(0x2315), true - case "tfr": // MATHEMATICAL FRAKTUR SMALL T - return rune(0x01d531), true - case "tgr": // GREEK SMALL LETTER TAU - return rune(0x03c4), true - case "there4": // THEREFORE - return rune(0x2234), true - case "therefore": // THEREFORE - return rune(0x2234), true - case "thermod": // THERMODYNAMIC - return rune(0x29e7), true - case "theta": // GREEK SMALL LETTER THETA - return rune(0x03b8), true - case "thetas": // GREEK SMALL LETTER THETA - return rune(0x03b8), true - case "thetasym": // GREEK THETA SYMBOL - return rune(0x03d1), true - case "thetav": // GREEK THETA SYMBOL - return rune(0x03d1), true - case "thgr": // GREEK SMALL LETTER THETA - return rune(0x03b8), true - case "thickapprox": // ALMOST EQUAL TO - return rune(0x2248), true - case "thicksim": // TILDE OPERATOR - return rune(0x223c), true - case "thinsp": // THIN SPACE - return rune(0x2009), true - case "thkap": // ALMOST EQUAL TO - return rune(0x2248), true - case "thksim": // TILDE OPERATOR - return rune(0x223c), true - case "thorn": // LATIN SMALL LETTER THORN - return rune(0xfe), true - case "tilde": // SMALL TILDE - return rune(0x02dc), true - case "timeint": // INTEGRAL WITH TIMES SIGN - return rune(0x2a18), true - case "times": // MULTIPLICATION SIGN - return rune(0xd7), true - case "timesb": // SQUARED TIMES - return rune(0x22a0), true - case "timesbar": // MULTIPLICATION SIGN WITH UNDERBAR - return rune(0x2a31), true - case "timesd": // MULTIPLICATION SIGN WITH DOT ABOVE - return rune(0x2a30), true - case "tint": // TRIPLE INTEGRAL - return rune(0x222d), true - case "toea": // NORTH EAST ARROW AND SOUTH EAST ARROW - return rune(0x2928), true - case "top": // DOWN TACK - return rune(0x22a4), true - case "topbot": // APL FUNCTIONAL SYMBOL I-BEAM - return rune(0x2336), true - case "topcir": // DOWN TACK WITH CIRCLE BELOW - return rune(0x2af1), true - case "topf": // MATHEMATICAL DOUBLE-STRUCK SMALL T - return rune(0x01d565), true - case "topfork": // PITCHFORK WITH TEE TOP - return rune(0x2ada), true - case "tosa": // SOUTH EAST ARROW AND SOUTH WEST ARROW - return rune(0x2929), true - case "tprime": // TRIPLE PRIME - return rune(0x2034), true - case "trade": // TRADE MARK SIGN - return rune(0x2122), true - case "triS": // S IN TRIANGLE - return rune(0x29cc), true - case "triangle": // WHITE UP-POINTING SMALL TRIANGLE - return rune(0x25b5), true - case "triangledown": // WHITE DOWN-POINTING SMALL TRIANGLE - return rune(0x25bf), true - case "triangleleft": // WHITE LEFT-POINTING SMALL TRIANGLE - return rune(0x25c3), true - case "trianglelefteq": // NORMAL SUBGROUP OF OR EQUAL TO - return rune(0x22b4), true - case "triangleq": // DELTA EQUAL TO - return rune(0x225c), true - case "triangleright": // WHITE RIGHT-POINTING SMALL TRIANGLE - return rune(0x25b9), true - case "trianglerighteq": // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO - return rune(0x22b5), true - case "tribar": // TRIANGLE WITH UNDERBAR - return rune(0x29cb), true - case "tridot": // WHITE UP-POINTING TRIANGLE WITH DOT - return rune(0x25ec), true - case "tridoto": // TRIANGLE WITH DOT ABOVE - return rune(0x29ca), true - case "trie": // DELTA EQUAL TO - return rune(0x225c), true - case "triminus": // MINUS SIGN IN TRIANGLE - return rune(0x2a3a), true - case "triplus": // PLUS SIGN IN TRIANGLE - return rune(0x2a39), true - case "trisb": // TRIANGLE WITH SERIFS AT BOTTOM - return rune(0x29cd), true - case "tritime": // MULTIPLICATION SIGN IN TRIANGLE - return rune(0x2a3b), true - case "trpezium": // WHITE TRAPEZIUM - return rune(0x23e2), true - case "tscr": // MATHEMATICAL SCRIPT SMALL T - return rune(0x01d4c9), true - case "tscy": // CYRILLIC SMALL LETTER TSE - return rune(0x0446), true - case "tshcy": // CYRILLIC SMALL LETTER TSHE - return rune(0x045b), true - case "tstrok": // LATIN SMALL LETTER T WITH STROKE - return rune(0x0167), true - case "tverbar": // TRIPLE VERTICAL BAR DELIMITER - return rune(0x2980), true - case "twixt": // BETWEEN - return rune(0x226c), true - case "twoheadleftarrow": // LEFTWARDS TWO HEADED ARROW - return rune(0x219e), true - case "twoheadrightarrow": // RIGHTWARDS TWO HEADED ARROW - return rune(0x21a0), true + case "target": // POSITION INDICATOR + return rune(0x2316), true + case "tau": // GREEK SMALL LETTER TAU + return rune(0x03c4), true + case "tbrk": // TOP SQUARE BRACKET + return rune(0x23b4), true + case "tcaron": // LATIN SMALL LETTER T WITH CARON + return rune(0x0165), true + case "tcedil": // LATIN SMALL LETTER T WITH CEDILLA + return rune(0x0163), true + case "tcy": // CYRILLIC SMALL LETTER TE + return rune(0x0442), true + case "tdot": // COMBINING THREE DOTS ABOVE + return rune(0x20db), true + case "telrec": // TELEPHONE RECORDER + return rune(0x2315), true + case "tfr": // MATHEMATICAL FRAKTUR SMALL T + return rune(0x01d531), true + case "tgr": // GREEK SMALL LETTER TAU + return rune(0x03c4), true + case "there4": // THEREFORE + return rune(0x2234), true + case "therefore": // THEREFORE + return rune(0x2234), true + case "thermod": // THERMODYNAMIC + return rune(0x29e7), true + case "theta": // GREEK SMALL LETTER THETA + return rune(0x03b8), true + case "thetas": // GREEK SMALL LETTER THETA + return rune(0x03b8), true + case "thetasym": // GREEK THETA SYMBOL + return rune(0x03d1), true + case "thetav": // GREEK THETA SYMBOL + return rune(0x03d1), true + case "thgr": // GREEK SMALL LETTER THETA + return rune(0x03b8), true + case "thickapprox": // ALMOST EQUAL TO + return rune(0x2248), true + case "thicksim": // TILDE OPERATOR + return rune(0x223c), true + case "thinsp": // THIN SPACE + return rune(0x2009), true + case "thkap": // ALMOST EQUAL TO + return rune(0x2248), true + case "thksim": // TILDE OPERATOR + return rune(0x223c), true + case "thorn": // LATIN SMALL LETTER THORN + return rune(0xfe), true + case "tilde": // SMALL TILDE + return rune(0x02dc), true + case "timeint": // INTEGRAL WITH TIMES SIGN + return rune(0x2a18), true + case "times": // MULTIPLICATION SIGN + return rune(0xd7), true + case "timesb": // SQUARED TIMES + return rune(0x22a0), true + case "timesbar": // MULTIPLICATION SIGN WITH UNDERBAR + return rune(0x2a31), true + case "timesd": // MULTIPLICATION SIGN WITH DOT ABOVE + return rune(0x2a30), true + case "tint": // TRIPLE INTEGRAL + return rune(0x222d), true + case "toea": // NORTH EAST ARROW AND SOUTH EAST ARROW + return rune(0x2928), true + case "top": // DOWN TACK + return rune(0x22a4), true + case "topbot": // APL FUNCTIONAL SYMBOL I-BEAM + return rune(0x2336), true + case "topcir": // DOWN TACK WITH CIRCLE BELOW + return rune(0x2af1), true + case "topf": // MATHEMATICAL DOUBLE-STRUCK SMALL T + return rune(0x01d565), true + case "topfork": // PITCHFORK WITH TEE TOP + return rune(0x2ada), true + case "tosa": // SOUTH EAST ARROW AND SOUTH WEST ARROW + return rune(0x2929), true + case "tprime": // TRIPLE PRIME + return rune(0x2034), true + case "trade": // TRADE MARK SIGN + return rune(0x2122), true + case "triS": // S IN TRIANGLE + return rune(0x29cc), true + case "triangle": // WHITE UP-POINTING SMALL TRIANGLE + return rune(0x25b5), true + case "triangledown": // WHITE DOWN-POINTING SMALL TRIANGLE + return rune(0x25bf), true + case "triangleleft": // WHITE LEFT-POINTING SMALL TRIANGLE + return rune(0x25c3), true + case "trianglelefteq": // NORMAL SUBGROUP OF OR EQUAL TO + return rune(0x22b4), true + case "triangleq": // DELTA EQUAL TO + return rune(0x225c), true + case "triangleright": // WHITE RIGHT-POINTING SMALL TRIANGLE + return rune(0x25b9), true + case "trianglerighteq": // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO + return rune(0x22b5), true + case "tribar": // TRIANGLE WITH UNDERBAR + return rune(0x29cb), true + case "tridot": // WHITE UP-POINTING TRIANGLE WITH DOT + return rune(0x25ec), true + case "tridoto": // TRIANGLE WITH DOT ABOVE + return rune(0x29ca), true + case "trie": // DELTA EQUAL TO + return rune(0x225c), true + case "triminus": // MINUS SIGN IN TRIANGLE + return rune(0x2a3a), true + case "triplus": // PLUS SIGN IN TRIANGLE + return rune(0x2a39), true + case "trisb": // TRIANGLE WITH SERIFS AT BOTTOM + return rune(0x29cd), true + case "tritime": // MULTIPLICATION SIGN IN TRIANGLE + return rune(0x2a3b), true + case "trpezium": // WHITE TRAPEZIUM + return rune(0x23e2), true + case "tscr": // MATHEMATICAL SCRIPT SMALL T + return rune(0x01d4c9), true + case "tscy": // CYRILLIC SMALL LETTER TSE + return rune(0x0446), true + case "tshcy": // CYRILLIC SMALL LETTER TSHE + return rune(0x045b), true + case "tstrok": // LATIN SMALL LETTER T WITH STROKE + return rune(0x0167), true + case "tverbar": // TRIPLE VERTICAL BAR DELIMITER + return rune(0x2980), true + case "twixt": // BETWEEN + return rune(0x226c), true + case "twoheadleftarrow": // LEFTWARDS TWO HEADED ARROW + return rune(0x219e), true + case "twoheadrightarrow": // RIGHTWARDS TWO HEADED ARROW + return rune(0x21a0), true } case 'u': switch name { - case "uAarr": // UPWARDS TRIPLE ARROW - return rune(0x290a), true - case "uArr": // UPWARDS DOUBLE ARROW - return rune(0x21d1), true - case "uHar": // UPWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT - return rune(0x2963), true - case "uacgr": // GREEK SMALL LETTER UPSILON WITH TONOS - return rune(0x03cd), true - case "uacute": // LATIN SMALL LETTER U WITH ACUTE - return rune(0xfa), true - case "uarr": // UPWARDS ARROW - return rune(0x2191), true - case "uarr2": // UPWARDS PAIRED ARROWS - return rune(0x21c8), true - case "uarrb": // UPWARDS ARROW TO BAR - return rune(0x2912), true - case "uarrln": // UPWARDS ARROW WITH HORIZONTAL STROKE - return rune(0x2909), true - case "ubrcy": // CYRILLIC SMALL LETTER SHORT U - return rune(0x045e), true - case "ubreve": // LATIN SMALL LETTER U WITH BREVE - return rune(0x016d), true - case "ucirc": // LATIN SMALL LETTER U WITH CIRCUMFLEX - return rune(0xfb), true - case "ucy": // CYRILLIC SMALL LETTER U - return rune(0x0443), true - case "udarr": // UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW - return rune(0x21c5), true - case "udblac": // LATIN SMALL LETTER U WITH DOUBLE ACUTE - return rune(0x0171), true - case "udhar": // UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT - return rune(0x296e), true - case "udiagr": // GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS - return rune(0x03b0), true - case "udigr": // GREEK SMALL LETTER UPSILON WITH DIALYTIKA - return rune(0x03cb), true - case "udrbrk": // BOTTOM SQUARE BRACKET - return rune(0x23b5), true - case "udrcub": // BOTTOM CURLY BRACKET - return rune(0x23df), true - case "udrpar": // BOTTOM PARENTHESIS - return rune(0x23dd), true - case "ufisht": // UP FISH TAIL - return rune(0x297e), true - case "ufr": // MATHEMATICAL FRAKTUR SMALL U - return rune(0x01d532), true - case "ugr": // GREEK SMALL LETTER UPSILON - return rune(0x03c5), true - case "ugrave": // LATIN SMALL LETTER U WITH GRAVE - return rune(0xf9), true - case "uharl": // UPWARDS HARPOON WITH BARB LEFTWARDS - return rune(0x21bf), true - case "uharr": // UPWARDS HARPOON WITH BARB RIGHTWARDS - return rune(0x21be), true - case "uhblk": // UPPER HALF BLOCK - return rune(0x2580), true - case "ulcorn": // TOP LEFT CORNER - return rune(0x231c), true - case "ulcorner": // TOP LEFT CORNER - return rune(0x231c), true - case "ulcrop": // TOP LEFT CROP - return rune(0x230f), true - case "uldlshar": // UP BARB LEFT DOWN BARB LEFT HARPOON - return rune(0x2951), true - case "ulharb": // UPWARDS HARPOON WITH BARB LEFT TO BAR - return rune(0x2958), true - case "ultri": // UPPER LEFT TRIANGLE - return rune(0x25f8), true - case "umacr": // LATIN SMALL LETTER U WITH MACRON - return rune(0x016b), true - case "uml": // DIAERESIS - return rune(0xa8), true - case "uogon": // LATIN SMALL LETTER U WITH OGONEK - return rune(0x0173), true - case "uopf": // MATHEMATICAL DOUBLE-STRUCK SMALL U - return rune(0x01d566), true - case "uparrow": // UPWARDS ARROW - return rune(0x2191), true - case "updownarrow": // UP DOWN ARROW - return rune(0x2195), true - case "upharpoonleft": // UPWARDS HARPOON WITH BARB LEFTWARDS - return rune(0x21bf), true - case "upharpoonright": // UPWARDS HARPOON WITH BARB RIGHTWARDS - return rune(0x21be), true - case "upint": // INTEGRAL WITH OVERBAR - return rune(0x2a1b), true - case "uplus": // MULTISET UNION - return rune(0x228e), true - case "upsi": // GREEK SMALL LETTER UPSILON - return rune(0x03c5), true - case "upsih": // GREEK UPSILON WITH HOOK SYMBOL - return rune(0x03d2), true - case "upsilon": // GREEK SMALL LETTER UPSILON - return rune(0x03c5), true - case "upuparrows": // UPWARDS PAIRED ARROWS - return rune(0x21c8), true - case "urcorn": // TOP RIGHT CORNER - return rune(0x231d), true - case "urcorner": // TOP RIGHT CORNER - return rune(0x231d), true - case "urcrop": // TOP RIGHT CROP - return rune(0x230e), true - case "urdrshar": // UP BARB RIGHT DOWN BARB RIGHT HARPOON - return rune(0x294f), true - case "urharb": // UPWARDS HARPOON WITH BARB RIGHT TO BAR - return rune(0x2954), true - case "uring": // LATIN SMALL LETTER U WITH RING ABOVE - return rune(0x016f), true - case "urtri": // UPPER RIGHT TRIANGLE - return rune(0x25f9), true - case "urtrif": // BLACK UPPER RIGHT TRIANGLE - return rune(0x25e5), true - case "uscr": // MATHEMATICAL SCRIPT SMALL U - return rune(0x01d4ca), true - case "utdot": // UP RIGHT DIAGONAL ELLIPSIS - return rune(0x22f0), true - case "utilde": // LATIN SMALL LETTER U WITH TILDE - return rune(0x0169), true - case "utri": // WHITE UP-POINTING SMALL TRIANGLE - return rune(0x25b5), true - case "utrif": // BLACK UP-POINTING SMALL TRIANGLE - return rune(0x25b4), true - case "uuarr": // UPWARDS PAIRED ARROWS - return rune(0x21c8), true - case "uuml": // LATIN SMALL LETTER U WITH DIAERESIS - return rune(0xfc), true - case "uwangle": // OBLIQUE ANGLE OPENING DOWN - return rune(0x29a7), true + case "uAarr": // UPWARDS TRIPLE ARROW + return rune(0x290a), true + case "uArr": // UPWARDS DOUBLE ARROW + return rune(0x21d1), true + case "uHar": // UPWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT + return rune(0x2963), true + case "uacgr": // GREEK SMALL LETTER UPSILON WITH TONOS + return rune(0x03cd), true + case "uacute": // LATIN SMALL LETTER U WITH ACUTE + return rune(0xfa), true + case "uarr": // UPWARDS ARROW + return rune(0x2191), true + case "uarr2": // UPWARDS PAIRED ARROWS + return rune(0x21c8), true + case "uarrb": // UPWARDS ARROW TO BAR + return rune(0x2912), true + case "uarrln": // UPWARDS ARROW WITH HORIZONTAL STROKE + return rune(0x2909), true + case "ubrcy": // CYRILLIC SMALL LETTER SHORT U + return rune(0x045e), true + case "ubreve": // LATIN SMALL LETTER U WITH BREVE + return rune(0x016d), true + case "ucirc": // LATIN SMALL LETTER U WITH CIRCUMFLEX + return rune(0xfb), true + case "ucy": // CYRILLIC SMALL LETTER U + return rune(0x0443), true + case "udarr": // UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW + return rune(0x21c5), true + case "udblac": // LATIN SMALL LETTER U WITH DOUBLE ACUTE + return rune(0x0171), true + case "udhar": // UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT + return rune(0x296e), true + case "udiagr": // GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + return rune(0x03b0), true + case "udigr": // GREEK SMALL LETTER UPSILON WITH DIALYTIKA + return rune(0x03cb), true + case "udrbrk": // BOTTOM SQUARE BRACKET + return rune(0x23b5), true + case "udrcub": // BOTTOM CURLY BRACKET + return rune(0x23df), true + case "udrpar": // BOTTOM PARENTHESIS + return rune(0x23dd), true + case "ufisht": // UP FISH TAIL + return rune(0x297e), true + case "ufr": // MATHEMATICAL FRAKTUR SMALL U + return rune(0x01d532), true + case "ugr": // GREEK SMALL LETTER UPSILON + return rune(0x03c5), true + case "ugrave": // LATIN SMALL LETTER U WITH GRAVE + return rune(0xf9), true + case "uharl": // UPWARDS HARPOON WITH BARB LEFTWARDS + return rune(0x21bf), true + case "uharr": // UPWARDS HARPOON WITH BARB RIGHTWARDS + return rune(0x21be), true + case "uhblk": // UPPER HALF BLOCK + return rune(0x2580), true + case "ulcorn": // TOP LEFT CORNER + return rune(0x231c), true + case "ulcorner": // TOP LEFT CORNER + return rune(0x231c), true + case "ulcrop": // TOP LEFT CROP + return rune(0x230f), true + case "uldlshar": // UP BARB LEFT DOWN BARB LEFT HARPOON + return rune(0x2951), true + case "ulharb": // UPWARDS HARPOON WITH BARB LEFT TO BAR + return rune(0x2958), true + case "ultri": // UPPER LEFT TRIANGLE + return rune(0x25f8), true + case "umacr": // LATIN SMALL LETTER U WITH MACRON + return rune(0x016b), true + case "uml": // DIAERESIS + return rune(0xa8), true + case "uogon": // LATIN SMALL LETTER U WITH OGONEK + return rune(0x0173), true + case "uopf": // MATHEMATICAL DOUBLE-STRUCK SMALL U + return rune(0x01d566), true + case "uparrow": // UPWARDS ARROW + return rune(0x2191), true + case "updownarrow": // UP DOWN ARROW + return rune(0x2195), true + case "upharpoonleft": // UPWARDS HARPOON WITH BARB LEFTWARDS + return rune(0x21bf), true + case "upharpoonright": // UPWARDS HARPOON WITH BARB RIGHTWARDS + return rune(0x21be), true + case "upint": // INTEGRAL WITH OVERBAR + return rune(0x2a1b), true + case "uplus": // MULTISET UNION + return rune(0x228e), true + case "upsi": // GREEK SMALL LETTER UPSILON + return rune(0x03c5), true + case "upsih": // GREEK UPSILON WITH HOOK SYMBOL + return rune(0x03d2), true + case "upsilon": // GREEK SMALL LETTER UPSILON + return rune(0x03c5), true + case "upuparrows": // UPWARDS PAIRED ARROWS + return rune(0x21c8), true + case "urcorn": // TOP RIGHT CORNER + return rune(0x231d), true + case "urcorner": // TOP RIGHT CORNER + return rune(0x231d), true + case "urcrop": // TOP RIGHT CROP + return rune(0x230e), true + case "urdrshar": // UP BARB RIGHT DOWN BARB RIGHT HARPOON + return rune(0x294f), true + case "urharb": // UPWARDS HARPOON WITH BARB RIGHT TO BAR + return rune(0x2954), true + case "uring": // LATIN SMALL LETTER U WITH RING ABOVE + return rune(0x016f), true + case "urtri": // UPPER RIGHT TRIANGLE + return rune(0x25f9), true + case "urtrif": // BLACK UPPER RIGHT TRIANGLE + return rune(0x25e5), true + case "uscr": // MATHEMATICAL SCRIPT SMALL U + return rune(0x01d4ca), true + case "utdot": // UP RIGHT DIAGONAL ELLIPSIS + return rune(0x22f0), true + case "utilde": // LATIN SMALL LETTER U WITH TILDE + return rune(0x0169), true + case "utri": // WHITE UP-POINTING SMALL TRIANGLE + return rune(0x25b5), true + case "utrif": // BLACK UP-POINTING SMALL TRIANGLE + return rune(0x25b4), true + case "uuarr": // UPWARDS PAIRED ARROWS + return rune(0x21c8), true + case "uuml": // LATIN SMALL LETTER U WITH DIAERESIS + return rune(0xfc), true + case "uwangle": // OBLIQUE ANGLE OPENING DOWN + return rune(0x29a7), true } case 'v': switch name { - case "vArr": // UP DOWN DOUBLE ARROW - return rune(0x21d5), true - case "vBar": // SHORT UP TACK WITH UNDERBAR - return rune(0x2ae8), true - case "vBarv": // SHORT UP TACK ABOVE SHORT DOWN TACK - return rune(0x2ae9), true - case "vDash": // TRUE - return rune(0x22a8), true - case "vDdash": // VERTICAL BAR TRIPLE RIGHT TURNSTILE - return rune(0x2ae2), true - case "vangrt": // RIGHT ANGLE VARIANT WITH SQUARE - return rune(0x299c), true - case "varepsilon": // GREEK LUNATE EPSILON SYMBOL - return rune(0x03f5), true - case "varkappa": // GREEK KAPPA SYMBOL - return rune(0x03f0), true - case "varnothing": // EMPTY SET - return rune(0x2205), true - case "varphi": // GREEK PHI SYMBOL - return rune(0x03d5), true - case "varpi": // GREEK PI SYMBOL - return rune(0x03d6), true - case "varpropto": // PROPORTIONAL TO - return rune(0x221d), true - case "varr": // UP DOWN ARROW - return rune(0x2195), true - case "varrho": // GREEK RHO SYMBOL - return rune(0x03f1), true - case "varsigma": // GREEK SMALL LETTER FINAL SIGMA - return rune(0x03c2), true - case "varsubsetneq": // SUBSET OF WITH NOT EQUAL TO - variant with stroke through bottom members - return rune(0x228a), true - case "varsubsetneqq": // SUBSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members - return rune(0x2acb), true - case "varsupsetneq": // SUPERSET OF WITH NOT EQUAL TO - variant with stroke through bottom members - return rune(0x228b), true - case "varsupsetneqq": // SUPERSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members - return rune(0x2acc), true - case "vartheta": // GREEK THETA SYMBOL - return rune(0x03d1), true - case "vartriangleleft": // NORMAL SUBGROUP OF - return rune(0x22b2), true - case "vartriangleright": // CONTAINS AS NORMAL SUBGROUP - return rune(0x22b3), true - case "vbrtri": // VERTICAL BAR BESIDE RIGHT TRIANGLE - return rune(0x29d0), true - case "vcy": // CYRILLIC SMALL LETTER VE - return rune(0x0432), true - case "vdash": // RIGHT TACK - return rune(0x22a2), true - case "vee": // LOGICAL OR - return rune(0x2228), true - case "veeBar": // LOGICAL OR WITH DOUBLE UNDERBAR - return rune(0x2a63), true - case "veebar": // XOR - return rune(0x22bb), true - case "veeeq": // EQUIANGULAR TO - return rune(0x225a), true - case "vellip": // VERTICAL ELLIPSIS - return rune(0x22ee), true - case "vellip4": // DOTTED FENCE - return rune(0x2999), true - case "vellipv": // TRIPLE COLON OPERATOR - return rune(0x2af6), true - case "verbar": // VERTICAL LINE - return rune(0x7c), true - case "vert": // VERTICAL LINE - return rune(0x7c), true - case "vert3": // TRIPLE VERTICAL BAR BINARY RELATION - return rune(0x2af4), true - case "vfr": // MATHEMATICAL FRAKTUR SMALL V - return rune(0x01d533), true - case "vldash": // LEFT SQUARE BRACKET LOWER CORNER - return rune(0x23a3), true - case "vltri": // NORMAL SUBGROUP OF - return rune(0x22b2), true - case "vnsub": // SUBSET OF with vertical line - return rune(0x2282), true - case "vnsup": // SUPERSET OF with vertical line - return rune(0x2283), true - case "vopf": // MATHEMATICAL DOUBLE-STRUCK SMALL V - return rune(0x01d567), true - case "vprime": // PRIME - return rune(0x2032), true - case "vprop": // PROPORTIONAL TO - return rune(0x221d), true - case "vrtri": // CONTAINS AS NORMAL SUBGROUP - return rune(0x22b3), true - case "vscr": // MATHEMATICAL SCRIPT SMALL V - return rune(0x01d4cb), true - case "vsubnE": // SUBSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members - return rune(0x2acb), true - case "vsubne": // SUBSET OF WITH NOT EQUAL TO - variant with stroke through bottom members - return rune(0x228a), true - case "vsupnE": // SUPERSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members - return rune(0x2acc), true - case "vsupne": // SUPERSET OF WITH NOT EQUAL TO - variant with stroke through bottom members - return rune(0x228b), true - case "vzigzag": // VERTICAL ZIGZAG LINE - return rune(0x299a), true + case "vArr": // UP DOWN DOUBLE ARROW + return rune(0x21d5), true + case "vBar": // SHORT UP TACK WITH UNDERBAR + return rune(0x2ae8), true + case "vBarv": // SHORT UP TACK ABOVE SHORT DOWN TACK + return rune(0x2ae9), true + case "vDash": // TRUE + return rune(0x22a8), true + case "vDdash": // VERTICAL BAR TRIPLE RIGHT TURNSTILE + return rune(0x2ae2), true + case "vangrt": // RIGHT ANGLE VARIANT WITH SQUARE + return rune(0x299c), true + case "varepsilon": // GREEK LUNATE EPSILON SYMBOL + return rune(0x03f5), true + case "varkappa": // GREEK KAPPA SYMBOL + return rune(0x03f0), true + case "varnothing": // EMPTY SET + return rune(0x2205), true + case "varphi": // GREEK PHI SYMBOL + return rune(0x03d5), true + case "varpi": // GREEK PI SYMBOL + return rune(0x03d6), true + case "varpropto": // PROPORTIONAL TO + return rune(0x221d), true + case "varr": // UP DOWN ARROW + return rune(0x2195), true + case "varrho": // GREEK RHO SYMBOL + return rune(0x03f1), true + case "varsigma": // GREEK SMALL LETTER FINAL SIGMA + return rune(0x03c2), true + case "varsubsetneq": // SUBSET OF WITH NOT EQUAL TO - variant with stroke through bottom members + return rune(0x228a), true + case "varsubsetneqq": // SUBSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members + return rune(0x2acb), true + case "varsupsetneq": // SUPERSET OF WITH NOT EQUAL TO - variant with stroke through bottom members + return rune(0x228b), true + case "varsupsetneqq": // SUPERSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members + return rune(0x2acc), true + case "vartheta": // GREEK THETA SYMBOL + return rune(0x03d1), true + case "vartriangleleft": // NORMAL SUBGROUP OF + return rune(0x22b2), true + case "vartriangleright": // CONTAINS AS NORMAL SUBGROUP + return rune(0x22b3), true + case "vbrtri": // VERTICAL BAR BESIDE RIGHT TRIANGLE + return rune(0x29d0), true + case "vcy": // CYRILLIC SMALL LETTER VE + return rune(0x0432), true + case "vdash": // RIGHT TACK + return rune(0x22a2), true + case "vee": // LOGICAL OR + return rune(0x2228), true + case "veeBar": // LOGICAL OR WITH DOUBLE UNDERBAR + return rune(0x2a63), true + case "veebar": // XOR + return rune(0x22bb), true + case "veeeq": // EQUIANGULAR TO + return rune(0x225a), true + case "vellip": // VERTICAL ELLIPSIS + return rune(0x22ee), true + case "vellip4": // DOTTED FENCE + return rune(0x2999), true + case "vellipv": // TRIPLE COLON OPERATOR + return rune(0x2af6), true + case "verbar": // VERTICAL LINE + return rune(0x7c), true + case "vert": // VERTICAL LINE + return rune(0x7c), true + case "vert3": // TRIPLE VERTICAL BAR BINARY RELATION + return rune(0x2af4), true + case "vfr": // MATHEMATICAL FRAKTUR SMALL V + return rune(0x01d533), true + case "vldash": // LEFT SQUARE BRACKET LOWER CORNER + return rune(0x23a3), true + case "vltri": // NORMAL SUBGROUP OF + return rune(0x22b2), true + case "vnsub": // SUBSET OF with vertical line + return rune(0x2282), true + case "vnsup": // SUPERSET OF with vertical line + return rune(0x2283), true + case "vopf": // MATHEMATICAL DOUBLE-STRUCK SMALL V + return rune(0x01d567), true + case "vprime": // PRIME + return rune(0x2032), true + case "vprop": // PROPORTIONAL TO + return rune(0x221d), true + case "vrtri": // CONTAINS AS NORMAL SUBGROUP + return rune(0x22b3), true + case "vscr": // MATHEMATICAL SCRIPT SMALL V + return rune(0x01d4cb), true + case "vsubnE": // SUBSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members + return rune(0x2acb), true + case "vsubne": // SUBSET OF WITH NOT EQUAL TO - variant with stroke through bottom members + return rune(0x228a), true + case "vsupnE": // SUPERSET OF ABOVE NOT EQUAL TO - variant with stroke through bottom members + return rune(0x2acc), true + case "vsupne": // SUPERSET OF WITH NOT EQUAL TO - variant with stroke through bottom members + return rune(0x228b), true + case "vzigzag": // VERTICAL ZIGZAG LINE + return rune(0x299a), true } case 'w': switch name { - case "wcirc": // LATIN SMALL LETTER W WITH CIRCUMFLEX - return rune(0x0175), true - case "wedbar": // LOGICAL AND WITH UNDERBAR - return rune(0x2a5f), true - case "wedge": // LOGICAL AND - return rune(0x2227), true - case "wedgeq": // ESTIMATES - return rune(0x2259), true - case "weierp": // SCRIPT CAPITAL P - return rune(0x2118), true - case "wfr": // MATHEMATICAL FRAKTUR SMALL W - return rune(0x01d534), true - case "wopf": // MATHEMATICAL DOUBLE-STRUCK SMALL W - return rune(0x01d568), true - case "wp": // SCRIPT CAPITAL P - return rune(0x2118), true - case "wr": // WREATH PRODUCT - return rune(0x2240), true - case "wreath": // WREATH PRODUCT - return rune(0x2240), true - case "wscr": // MATHEMATICAL SCRIPT SMALL W - return rune(0x01d4cc), true + case "wcirc": // LATIN SMALL LETTER W WITH CIRCUMFLEX + return rune(0x0175), true + case "wedbar": // LOGICAL AND WITH UNDERBAR + return rune(0x2a5f), true + case "wedge": // LOGICAL AND + return rune(0x2227), true + case "wedgeq": // ESTIMATES + return rune(0x2259), true + case "weierp": // SCRIPT CAPITAL P + return rune(0x2118), true + case "wfr": // MATHEMATICAL FRAKTUR SMALL W + return rune(0x01d534), true + case "wopf": // MATHEMATICAL DOUBLE-STRUCK SMALL W + return rune(0x01d568), true + case "wp": // SCRIPT CAPITAL P + return rune(0x2118), true + case "wr": // WREATH PRODUCT + return rune(0x2240), true + case "wreath": // WREATH PRODUCT + return rune(0x2240), true + case "wscr": // MATHEMATICAL SCRIPT SMALL W + return rune(0x01d4cc), true } case 'x': switch name { - case "xandand": // TWO LOGICAL AND OPERATOR - return rune(0x2a07), true - case "xbsol": // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT - return rune(0x2571), true - case "xcap": // N-ARY INTERSECTION - return rune(0x22c2), true - case "xcirc": // LARGE CIRCLE - return rune(0x25ef), true - case "xcup": // N-ARY UNION - return rune(0x22c3), true - case "xcupdot": // N-ARY UNION OPERATOR WITH DOT - return rune(0x2a03), true - case "xdtri": // WHITE DOWN-POINTING TRIANGLE - return rune(0x25bd), true - case "xfr": // MATHEMATICAL FRAKTUR SMALL X - return rune(0x01d535), true - case "xgr": // GREEK SMALL LETTER XI - return rune(0x03be), true - case "xhArr": // LONG LEFT RIGHT DOUBLE ARROW - return rune(0x27fa), true - case "xharr": // LONG LEFT RIGHT ARROW - return rune(0x27f7), true - case "xi": // GREEK SMALL LETTER XI - return rune(0x03be), true - case "xlArr": // LONG LEFTWARDS DOUBLE ARROW - return rune(0x27f8), true - case "xlarr": // LONG LEFTWARDS ARROW - return rune(0x27f5), true - case "xmap": // LONG RIGHTWARDS ARROW FROM BAR - return rune(0x27fc), true - case "xnis": // CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE - return rune(0x22fb), true - case "xodot": // N-ARY CIRCLED DOT OPERATOR - return rune(0x2a00), true - case "xopf": // MATHEMATICAL DOUBLE-STRUCK SMALL X - return rune(0x01d569), true - case "xoplus": // N-ARY CIRCLED PLUS OPERATOR - return rune(0x2a01), true - case "xoror": // TWO LOGICAL OR OPERATOR - return rune(0x2a08), true - case "xotime": // N-ARY CIRCLED TIMES OPERATOR - return rune(0x2a02), true - case "xrArr": // LONG RIGHTWARDS DOUBLE ARROW - return rune(0x27f9), true - case "xrarr": // LONG RIGHTWARDS ARROW - return rune(0x27f6), true - case "xscr": // MATHEMATICAL SCRIPT SMALL X - return rune(0x01d4cd), true - case "xsol": // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT - return rune(0x2572), true - case "xsqcap": // N-ARY SQUARE INTERSECTION OPERATOR - return rune(0x2a05), true - case "xsqcup": // N-ARY SQUARE UNION OPERATOR - return rune(0x2a06), true - case "xsqu": // WHITE MEDIUM SQUARE - return rune(0x25fb), true - case "xsquf": // BLACK MEDIUM SQUARE - return rune(0x25fc), true - case "xtimes": // N-ARY TIMES OPERATOR - return rune(0x2a09), true - case "xuplus": // N-ARY UNION OPERATOR WITH PLUS - return rune(0x2a04), true - case "xutri": // WHITE UP-POINTING TRIANGLE - return rune(0x25b3), true - case "xvee": // N-ARY LOGICAL OR - return rune(0x22c1), true - case "xwedge": // N-ARY LOGICAL AND - return rune(0x22c0), true + case "xandand": // TWO LOGICAL AND OPERATOR + return rune(0x2a07), true + case "xbsol": // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT + return rune(0x2571), true + case "xcap": // N-ARY INTERSECTION + return rune(0x22c2), true + case "xcirc": // LARGE CIRCLE + return rune(0x25ef), true + case "xcup": // N-ARY UNION + return rune(0x22c3), true + case "xcupdot": // N-ARY UNION OPERATOR WITH DOT + return rune(0x2a03), true + case "xdtri": // WHITE DOWN-POINTING TRIANGLE + return rune(0x25bd), true + case "xfr": // MATHEMATICAL FRAKTUR SMALL X + return rune(0x01d535), true + case "xgr": // GREEK SMALL LETTER XI + return rune(0x03be), true + case "xhArr": // LONG LEFT RIGHT DOUBLE ARROW + return rune(0x27fa), true + case "xharr": // LONG LEFT RIGHT ARROW + return rune(0x27f7), true + case "xi": // GREEK SMALL LETTER XI + return rune(0x03be), true + case "xlArr": // LONG LEFTWARDS DOUBLE ARROW + return rune(0x27f8), true + case "xlarr": // LONG LEFTWARDS ARROW + return rune(0x27f5), true + case "xmap": // LONG RIGHTWARDS ARROW FROM BAR + return rune(0x27fc), true + case "xnis": // CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE + return rune(0x22fb), true + case "xodot": // N-ARY CIRCLED DOT OPERATOR + return rune(0x2a00), true + case "xopf": // MATHEMATICAL DOUBLE-STRUCK SMALL X + return rune(0x01d569), true + case "xoplus": // N-ARY CIRCLED PLUS OPERATOR + return rune(0x2a01), true + case "xoror": // TWO LOGICAL OR OPERATOR + return rune(0x2a08), true + case "xotime": // N-ARY CIRCLED TIMES OPERATOR + return rune(0x2a02), true + case "xrArr": // LONG RIGHTWARDS DOUBLE ARROW + return rune(0x27f9), true + case "xrarr": // LONG RIGHTWARDS ARROW + return rune(0x27f6), true + case "xscr": // MATHEMATICAL SCRIPT SMALL X + return rune(0x01d4cd), true + case "xsol": // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT + return rune(0x2572), true + case "xsqcap": // N-ARY SQUARE INTERSECTION OPERATOR + return rune(0x2a05), true + case "xsqcup": // N-ARY SQUARE UNION OPERATOR + return rune(0x2a06), true + case "xsqu": // WHITE MEDIUM SQUARE + return rune(0x25fb), true + case "xsquf": // BLACK MEDIUM SQUARE + return rune(0x25fc), true + case "xtimes": // N-ARY TIMES OPERATOR + return rune(0x2a09), true + case "xuplus": // N-ARY UNION OPERATOR WITH PLUS + return rune(0x2a04), true + case "xutri": // WHITE UP-POINTING TRIANGLE + return rune(0x25b3), true + case "xvee": // N-ARY LOGICAL OR + return rune(0x22c1), true + case "xwedge": // N-ARY LOGICAL AND + return rune(0x22c0), true } case 'y': switch name { - case "yacute": // LATIN SMALL LETTER Y WITH ACUTE - return rune(0xfd), true - case "yacy": // CYRILLIC SMALL LETTER YA - return rune(0x044f), true - case "ycirc": // LATIN SMALL LETTER Y WITH CIRCUMFLEX - return rune(0x0177), true - case "ycy": // CYRILLIC SMALL LETTER YERU - return rune(0x044b), true - case "yen": // YEN SIGN - return rune(0xa5), true - case "yfr": // MATHEMATICAL FRAKTUR SMALL Y - return rune(0x01d536), true - case "yicy": // CYRILLIC SMALL LETTER YI - return rune(0x0457), true - case "yopf": // MATHEMATICAL DOUBLE-STRUCK SMALL Y - return rune(0x01d56a), true - case "yscr": // MATHEMATICAL SCRIPT SMALL Y - return rune(0x01d4ce), true - case "yucy": // CYRILLIC SMALL LETTER YU - return rune(0x044e), true - case "yuml": // LATIN SMALL LETTER Y WITH DIAERESIS - return rune(0xff), true + case "yacute": // LATIN SMALL LETTER Y WITH ACUTE + return rune(0xfd), true + case "yacy": // CYRILLIC SMALL LETTER YA + return rune(0x044f), true + case "ycirc": // LATIN SMALL LETTER Y WITH CIRCUMFLEX + return rune(0x0177), true + case "ycy": // CYRILLIC SMALL LETTER YERU + return rune(0x044b), true + case "yen": // YEN SIGN + return rune(0xa5), true + case "yfr": // MATHEMATICAL FRAKTUR SMALL Y + return rune(0x01d536), true + case "yicy": // CYRILLIC SMALL LETTER YI + return rune(0x0457), true + case "yopf": // MATHEMATICAL DOUBLE-STRUCK SMALL Y + return rune(0x01d56a), true + case "yscr": // MATHEMATICAL SCRIPT SMALL Y + return rune(0x01d4ce), true + case "yucy": // CYRILLIC SMALL LETTER YU + return rune(0x044e), true + case "yuml": // LATIN SMALL LETTER Y WITH DIAERESIS + return rune(0xff), true } case 'z': switch name { - case "zacute": // LATIN SMALL LETTER Z WITH ACUTE - return rune(0x017a), true - case "zcaron": // LATIN SMALL LETTER Z WITH CARON - return rune(0x017e), true - case "zcy": // CYRILLIC SMALL LETTER ZE - return rune(0x0437), true - case "zdot": // LATIN SMALL LETTER Z WITH DOT ABOVE - return rune(0x017c), true - case "zeetrf": // BLACK-LETTER CAPITAL Z - return rune(0x2128), true - case "zeta": // GREEK SMALL LETTER ZETA - return rune(0x03b6), true - case "zfr": // MATHEMATICAL FRAKTUR SMALL Z - return rune(0x01d537), true - case "zgr": // GREEK SMALL LETTER ZETA - return rune(0x03b6), true - case "zhcy": // CYRILLIC SMALL LETTER ZHE - return rune(0x0436), true - case "zigrarr": // RIGHTWARDS SQUIGGLE ARROW - return rune(0x21dd), true - case "zopf": // MATHEMATICAL DOUBLE-STRUCK SMALL Z - return rune(0x01d56b), true - case "zscr": // MATHEMATICAL SCRIPT SMALL Z - return rune(0x01d4cf), true - case "zwj": // ZERO WIDTH JOINER - return rune(0x200d), true - case "zwnj": // ZERO WIDTH NON-JOINER - return rune(0x200c), true + case "zacute": // LATIN SMALL LETTER Z WITH ACUTE + return rune(0x017a), true + case "zcaron": // LATIN SMALL LETTER Z WITH CARON + return rune(0x017e), true + case "zcy": // CYRILLIC SMALL LETTER ZE + return rune(0x0437), true + case "zdot": // LATIN SMALL LETTER Z WITH DOT ABOVE + return rune(0x017c), true + case "zeetrf": // BLACK-LETTER CAPITAL Z + return rune(0x2128), true + case "zeta": // GREEK SMALL LETTER ZETA + return rune(0x03b6), true + case "zfr": // MATHEMATICAL FRAKTUR SMALL Z + return rune(0x01d537), true + case "zgr": // GREEK SMALL LETTER ZETA + return rune(0x03b6), true + case "zhcy": // CYRILLIC SMALL LETTER ZHE + return rune(0x0436), true + case "zigrarr": // RIGHTWARDS SQUIGGLE ARROW + return rune(0x21dd), true + case "zopf": // MATHEMATICAL DOUBLE-STRUCK SMALL Z + return rune(0x01d56b), true + case "zscr": // MATHEMATICAL SCRIPT SMALL Z + return rune(0x01d4cf), true + case "zwj": // ZERO WIDTH JOINER + return rune(0x200d), true + case "zwnj": // ZERO WIDTH NON-JOINER + return rune(0x200c), true } } return -1, false diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index 2933adf9a..0464c24d1 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -25,7 +25,7 @@ Marshal_Options :: struct { spec: Specification, // Use line breaks & tabs/spaces - pretty: bool, + pretty: bool, // Use spaces for indentation instead of tabs use_spaces: bool, @@ -34,7 +34,7 @@ Marshal_Options :: struct { spaces: int, // Output uint as hex in JSON5 & MJSON - write_uint_as_hex: bool, + write_uint_as_hex: bool, // If spec is MJSON and this is true, then keys will be quoted. // @@ -138,7 +138,7 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: // allow uints to be printed as hex if opt.write_uint_as_hex && (opt.spec == .JSON5 || opt.spec == .MJSON) { switch i in a { - case u8, u16, u32, u64, u128: + case u8, u16, u32, u64, u128: s = strconv.append_bits_128(buf[:], u, 16, info.signed, 8*ti.size, "0123456789abcdef", { .Prefix }) case: @@ -239,7 +239,7 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: case runtime.Type_Info_Array: opt_write_start(w, opt, '[') or_return for i in 0.. (err: case runtime.Type_Info_Enumerated_Array: opt_write_start(w, opt, '[') or_return for i in 0.. (err: opt_write_start(w, opt, '[') or_return array := cast(^mem.Raw_Dynamic_Array)v.data for i in 0.. (err: opt_write_start(w, opt, '[') or_return slice := cast(^mem.Raw_Slice)v.data for i in 0.. (err: for bucket_index in 0.. (err: slice.sort_by(sorted[:], proc(i, j: Entry) -> bool { return i.key < j.key }) for s, i in sorted { - opt_write_iteration(w, opt, i) or_return + opt_write_iteration(w, opt, i == 0) or_return opt_write_key(w, opt, s.key) or_return marshal_to_writer(w, s.value, opt) or_return } @@ -387,17 +387,17 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: case runtime.Type_Info_Pointer, runtime.Type_Info_Multi_Pointer, runtime.Type_Info_Procedure: - return (^rawptr)(v.data)^ == nil + return (^rawptr)(v.data)^ == nil case runtime.Type_Info_Dynamic_Array: - return (^runtime.Raw_Dynamic_Array)(v.data).len == 0 + return (^runtime.Raw_Dynamic_Array)(v.data).len == 0 case runtime.Type_Info_Slice: - return (^runtime.Raw_Slice)(v.data).len == 0 + return (^runtime.Raw_Slice)(v.data).len == 0 case runtime.Type_Info_Union, runtime.Type_Info_Bit_Set, runtime.Type_Info_Soa_Pointer: return reflect.is_nil(v) case runtime.Type_Info_Map: - return (^runtime.Raw_Map)(v.data).len == 0 + return (^runtime.Raw_Map)(v.data).len == 0 } return false } @@ -405,6 +405,7 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: marshal_struct_fields :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: Marshal_Error) { ti := runtime.type_info_base(type_info_of(v.id)) info := ti.variant.(runtime.Type_Info_Struct) + first_iteration := true for name, i in info.names { omitempty := false @@ -424,7 +425,8 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: continue } - opt_write_iteration(w, opt, i) or_return + opt_write_iteration(w, opt, first_iteration) or_return + first_iteration = false if json_name != "" { opt_write_key(w, opt, json_name) or_return } else { @@ -588,10 +590,10 @@ opt_write_start :: proc(w: io.Writer, opt: ^Marshal_Options, c: byte) -> (err: i } // insert comma separation and write indentations -opt_write_iteration :: proc(w: io.Writer, opt: ^Marshal_Options, iteration: int) -> (err: io.Error) { +opt_write_iteration :: proc(w: io.Writer, opt: ^Marshal_Options, first_iteration: bool) -> (err: io.Error) { switch opt.spec { - case .JSON, .JSON5: - if iteration > 0 { + case .JSON, .JSON5: + if !first_iteration { io.write_byte(w, ',') or_return if opt.pretty { @@ -601,8 +603,8 @@ opt_write_iteration :: proc(w: io.Writer, opt: ^Marshal_Options, iteration: int) opt_write_indentation(w, opt) or_return - case .MJSON: - if iteration > 0 { + case .MJSON: + if !first_iteration { // on pretty no commas necessary if opt.pretty { io.write_byte(w, '\n') or_return diff --git a/core/encoding/uuid/LICENSE b/core/encoding/uuid/LICENSE new file mode 100644 index 000000000..e4e21e62d --- /dev/null +++ b/core/encoding/uuid/LICENSE @@ -0,0 +1,28 @@ +BSD 3-Clause License + +Copyright (c) 2024, Feoramund + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +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. diff --git a/core/encoding/uuid/definitions.odin b/core/encoding/uuid/definitions.odin new file mode 100644 index 000000000..fe13ca99a --- /dev/null +++ b/core/encoding/uuid/definitions.odin @@ -0,0 +1,67 @@ +package uuid + +// A RFC 4122 Universally Unique Identifier +Identifier :: distinct [16]u8 + +EXPECTED_LENGTH :: 8 + 4 + 4 + 4 + 12 + 4 + +VERSION_BYTE_INDEX :: 6 +VARIANT_BYTE_INDEX :: 8 + +// The number of 100-nanosecond intervals between 1582-10-15 and 1970-01-01. +HNS_INTERVALS_BETWEEN_GREG_AND_UNIX :: 141427 * 24 * 60 * 60 * 1000 * 1000 * 10 + +VERSION_7_TIME_MASK :: 0xffffffff_ffff0000_00000000_00000000 +VERSION_7_TIME_SHIFT :: 80 +VERSION_7_COUNTER_MASK :: 0x00000000_00000fff_00000000_00000000 +VERSION_7_COUNTER_SHIFT :: 64 + +@(private) +NO_CSPRNG_ERROR :: "The context random generator is not cryptographic. See the documentation for an example of how to set one up." +@(private) +BIG_CLOCK_ERROR :: "The clock sequence can only hold 14 bits of data, therefore no number greater than 16,383 (0x3FFF)." +@(private) +VERSION_7_BIG_COUNTER_ERROR :: "This implementation of the version 7 UUID counter can only hold 12 bits of data, therefore no number greater than 4,095 (0xFFF)." + +Read_Error :: enum { + None, + Invalid_Length, + Invalid_Hexadecimal, + Invalid_Separator, +} + +Variant_Type :: enum { + Unknown, + Reserved_Apollo_NCS, // 0b0xx + RFC_4122, // 0b10x + Reserved_Microsoft_COM, // 0b110 + Reserved_Future, // 0b111 +} + +// Name string is a fully-qualified domain name. +@(rodata) +Namespace_DNS := Identifier { + 0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, + 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, +} + +// Name string is a URL. +@(rodata) +Namespace_URL := Identifier { + 0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1, + 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, +} + +// Name string is an ISO OID. +@(rodata) +Namespace_OID := Identifier { + 0x6b, 0xa7, 0xb8, 0x12, 0x9d, 0xad, 0x11, 0xd1, + 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, +} + +// Name string is an X.500 DN (in DER or a text output format). +@(rodata) +Namespace_X500 := Identifier { + 0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1, + 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, +} diff --git a/core/encoding/uuid/doc.odin b/core/encoding/uuid/doc.odin new file mode 100644 index 000000000..6fa375b72 --- /dev/null +++ b/core/encoding/uuid/doc.odin @@ -0,0 +1,46 @@ +/* +package uuid implements Universally Unique Identifiers according to the +standard originally outlined in RFC 4122 with additions from RFC 9562. + +The UUIDs are textually represented and read in the following string format: +`00000000-0000-v000-V000-000000000000` + +`v` is where the version bits reside, and `V` is where the variant bits reside. +The meaning of the other bits is version-dependent. + +Outside of string representations, UUIDs are represented in memory by a 128-bit +structure organized as an array of 16 bytes. + + +Of the UUID versions which may make use of random number generation, a +requirement is placed upon them that the underlying generator be +cryptographically-secure, per RFC 9562's suggestion. + +- Version 1 without a node argument. +- Version 4 in all cases. +- Version 6 without either a clock or node argument. +- Version 7 in all cases. + +Here's an example of how to set up one: + + import "core:crypto" + import "core:encoding/uuid" + + main :: proc() { + my_uuid: uuid.Identifier + + { + // This scope will have a CSPRNG. + context.random_generator = crypto.random_generator() + my_uuid = uuid.generate_v7() + } + + // Back to the default random number generator. + } + + +For more information on the specifications, see here: +- https://www.rfc-editor.org/rfc/rfc4122.html +- https://www.rfc-editor.org/rfc/rfc9562.html +*/ +package uuid diff --git a/core/encoding/uuid/generation.odin b/core/encoding/uuid/generation.odin new file mode 100644 index 000000000..7c9d4b80c --- /dev/null +++ b/core/encoding/uuid/generation.odin @@ -0,0 +1,333 @@ +package uuid + +import "base:runtime" +import "core:crypto/hash" +import "core:math/rand" +import "core:time" + +/* +Generate a version 1 UUID. + +Inputs: +- clock_seq: The clock sequence, a number which must be initialized to a random number once in the lifetime of a system. +- node: An optional 48-bit spatially unique identifier, specified to be the IEEE 802 address of the system. + If one is not provided or available, 48 bits of random state will take its place. +- timestamp: A timestamp from the `core:time` package, or `nil` to use the current time. + +Returns: +- result: The generated UUID. +*/ +generate_v1 :: proc(clock_seq: u16, node: Maybe([6]u8) = nil, timestamp: Maybe(time.Time) = nil) -> (result: Identifier) { + assert(clock_seq <= 0x3FFF, BIG_CLOCK_ERROR) + unix_time_in_hns_intervals := time.to_unix_nanoseconds(timestamp.? or_else time.now()) / 100 + + uuid_timestamp := cast(u64le)(HNS_INTERVALS_BETWEEN_GREG_AND_UNIX + unix_time_in_hns_intervals) + uuid_timestamp_octets := transmute([8]u8)uuid_timestamp + + result[0] = uuid_timestamp_octets[0] + result[1] = uuid_timestamp_octets[1] + result[2] = uuid_timestamp_octets[2] + result[3] = uuid_timestamp_octets[3] + result[4] = uuid_timestamp_octets[4] + result[5] = uuid_timestamp_octets[5] + + result[6] = uuid_timestamp_octets[6] >> 4 + result[7] = uuid_timestamp_octets[6] << 4 | uuid_timestamp_octets[7] + + if realized_node, ok := node.?; ok { + mutable_node := realized_node + runtime.mem_copy_non_overlapping(&result[10], &mutable_node[0], 6) + } else { + assert(.Cryptographic in runtime.random_generator_query_info(context.random_generator), NO_CSPRNG_ERROR) + bytes_generated := rand.read(result[10:]) + assert(bytes_generated == 6, "RNG failed to generate 6 bytes for UUID v1.") + } + + result[VERSION_BYTE_INDEX] |= 0x10 + result[VARIANT_BYTE_INDEX] |= 0x80 + + result[8] |= cast(u8)(clock_seq & 0x3F00 >> 8) + result[9] = cast(u8)clock_seq + + return +} + +/* +Generate a version 4 UUID. + +This UUID will be pseudorandom, save for 6 pre-determined version and variant bits. + +Returns: +- result: The generated UUID. +*/ +generate_v4 :: proc() -> (result: Identifier) { + assert(.Cryptographic in runtime.random_generator_query_info(context.random_generator), NO_CSPRNG_ERROR) + bytes_generated := rand.read(result[:]) + assert(bytes_generated == 16, "RNG failed to generate 16 bytes for UUID v4.") + + result[VERSION_BYTE_INDEX] &= 0x0F + result[VERSION_BYTE_INDEX] |= 0x40 + + result[VARIANT_BYTE_INDEX] &= 0x3F + result[VARIANT_BYTE_INDEX] |= 0x80 + + return +} + +/* +Generate a version 6 UUID. + +Inputs: +- clock_seq: The clock sequence from version 1, now made optional. + If unspecified, it will be replaced with random bits. +- node: An optional 48-bit spatially unique identifier, specified to be the IEEE 802 address of the system. + If one is not provided or available, 48 bits of random state will take its place. +- timestamp: A timestamp from the `core:time` package, or `nil` to use the current time. + +Returns: +- result: The generated UUID. +*/ +generate_v6 :: proc(clock_seq: Maybe(u16) = nil, node: Maybe([6]u8) = nil, timestamp: Maybe(time.Time) = nil) -> (result: Identifier) { + unix_time_in_hns_intervals := time.to_unix_nanoseconds(timestamp.? or_else time.now()) / 100 + + uuid_timestamp := cast(u128be)(HNS_INTERVALS_BETWEEN_GREG_AND_UNIX + unix_time_in_hns_intervals) + + result = transmute(Identifier)( + uuid_timestamp & 0x0FFFFFFF_FFFFF000 << 68 | + uuid_timestamp & 0x00000000_00000FFF << 64 + ) + + if realized_clock_seq, ok := clock_seq.?; ok { + assert(realized_clock_seq <= 0x3FFF, BIG_CLOCK_ERROR) + result[8] |= cast(u8)(realized_clock_seq & 0x3F00 >> 8) + result[9] = cast(u8)realized_clock_seq + } else { + assert(.Cryptographic in runtime.random_generator_query_info(context.random_generator), NO_CSPRNG_ERROR) + temporary: [2]u8 + bytes_generated := rand.read(temporary[:]) + assert(bytes_generated == 2, "RNG failed to generate 2 bytes for UUID v1.") + result[8] |= temporary[0] & 0x3F + result[9] = temporary[1] + } + + if realized_node, ok := node.?; ok { + mutable_node := realized_node + runtime.mem_copy_non_overlapping(&result[10], &mutable_node[0], 6) + } else { + assert(.Cryptographic in runtime.random_generator_query_info(context.random_generator), NO_CSPRNG_ERROR) + bytes_generated := rand.read(result[10:]) + assert(bytes_generated == 6, "RNG failed to generate 6 bytes for UUID v1.") + } + + result[VERSION_BYTE_INDEX] |= 0x60 + result[VARIANT_BYTE_INDEX] |= 0x80 + + return +} + +/* +Generate a version 7 UUID. + +This UUID will be pseudorandom, save for 6 pre-determined version and variant +bits and a 48-bit timestamp. + +It is designed with time-based sorting in mind, such as for database usage, as +the highest bits are allocated from the timestamp of when it is created. + +Inputs: +- timestamp: A timestamp from the `core:time` package, or `nil` to use the current time. + +Returns: +- result: The generated UUID. +*/ +generate_v7_basic :: proc(timestamp: Maybe(time.Time) = nil) -> (result: Identifier) { + assert(.Cryptographic in runtime.random_generator_query_info(context.random_generator), NO_CSPRNG_ERROR) + unix_time_in_milliseconds := time.to_unix_nanoseconds(timestamp.? or_else time.now()) / 1e6 + + result = transmute(Identifier)(cast(u128be)unix_time_in_milliseconds << VERSION_7_TIME_SHIFT) + + bytes_generated := rand.read(result[6:]) + assert(bytes_generated == 10, "RNG failed to generate 10 bytes for UUID v7.") + + result[VERSION_BYTE_INDEX] &= 0x0F + result[VERSION_BYTE_INDEX] |= 0x70 + + result[VARIANT_BYTE_INDEX] &= 0x3F + result[VARIANT_BYTE_INDEX] |= 0x80 + + return +} + +/* +Generate a version 7 UUID that has an incremented counter. + +This UUID will be pseudorandom, save for 6 pre-determined version and variant +bits, a 48-bit timestamp, and 12 bits of counter state. + +It is designed with time-based sorting in mind, such as for database usage, as +the highest bits are allocated from the timestamp of when it is created. + +This procedure is preferable if you are generating hundreds or thousands of +UUIDs as a batch within the span of a millisecond. Do note that the counter +only has 12 bits of state, thus `counter` cannot exceed the number 4,095. + +Example: + + import "core:uuid" + + // Create a batch of UUIDs all at once. + batch: [dynamic]uuid.Identifier + + for i: u16 = 0; i < 1000; i += 1 { + my_uuid := uuid.generate_v7_counter(i) + append(&batch, my_uuid) + } + +Inputs: +- counter: A 12-bit value which should be incremented each time a UUID is generated in a batch. +- timestamp: A timestamp from the `core:time` package, or `nil` to use the current time. + +Returns: +- result: The generated UUID. +*/ +generate_v7_with_counter :: proc(counter: u16, timestamp: Maybe(time.Time) = nil) -> (result: Identifier) { + assert(.Cryptographic in runtime.random_generator_query_info(context.random_generator), NO_CSPRNG_ERROR) + assert(counter <= 0x0fff, VERSION_7_BIG_COUNTER_ERROR) + unix_time_in_milliseconds := time.to_unix_nanoseconds(timestamp.? or_else time.now()) / 1e6 + + result = transmute(Identifier)( + cast(u128be)unix_time_in_milliseconds << VERSION_7_TIME_SHIFT | + cast(u128be)counter << VERSION_7_COUNTER_SHIFT + ) + + bytes_generated := rand.read(result[8:]) + assert(bytes_generated == 8, "RNG failed to generate 8 bytes for UUID v7.") + + result[VERSION_BYTE_INDEX] &= 0x0F + result[VERSION_BYTE_INDEX] |= 0x70 + + result[VARIANT_BYTE_INDEX] &= 0x3F + result[VARIANT_BYTE_INDEX] |= 0x80 + + return +} + +generate_v7 :: proc { + generate_v7_basic, + generate_v7_with_counter, +} + +/* +Generate a version 8 UUID using a specific hashing algorithm. + +This UUID is generated by hashing a name with a namespace. + +Note that all version 8 UUIDs are for experimental or vendor-specific use +cases, per the specification. This use case in particular is for offering a +non-legacy alternative to UUID versions 3 and 5. + +Inputs: +- namespace: An `Identifier` that is used to represent the underlying namespace. + This can be any one of the `Namespace_*` values provided in this package. +- name: The byte slice which will be hashed with the namespace. +- algorithm: A hashing algorithm from `core:crypto/hash`. + +Returns: +- result: The generated UUID. + +Example: + import "core:crypto/hash" + import "core:encoding/uuid" + import "core:fmt" + + main :: proc() { + my_uuid := uuid.generate_v8_hash(uuid.Namespace_DNS, "www.odin-lang.org", .SHA256) + my_uuid_string := uuid.to_string(my_uuid, context.temp_allocator) + fmt.println(my_uuid_string) + } + +Output: + + 3730f688-4bff-8dce-9cbf-74a3960c5703 + +*/ +generate_v8_hash_bytes :: proc( + namespace: Identifier, + name: []byte, + algorithm: hash.Algorithm, +) -> ( + result: Identifier, +) { + // 128 bytes should be enough for the foreseeable future. + digest: [128]byte + + assert(hash.DIGEST_SIZES[algorithm] >= 16, "Per RFC 9562, the hashing algorithm used must generate a digest of 128 bits or larger.") + assert(hash.DIGEST_SIZES[algorithm] < len(digest), "Digest size is too small for this algorithm. The buffer must be increased.") + + hash_context: hash.Context + hash.init(&hash_context, algorithm) + + mutable_namespace := namespace + hash.update(&hash_context, mutable_namespace[:]) + hash.update(&hash_context, name[:]) + hash.final(&hash_context, digest[:]) + + runtime.mem_copy_non_overlapping(&result, &digest, 16) + + result[VERSION_BYTE_INDEX] &= 0x0F + result[VERSION_BYTE_INDEX] |= 0x80 + + result[VARIANT_BYTE_INDEX] &= 0x3F + result[VARIANT_BYTE_INDEX] |= 0x80 + + return +} + +/* +Generate a version 8 UUID using a specific hashing algorithm. + +This UUID is generated by hashing a name with a namespace. + +Note that all version 8 UUIDs are for experimental or vendor-specific use +cases, per the specification. This use case in particular is for offering a +non-legacy alternative to UUID versions 3 and 5. + +Inputs: +- namespace: An `Identifier` that is used to represent the underlying namespace. + This can be any one of the `Namespace_*` values provided in this package. +- name: The string which will be hashed with the namespace. +- algorithm: A hashing algorithm from `core:crypto/hash`. + +Returns: +- result: The generated UUID. + +Example: + import "core:crypto/hash" + import "core:encoding/uuid" + import "core:fmt" + + main :: proc() { + my_uuid := uuid.generate_v8_hash(uuid.Namespace_DNS, "www.odin-lang.org", .SHA256) + my_uuid_string := uuid.to_string(my_uuid, context.temp_allocator) + fmt.println(my_uuid_string) + } + +Output: + + 3730f688-4bff-8dce-9cbf-74a3960c5703 + +*/ +generate_v8_hash_string :: proc( + namespace: Identifier, + name: string, + algorithm: hash.Algorithm, +) -> ( + result: Identifier, +) { + return generate_v8_hash_bytes(namespace, transmute([]byte)name, algorithm) +} + +generate_v8_hash :: proc { + generate_v8_hash_bytes, + generate_v8_hash_string, +} diff --git a/core/encoding/uuid/legacy/legacy.odin b/core/encoding/uuid/legacy/legacy.odin new file mode 100644 index 000000000..d5f3df617 --- /dev/null +++ b/core/encoding/uuid/legacy/legacy.odin @@ -0,0 +1,146 @@ +/* +package uuid/legacy implements versions 3 and 5 of UUID generation, both of +which are using hashing algorithms (MD5 and SHA1, respectively) that are known +these days to no longer be secure. +*/ +package uuid_legacy + +import "base:runtime" +import "core:crypto/legacy/md5" +import "core:crypto/legacy/sha1" +import "core:encoding/uuid" + +Identifier :: uuid.Identifier +VERSION_BYTE_INDEX :: uuid.VERSION_BYTE_INDEX +VARIANT_BYTE_INDEX :: uuid.VARIANT_BYTE_INDEX + + +/* +Generate a version 3 UUID. + +This UUID is generated with a MD5 hash of a name and a namespace. + +Inputs: +- namespace: An `Identifier` that is used to represent the underlying namespace. + This can be any one of the `Namespace_*` values provided in the `uuid` package. +- name: The byte slice which will be hashed with the namespace. + +Returns: +- result: The generated UUID. +*/ +generate_v3_bytes :: proc( + namespace: Identifier, + name: []byte, +) -> ( + result: Identifier, +) { + namespace := namespace + + ctx: md5.Context + md5.init(&ctx) + md5.update(&ctx, namespace[:]) + md5.update(&ctx, name) + md5.final(&ctx, result[:]) + + result[VERSION_BYTE_INDEX] &= 0x0F + result[VERSION_BYTE_INDEX] |= 0x30 + + result[VARIANT_BYTE_INDEX] &= 0x3F + result[VARIANT_BYTE_INDEX] |= 0x80 + + return +} + +/* +Generate a version 3 UUID. + +This UUID is generated with a MD5 hash of a name and a namespace. + +Inputs: +- namespace: An `Identifier` that is used to represent the underlying namespace. + This can be any one of the `Namespace_*` values provided in the `uuid` package. +- name: The string which will be hashed with the namespace. + +Returns: +- result: The generated UUID. +*/ +generate_v3_string :: proc( + namespace: Identifier, + name: string, +) -> ( + result: Identifier, +) { + return generate_v3_bytes(namespace, transmute([]byte)name) +} + +generate_v3 :: proc { + generate_v3_bytes, + generate_v3_string, +} + +/* +Generate a version 5 UUID. + +This UUID is generated with a SHA1 hash of a name and a namespace. + +Inputs: +- namespace: An `Identifier` that is used to represent the underlying namespace. + This can be any one of the `Namespace_*` values provided in the `uuid` package. +- name: The byte slice which will be hashed with the namespace. + +Returns: +- result: The generated UUID. +*/ +generate_v5_bytes :: proc( + namespace: Identifier, + name: []byte, +) -> ( + result: Identifier, +) { + namespace := namespace + digest: [sha1.DIGEST_SIZE]byte + + ctx: sha1.Context + sha1.init(&ctx) + sha1.update(&ctx, namespace[:]) + sha1.update(&ctx, name) + sha1.final(&ctx, digest[:]) + + runtime.mem_copy_non_overlapping(&result, &digest, 16) + + result[VERSION_BYTE_INDEX] &= 0x0F + result[VERSION_BYTE_INDEX] |= 0x50 + + result[VARIANT_BYTE_INDEX] &= 0x3F + result[VARIANT_BYTE_INDEX] |= 0x80 + + return +} + +/* +Generate a version 5 UUID. + +This UUID is generated with a SHA1 hash of a name and a namespace. + +Inputs: +- namespace: An `Identifier` that is used to represent the underlying namespace. + This can be any one of the `Namespace_*` values provided in the `uuid` package. +- name: The string which will be hashed with the namespace. + +Returns: +- result: The generated UUID. +*/ +generate_v5_string :: proc( + namespace: Identifier, + name: string, +) -> ( + result: Identifier, +) { + return generate_v5_bytes(namespace, transmute([]byte)name) +} + +generate_v5 :: proc { + generate_v5_bytes, + generate_v5_string, +} + diff --git a/core/encoding/uuid/reading.odin b/core/encoding/uuid/reading.odin new file mode 100644 index 000000000..c91c82465 --- /dev/null +++ b/core/encoding/uuid/reading.odin @@ -0,0 +1,242 @@ +package uuid + +import "base:runtime" +import "core:time" + +/* +Convert a string to a UUID. + +Inputs: +- str: A string in the 8-4-4-4-12 format. + +Returns: +- id: The converted identifier, or `nil` if there is an error. +- error: A description of the error, or `nil` if successful. +*/ +read :: proc "contextless" (str: string) -> (id: Identifier, error: Read_Error) #no_bounds_check { + // Only exact-length strings are acceptable. + if len(str) != EXPECTED_LENGTH { + return {}, .Invalid_Length + } + + // Check ahead to see if the separators are in the right places. + if str[8] != '-' || str[13] != '-' || str[18] != '-' || str[23] != '-' { + return {}, .Invalid_Separator + } + + read_nibble :: proc "contextless" (nibble: u8) -> u8 { + switch nibble { + case '0' ..= '9': + return nibble - '0' + case 'A' ..= 'F': + return nibble - 'A' + 10 + case 'a' ..= 'f': + return nibble - 'a' + 10 + case: + // Return an error value. + return 0xFF + } + } + + index := 0 + octet_index := 0 + + CHUNKS :: [5]int{8, 4, 4, 4, 12} + + for chunk in CHUNKS { + for i := index; i < index + chunk; i += 2 { + high := read_nibble(str[i]) + low := read_nibble(str[i + 1]) + + if high | low > 0xF { + return {}, .Invalid_Hexadecimal + } + + id[octet_index] = low | high << 4 + octet_index += 1 + } + + index += chunk + 1 + } + + return +} + +/* +Get the version of a UUID. + +Inputs: +- id: The identifier. + +Returns: +- number: The version number. +*/ +version :: proc "contextless" (id: Identifier) -> (number: int) #no_bounds_check { + return cast(int)(id[VERSION_BYTE_INDEX] & 0xF0 >> 4) +} + +/* +Get the variant of a UUID. + +Inputs: +- id: The identifier. + +Returns: +- variant: The variant type. +*/ +variant :: proc "contextless" (id: Identifier) -> (variant: Variant_Type) #no_bounds_check { + switch { + case id[VARIANT_BYTE_INDEX] & 0x80 == 0: + return .Reserved_Apollo_NCS + case id[VARIANT_BYTE_INDEX] & 0xC0 == 0x80: + return .RFC_4122 + case id[VARIANT_BYTE_INDEX] & 0xE0 == 0xC0: + return .Reserved_Microsoft_COM + case id[VARIANT_BYTE_INDEX] & 0xF0 == 0xE0: + return .Reserved_Future + case: + return .Unknown + } +} + +/* +Get the clock sequence of a version 1 or version 6 UUID. + +Inputs: +- id: The identifier. + +Returns: +- clock_seq: The 14-bit clock sequence field. +*/ +clock_seq :: proc "contextless" (id: Identifier) -> (clock_seq: u16) { + return cast(u16)id[9] | cast(u16)id[8] & 0x3F << 8 +} + +/* +Get the node of a version 1 or version 6 UUID. + +Inputs: +- id: The identifier. + +Returns: +- node: The 48-bit spatially unique identifier. +*/ +node :: proc "contextless" (id: Identifier) -> (node: [6]u8) { + mutable_id := id + runtime.mem_copy_non_overlapping(&node, &mutable_id[10], 6) + return +} + +/* +Get the raw timestamp of a version 1 UUID. + +Inputs: +- id: The identifier. + +Returns: +- timestamp: The timestamp, in 100-nanosecond intervals since 1582-10-15. +*/ +raw_time_v1 :: proc "contextless" (id: Identifier) -> (timestamp: u64) { + timestamp_octets: [8]u8 + + timestamp_octets[0] = id[0] + timestamp_octets[1] = id[1] + timestamp_octets[2] = id[2] + timestamp_octets[3] = id[3] + timestamp_octets[4] = id[4] + timestamp_octets[5] = id[5] + + timestamp_octets[6] = id[6] << 4 | id[7] >> 4 + timestamp_octets[7] = id[7] & 0xF + + return cast(u64)transmute(u64le)timestamp_octets +} + + +/* +Get the timestamp of a version 1 UUID. + +Inputs: +- id: The identifier. + +Returns: +- timestamp: The timestamp of the UUID. +*/ +time_v1 :: proc "contextless" (id: Identifier) -> (timestamp: time.Time) { + return time.from_nanoseconds(cast(i64)(raw_time_v1(id) - HNS_INTERVALS_BETWEEN_GREG_AND_UNIX) * 100) +} + +/* +Get the raw timestamp of a version 6 UUID. + +Inputs: +- id: The identifier. + +Returns: +- timestamp: The timestamp, in 100-nanosecond intervals since 1582-10-15. +*/ +raw_time_v6 :: proc "contextless" (id: Identifier) -> (timestamp: u64) { + temporary := transmute(u128be)id + + timestamp |= cast(u64)(temporary & 0xFFFFFFFF_FFFF0000_00000000_00000000 >> 68) + timestamp |= cast(u64)(temporary & 0x00000000_00000FFF_00000000_00000000 >> 64) + + return timestamp +} + +/* +Get the timestamp of a version 6 UUID. + +Inputs: +- id: The identifier. + +Returns: +- timestamp: The timestamp, in 100-nanosecond intervals since 1582-10-15. +*/ +time_v6 :: proc "contextless" (id: Identifier) -> (timestamp: time.Time) { + return time.from_nanoseconds(cast(i64)(raw_time_v6(id) - HNS_INTERVALS_BETWEEN_GREG_AND_UNIX) * 100) +} + +/* +Get the raw timestamp of a version 7 UUID. + +Inputs: +- id: The identifier. + +Returns: +- timestamp: The timestamp, in milliseconds since the UNIX epoch. +*/ +raw_time_v7 :: proc "contextless" (id: Identifier) -> (timestamp: u64) { + time_bits := transmute(u128be)id & VERSION_7_TIME_MASK + return cast(u64)(time_bits >> VERSION_7_TIME_SHIFT) +} + +/* +Get the timestamp of a version 7 UUID. + +Inputs: +- id: The identifier. + +Returns: +- timestamp: The timestamp, in milliseconds since the UNIX epoch. +*/ +time_v7 :: proc "contextless" (id: Identifier) -> (timestamp: time.Time) { + return time.from_nanoseconds(cast(i64)raw_time_v7(id) * 1e6) +} + +/* +Get the 12-bit counter value of a version 7 UUID. + +The UUID must have been generated with a counter, otherwise this procedure will +return random bits. + +Inputs: +- id: The identifier. + +Returns: +- counter: The 12-bit counter value. +*/ +counter_v7 :: proc "contextless" (id: Identifier) -> (counter: u16) { + counter_bits := transmute(u128be)id & VERSION_7_COUNTER_MASK + return cast(u16)(counter_bits >> VERSION_7_COUNTER_SHIFT) +} diff --git a/core/encoding/uuid/stamping.odin b/core/encoding/uuid/stamping.odin new file mode 100644 index 000000000..3ca61fe44 --- /dev/null +++ b/core/encoding/uuid/stamping.odin @@ -0,0 +1,89 @@ +package uuid + +import "base:runtime" + +/* +Stamp a 128-bit integer as being a valid version 8 UUID. + +Per the specification, all version 8 UUIDs are either for experimental or +vendor-specific purposes. This procedure allows for converting arbitrary data +into custom UUIDs. + +Inputs: +- integer: Any integer type. + +Returns: +- result: A valid version 8 UUID. +*/ +stamp_v8_int :: proc(#any_int integer: u128) -> (result: Identifier) { + result = transmute(Identifier)cast(u128be)integer + + result[VERSION_BYTE_INDEX] &= 0x0F + result[VERSION_BYTE_INDEX] |= 0x80 + + result[VARIANT_BYTE_INDEX] &= 0x3F + result[VARIANT_BYTE_INDEX] |= 0x80 + + return +} + +/* +Stamp an array of 16 bytes as being a valid version 8 UUID. + +Per the specification, all version 8 UUIDs are either for experimental or +vendor-specific purposes. This procedure allows for converting arbitrary data +into custom UUIDs. + +Inputs: +- array: An array of 16 bytes. + +Returns: +- result: A valid version 8 UUID. +*/ +stamp_v8_array :: proc(array: [16]u8) -> (result: Identifier) { + result = Identifier(array) + + result[VERSION_BYTE_INDEX] &= 0x0F + result[VERSION_BYTE_INDEX] |= 0x80 + + result[VARIANT_BYTE_INDEX] &= 0x3F + result[VARIANT_BYTE_INDEX] |= 0x80 + + return +} + +/* +Stamp a slice of bytes as being a valid version 8 UUID. + +If the slice is less than 16 bytes long, the data available will be used. +If it is longer than 16 bytes, only the first 16 will be used. + +This procedure does not modify the underlying slice. + +Per the specification, all version 8 UUIDs are either for experimental or +vendor-specific purposes. This procedure allows for converting arbitrary data +into custom UUIDs. + +Inputs: +- slice: A slice of bytes. + +Returns: +- result: A valid version 8 UUID. +*/ +stamp_v8_slice :: proc(slice: []u8) -> (result: Identifier) { + runtime.mem_copy_non_overlapping(&result, &slice[0], min(16, len(slice))) + + result[VERSION_BYTE_INDEX] &= 0x0F + result[VERSION_BYTE_INDEX] |= 0x80 + + result[VARIANT_BYTE_INDEX] &= 0x3F + result[VARIANT_BYTE_INDEX] |= 0x80 + + return +} + +stamp_v8 :: proc { + stamp_v8_int, + stamp_v8_array, + stamp_v8_slice, +} diff --git a/core/encoding/uuid/writing.odin b/core/encoding/uuid/writing.odin new file mode 100644 index 000000000..499cba72b --- /dev/null +++ b/core/encoding/uuid/writing.odin @@ -0,0 +1,131 @@ +package uuid + +import "base:runtime" +import "core:io" +import "core:strconv" +import "core:strings" + +/* +Write a UUID in the 8-4-4-4-12 format. + +This procedure performs error checking with every byte written. + +If you can guarantee beforehand that your stream has enough space to hold the +UUID (32 bytes), then it is better to use `unsafe_write` instead as that will +be faster. + +Inputs: +- w: A writable stream. +- id: The identifier to convert. + +Returns: +- error: An `io` error, if one occurred, otherwise `nil`. +*/ +write :: proc(w: io.Writer, id: Identifier) -> (error: io.Error) #no_bounds_check { + write_octet :: proc (w: io.Writer, octet: u8) -> io.Error #no_bounds_check { + high_nibble := octet >> 4 + low_nibble := octet & 0xF + + io.write_byte(w, strconv.digits[high_nibble]) or_return + io.write_byte(w, strconv.digits[low_nibble]) or_return + return nil + } + + for index in 0 ..< 4 { write_octet(w, id[index]) or_return } + io.write_byte(w, '-') or_return + for index in 4 ..< 6 { write_octet(w, id[index]) or_return } + io.write_byte(w, '-') or_return + for index in 6 ..< 8 { write_octet(w, id[index]) or_return } + io.write_byte(w, '-') or_return + for index in 8 ..< 10 { write_octet(w, id[index]) or_return } + io.write_byte(w, '-') or_return + for index in 10 ..< 16 { write_octet(w, id[index]) or_return } + + return nil +} + +/* +Write a UUID in the 8-4-4-4-12 format. + +This procedure performs no error checking on the underlying stream. + +Inputs: +- w: A writable stream. +- id: The identifier to convert. +*/ +unsafe_write :: proc(w: io.Writer, id: Identifier) #no_bounds_check { + write_octet :: proc (w: io.Writer, octet: u8) #no_bounds_check { + high_nibble := octet >> 4 + low_nibble := octet & 0xF + + io.write_byte(w, strconv.digits[high_nibble]) + io.write_byte(w, strconv.digits[low_nibble]) + } + + for index in 0 ..< 4 { write_octet(w, id[index]) } + io.write_byte(w, '-') + for index in 4 ..< 6 { write_octet(w, id[index]) } + io.write_byte(w, '-') + for index in 6 ..< 8 { write_octet(w, id[index]) } + io.write_byte(w, '-') + for index in 8 ..< 10 { write_octet(w, id[index]) } + io.write_byte(w, '-') + for index in 10 ..< 16 { write_octet(w, id[index]) } +} + +/* +Convert a UUID to a string in the 8-4-4-4-12 format. + +*Allocates Using Provided Allocator* + +Inputs: +- id: The identifier to convert. +- allocator: (default: context.allocator) +- loc: The caller location for debugging purposes (default: #caller_location) + +Returns: +- str: The allocated and converted string. +- error: An optional allocator error if one occured, `nil` otherwise. +*/ +to_string_allocated :: proc( + id: Identifier, + allocator := context.allocator, + loc := #caller_location, +) -> ( + str: string, + error: runtime.Allocator_Error, +) #optional_allocator_error { + buf := make([]byte, EXPECTED_LENGTH, allocator, loc) or_return + builder := strings.builder_from_bytes(buf[:]) + unsafe_write(strings.to_writer(&builder), id) + return strings.to_string(builder), nil +} + +/* +Convert a UUID to a string in the 8-4-4-4-12 format. + +Inputs: +- id: The identifier to convert. +- buffer: A byte buffer to store the result. Must be at least 32 bytes large. +- loc: The caller location for debugging purposes (default: #caller_location) + +Returns: +- str: The converted string which will be stored in `buffer`. +*/ +to_string_buffer :: proc( + id: Identifier, + buffer: []byte, + loc := #caller_location, +) -> ( + str: string, +) { + assert(len(buffer) >= EXPECTED_LENGTH, "The buffer provided is not at least 32 bytes large.", loc) + builder := strings.builder_from_bytes(buffer) + unsafe_write(strings.to_writer(&builder), id) + return strings.to_string(builder) +} + +to_string :: proc { + to_string_allocated, + to_string_buffer, +} diff --git a/core/encoding/xml/debug_print.odin b/core/encoding/xml/debug_print.odin index be958baaa..acced262a 100644 --- a/core/encoding/xml/debug_print.odin +++ b/core/encoding/xml/debug_print.odin @@ -33,7 +33,7 @@ print :: proc(writer: io.Writer, doc: ^Document) -> (written: int, err: io.Error written += fmt.wprintf(writer, "[DOCTYPE] %v\n", doc.doctype.ident) if len(doc.doctype.rest) > 0 { - fmt.wprintf(writer, "\t%v\n", doc.doctype.rest) + fmt.wprintf(writer, "\t%v\n", doc.doctype.rest) } } @@ -42,10 +42,10 @@ print :: proc(writer: io.Writer, doc: ^Document) -> (written: int, err: io.Error } if len(doc.elements) > 0 { - fmt.wprintln(writer, " --- ") - print_element(writer, doc, 0) - fmt.wprintln(writer, " --- ") - } + fmt.wprintln(writer, " --- ") + print_element(writer, doc, 0) + fmt.wprintln(writer, " --- ") + } return written, .None } diff --git a/core/flags/internal_rtti.odin b/core/flags/internal_rtti.odin index c9b1f59fd..b7aecdef3 100644 --- a/core/flags/internal_rtti.odin +++ b/core/flags/internal_rtti.odin @@ -45,45 +45,45 @@ parse_and_set_pointer_by_base_type :: proc(ptr: rawptr, str: string, type_info: if specific_type_info.signed { value := strconv.parse_i128(str) or_return switch type_info.id { - case i8: (cast(^i8) ptr)^ = cast(i8) bounded_int(value, cast(i128)min(i8), cast(i128)max(i8) ) or_return - case i16: (cast(^i16) ptr)^ = cast(i16) bounded_int(value, cast(i128)min(i16), cast(i128)max(i16) ) or_return - case i32: (cast(^i32) ptr)^ = cast(i32) bounded_int(value, cast(i128)min(i32), cast(i128)max(i32) ) or_return - case i64: (cast(^i64) ptr)^ = cast(i64) bounded_int(value, cast(i128)min(i64), cast(i128)max(i64) ) or_return - case i128: (cast(^i128) ptr)^ = value + case i8: (^i8) (ptr)^ = cast(i8) bounded_int(value, cast(i128)min(i8), cast(i128)max(i8) ) or_return + case i16: (^i16) (ptr)^ = cast(i16) bounded_int(value, cast(i128)min(i16), cast(i128)max(i16) ) or_return + case i32: (^i32) (ptr)^ = cast(i32) bounded_int(value, cast(i128)min(i32), cast(i128)max(i32) ) or_return + case i64: (^i64) (ptr)^ = cast(i64) bounded_int(value, cast(i128)min(i64), cast(i128)max(i64) ) or_return + case i128: (^i128) (ptr)^ = value - case int: (cast(^int) ptr)^ = cast(int) bounded_int(value, cast(i128)min(int), cast(i128)max(int) ) or_return + case int: (^int) (ptr)^ = cast(int) bounded_int(value, cast(i128)min(int), cast(i128)max(int) ) or_return - case i16le: (cast(^i16le) ptr)^ = cast(i16le) bounded_int(value, cast(i128)min(i16le), cast(i128)max(i16le) ) or_return - case i32le: (cast(^i32le) ptr)^ = cast(i32le) bounded_int(value, cast(i128)min(i32le), cast(i128)max(i32le) ) or_return - case i64le: (cast(^i64le) ptr)^ = cast(i64le) bounded_int(value, cast(i128)min(i64le), cast(i128)max(i64le) ) or_return - case i128le: (cast(^i128le)ptr)^ = cast(i128le) bounded_int(value, cast(i128)min(i128le), cast(i128)max(i128le)) or_return + case i16le: (^i16le) (ptr)^ = cast(i16le) bounded_int(value, cast(i128)min(i16le), cast(i128)max(i16le) ) or_return + case i32le: (^i32le) (ptr)^ = cast(i32le) bounded_int(value, cast(i128)min(i32le), cast(i128)max(i32le) ) or_return + case i64le: (^i64le) (ptr)^ = cast(i64le) bounded_int(value, cast(i128)min(i64le), cast(i128)max(i64le) ) or_return + case i128le: (^i128le)(ptr)^ = cast(i128le) bounded_int(value, cast(i128)min(i128le), cast(i128)max(i128le)) or_return - case i16be: (cast(^i16be) ptr)^ = cast(i16be) bounded_int(value, cast(i128)min(i16be), cast(i128)max(i16be) ) or_return - case i32be: (cast(^i32be) ptr)^ = cast(i32be) bounded_int(value, cast(i128)min(i32be), cast(i128)max(i32be) ) or_return - case i64be: (cast(^i64be) ptr)^ = cast(i64be) bounded_int(value, cast(i128)min(i64be), cast(i128)max(i64be) ) or_return - case i128be: (cast(^i128be)ptr)^ = cast(i128be) bounded_int(value, cast(i128)min(i128be), cast(i128)max(i128be)) or_return + case i16be: (^i16be) (ptr)^ = cast(i16be) bounded_int(value, cast(i128)min(i16be), cast(i128)max(i16be) ) or_return + case i32be: (^i32be) (ptr)^ = cast(i32be) bounded_int(value, cast(i128)min(i32be), cast(i128)max(i32be) ) or_return + case i64be: (^i64be) (ptr)^ = cast(i64be) bounded_int(value, cast(i128)min(i64be), cast(i128)max(i64be) ) or_return + case i128be: (^i128be)(ptr)^ = cast(i128be) bounded_int(value, cast(i128)min(i128be), cast(i128)max(i128be)) or_return } } else { value := strconv.parse_u128(str) or_return switch type_info.id { - case u8: (cast(^u8) ptr)^ = cast(u8) bounded_uint(value, cast(u128)max(u8) ) or_return - case u16: (cast(^u16) ptr)^ = cast(u16) bounded_uint(value, cast(u128)max(u16) ) or_return - case u32: (cast(^u32) ptr)^ = cast(u32) bounded_uint(value, cast(u128)max(u32) ) or_return - case u64: (cast(^u64) ptr)^ = cast(u64) bounded_uint(value, cast(u128)max(u64) ) or_return - case u128: (cast(^u128) ptr)^ = value + case u8: (^u8) (ptr)^ = cast(u8) bounded_uint(value, cast(u128)max(u8) ) or_return + case u16: (^u16) (ptr)^ = cast(u16) bounded_uint(value, cast(u128)max(u16) ) or_return + case u32: (^u32) (ptr)^ = cast(u32) bounded_uint(value, cast(u128)max(u32) ) or_return + case u64: (^u64) (ptr)^ = cast(u64) bounded_uint(value, cast(u128)max(u64) ) or_return + case u128: (^u128) (ptr)^ = value - case uint: (cast(^uint) ptr)^ = cast(uint) bounded_uint(value, cast(u128)max(uint) ) or_return - case uintptr: (cast(^uintptr)ptr)^ = cast(uintptr) bounded_uint(value, cast(u128)max(uintptr)) or_return + case uint: (^uint) (ptr)^ = cast(uint) bounded_uint(value, cast(u128)max(uint) ) or_return + case uintptr: (^uintptr)(ptr)^ = cast(uintptr) bounded_uint(value, cast(u128)max(uintptr)) or_return - case u16le: (cast(^u16le) ptr)^ = cast(u16le) bounded_uint(value, cast(u128)max(u16le) ) or_return - case u32le: (cast(^u32le) ptr)^ = cast(u32le) bounded_uint(value, cast(u128)max(u32le) ) or_return - case u64le: (cast(^u64le) ptr)^ = cast(u64le) bounded_uint(value, cast(u128)max(u64le) ) or_return - case u128le: (cast(^u128le) ptr)^ = cast(u128le) bounded_uint(value, cast(u128)max(u128le) ) or_return + case u16le: (^u16le) (ptr)^ = cast(u16le) bounded_uint(value, cast(u128)max(u16le) ) or_return + case u32le: (^u32le) (ptr)^ = cast(u32le) bounded_uint(value, cast(u128)max(u32le) ) or_return + case u64le: (^u64le) (ptr)^ = cast(u64le) bounded_uint(value, cast(u128)max(u64le) ) or_return + case u128le: (^u128le) (ptr)^ = cast(u128le) bounded_uint(value, cast(u128)max(u128le) ) or_return - case u16be: (cast(^u16be) ptr)^ = cast(u16be) bounded_uint(value, cast(u128)max(u16be) ) or_return - case u32be: (cast(^u32be) ptr)^ = cast(u32be) bounded_uint(value, cast(u128)max(u32be) ) or_return - case u64be: (cast(^u64be) ptr)^ = cast(u64be) bounded_uint(value, cast(u128)max(u64be) ) or_return - case u128be: (cast(^u128be) ptr)^ = cast(u128be) bounded_uint(value, cast(u128)max(u128be) ) or_return + case u16be: (^u16be) (ptr)^ = cast(u16be) bounded_uint(value, cast(u128)max(u16be) ) or_return + case u32be: (^u32be) (ptr)^ = cast(u32be) bounded_uint(value, cast(u128)max(u32be) ) or_return + case u64be: (^u64be) (ptr)^ = cast(u64be) bounded_uint(value, cast(u128)max(u64be) ) or_return + case u128be: (^u128be) (ptr)^ = cast(u128be) bounded_uint(value, cast(u128)max(u128be) ) or_return } } @@ -92,60 +92,60 @@ parse_and_set_pointer_by_base_type :: proc(ptr: rawptr, str: string, type_info: return false } - (cast(^rune)ptr)^ = utf8.rune_at_pos(str, 0) + (^rune)(ptr)^ = utf8.rune_at_pos(str, 0) case runtime.Type_Info_Float: value := strconv.parse_f64(str) or_return switch type_info.id { - case f16: (cast(^f16) ptr)^ = cast(f16) value - case f32: (cast(^f32) ptr)^ = cast(f32) value - case f64: (cast(^f64) ptr)^ = value + case f16: (^f16) (ptr)^ = cast(f16) value + case f32: (^f32) (ptr)^ = cast(f32) value + case f64: (^f64) (ptr)^ = value - case f16le: (cast(^f16le)ptr)^ = cast(f16le) value - case f32le: (cast(^f32le)ptr)^ = cast(f32le) value - case f64le: (cast(^f64le)ptr)^ = cast(f64le) value + case f16le: (^f16le)(ptr)^ = cast(f16le) value + case f32le: (^f32le)(ptr)^ = cast(f32le) value + case f64le: (^f64le)(ptr)^ = cast(f64le) value - case f16be: (cast(^f16be)ptr)^ = cast(f16be) value - case f32be: (cast(^f32be)ptr)^ = cast(f32be) value - case f64be: (cast(^f64be)ptr)^ = cast(f64be) value + case f16be: (^f16be)(ptr)^ = cast(f16be) value + case f32be: (^f32be)(ptr)^ = cast(f32be) value + case f64be: (^f64be)(ptr)^ = cast(f64be) value } case runtime.Type_Info_Complex: value := strconv.parse_complex128(str) or_return switch type_info.id { - case complex128: (cast(^complex128)ptr)^ = value - case complex64: (cast(^complex64) ptr)^ = cast(complex64)value - case complex32: (cast(^complex32) ptr)^ = cast(complex32)value + case complex32: (^complex32) (ptr)^ = (complex32)(value) + case complex64: (^complex64) (ptr)^ = (complex64)(value) + case complex128: (^complex128)(ptr)^ = value } case runtime.Type_Info_Quaternion: value := strconv.parse_quaternion256(str) or_return switch type_info.id { - case quaternion256: (cast(^quaternion256)ptr)^ = value - case quaternion128: (cast(^quaternion128)ptr)^ = cast(quaternion128)value - case quaternion64: (cast(^quaternion64) ptr)^ = cast(quaternion64)value + case quaternion64: (^quaternion64) (ptr)^ = (quaternion64)(value) + case quaternion128: (^quaternion128)(ptr)^ = (quaternion128)(value) + case quaternion256: (^quaternion256)(ptr)^ = value } case runtime.Type_Info_String: if specific_type_info.is_cstring { - cstr_ptr := cast(^cstring)ptr + cstr_ptr := (^cstring)(ptr) if cstr_ptr != nil { // Prevent memory leaks from us setting this value multiple times. delete(cstr_ptr^) } cstr_ptr^ = strings.clone_to_cstring(str) } else { - (cast(^string)ptr)^ = str + (^string)(ptr)^ = str } case runtime.Type_Info_Boolean: value := strconv.parse_bool(str) or_return switch type_info.id { - case bool: (cast(^bool) ptr)^ = value - case b8: (cast(^b8) ptr)^ = cast(b8) value - case b16: (cast(^b16) ptr)^ = cast(b16) value - case b32: (cast(^b32) ptr)^ = cast(b32) value - case b64: (cast(^b64) ptr)^ = cast(b64) value + case bool: (^bool)(ptr)^ = value + case b8: (^b8) (ptr)^ = b8(value) + case b16: (^b16) (ptr)^ = b16(value) + case b32: (^b32) (ptr)^ = b32(value) + case b64: (^b64) (ptr)^ = b64(value) } case runtime.Type_Info_Bit_Set: @@ -154,9 +154,9 @@ parse_and_set_pointer_by_base_type :: proc(ptr: rawptr, str: string, type_info: value: u128 // NOTE: `upper` is inclusive, i.e: `0..=31` - max_bit_index := cast(u128)(1 + specific_type_info.upper - specific_type_info.lower) - bit_index : u128 = 0 - #no_bounds_check for string_index : uint = 0; string_index < len(str); string_index += 1 { + max_bit_index := u128(1 + specific_type_info.upper - specific_type_info.lower) + bit_index := u128(0) + #no_bounds_check for string_index in 0.. (int, bool) { if args_tag, ok := reflect.struct_tag_lookup(field.tag, TAG_ARGS); ok { if pos_subtag, pos_ok := get_struct_subtag(args_tag, SUBTAG_POS); pos_ok { if value, parse_ok := strconv.parse_u64_of_base(pos_subtag, 10); parse_ok { - return cast(int)value, true + return int(value), true } } } @@ -516,15 +516,8 @@ get_field_by_name :: proc(model: ^$T, name: string) -> (result: reflect.Struct_F // Get a struct field by its `pos` subtag. get_field_by_pos :: proc(model: ^$T, pos: int) -> (result: reflect.Struct_Field, index: int, ok: bool) { for field, i in reflect.struct_fields_zipped(T) { - args_tag, tag_ok := reflect.struct_tag_lookup(field.tag, TAG_ARGS) - if !tag_ok { - continue - } - - pos_subtag, pos_ok := get_struct_subtag(args_tag, SUBTAG_POS) - if !pos_ok { - continue - } + args_tag := reflect.struct_tag_lookup(field.tag, TAG_ARGS) or_continue + pos_subtag := get_struct_subtag(args_tag, SUBTAG_POS) or_continue value, parse_ok := strconv.parse_u64_of_base(pos_subtag, 10) if parse_ok && cast(int)value == pos { diff --git a/core/fmt/fmt.odin b/core/fmt/fmt.odin index 424e4e6e8..bd5f2b155 100644 --- a/core/fmt/fmt.odin +++ b/core/fmt/fmt.odin @@ -92,7 +92,7 @@ _user_formatters: ^map[typeid]User_Formatter // set_user_formatters :: proc(m: ^map[typeid]User_Formatter) { assert(_user_formatters == nil, "set_user_formatters must not be called more than once.") - _user_formatters = m + _user_formatters = m } // Registers a user-defined formatter for a specific typeid // @@ -1072,8 +1072,8 @@ _fmt_int :: proc(fi: ^Info, u: u64, base: int, is_signed: bool, bit_size: int, d } flags: strconv.Int_Flags - if fi.hash && !fi.zero && start == 0 { flags |= {.Prefix} } - if fi.plus { flags |= {.Plus} } + if fi.hash && !fi.zero && start == 0 { flags += {.Prefix} } + if fi.plus { flags += {.Plus} } s := strconv.append_bits(buf[start:], u, base, is_signed, bit_size, digits, flags) prev_zero := fi.zero defer fi.zero = prev_zero @@ -1157,8 +1157,8 @@ _fmt_int_128 :: proc(fi: ^Info, u: u128, base: int, is_signed: bool, bit_size: i } flags: strconv.Int_Flags - if fi.hash && !fi.zero && start == 0 { flags |= {.Prefix} } - if fi.plus { flags |= {.Plus} } + if fi.hash && !fi.zero && start == 0 { flags += {.Prefix} } + if fi.plus { flags += {.Plus} } s := strconv.append_bits_128(buf[start:], u, base, is_signed, bit_size, digits, flags) if fi.hash && fi.zero && fi.indent == 0 { @@ -1229,10 +1229,10 @@ _fmt_memory :: proc(fi: ^Info, u: u64, is_signed: bool, bit_size: int, units: st // Add the unit at the end. copy(buf[len(str):], units[off:off+unit_len]) str = string(buf[:len(str)+unit_len]) - - if !fi.plus { - // Strip sign from "+" but not "+Inf". - if str[0] == '+' && str[1] != 'I' { + + if !fi.plus { + // Strip sign from "+" but not "+Inf". + if str[0] == '+' && str[1] != 'I' { str = str[1:] } } @@ -1460,13 +1460,10 @@ fmt_string :: proc(fi: ^Info, s: string, verb: rune) { if !fi.minus { io.write_string(fi.writer, s, &fi.n) } - } - else { + } else { io.write_string(fi.writer, s, &fi.n) } - } - else - { + } else { io.write_string(fi.writer, s, &fi.n) } @@ -1768,7 +1765,7 @@ fmt_bit_set :: proc(fi: ^Info, v: any, name: string = "", verb: rune = 'v') { if is_enum { enum_name: string - if ti_named, is_named := info.elem.variant.(runtime.Type_Info_Named); is_named { + if ti_named, is_named := info.elem.variant.(runtime.Type_Info_Named); is_named { enum_name = ti_named.name } for ev, evi in e.values { @@ -2712,7 +2709,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { return } if fi.indirection_level < 1 { - fi.indirection_level += 1 + fi.indirection_level += 1 defer fi.indirection_level -= 1 io.write_byte(fi.writer, '&') fmt_value(fi, a, verb) @@ -2781,7 +2778,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { runtime.Type_Info_Dynamic_Array, runtime.Type_Info_Map: if fi.indirection_level < 1 { - fi.indirection_level += 1 + fi.indirection_level += 1 defer fi.indirection_level -= 1 io.write_byte(fi.writer, '&', &fi.n) fmt_value(fi, a, verb) diff --git a/core/hash/xxhash/xxhash_3.odin b/core/hash/xxhash/xxhash_3.odin index 611f4dc9f..be2531b6e 100644 --- a/core/hash/xxhash/xxhash_3.odin +++ b/core/hash/xxhash/xxhash_3.odin @@ -897,19 +897,20 @@ XXH3_hashLong_64b_default :: #force_no_inline proc(input: []u8, seed64: xxh_u64, why (uop cache maybe?), but the difference is large and easily measurable. */ @(optimization_mode="speed") -XXH3_hashLong_64b_withSeed_internal :: #force_no_inline proc(input: []u8, - seed: xxh_u64, - f_acc512: XXH3_accumulate_512_f, - f_scramble: XXH3_scramble_accumulator_f, - f_init_sec: XXH3_init_custom_secret_f) -> (hash: xxh_u64) { +XXH3_hashLong_64b_withSeed_internal :: #force_no_inline proc( + input: []u8, + seed: xxh_u64, + f_acc512: XXH3_accumulate_512_f, + f_scramble: XXH3_scramble_accumulator_f, + f_init_sec: XXH3_init_custom_secret_f, +) -> (hash: xxh_u64) { if seed == 0 { return XXH3_hashLong_64b_internal(input, XXH3_kSecret[:], f_acc512, f_scramble) } - { - secret: [XXH_SECRET_DEFAULT_SIZE]u8 - f_init_sec(secret[:], seed) - return XXH3_hashLong_64b_internal(input, secret[:], f_acc512, f_scramble) - } + + secret: [XXH_SECRET_DEFAULT_SIZE]u8 + f_init_sec(secret[:], seed) + return XXH3_hashLong_64b_internal(input, secret[:], f_acc512, f_scramble) } /* diff --git a/core/image/bmp/bmp.odin b/core/image/bmp/bmp.odin index 64fc1d5a8..a50ad8996 100644 --- a/core/image/bmp/bmp.odin +++ b/core/image/bmp/bmp.odin @@ -71,7 +71,7 @@ save_to_buffer :: proc(output: ^bytes.Buffer, img: ^Image, options := Options{} written := 0 if resize(&output.buf, int(header.size)) != nil { - return .Unable_To_Allocate_Or_Resize + return .Unable_To_Allocate_Or_Resize } header_bytes := transmute([size_of(image.BMP_Header)]u8)header @@ -131,7 +131,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() if .info in options { - options |= {.return_metadata, .do_not_decompress_image} + options += {.return_metadata, .do_not_decompress_image} options -= {.info} } @@ -735,7 +735,7 @@ destroy :: proc(img: ^Image) { bytes.buffer_destroy(&img.pixels) if v, ok := img.metadata.(^image.BMP_Info); ok { - free(v) + free(v) } free(img) } diff --git a/core/image/common.odin b/core/image/common.odin index fed2c1470..07152e7db 100644 --- a/core/image/common.odin +++ b/core/image/common.odin @@ -1313,55 +1313,55 @@ expand_grayscale :: proc(img: ^Image, allocator := context.allocator) -> (ok: bo } switch img.depth { - case 8: - switch img.channels { - case 1: // Turn Gray into RGB - out := mem.slice_data_cast([]RGB_Pixel, buf.buf[:]) + case 8: + switch img.channels { + case 1: // Turn Gray into RGB + out := mem.slice_data_cast([]RGB_Pixel, buf.buf[:]) - for p in img.pixels.buf { - out[0] = p // Broadcast gray value into RGB components. - out = out[1:] - } - - case 2: // Turn Gray + Alpha into RGBA - inp := mem.slice_data_cast([]GA_Pixel, img.pixels.buf[:]) - out := mem.slice_data_cast([]RGBA_Pixel, buf.buf[:]) - - for p in inp { - out[0].rgb = p.r // Gray component. - out[0].a = p.g // Alpha component. - } - - case: - unreachable() + for p in img.pixels.buf { + out[0] = p // Broadcast gray value into RGB components. + out = out[1:] } - case 16: - switch img.channels { - case 1: // Turn Gray into RGB - inp := mem.slice_data_cast([]u16, img.pixels.buf[:]) - out := mem.slice_data_cast([]RGB_Pixel_16, buf.buf[:]) + case 2: // Turn Gray + Alpha into RGBA + inp := mem.slice_data_cast([]GA_Pixel, img.pixels.buf[:]) + out := mem.slice_data_cast([]RGBA_Pixel, buf.buf[:]) - for p in inp { - out[0] = p // Broadcast gray value into RGB components. - out = out[1:] - } - - case 2: // Turn Gray + Alpha into RGBA - inp := mem.slice_data_cast([]GA_Pixel_16, img.pixels.buf[:]) - out := mem.slice_data_cast([]RGBA_Pixel_16, buf.buf[:]) - - for p in inp { - out[0].rgb = p.r // Gray component. - out[0].a = p.g // Alpha component. - } - - case: - unreachable() + for p in inp { + out[0].rgb = p.r // Gray component. + out[0].a = p.g // Alpha component. } case: unreachable() + } + + case 16: + switch img.channels { + case 1: // Turn Gray into RGB + inp := mem.slice_data_cast([]u16, img.pixels.buf[:]) + out := mem.slice_data_cast([]RGB_Pixel_16, buf.buf[:]) + + for p in inp { + out[0] = p // Broadcast gray value into RGB components. + out = out[1:] + } + + case 2: // Turn Gray + Alpha into RGBA + inp := mem.slice_data_cast([]GA_Pixel_16, img.pixels.buf[:]) + out := mem.slice_data_cast([]RGBA_Pixel_16, buf.buf[:]) + + for p in inp { + out[0].rgb = p.r // Gray component. + out[0].a = p.g // Alpha component. + } + + case: + unreachable() + } + + case: + unreachable() } diff --git a/core/image/png/png.odin b/core/image/png/png.odin index aa1c5f781..177269722 100644 --- a/core/image/png/png.odin +++ b/core/image/png/png.odin @@ -341,7 +341,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a options := options if .info in options { - options |= {.return_metadata, .do_not_decompress_image} + options += {.return_metadata, .do_not_decompress_image} options -= {.info} } @@ -354,7 +354,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a } if .do_not_expand_channels in options { - options |= {.do_not_expand_grayscale, .do_not_expand_indexed} + options += {.do_not_expand_grayscale, .do_not_expand_indexed} } if img == nil { @@ -535,28 +535,28 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a ct := transmute(u8)info.header.color_type switch ct { - case 3: // Indexed color - if c.header.length != 1 { - return {}, .BKGD_Invalid_Length - } - col := _plte.entries[c.data[0]] - img.background = [3]u16{ - u16(col[0]) << 8 | u16(col[0]), - u16(col[1]) << 8 | u16(col[1]), - u16(col[2]) << 8 | u16(col[2]), - } - case 0, 4: // Grayscale, with and without Alpha - if c.header.length != 2 { - return {}, .BKGD_Invalid_Length - } - col := u16(mem.slice_data_cast([]u16be, c.data[:])[0]) - img.background = [3]u16{col, col, col} - case 2, 6: // Color, with and without Alpha - if c.header.length != 6 { - return {}, .BKGD_Invalid_Length - } - col := mem.slice_data_cast([]u16be, c.data[:]) - img.background = [3]u16{u16(col[0]), u16(col[1]), u16(col[2])} + case 3: // Indexed color + if c.header.length != 1 { + return {}, .BKGD_Invalid_Length + } + col := _plte.entries[c.data[0]] + img.background = [3]u16{ + u16(col[0]) << 8 | u16(col[0]), + u16(col[1]) << 8 | u16(col[1]), + u16(col[2]) << 8 | u16(col[2]), + } + case 0, 4: // Grayscale, with and without Alpha + if c.header.length != 2 { + return {}, .BKGD_Invalid_Length + } + col := u16(mem.slice_data_cast([]u16be, c.data[:])[0]) + img.background = [3]u16{col, col, col} + case 2, 6: // Color, with and without Alpha + if c.header.length != 6 { + return {}, .BKGD_Invalid_Length + } + col := mem.slice_data_cast([]u16be, c.data[:]) + img.background = [3]u16{u16(col[0]), u16(col[1]), u16(col[2])} } case .tRNS: diff --git a/core/image/qoi/qoi.odin b/core/image/qoi/qoi.odin index 061943f68..989e7ca6e 100644 --- a/core/image/qoi/qoi.odin +++ b/core/image/qoi/qoi.odin @@ -139,15 +139,13 @@ save_to_buffer :: proc(output: ^bytes.Buffer, img: ^Image, options := Options{} } else { // Write RGB literal output.buf[written] = u8(QOI_Opcode_Tag.RGB) - pix_bytes := transmute([4]u8)pix - copy(output.buf[written + 1:], pix_bytes[:3]) + copy(output.buf[written + 1:], pix[:3]) written += 4 } } else { // Write RGBA literal output.buf[written] = u8(QOI_Opcode_Tag.RGBA) - pix_bytes := transmute([4]u8)pix - copy(output.buf[written + 1:], pix_bytes[:]) + copy(output.buf[written + 1:], pix[:]) written += 5 } } @@ -178,7 +176,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a options := options if .info in options { - options |= {.return_metadata, .do_not_decompress_image} + options += {.return_metadata, .do_not_decompress_image} options -= {.info} } @@ -232,7 +230,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a bytes_needed := image.compute_buffer_size(int(header.width), int(header.height), img.channels, 8) if resize(&img.pixels.buf, bytes_needed) != nil { - return img, .Unable_To_Allocate_Or_Resize + return img, .Unable_To_Allocate_Or_Resize } /* @@ -343,7 +341,7 @@ destroy :: proc(img: ^Image) { bytes.buffer_destroy(&img.pixels) if v, ok := img.metadata.(^image.QOI_Info); ok { - free(v) + free(v) } free(img) } diff --git a/core/image/tga/tga.odin b/core/image/tga/tga.odin index 03ef1a386..46e37a0cf 100644 --- a/core/image/tga/tga.odin +++ b/core/image/tga/tga.odin @@ -100,7 +100,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a } if .info in options { - options |= {.return_metadata, .do_not_decompress_image} + options += {.return_metadata, .do_not_decompress_image} options -= {.info} } diff --git a/core/math/big/private.odin b/core/math/big/private.odin index 2ee6cfafa..bb6b9497c 100644 --- a/core/math/big/private.odin +++ b/core/math/big/private.odin @@ -787,8 +787,8 @@ _private_int_sqr_comba :: proc(dest, src: ^Int, allocator := context.allocator) /* Karatsuba squaring, computes `dest` = `src` * `src` using three half-size squarings. - See comments of `_private_int_mul_karatsuba` for details. - It is essentially the same algorithm but merely tuned to perform recursive squarings. + See comments of `_private_int_mul_karatsuba` for details. + It is essentially the same algorithm but merely tuned to perform recursive squarings. */ _private_int_sqr_karatsuba :: proc(dest, src: ^Int, allocator := context.allocator) -> (err: Error) { context.allocator = allocator @@ -967,7 +967,7 @@ _private_int_div_3 :: proc(quotient, numerator: ^Int, allocator := context.alloc /* b = 2^_DIGIT_BITS / 3 */ - b := _WORD(1) << _WORD(_DIGIT_BITS) / _WORD(3) + b := _WORD(1) << _WORD(_DIGIT_BITS) / _WORD(3) q := &Int{} internal_grow(q, numerator.used) or_return @@ -975,7 +975,7 @@ _private_int_div_3 :: proc(quotient, numerator: ^Int, allocator := context.alloc q.sign = numerator.sign w, t: _WORD - #no_bounds_check for ix := numerator.used; ix >= 0; ix -= 1 { + #no_bounds_check for ix := numerator.used - 1; ix >= 0; ix -= 1 { w = (w << _WORD(_DIGIT_BITS)) | _WORD(numerator.digit[ix]) if w >= 3 { /* @@ -1007,8 +1007,8 @@ _private_int_div_3 :: proc(quotient, numerator: ^Int, allocator := context.alloc */ if quotient != nil { err = clamp(q) - internal_swap(q, quotient) - } + internal_swap(q, quotient) + } internal_destroy(q) return remainder, nil } @@ -1555,24 +1555,24 @@ _private_int_gcd_lcm :: proc(res_gcd, res_lcm, a, b: ^Int, allocator := context. /* If neither `a` or `b` was zero, we need to compute `gcd`. - Get copies of `a` and `b` we can modify. - */ + Get copies of `a` and `b` we can modify. + */ u, v := &Int{}, &Int{} defer internal_destroy(u, v) internal_copy(u, a) or_return internal_copy(v, b) or_return - /* - Must be positive for the remainder of the algorithm. - */ + /* + Must be positive for the remainder of the algorithm. + */ u.sign = .Zero_or_Positive; v.sign = .Zero_or_Positive - /* - B1. Find the common power of two for `u` and `v`. - */ - u_lsb, _ := internal_count_lsb(u) - v_lsb, _ := internal_count_lsb(v) - k := min(u_lsb, v_lsb) + /* + B1. Find the common power of two for `u` and `v`. + */ + u_lsb, _ := internal_count_lsb(u) + v_lsb, _ := internal_count_lsb(v) + k := min(u_lsb, v_lsb) if k > 0 { /* @@ -1615,11 +1615,11 @@ _private_int_gcd_lcm :: proc(res_gcd, res_lcm, a, b: ^Int, allocator := context. internal_shr(v, v, b) or_return } - /* - Multiply by 2**k which we divided out at the beginning. - */ - internal_shl(temp_gcd_res, u, k) or_return - temp_gcd_res.sign = .Zero_or_Positive + /* + Multiply by 2**k which we divided out at the beginning. + */ + internal_shl(temp_gcd_res, u, k) or_return + temp_gcd_res.sign = .Zero_or_Positive /* We've computed `gcd`, either the long way, or because one of the inputs was zero. @@ -1786,8 +1786,8 @@ _private_montgomery_reduce_comba :: proc(x, n: ^Int, rho: DIGIT, allocator := co `a = a + mu * m * b**i` This is computed in place and on the fly. The multiplication - by b**i is handled by offseting which columns the results - are added to. + by b**i is handled by offseting which columns the results + are added to. Note the comba method normally doesn't handle carries in the inner loop In this case we fix the carry from the previous diff --git a/core/math/linalg/general.odin b/core/math/linalg/general.odin index 37c0447cb..90fe7332c 100644 --- a/core/math/linalg/general.odin +++ b/core/math/linalg/general.odin @@ -3,7 +3,7 @@ package linalg import "core:math" import "base:builtin" import "base:intrinsics" -import "base:runtime" +@require import "base:runtime" // Generic diff --git a/core/math/noise/internal.odin b/core/math/noise/internal.odin index 5837f9235..b83c4f1b1 100644 --- a/core/math/noise/internal.odin +++ b/core/math/noise/internal.odin @@ -637,22 +637,20 @@ _internal_noise_4d_unskewed_base :: proc(seed: i64, coord: Vec4) -> (value: f32) // Next point is the closest vertex on the 4-simplex whose base vertex is the aforementioned vertex. score := 1.0 + ssi * (-1.0 / UNSKEW_4D) // Seems slightly faster than 1.0-xsi-ysi-zsi-wsi - if si.x >= si.x && si.x >= si.z && si.x >= si.w && si.x >= score { + switch { + case si.x >= si.x && si.x >= si.z && si.x >= si.w && si.x >= score: svp.x += PRIME_X si.x -= 1 ssi -= UNSKEW_4D - } - else if si.y > si.x && si.y >= si.z && si.y >= si.w && si.y >= score { + case si.y > si.x && si.y >= si.z && si.y >= si.w && si.y >= score: svp.y += PRIME_Y si.y -= 1 ssi -= UNSKEW_4D - } - else if si.z > si.x && si.z > si.y && si.z >= si.w && si.z >= score { + case si.z > si.x && si.z > si.y && si.z >= si.w && si.z >= score: svp.z += PRIME_Z si.z -= 1 ssi -= UNSKEW_4D - } - else if si.w > si.x && si.w > si.y && si.w > si.z && si.w >= score { + case si.w > si.x && si.w > si.y && si.w > si.z && si.w >= score: svp.w += PRIME_W si.w -= 1 ssi -= UNSKEW_4D diff --git a/core/math/rand/rand.odin b/core/math/rand/rand.odin index 8e3c0264d..2b7b55096 100644 --- a/core/math/rand/rand.odin +++ b/core/math/rand/rand.odin @@ -655,7 +655,7 @@ choice_enum :: proc($T: typeid) -> T where intrinsics.type_is_enum(T), size_of(T) <= 8, - len(T) == cap(T) /* Only allow contiguous enum types */ + len(T) == cap(T) /* Only allow contiguous enum types */ \ { when intrinsics.type_is_unsigned(intrinsics.type_core_type(T)) && u64(max(T)) > u64(max(i64)) { diff --git a/core/mem/tlsf/tlsf.odin b/core/mem/tlsf/tlsf.odin index 76ecbb4b1..8ec5f52b7 100644 --- a/core/mem/tlsf/tlsf.odin +++ b/core/mem/tlsf/tlsf.odin @@ -97,6 +97,10 @@ init :: proc{init_from_buffer, init_from_allocator} destroy :: proc(control: ^Allocator) { if control == nil { return } + if control.pool.allocator.procedure != nil { + runtime.delete(control.pool.data, control.pool.allocator) + } + // No need to call `pool_remove` or anything, as they're they're embedded in the backing memory. // We do however need to free the `Pool` tracking entities and the backing memory itself. // As `Allocator` is embedded in the first backing slice, the `control` pointer will be @@ -132,8 +136,9 @@ allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mode, return nil, nil case .Free_All: - clear(control) - return nil, nil + // NOTE: this doesn't work right at the moment, Jeroen has it on his to-do list :) + // clear(control) + return nil, .Mode_Not_Implemented case .Resize: return resize(control, old_memory, uint(old_size), uint(size), uint(alignment)) @@ -144,7 +149,7 @@ allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mode, case .Query_Features: set := (^runtime.Allocator_Mode_Set)(old_memory) if set != nil { - set^ = {.Alloc, .Alloc_Non_Zeroed, .Free, .Free_All, .Resize, .Resize_Non_Zeroed, .Query_Features} + set^ = {.Alloc, .Alloc_Non_Zeroed, .Free, /* .Free_All, */ .Resize, .Resize_Non_Zeroed, .Query_Features} } return nil, nil @@ -153,4 +158,4 @@ allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mode, } return nil, nil -} \ No newline at end of file +} diff --git a/core/mem/tlsf/tlsf_internal.odin b/core/mem/tlsf/tlsf_internal.odin index 6f33e516c..1c7c326eb 100644 --- a/core/mem/tlsf/tlsf_internal.odin +++ b/core/mem/tlsf/tlsf_internal.odin @@ -214,7 +214,7 @@ block_next :: proc(block: ^Block_Header) -> (next: ^Block_Header) { block_link_next :: proc(block: ^Block_Header) -> (next: ^Block_Header) { next = block_next(block) next.prev_phys_block = block - return + return } block_mark_as_free :: proc(block: ^Block_Header) { @@ -630,7 +630,7 @@ alloc_bytes_non_zeroed :: proc(control: ^Allocator, size: uint, align: uint) -> @(require_results) alloc_bytes :: proc(control: ^Allocator, size: uint, align: uint) -> (res: []byte, err: runtime.Allocator_Error) { res, err = alloc_bytes_non_zeroed(control, size, align) - if err != nil { + if err == nil { intrinsics.mem_zero(raw_data(res), len(res)) } return @@ -735,4 +735,4 @@ resize_non_zeroed :: proc(control: ^Allocator, ptr: rawptr, old_size, new_size: block_trim_used(control, block, adjust) res = ([^]byte)(ptr)[:new_size] return -} \ No newline at end of file +} diff --git a/core/mem/virtual/virtual_linux.odin b/core/mem/virtual/virtual_linux.odin index 816a8bb84..0b4532baa 100644 --- a/core/mem/virtual/virtual_linux.odin +++ b/core/mem/virtual/virtual_linux.odin @@ -36,9 +36,9 @@ _release :: proc "contextless" (data: rawptr, size: uint) { _protect :: proc "contextless" (data: rawptr, size: uint, flags: Protect_Flags) -> bool { pflags: linux.Mem_Protection pflags = {} - if .Read in flags { pflags |= {.READ} } - if .Write in flags { pflags |= {.WRITE} } - if .Execute in flags { pflags |= {.EXEC} } + if .Read in flags { pflags += {.READ} } + if .Write in flags { pflags += {.WRITE} } + if .Execute in flags { pflags += {.EXEC} } errno := linux.mprotect(data, size, pflags) return errno == .NONE } diff --git a/core/net/addr.odin b/core/net/addr.odin index c01724d99..eed3fb3b9 100644 --- a/core/net/addr.odin +++ b/core/net/addr.odin @@ -370,7 +370,7 @@ parse_ip6_address :: proc(address_and_maybe_port: string) -> (addr: IP6_Address, val |= u16(ipv4[3]) piece_values[7] = u16be(val) } - return transmute(IP6_Address)piece_values, true + return IP6_Address(piece_values), true } /* @@ -522,10 +522,9 @@ address_to_string :: proc(addr: Address, allocator := context.temp_allocator) -> run := Zero_Run{-1, -1} best := Zero_Run{-1, -1} - addr := transmute([8]u16be)v last := u16be(1) - for val, i in addr { + for val, i in v { /* If we encounter adjacent zeroes, then start a new run if not already in one. Also remember the rightmost index regardless, because it'll be the new @@ -559,7 +558,7 @@ address_to_string :: proc(addr: Address, allocator := context.temp_allocator) -> last = val } - for val, i in addr { + for val, i in v { if best.start == i || best.end == i { // For the left and right side of the best zero run, print a `:`. fmt.sbprint(&b, ":") diff --git a/core/net/errors_windows.odin b/core/net/errors_windows.odin index 0538c2b82..f63f17f4e 100644 --- a/core/net/errors_windows.odin +++ b/core/net/errors_windows.odin @@ -135,6 +135,7 @@ TCP_Send_Error :: enum c.int { No_Buffer_Space_Available = win.WSAENOBUFS, Network_Subsystem_Failure = win.WSAENETDOWN, Host_Unreachable = win.WSAEHOSTUNREACH, + Would_Block = win.WSAEWOULDBLOCK, // TODO: verify possible, as not mentioned in docs Offline = win.WSAENETUNREACH, diff --git a/core/net/interface_darwin.odin b/core/net/interface_darwin.odin index 59b0e01c5..e2a9a73ca 100644 --- a/core/net/interface_darwin.odin +++ b/core/net/interface_darwin.odin @@ -59,24 +59,21 @@ _enumerate_interfaces :: proc(allocator := context.allocator) -> (interfaces: [] switch int(ifaddr.address.family) { case os.AF_INET, os.AF_INET6: address = _sockaddr_basic_to_endpoint(ifaddr.address).address - case: } } if ifaddr.netmask != nil { switch int(ifaddr.netmask.family) { case os.AF_INET, os.AF_INET6: - netmask = Netmask(_sockaddr_basic_to_endpoint(ifaddr.netmask).address) - case: + netmask = Netmask(_sockaddr_basic_to_endpoint(ifaddr.netmask).address) } } if ifaddr.broadcast_or_dest != nil && .BROADCAST in ifaddr.flags { switch int(ifaddr.broadcast_or_dest.family) { case os.AF_INET, os.AF_INET6: - broadcast := _sockaddr_basic_to_endpoint(ifaddr.broadcast_or_dest).address - append(&iface.multicast, broadcast) - case: + broadcast := _sockaddr_basic_to_endpoint(ifaddr.broadcast_or_dest).address + append(&iface.multicast, broadcast) } } @@ -91,19 +88,19 @@ _enumerate_interfaces :: proc(allocator := context.allocator) -> (interfaces: [] /* TODO: Refine this based on the type of adapter. */ - state := Link_State{} + state := Link_State{} - if .UP in ifaddr.flags { - state |= {.Up} - } + if .UP in ifaddr.flags { + state += {.Up} + } - /*if .DORMANT in ifaddr.flags { - state |= {.Dormant} - }*/ + /*if .DORMANT in ifaddr.flags { + state |= {.Dormant} + }*/ - if .LOOPBACK in ifaddr.flags { - state |= {.Loopback} - } + if .LOOPBACK in ifaddr.flags { + state += {.Loopback} + } iface.link.state = state } diff --git a/core/net/interface_windows.odin b/core/net/interface_windows.odin index f8bac253a..b9abcff48 100644 --- a/core/net/interface_windows.odin +++ b/core/net/interface_windows.odin @@ -24,42 +24,42 @@ import strings "core:strings" _enumerate_interfaces :: proc(allocator := context.allocator) -> (interfaces: []Network_Interface, err: Network_Error) { context.allocator = allocator - buf: []u8 - defer delete(buf) + buf: []u8 + defer delete(buf) - buf_size: u32 - res: u32 + buf_size: u32 + res: u32 - gaa: for _ in 1..=MAX_INTERFACE_ENUMERATION_TRIES { - res = sys.get_adapters_addresses( - .Unspecified, // Return both IPv4 and IPv6 adapters. + gaa: for _ in 1..=MAX_INTERFACE_ENUMERATION_TRIES { + res = sys.get_adapters_addresses( + .Unspecified, // Return both IPv4 and IPv6 adapters. sys.GAA_Flags{ .Include_Prefix, // (XP SP1+) Return a list of IP address prefixes on this adapter. When this flag is set, IP address prefixes are returned for both IPv6 and IPv4 addresses. .Include_Gateways, // (Vista+) Return the addresses of default gateways. .Include_Tunnel_Binding_Order, // (Vista+) Return the adapter addresses sorted in tunnel binding order. }, - nil, // Reserved - (^sys.IP_Adapter_Addresses)(raw_data(buf)), - &buf_size, - ) + nil, // Reserved + (^sys.IP_Adapter_Addresses)(raw_data(buf)), + &buf_size, + ) - switch res { - case 111: // ERROR_BUFFER_OVERFLOW: - delete(buf) - buf = make([]u8, buf_size) - case 0: - break gaa - case: - return {}, Platform_Error(res) - } - } + switch res { + case 111: // ERROR_BUFFER_OVERFLOW: + delete(buf) + buf = make([]u8, buf_size) + case 0: + break gaa + case: + return {}, Platform_Error(res) + } + } - if res != 0 { - return {}, .Unable_To_Enumerate_Network_Interfaces - } + if res != 0 { + return {}, .Unable_To_Enumerate_Network_Interfaces + } - _interfaces := make([dynamic]Network_Interface, 0, allocator) - for adapter := (^sys.IP_Adapter_Addresses)(raw_data(buf)); adapter != nil; adapter = adapter.Next { + _interfaces := make([dynamic]Network_Interface, 0, allocator) + for adapter := (^sys.IP_Adapter_Addresses)(raw_data(buf)); adapter != nil; adapter = adapter.Next { friendly_name, err1 := sys.wstring_to_utf8(sys.wstring(adapter.FriendlyName), 256, allocator) if err1 != nil { return {}, Platform_Error(err1) } @@ -71,74 +71,74 @@ _enumerate_interfaces :: proc(allocator := context.allocator) -> (interfaces: [] interface := Network_Interface{ adapter_name = strings.clone(string(adapter.AdapterName)), - friendly_name = friendly_name, - description = description, - dns_suffix = dns_suffix, + friendly_name = friendly_name, + description = description, + dns_suffix = dns_suffix, - mtu = adapter.MTU, + mtu = adapter.MTU, - link = { + link = { transmit_speed = adapter.TransmitLinkSpeed, receive_speed = adapter.ReceiveLinkSpeed, - }, - } + }, + } - if adapter.PhysicalAddressLength > 0 && adapter.PhysicalAddressLength <= len(adapter.PhysicalAddress) { - interface.physical_address = physical_address_to_string(adapter.PhysicalAddress[:adapter.PhysicalAddressLength]) - } + if adapter.PhysicalAddressLength > 0 && adapter.PhysicalAddressLength <= len(adapter.PhysicalAddress) { + interface.physical_address = physical_address_to_string(adapter.PhysicalAddress[:adapter.PhysicalAddressLength]) + } - for u_addr := (^sys.IP_ADAPTER_UNICAST_ADDRESS_LH)(adapter.FirstUnicastAddress); u_addr != nil; u_addr = u_addr.Next { - win_addr := parse_socket_address(u_addr.Address) + for u_addr := (^sys.IP_ADAPTER_UNICAST_ADDRESS_LH)(adapter.FirstUnicastAddress); u_addr != nil; u_addr = u_addr.Next { + win_addr := parse_socket_address(u_addr.Address) - lease := Lease{ - address = win_addr.address, - origin = { - prefix = Prefix_Origin(u_addr.PrefixOrigin), - suffix = Suffix_Origin(u_addr.SuffixOrigin), - }, - lifetime = { - valid = u_addr.ValidLifetime, - preferred = u_addr.PreferredLifetime, - lease = u_addr.LeaseLifetime, - }, - address_duplication = Address_Duplication(u_addr.DadState), - } - append(&interface.unicast, lease) - } + lease := Lease{ + address = win_addr.address, + origin = { + prefix = Prefix_Origin(u_addr.PrefixOrigin), + suffix = Suffix_Origin(u_addr.SuffixOrigin), + }, + lifetime = { + valid = u_addr.ValidLifetime, + preferred = u_addr.PreferredLifetime, + lease = u_addr.LeaseLifetime, + }, + address_duplication = Address_Duplication(u_addr.DadState), + } + append(&interface.unicast, lease) + } - for a_addr := (^sys.IP_ADAPTER_ANYCAST_ADDRESS_XP)(adapter.FirstAnycastAddress); a_addr != nil; a_addr = a_addr.Next { - addr := parse_socket_address(a_addr.Address) - append(&interface.anycast, addr.address) - } + for a_addr := (^sys.IP_ADAPTER_ANYCAST_ADDRESS_XP)(adapter.FirstAnycastAddress); a_addr != nil; a_addr = a_addr.Next { + addr := parse_socket_address(a_addr.Address) + append(&interface.anycast, addr.address) + } - for m_addr := (^sys.IP_ADAPTER_MULTICAST_ADDRESS_XP)(adapter.FirstMulticastAddress); m_addr != nil; m_addr = m_addr.Next { - addr := parse_socket_address(m_addr.Address) - append(&interface.multicast, addr.address) - } + for m_addr := (^sys.IP_ADAPTER_MULTICAST_ADDRESS_XP)(adapter.FirstMulticastAddress); m_addr != nil; m_addr = m_addr.Next { + addr := parse_socket_address(m_addr.Address) + append(&interface.multicast, addr.address) + } - for g_addr := (^sys.IP_ADAPTER_GATEWAY_ADDRESS_LH)(adapter.FirstGatewayAddress); g_addr != nil; g_addr = g_addr.Next { - addr := parse_socket_address(g_addr.Address) - append(&interface.gateways, addr.address) - } + for g_addr := (^sys.IP_ADAPTER_GATEWAY_ADDRESS_LH)(adapter.FirstGatewayAddress); g_addr != nil; g_addr = g_addr.Next { + addr := parse_socket_address(g_addr.Address) + append(&interface.gateways, addr.address) + } interface.dhcp_v4 = parse_socket_address(adapter.Dhcpv4Server).address interface.dhcp_v6 = parse_socket_address(adapter.Dhcpv6Server).address - switch adapter.OperStatus { - case .Up: interface.link.state = {.Up} - case .Down: interface.link.state = {.Down} - case .Testing: interface.link.state = {.Testing} - case .Dormant: interface.link.state = {.Dormant} - case .NotPresent: interface.link.state = {.Not_Present} - case .LowerLayerDown: interface.link.state = {.Lower_Layer_Down} - case .Unknown: fallthrough - case: interface.link.state = {} - } + switch adapter.OperStatus { + case .Up: interface.link.state = {.Up} + case .Down: interface.link.state = {.Down} + case .Testing: interface.link.state = {.Testing} + case .Dormant: interface.link.state = {.Dormant} + case .NotPresent: interface.link.state = {.Not_Present} + case .LowerLayerDown: interface.link.state = {.Lower_Layer_Down} + case .Unknown: fallthrough + case: interface.link.state = {} + } - interface.tunnel_type = Tunnel_Type(adapter.TunnelType) + interface.tunnel_type = Tunnel_Type(adapter.TunnelType) - append(&_interfaces, interface) - } + append(&_interfaces, interface) + } return _interfaces[:], {} } diff --git a/core/net/socket_darwin.odin b/core/net/socket_darwin.odin index ba86f1005..fc422b3a9 100644 --- a/core/net/socket_darwin.odin +++ b/core/net/socket_darwin.odin @@ -274,8 +274,7 @@ _set_option :: proc(s: Any_Socket, option: Socket_Option, value: any, loc := #ca .Linger, .Send_Timeout, .Receive_Timeout: - t, ok := value.(time.Duration) - if !ok do panic("set_option() value must be a time.Duration here", loc) + t := value.(time.Duration) or_else panic("set_option() value must be a time.Duration here", loc) micros := i64(time.duration_microseconds(t)) timeval_value.microseconds = int(micros % 1e6) @@ -320,7 +319,7 @@ _set_blocking :: proc(socket: Any_Socket, should_block: bool) -> (err: Network_E } if should_block { - flags &= ~int(os.O_NONBLOCK) + flags &~= int(os.O_NONBLOCK) } else { flags |= int(os.O_NONBLOCK) } diff --git a/core/net/socket_linux.odin b/core/net/socket_linux.odin index a4d75b92b..a5d553234 100644 --- a/core/net/socket_linux.odin +++ b/core/net/socket_linux.odin @@ -80,14 +80,14 @@ _unwrap_os_addr :: proc "contextless" (endpoint: Endpoint)->(linux.Sock_Addr_Any ipv4 = { sin_family = .INET, sin_port = u16be(endpoint.port), - sin_addr = transmute([4]u8) endpoint.address.(IP4_Address), + sin_addr = ([4]u8)(endpoint.address.(IP4_Address)), }, } case IP6_Address: return { ipv6 = { sin6_port = u16be(endpoint.port), - sin6_addr = transmute([16]u8) endpoint.address.(IP6_Address), + sin6_addr = transmute([16]u8)endpoint.address.(IP6_Address), sin6_family = .INET6, }, } @@ -377,9 +377,9 @@ _set_blocking :: proc(sock: Any_Socket, should_block: bool) -> (err: Network_Err return Set_Blocking_Error(errno) } if should_block { - flags &= ~{.NONBLOCK} + flags -= {.NONBLOCK} } else { - flags |= {.NONBLOCK} + flags += {.NONBLOCK} } errno = linux.fcntl(os_sock, linux.F_SETFL, flags) if errno != .NONE { diff --git a/core/net/socket_windows.odin b/core/net/socket_windows.odin index 3b9623749..eef0df583 100644 --- a/core/net/socket_windows.odin +++ b/core/net/socket_windows.odin @@ -263,12 +263,15 @@ _set_option :: proc(s: Any_Socket, option: Socket_Option, value: any, loc := #ca ptr = &bool_value len = size_of(bool_value) case .Linger: - t, ok := value.(time.Duration) - if !ok do panic("set_option() value must be a time.Duration here", loc) + t := value.(time.Duration) or_else panic("set_option() value must be a time.Duration here", loc) num_secs := i64(time.duration_seconds(t)) - if time.Duration(num_secs * 1e9) != t do return .Linger_Only_Supports_Whole_Seconds - if num_secs > i64(max(u16)) do return .Value_Out_Of_Range + if time.Duration(num_secs * 1e9) != t { + return .Linger_Only_Supports_Whole_Seconds + } + if num_secs > i64(max(u16)) { + return .Value_Out_Of_Range + } linger_value.l_onoff = 1 linger_value.l_linger = c.ushort(num_secs) @@ -277,8 +280,7 @@ _set_option :: proc(s: Any_Socket, option: Socket_Option, value: any, loc := #ca case .Receive_Timeout, .Send_Timeout: - t, ok := value.(time.Duration) - if !ok do panic("set_option() value must be a time.Duration here", loc) + t := value.(time.Duration) or_else panic("set_option() value must be a time.Duration here", loc) int_value = i32(time.duration_milliseconds(t)) ptr = &int_value diff --git a/core/odin/ast/ast.odin b/core/odin/ast/ast.odin index 229f03d3d..92d00b47c 100644 --- a/core/odin/ast/ast.odin +++ b/core/odin/ast/ast.odin @@ -513,6 +513,7 @@ Package_Decl :: struct { Import_Decl :: struct { using node: Decl, docs: ^Comment_Group, + attributes: [dynamic]^Attribute, // dynamic as parsing will add to them lazily is_using: bool, import_tok: tokenizer.Token, name: tokenizer.Token, diff --git a/core/odin/parser/parser.odin b/core/odin/parser/parser.odin index 6b0aa2888..dec892f84 100644 --- a/core/odin/parser/parser.odin +++ b/core/odin/parser/parser.odin @@ -308,7 +308,7 @@ consume_comment_group :: proc(p: ^Parser, n: int) -> (comments: ^ast.Comment_Gro end_line = p.curr_tok.pos.line for p.curr_tok.kind == .Comment && p.curr_tok.pos.line <= end_line+n { - comment: tokenizer.Token + comment: tokenizer.Token comment, end_line = consume_comment(p) append(&list, comment) } @@ -689,7 +689,12 @@ parse_when_stmt :: proc(p: ^Parser) -> ^ast.When_Stmt { prev_level := p.expr_level p.expr_level = -1 + prev_allow_in_expr := p.allow_in_expr + p.allow_in_expr = true + cond = parse_expr(p, false) + + p.allow_in_expr = prev_allow_in_expr p.expr_level = prev_level if cond == nil { @@ -1103,6 +1108,9 @@ parse_attribute :: proc(p: ^Parser, tok: tokenizer.Token, open_kind, close_kind: case ^ast.Foreign_Import_Decl: if d.docs == nil { d.docs = docs } append(&d.attributes, attribute) + case ^ast.Import_Decl: + if d.docs == nil { d.docs = docs } + append(&d.attributes, attribute) case: error(p, decl.pos, "expected a value or foreign declaration after an attribute") free(attribute) @@ -1307,8 +1315,8 @@ parse_stmt :: proc(p: ^Parser) -> ^ast.Stmt { // Unary Expressions .Add, .Sub, .Xor, .Not, .And: - s := parse_simple_stmt(p, {Stmt_Allow_Flag.Label}) - expect_semicolon(p, s) + s := parse_simple_stmt(p, {Stmt_Allow_Flag.Label}) + expect_semicolon(p, s) return s @@ -1845,7 +1853,7 @@ parse_ident_list :: proc(p: ^Parser, allow_poly_names: bool) -> []^ast.Expr { } if p.curr_tok.kind != .Comma || p.curr_tok.kind == .EOF { - break + break } advance_token(p) } @@ -2208,10 +2216,10 @@ parse_operand :: proc(p: ^Parser, lhs: bool) -> ^ast.Expr { case .Integer, .Float, .Imag, .Rune, .String: - tok := advance_token(p) - bl := ast.new(ast.Basic_Lit, tok.pos, end_pos(tok)) - bl.tok = tok - return bl + tok := advance_token(p) + bl := ast.new(ast.Basic_Lit, tok.pos, end_pos(tok)) + bl.tok = tok + return bl case .Open_Brace: if !lhs { @@ -2999,7 +3007,7 @@ parse_literal_value :: proc(p: ^Parser, type: ^ast.Expr) -> ^ast.Comp_Lit { } p.expr_level -= 1 - skip_possible_newline(p) + skip_possible_newline(p) close := expect_closing_brace_of_field_list(p) pos := type.pos if type != nil else open.pos diff --git a/core/os/os.odin b/core/os/os.odin index aa460fe01..51652a52b 100644 --- a/core/os/os.odin +++ b/core/os/os.odin @@ -111,7 +111,7 @@ read_entire_file_from_handle :: proc(fd: Handle, allocator := context.allocator, length: i64 err: Errno if length, err = file_size(fd); err != 0 { - return nil, false + return nil, false } if length <= 0 { @@ -120,7 +120,7 @@ read_entire_file_from_handle :: proc(fd: Handle, allocator := context.allocator, data = make([]byte, int(length), allocator, loc) if data == nil { - return nil, false + return nil, false } bytes_read, read_err := read_full(fd, data) diff --git a/core/os/os2/env_linux.odin b/core/os/os2/env_linux.odin index eb463f22c..99dd00d90 100644 --- a/core/os/os2/env_linux.odin +++ b/core/os/os2/env_linux.odin @@ -2,29 +2,230 @@ package os2 import "base:runtime" +import "base:intrinsics" + +import "core:sync" +import "core:slice" +import "core:strings" + +// TODO: IF NO_CRT: +// Override the libc environment functions' weak linkage to +// allow us to interact with 3rd party code that DOES link +// to libc. Otherwise, our environment can be out of sync. +// ELSE: +// Just use the libc. + +NOT_FOUND :: -1 + +// the environment is a 0 delimited list of = strings +_env: [dynamic]string + +_env_mutex: sync.Mutex + +// We need to be able to figure out if the environment variable +// is contained in the original environment or not. This also +// serves as a flag to determine if we have built _env. +_org_env_begin: uintptr +_org_env_end: uintptr + +// Returns value + index location into _env +// or -1 if not found +_lookup :: proc(key: string) -> (value: string, idx: int) { + sync.mutex_lock(&_env_mutex) + defer sync.mutex_unlock(&_env_mutex) + + for entry, i in _env { + if k, v := _kv_from_entry(entry); k == key { + return v, i + } + } + return "", -1 +} _lookup_env :: proc(key: string, allocator: runtime.Allocator) -> (value: string, found: bool) { - //TODO + if _org_env_begin == 0 { + _build_env() + } + + if v, idx := _lookup(key); idx != -1 { + found = true + value, _ = clone_string(v, allocator) + } return } -_set_env :: proc(key, value: string) -> bool { - //TODO - return false +_set_env :: proc(key, v_new: string) -> bool { + if _org_env_begin == 0 { + _build_env() + } + + // all key values are stored as "key=value\x00" + kv_size := len(key) + len(v_new) + 2 + if v_curr, idx := _lookup(key); idx != NOT_FOUND { + if v_curr == v_new { + return true + } + sync.mutex_lock(&_env_mutex) + defer sync.mutex_unlock(&_env_mutex) + + unordered_remove(&_env, idx) + + if !_is_in_org_env(v_curr) { + // We allocated this key-value. Possibly resize and + // overwrite the value only. Otherwise, treat as if it + // wasn't in the environment in the first place. + k_addr, v_addr := _kv_addr_from_val(v_curr, key) + if len(v_new) > len(v_curr) { + k_addr = ([^]u8)(heap_resize(k_addr, kv_size)) + if k_addr == nil { + return false + } + v_addr = &k_addr[len(key) + 1] + } + intrinsics.mem_copy_non_overlapping(v_addr, raw_data(v_new), len(v_new)) + v_addr[len(v_new)] = 0 + + append(&_env, string(k_addr[:kv_size])) + return true + } + } + + k_addr := ([^]u8)(heap_alloc(kv_size)) + if k_addr == nil { + return false + } + intrinsics.mem_copy_non_overlapping(k_addr, raw_data(key), len(key)) + k_addr[len(key)] = '=' + + val_slice := k_addr[len(key) + 1:] + intrinsics.mem_copy_non_overlapping(&val_slice[0], raw_data(v_new), len(v_new)) + val_slice[len(v_new)] = 0 + + sync.mutex_lock(&_env_mutex) + append(&_env, string(k_addr[:kv_size - 1])) + sync.mutex_unlock(&_env_mutex) + return true } _unset_env :: proc(key: string) -> bool { - //TODO - return false + if _org_env_begin == 0 { + _build_env() + } + + v: string + i: int + if v, i = _lookup(key); i == -1 { + return false + } + + sync.mutex_lock(&_env_mutex) + unordered_remove(&_env, i) + sync.mutex_unlock(&_env_mutex) + + if _is_in_org_env(v) { + return true + } + + // if we got this far, the envrionment variable + // existed AND was allocated by us. + k_addr, _ := _kv_addr_from_val(v, key) + heap_free(k_addr) + return true } _clear_env :: proc() { - //TODO + sync.mutex_lock(&_env_mutex) + defer sync.mutex_unlock(&_env_mutex) + + for kv in _env { + if !_is_in_org_env(kv) { + heap_free(raw_data(kv)) + } + } + clear(&_env) + + // nothing resides in the original environment either + _org_env_begin = ~uintptr(0) + _org_env_end = ~uintptr(0) } _environ :: proc(allocator: runtime.Allocator) -> []string { - //TODO - return nil + if _org_env_begin == 0 { + _build_env() + } + env := make([]string, len(_env), allocator) + + sync.mutex_lock(&_env_mutex) + defer sync.mutex_unlock(&_env_mutex) + for entry, i in _env { + env[i], _ = clone_string(entry, allocator) + } + return env } +// The entire environment is stored as 0 terminated strings, +// so there is no need to clone/free individual variables +export_cstring_environment :: proc(allocator: runtime.Allocator) -> []cstring { + if _org_env_begin == 0 { + // The environment has not been modified, so we can just + // send the original environment + org_env := _get_original_env() + n: int + for ; org_env[n] != nil; n += 1 {} + return slice.clone(org_env[:n + 1], allocator) + } + // NOTE: already terminated by nil pointer via + 1 + env := make([]cstring, len(_env) + 1, allocator) + + sync.mutex_lock(&_env_mutex) + defer sync.mutex_unlock(&_env_mutex) + for entry, i in _env { + env[i] = cstring(raw_data(entry)) + } + return env +} + +_build_env :: proc() { + sync.mutex_lock(&_env_mutex) + defer sync.mutex_unlock(&_env_mutex) + if _org_env_begin != 0 { + return + } + + _env = make(type_of(_env), heap_allocator()) + cstring_env := _get_original_env() + _org_env_begin = uintptr(rawptr(cstring_env[0])) + for i := 0; cstring_env[i] != nil; i += 1 { + bytes := ([^]u8)(cstring_env[i]) + n := len(cstring_env[i]) + _org_env_end = uintptr(&bytes[n]) + append(&_env, string(bytes[:n])) + } +} + +_get_original_env :: #force_inline proc() -> [^]cstring { + // essentially &argv[argc] which should be a nil pointer! + #no_bounds_check env: [^]cstring = &runtime.args__[len(runtime.args__)] + assert(env[0] == nil) + return &env[1] +} + +_kv_from_entry :: #force_inline proc(entry: string) -> (k, v: string) { + eq_idx := strings.index_byte(entry, '=') + if eq_idx == -1 { + return entry, "" + } + return entry[:eq_idx], entry[eq_idx + 1:] +} + +_kv_addr_from_val :: #force_inline proc(val: string, key: string) -> ([^]u8, [^]u8) { + v_addr := raw_data(val) + k_addr := ([^]u8)(&v_addr[-(len(key) + 1)]) + return k_addr, v_addr +} + +_is_in_org_env :: #force_inline proc(env_data: string) -> bool { + addr := uintptr(raw_data(env_data)) + return addr >= _org_env_begin && addr < _org_env_end +} diff --git a/core/os/os2/errors.odin b/core/os/os2/errors.odin index 2c570170d..51d8314b4 100644 --- a/core/os/os2/errors.odin +++ b/core/os/os2/errors.odin @@ -99,3 +99,19 @@ error_string :: proc(ferr: Error) -> string { return "unknown error" } + +print_error :: proc(f: ^File, ferr: Error, msg: string) { + TEMP_ALLOCATOR_GUARD() + err_str := error_string(ferr) + + // msg + ": " + err_str + '\n' + length := len(msg) + 2 + len(err_str) + 1 + buf := make([]u8, length, temp_allocator()) + + copy(buf, msg) + buf[len(msg)] = ':' + buf[len(msg) + 1] = ' ' + copy(buf[len(msg) + 2:], err_str) + buf[length - 1] = '\n' + write(f, buf) +} diff --git a/core/os/os2/errors_linux.odin b/core/os/os2/errors_linux.odin index 053256fbd..d7234ce8b 100644 --- a/core/os/os2/errors_linux.odin +++ b/core/os/os2/errors_linux.odin @@ -1,145 +1,165 @@ //+private package os2 -import "core:sys/unix" +import "core:sys/linux" -EPERM :: 1 -ENOENT :: 2 -ESRCH :: 3 -EINTR :: 4 -EIO :: 5 -ENXIO :: 6 -EBADF :: 9 -EAGAIN :: 11 -ENOMEM :: 12 -EACCES :: 13 -EFAULT :: 14 -EEXIST :: 17 -ENODEV :: 19 -ENOTDIR :: 20 -EISDIR :: 21 -EINVAL :: 22 -ENFILE :: 23 -EMFILE :: 24 -ETXTBSY :: 26 -EFBIG :: 27 -ENOSPC :: 28 -ESPIPE :: 29 -EROFS :: 30 -EPIPE :: 32 -ERANGE :: 34 /* Result too large */ -EDEADLK :: 35 /* Resource deadlock would occur */ -ENAMETOOLONG :: 36 /* File name too long */ -ENOLCK :: 37 /* No record locks available */ -ENOSYS :: 38 /* Invalid system call number */ -ENOTEMPTY :: 39 /* Directory not empty */ -ELOOP :: 40 /* Too many symbolic links encountered */ -EWOULDBLOCK :: EAGAIN /* Operation would block */ -ENOMSG :: 42 /* No message of desired type */ -EIDRM :: 43 /* Identifier removed */ -ECHRNG :: 44 /* Channel number out of range */ -EL2NSYNC :: 45 /* Level 2 not synchronized */ -EL3HLT :: 46 /* Level 3 halted */ -EL3RST :: 47 /* Level 3 reset */ -ELNRNG :: 48 /* Link number out of range */ -EUNATCH :: 49 /* Protocol driver not attached */ -ENOCSI :: 50 /* No CSI structure available */ -EL2HLT :: 51 /* Level 2 halted */ -EBADE :: 52 /* Invalid exchange */ -EBADR :: 53 /* Invalid request descriptor */ -EXFULL :: 54 /* Exchange full */ -ENOANO :: 55 /* No anode */ -EBADRQC :: 56 /* Invalid request code */ -EBADSLT :: 57 /* Invalid slot */ -EDEADLOCK :: EDEADLK -EBFONT :: 59 /* Bad font file format */ -ENOSTR :: 60 /* Device not a stream */ -ENODATA :: 61 /* No data available */ -ETIME :: 62 /* Timer expired */ -ENOSR :: 63 /* Out of streams resources */ -ENONET :: 64 /* Machine is not on the network */ -ENOPKG :: 65 /* Package not installed */ -EREMOTE :: 66 /* Object is remote */ -ENOLINK :: 67 /* Link has been severed */ -EADV :: 68 /* Advertise error */ -ESRMNT :: 69 /* Srmount error */ -ECOMM :: 70 /* Communication error on send */ -EPROTO :: 71 /* Protocol error */ -EMULTIHOP :: 72 /* Multihop attempted */ -EDOTDOT :: 73 /* RFS specific error */ -EBADMSG :: 74 /* Not a data message */ -EOVERFLOW :: 75 /* Value too large for defined data type */ -ENOTUNIQ :: 76 /* Name not unique on network */ -EBADFD :: 77 /* File descriptor in bad state */ -EREMCHG :: 78 /* Remote address changed */ -ELIBACC :: 79 /* Can not access a needed shared library */ -ELIBBAD :: 80 /* Accessing a corrupted shared library */ -ELIBSCN :: 81 /* .lib section in a.out corrupted */ -ELIBMAX :: 82 /* Attempting to link in too many shared libraries */ -ELIBEXEC :: 83 /* Cannot exec a shared library directly */ -EILSEQ :: 84 /* Illegal byte sequence */ -ERESTART :: 85 /* Interrupted system call should be restarted */ -ESTRPIPE :: 86 /* Streams pipe error */ -EUSERS :: 87 /* Too many users */ -ENOTSOCK :: 88 /* Socket operation on non-socket */ -EDESTADDRREQ :: 89 /* Destination address required */ -EMSGSIZE :: 90 /* Message too long */ -EPROTOTYPE :: 91 /* Protocol wrong type for socket */ -ENOPROTOOPT :: 92 /* Protocol not available */ -EPROTONOSUPPORT:: 93 /* Protocol not supported */ -ESOCKTNOSUPPORT:: 94 /* Socket type not supported */ -EOPNOTSUPP :: 95 /* Operation not supported on transport endpoint */ -EPFNOSUPPORT :: 96 /* Protocol family not supported */ -EAFNOSUPPORT :: 97 /* Address family not supported by protocol */ -EADDRINUSE :: 98 /* Address already in use */ -EADDRNOTAVAIL :: 99 /* Cannot assign requested address */ -ENETDOWN :: 100 /* Network is down */ -ENETUNREACH :: 101 /* Network is unreachable */ -ENETRESET :: 102 /* Network dropped connection because of reset */ -ECONNABORTED :: 103 /* Software caused connection abort */ -ECONNRESET :: 104 /* Connection reset by peer */ -ENOBUFS :: 105 /* No buffer space available */ -EISCONN :: 106 /* Transport endpoint is already connected */ -ENOTCONN :: 107 /* Transport endpoint is not connected */ -ESHUTDOWN :: 108 /* Cannot send after transport endpoint shutdown */ -ETOOMANYREFS :: 109 /* Too many references: cannot splice */ -ETIMEDOUT :: 110 /* Connection timed out */ -ECONNREFUSED :: 111 /* Connection refused */ -EHOSTDOWN :: 112 /* Host is down */ -EHOSTUNREACH :: 113 /* No route to host */ -EALREADY :: 114 /* Operation already in progress */ -EINPROGRESS :: 115 /* Operation now in progress */ -ESTALE :: 116 /* Stale file handle */ -EUCLEAN :: 117 /* Structure needs cleaning */ -ENOTNAM :: 118 /* Not a XENIX named type file */ -ENAVAIL :: 119 /* No XENIX semaphores available */ -EISNAM :: 120 /* Is a named type file */ -EREMOTEIO :: 121 /* Remote I/O error */ -EDQUOT :: 122 /* Quota exceeded */ -ENOMEDIUM :: 123 /* No medium found */ -EMEDIUMTYPE :: 124 /* Wrong medium type */ -ECANCELED :: 125 /* Operation Canceled */ -ENOKEY :: 126 /* Required key not available */ -EKEYEXPIRED :: 127 /* Key has expired */ -EKEYREVOKED :: 128 /* Key has been revoked */ -EKEYREJECTED :: 129 /* Key was rejected by service */ -EOWNERDEAD :: 130 /* Owner died */ -ENOTRECOVERABLE:: 131 /* State not recoverable */ -ERFKILL :: 132 /* Operation not possible due to RF-kill */ -EHWPOISON :: 133 /* Memory page has hardware error */ +@(rodata) +_errno_strings : [linux.Errno]string = { + .NONE = "Success", + .EPERM = "Operation not permitted", + .ENOENT = "No such file or directory", + .ESRCH = "No such process", + .EINTR = "Interrupted system call", + .EIO = "Input/output error", + .ENXIO = "No such device or address", + .E2BIG = "Argument list too long", + .ENOEXEC = "Exec format error", + .EBADF = "Bad file descriptor", + .ECHILD = "No child processes", + .EAGAIN = "Resource temporarily unavailable", + .ENOMEM = "Cannot allocate memory", + .EACCES = "Permission denied", + .EFAULT = "Bad address", + .ENOTBLK = "Block device required", + .EBUSY = "Device or resource busy", + .EEXIST = "File exists", + .EXDEV = "Invalid cross-device link", + .ENODEV = "No such device", + .ENOTDIR = "Not a directory", + .EISDIR = "Is a directory", + .EINVAL = "Invalid argument", + .ENFILE = "Too many open files in system", + .EMFILE = "Too many open files", + .ENOTTY = "Inappropriate ioctl for device", + .ETXTBSY = "Text file busy", + .EFBIG = "File too large", + .ENOSPC = "No space left on device", + .ESPIPE = "Illegal seek", + .EROFS = "Read-only file system", + .EMLINK = "Too many links", + .EPIPE = "Broken pipe", + .EDOM = "Numerical argument out of domain", + .ERANGE = "Numerical result out of range", + .EDEADLK = "Resource deadlock avoided", + .ENAMETOOLONG = "File name too long", + .ENOLCK = "No locks available", + .ENOSYS = "Function not implemented", + .ENOTEMPTY = "Directory not empty", + .ELOOP = "Too many levels of symbolic links", + .EUNKNOWN_41 = "Unknown Error (41)", + .ENOMSG = "No message of desired type", + .EIDRM = "Identifier removed", + .ECHRNG = "Channel number out of range", + .EL2NSYNC = "Level 2 not synchronized", + .EL3HLT = "Level 3 halted", + .EL3RST = "Level 3 reset", + .ELNRNG = "Link number out of range", + .EUNATCH = "Protocol driver not attached", + .ENOCSI = "No CSI structure available", + .EL2HLT = "Level 2 halted", + .EBADE = "Invalid exchange", + .EBADR = "Invalid request descriptor", + .EXFULL = "Exchange full", + .ENOANO = "No anode", + .EBADRQC = "Invalid request code", + .EBADSLT = "Invalid slot", + .EUNKNOWN_58 = "Unknown Error (58)", + .EBFONT = "Bad font file format", + .ENOSTR = "Device not a stream", + .ENODATA = "No data available", + .ETIME = "Timer expired", + .ENOSR = "Out of streams resources", + .ENONET = "Machine is not on the network", + .ENOPKG = "Package not installed", + .EREMOTE = "Object is remote", + .ENOLINK = "Link has been severed", + .EADV = "Advertise error", + .ESRMNT = "Srmount error", + .ECOMM = "Communication error on send", + .EPROTO = "Protocol error", + .EMULTIHOP = "Multihop attempted", + .EDOTDOT = "RFS specific error", + .EBADMSG = "Bad message", + .EOVERFLOW = "Value too large for defined data type", + .ENOTUNIQ = "Name not unique on network", + .EBADFD = "File descriptor in bad state", + .EREMCHG = "Remote address changed", + .ELIBACC = "Can not access a needed shared library", + .ELIBBAD = "Accessing a corrupted shared library", + .ELIBSCN = ".lib section in a.out corrupted", + .ELIBMAX = "Attempting to link in too many shared libraries", + .ELIBEXEC = "Cannot exec a shared library directly", + .EILSEQ = "Invalid or incomplete multibyte or wide character", + .ERESTART = "Interrupted system call should be restarted", + .ESTRPIPE = "Streams pipe error", + .EUSERS = "Too many users", + .ENOTSOCK = "Socket operation on non-socket", + .EDESTADDRREQ = "Destination address required", + .EMSGSIZE = "Message too long", + .EPROTOTYPE = "Protocol wrong type for socket", + .ENOPROTOOPT = "Protocol not available", + .EPROTONOSUPPORT = "Protocol not supported", + .ESOCKTNOSUPPORT = "Socket type not supported", + .EOPNOTSUPP = "Operation not supported", + .EPFNOSUPPORT = "Protocol family not supported", + .EAFNOSUPPORT = "Address family not supported by protocol", + .EADDRINUSE = "Address already in use", + .EADDRNOTAVAIL = "Cannot assign requested address", + .ENETDOWN = "Network is down", + .ENETUNREACH = "Network is unreachable", + .ENETRESET = "Network dropped connection on reset", + .ECONNABORTED = "Software caused connection abort", + .ECONNRESET = "Connection reset by peer", + .ENOBUFS = "No buffer space available", + .EISCONN = "Transport endpoint is already connected", + .ENOTCONN = "Transport endpoint is not connected", + .ESHUTDOWN = "Cannot send after transport endpoint shutdown", + .ETOOMANYREFS = "Too many references: cannot splice", + .ETIMEDOUT = "Connection timed out", + .ECONNREFUSED = "Connection refused", + .EHOSTDOWN = "Host is down", + .EHOSTUNREACH = "No route to host", + .EALREADY = "Operation already in progress", + .EINPROGRESS = "Operation now in progress", + .ESTALE = "Stale file handle", + .EUCLEAN = "Structure needs cleaning", + .ENOTNAM = "Not a XENIX named type file", + .ENAVAIL = "No XENIX semaphores available", + .EISNAM = "Is a named type file", + .EREMOTEIO = "Remote I/O error", + .EDQUOT = "Disk quota exceeded", + .ENOMEDIUM = "No medium found", + .EMEDIUMTYPE = "Wrong medium type", + .ECANCELED = "Operation canceled", + .ENOKEY = "Required key not available", + .EKEYEXPIRED = "Key has expired", + .EKEYREVOKED = "Key has been revoked", + .EKEYREJECTED = "Key was rejected by service", + .EOWNERDEAD = "Owner died", + .ENOTRECOVERABLE = "State not recoverable", + .ERFKILL = "Operation not possible due to RF-kill", + .EHWPOISON = "Memory page has hardware error", +} + + +_get_platform_error :: proc(errno: linux.Errno) -> Error { + #partial switch errno { + case .NONE: + return nil + case .EPERM: + return .Permission_Denied + case .EEXIST: + return .Exist + case .ENOENT: + return .Not_Exist + } -_get_platform_error :: proc(res: int) -> Error { - errno := unix.get_errno(res) return Platform_Error(i32(errno)) } -_ok_or_error :: proc(res: int) -> Error { - return res >= 0 ? nil : _get_platform_error(res) -} - _error_string :: proc(errno: i32) -> string { - if errno == 0 { - return "" + if errno >= 0 && errno <= i32(max(linux.Errno)) { + return _errno_strings[linux.Errno(errno)] } - return "Error" + return "Unknown Error" } diff --git a/core/os/os2/file.odin b/core/os/os2/file.odin index 4f4bd942e..236423163 100644 --- a/core/os/os2/file.odin +++ b/core/os/os2/file.odin @@ -45,13 +45,10 @@ O_TRUNC :: File_Flags{.Trunc} O_SPARSE :: File_Flags{.Sparse} O_CLOEXEC :: File_Flags{.Close_On_Exec} - - stdin: ^File = nil // OS-Specific stdout: ^File = nil // OS-Specific stderr: ^File = nil // OS-Specific - @(require_results) create :: proc(name: string) -> (^File, Error) { return open(name, {.Read, .Write, .Create}, File_Mode(0o777)) diff --git a/core/os/os2/file_linux.odin b/core/os/os2/file_linux.odin index 8f298be88..8e7db9751 100644 --- a/core/os/os2/file_linux.odin +++ b/core/os/os2/file_linux.odin @@ -1,39 +1,64 @@ //+private package os2 -import "base:runtime" import "core:io" import "core:time" -import "core:sys/unix" - -INVALID_HANDLE :: -1 - -_O_RDONLY :: 0o00000000 -_O_WRONLY :: 0o00000001 -_O_RDWR :: 0o00000002 -_O_CREAT :: 0o00000100 -_O_EXCL :: 0o00000200 -_O_NOCTTY :: 0o00000400 -_O_TRUNC :: 0o00001000 -_O_APPEND :: 0o00002000 -_O_NONBLOCK :: 0o00004000 -_O_LARGEFILE :: 0o00100000 -_O_DIRECTORY :: 0o00200000 -_O_NOFOLLOW :: 0o00400000 -_O_SYNC :: 0o04010000 -_O_CLOEXEC :: 0o02000000 -_O_PATH :: 0o10000000 - -_AT_FDCWD :: -100 - -_CSTRING_NAME_HEAP_THRESHOLD :: 512 +import "base:runtime" +import "core:sys/linux" _File :: struct { name: string, - fd: int, + fd: linux.Fd, allocator: runtime.Allocator, } +_stdin : File = { + impl = { + name = "/proc/self/fd/0", + fd = 0, + allocator = _file_allocator(), + }, + stream = { + procedure = _file_stream_proc, + }, +} +_stdout : File = { + impl = { + name = "/proc/self/fd/1", + fd = 1, + allocator = _file_allocator(), + }, + stream = { + procedure = _file_stream_proc, + }, +} +_stderr : File = { + impl = { + name = "/proc/self/fd/2", + fd = 2, + allocator = _file_allocator(), + }, + stream = { + procedure = _file_stream_proc, + }, +} + +@init +_standard_stream_init :: proc() { + // cannot define these manually because cyclic reference + _stdin.stream.data = &_stdin + _stdout.stream.data = &_stdout + _stderr.stream.data = &_stderr + + stdin = &_stdin + stdout = &_stdout + stderr = &_stderr +} + +_file_allocator :: proc() -> runtime.Allocator { + return heap_allocator() +} + _open :: proc(name: string, flags: File_Flags, perm: File_Mode) -> (f: ^File, err: Error) { TEMP_ALLOCATOR_GUARD() name_cstr := temp_cstring(name) or_return @@ -41,40 +66,48 @@ _open :: proc(name: string, flags: File_Flags, perm: File_Mode) -> (f: ^File, er // Just default to using O_NOCTTY because needing to open a controlling // terminal would be incredibly rare. This has no effect on files while // allowing us to open serial devices. - flags_i: int = _O_NOCTTY + sys_flags: linux.Open_Flags = {.NOCTTY} switch flags & O_RDONLY|O_WRONLY|O_RDWR { - case O_RDONLY: flags_i = _O_RDONLY - case O_WRONLY: flags_i = _O_WRONLY - case O_RDWR: flags_i = _O_RDWR + case O_RDONLY: + case O_WRONLY: sys_flags += {.WRONLY} + case O_RDWR: sys_flags += {.RDWR} } - if .Append in flags { flags_i |= _O_APPEND } - if .Create in flags { flags_i |= _O_CREAT } - if .Excl in flags { flags_i |= _O_EXCL } - if .Sync in flags { flags_i |= _O_SYNC } - if .Trunc in flags { flags_i |= _O_TRUNC } - if .Close_On_Exec in flags { flags_i |= _O_CLOEXEC } + if .Append in flags { sys_flags += {.APPEND} } + if .Create in flags { sys_flags += {.CREAT} } + if .Excl in flags { sys_flags += {.EXCL} } + if .Sync in flags { sys_flags += {.DSYNC} } + if .Trunc in flags { sys_flags += {.TRUNC} } + if .Close_On_Exec in flags { sys_flags += {.CLOEXEC} } - fd := unix.sys_open(name_cstr, flags_i, uint(perm)) - if fd < 0 { - return nil, _get_platform_error(fd) + fd, errno := linux.open(name_cstr, sys_flags, transmute(linux.Mode)(u32(perm))) + if errno != .NONE { + return nil, _get_platform_error(errno) } return _new_file(uintptr(fd), name), nil } -_new_file :: proc(fd: uintptr, _: string) -> ^File { +_new_file :: proc(fd: uintptr, _: string = "") -> ^File { file := new(File, file_allocator()) - file.impl.fd = int(fd) - file.impl.allocator = file_allocator() - file.impl.name = _get_full_path(file.impl.fd, file.impl.allocator) - file.stream = { - data = file, - procedure = _file_stream_proc, - } + _construct_file(file, fd, "") return file } +_construct_file :: proc(file: ^File, fd: uintptr, _: string = "") { + file^ = { + impl = { + fd = linux.Fd(fd), + allocator = file_allocator(), + name = _get_full_path(file.impl.fd, file.impl.allocator), + }, + stream = { + data = file, + procedure = _file_stream_proc, + }, + } +} + _destroy :: proc(f: ^File) -> Error { if f == nil { return nil @@ -86,12 +119,15 @@ _destroy :: proc(f: ^File) -> Error { _close :: proc(f: ^File) -> Error { - if f != nil { - res := unix.sys_close(f.impl.fd) - _destroy(f) - return _ok_or_error(res) + if f == nil { + return nil } - return nil + errno := linux.close(f.impl.fd) + if errno == .EBADF { // avoid possible double free + return _get_platform_error(errno) + } + _destroy(f) + return _get_platform_error(errno) } _fd :: proc(f: ^File) -> uintptr { @@ -106,20 +142,32 @@ _name :: proc(f: ^File) -> string { } _seek :: proc(f: ^File, offset: i64, whence: io.Seek_From) -> (ret: i64, err: Error) { - res := unix.sys_lseek(f.impl.fd, offset, int(whence)) - if res < 0 { - return -1, _get_platform_error(int(res)) + n, errno := linux.lseek(f.impl.fd, offset, linux.Seek_Whence(whence)) + if errno != .NONE { + return -1, _get_platform_error(errno) } - return res, nil + return n, nil } _read :: proc(f: ^File, p: []byte) -> (i64, Error) { if len(p) == 0 { return 0, nil } - n := unix.sys_read(f.impl.fd, &p[0], len(p)) - if n < 0 { - return -1, _get_platform_error(n) + n, errno := linux.read(f.impl.fd, p[:]) + if errno != .NONE { + return -1, _get_platform_error(errno) + } + return i64(n), n == 0 ? io.Error.EOF : nil +} + +_read_at :: proc(f: ^File, p: []byte, offset: i64) -> (i64, Error) { + if offset < 0 { + return 0, .Invalid_Offset + } + + n, errno := linux.pread(f.impl.fd, p[:], offset) + if errno != .NONE { + return -1, _get_platform_error(errno) } if n == 0 { return 0, .EOF @@ -127,91 +175,67 @@ _read :: proc(f: ^File, p: []byte) -> (i64, Error) { return i64(n), nil } -_read_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: i64, err: Error) { - if offset < 0 { - return 0, .Invalid_Offset - } - - b, offset := p, offset - for len(b) > 0 { - m := unix.sys_pread(f.impl.fd, &b[0], len(b), offset) - if m < 0 { - return -1, _get_platform_error(m) - } - if m == 0 { - return 0, .EOF - } - n += i64(m) - b = b[m:] - offset += i64(m) - } - return -} - _write :: proc(f: ^File, p: []byte) -> (i64, Error) { if len(p) == 0 { return 0, nil } - n := unix.sys_write(f.impl.fd, &p[0], uint(len(p))) - if n < 0 { - return -1, _get_platform_error(n) + n, errno := linux.write(f.impl.fd, p[:]) + if errno != .NONE { + return -1, _get_platform_error(errno) } return i64(n), nil } -_write_at :: proc(f: ^File, p: []byte, offset: i64) -> (n: i64, err: Error) { +_write_at :: proc(f: ^File, p: []byte, offset: i64) -> (i64, Error) { if offset < 0 { return 0, .Invalid_Offset } - b, offset := p, offset - for len(b) > 0 { - m := unix.sys_pwrite(f.impl.fd, &b[0], len(b), offset) - if m < 0 { - return -1, _get_platform_error(m) - } - n += i64(m) - b = b[m:] - offset += i64(m) + n, errno := linux.pwrite(f.impl.fd, p[:], offset) + if errno != .NONE { + return -1, _get_platform_error(errno) } - return + return i64(n), nil } _file_size :: proc(f: ^File) -> (n: i64, err: Error) { - s: _Stat = --- - res := unix.sys_fstat(f.impl.fd, &s) - if res < 0 { - return -1, _get_platform_error(res) + s: linux.Stat = --- + errno := linux.fstat(f.impl.fd, &s) + if errno != .NONE { + return -1, _get_platform_error(errno) } - return s.size, nil + return i64(s.size), nil } _sync :: proc(f: ^File) -> Error { - return _ok_or_error(unix.sys_fsync(f.impl.fd)) + return _get_platform_error(linux.fsync(f.impl.fd)) } _flush :: proc(f: ^File) -> Error { - return _ok_or_error(unix.sys_fsync(f.impl.fd)) + return _get_platform_error(linux.fsync(f.impl.fd)) } _truncate :: proc(f: ^File, size: i64) -> Error { - return _ok_or_error(unix.sys_ftruncate(f.impl.fd, size)) + return _get_platform_error(linux.ftruncate(f.impl.fd, size)) } _remove :: proc(name: string) -> Error { TEMP_ALLOCATOR_GUARD() name_cstr := temp_cstring(name) or_return - fd := unix.sys_open(name_cstr, int(File_Flags.Read)) - if fd < 0 { - return _get_platform_error(fd) + fd, errno := linux.open(name_cstr, {.NOFOLLOW}) + #partial switch (errno) { + case .ELOOP: /* symlink */ + case .NONE: + defer linux.close(fd) + if _is_dir_fd(fd) { + return _get_platform_error(linux.rmdir(name_cstr)) + } + case: + return _get_platform_error(errno) } - defer unix.sys_close(fd) - if _is_dir_fd(fd) { - return _ok_or_error(unix.sys_rmdir(name_cstr)) - } - return _ok_or_error(unix.sys_unlink(name_cstr)) + return _get_platform_error(linux.unlink(name_cstr)) } _rename :: proc(old_name, new_name: string) -> Error { @@ -219,7 +243,7 @@ _rename :: proc(old_name, new_name: string) -> Error { old_name_cstr := temp_cstring(old_name) or_return new_name_cstr := temp_cstring(new_name) or_return - return _ok_or_error(unix.sys_rename(old_name_cstr, new_name_cstr)) + return _get_platform_error(linux.rename(old_name_cstr, new_name_cstr)) } _link :: proc(old_name, new_name: string) -> Error { @@ -227,148 +251,194 @@ _link :: proc(old_name, new_name: string) -> Error { old_name_cstr := temp_cstring(old_name) or_return new_name_cstr := temp_cstring(new_name) or_return - return _ok_or_error(unix.sys_link(old_name_cstr, new_name_cstr)) + return _get_platform_error(linux.link(old_name_cstr, new_name_cstr)) } _symlink :: proc(old_name, new_name: string) -> Error { TEMP_ALLOCATOR_GUARD() old_name_cstr := temp_cstring(old_name) or_return new_name_cstr := temp_cstring(new_name) or_return - - return _ok_or_error(unix.sys_symlink(old_name_cstr, new_name_cstr)) + return _get_platform_error(linux.symlink(old_name_cstr, new_name_cstr)) } _read_link_cstr :: proc(name_cstr: cstring, allocator: runtime.Allocator) -> (string, Error) { bufsz : uint = 256 buf := make([]byte, bufsz, allocator) for { - rc := unix.sys_readlink(name_cstr, &buf[0], bufsz) - if rc < 0 { - delete(buf) - return "", _get_platform_error(rc) - } else if rc == int(bufsz) { + sz, errno := linux.readlink(name_cstr, buf[:]) + if errno != .NONE { + delete(buf, allocator) + return "", _get_platform_error(errno) + } else if sz == int(bufsz) { bufsz *= 2 - delete(buf) + delete(buf, allocator) buf = make([]byte, bufsz, allocator) } else { - return string(buf[:rc]), nil + return string(buf[:sz]), nil } } } -_read_link :: proc(name: string, allocator: runtime.Allocator) -> (path: string, err: Error) { +_read_link :: proc(name: string, allocator: runtime.Allocator) -> (s: string, e: Error) { TEMP_ALLOCATOR_GUARD() name_cstr := temp_cstring(name) or_return return _read_link_cstr(name_cstr, allocator) } -_unlink :: proc(name: string) -> Error { - TEMP_ALLOCATOR_GUARD() - name_cstr := temp_cstring(name) or_return - return _ok_or_error(unix.sys_unlink(name_cstr)) -} - _chdir :: proc(name: string) -> Error { TEMP_ALLOCATOR_GUARD() name_cstr := temp_cstring(name) or_return - return _ok_or_error(unix.sys_chdir(name_cstr)) + return _get_platform_error(linux.chdir(name_cstr)) } _fchdir :: proc(f: ^File) -> Error { - return _ok_or_error(unix.sys_fchdir(f.impl.fd)) + return _get_platform_error(linux.fchdir(f.impl.fd)) } _chmod :: proc(name: string, mode: File_Mode) -> Error { TEMP_ALLOCATOR_GUARD() name_cstr := temp_cstring(name) or_return - return _ok_or_error(unix.sys_chmod(name_cstr, uint(mode))) + return _get_platform_error(linux.chmod(name_cstr, transmute(linux.Mode)(u32(mode)))) } _fchmod :: proc(f: ^File, mode: File_Mode) -> Error { - return _ok_or_error(unix.sys_fchmod(f.impl.fd, uint(mode))) + return _get_platform_error(linux.fchmod(f.impl.fd, transmute(linux.Mode)(u32(mode)))) } // NOTE: will throw error without super user priviledges _chown :: proc(name: string, uid, gid: int) -> Error { TEMP_ALLOCATOR_GUARD() name_cstr := temp_cstring(name) or_return - return _ok_or_error(unix.sys_chown(name_cstr, uid, gid)) + return _get_platform_error(linux.chown(name_cstr, linux.Uid(uid), linux.Gid(gid))) } // NOTE: will throw error without super user priviledges _lchown :: proc(name: string, uid, gid: int) -> Error { TEMP_ALLOCATOR_GUARD() name_cstr := temp_cstring(name) or_return - return _ok_or_error(unix.sys_lchown(name_cstr, uid, gid)) + return _get_platform_error(linux.lchown(name_cstr, linux.Uid(uid), linux.Gid(gid))) } // NOTE: will throw error without super user priviledges _fchown :: proc(f: ^File, uid, gid: int) -> Error { - return _ok_or_error(unix.sys_fchown(f.impl.fd, uid, gid)) + return _get_platform_error(linux.fchown(f.impl.fd, linux.Uid(uid), linux.Gid(gid))) } _chtimes :: proc(name: string, atime, mtime: time.Time) -> Error { TEMP_ALLOCATOR_GUARD() name_cstr := temp_cstring(name) or_return - times := [2]Unix_File_Time { - { atime._nsec, 0 }, - { mtime._nsec, 0 }, + times := [2]linux.Time_Spec { + { + uint(atime._nsec) / uint(time.Second), + uint(atime._nsec) % uint(time.Second), + }, + { + uint(mtime._nsec) / uint(time.Second), + uint(mtime._nsec) % uint(time.Second), + }, } - return _ok_or_error(unix.sys_utimensat(_AT_FDCWD, name_cstr, ×, 0)) + return _get_platform_error(linux.utimensat(linux.AT_FDCWD, name_cstr, ×[0], nil)) } _fchtimes :: proc(f: ^File, atime, mtime: time.Time) -> Error { - times := [2]Unix_File_Time { - { atime._nsec, 0 }, - { mtime._nsec, 0 }, + times := [2]linux.Time_Spec { + { + uint(atime._nsec) / uint(time.Second), + uint(atime._nsec) % uint(time.Second), + }, + { + uint(mtime._nsec) / uint(time.Second), + uint(mtime._nsec) % uint(time.Second), + }, } - return _ok_or_error(unix.sys_utimensat(f.impl.fd, nil, ×, 0)) + return _get_platform_error(linux.utimensat(f.impl.fd, nil, ×[0], nil)) } _exists :: proc(name: string) -> bool { TEMP_ALLOCATOR_GUARD() name_cstr, _ := temp_cstring(name) - return unix.sys_access(name_cstr, F_OK) == 0 + res, errno := linux.access(name_cstr, linux.F_OK) + return !res && errno == .NONE } _is_file :: proc(name: string) -> bool { TEMP_ALLOCATOR_GUARD() name_cstr, _ := temp_cstring(name) - s: _Stat - res := unix.sys_stat(name_cstr, &s) - if res < 0 { + s: linux.Stat + if linux.stat(name_cstr, &s) != .NONE { return false } - return S_ISREG(s.mode) + return linux.S_ISREG(s.mode) } -_is_file_fd :: proc(fd: int) -> bool { - s: _Stat - res := unix.sys_fstat(fd, &s) - if res < 0 { // error +_is_file_fd :: proc(fd: linux.Fd) -> bool { + s: linux.Stat + if linux.fstat(fd, &s) != .NONE { return false } - return S_ISREG(s.mode) + return linux.S_ISREG(s.mode) } _is_dir :: proc(name: string) -> bool { TEMP_ALLOCATOR_GUARD() name_cstr, _ := temp_cstring(name) - s: _Stat - res := unix.sys_stat(name_cstr, &s) - if res < 0 { + s: linux.Stat + if linux.stat(name_cstr, &s) != .NONE { return false } - return S_ISDIR(s.mode) + return linux.S_ISDIR(s.mode) } -_is_dir_fd :: proc(fd: int) -> bool { - s: _Stat - res := unix.sys_fstat(fd, &s) - if res < 0 { // error +_is_dir_fd :: proc(fd: linux.Fd) -> bool { + s: linux.Stat + if linux.fstat(fd, &s) != .NONE { return false } - return S_ISDIR(s.mode) + return linux.S_ISDIR(s.mode) +} + +/* Certain files in the Linux file system are not actual + * files (e.g. everything in /proc/). Therefore, the + * read_entire_file procs fail to actually read anything + * since these "files" stat to a size of 0. Here, we just + * read until there is nothing left. + */ +_read_entire_pseudo_file :: proc { _read_entire_pseudo_file_string, _read_entire_pseudo_file_cstring } + +_read_entire_pseudo_file_string :: proc(name: string, allocator: runtime.Allocator) -> (b: []u8, e: Error) { + name_cstr := clone_to_cstring(name, allocator) or_return + defer delete(name, allocator) + return _read_entire_pseudo_file_cstring(name_cstr, allocator) +} + +_read_entire_pseudo_file_cstring :: proc(name: cstring, allocator: runtime.Allocator) -> ([]u8, Error) { + fd, errno := linux.open(name, {}) + if errno != .NONE { + return nil, _get_platform_error(errno) + } + defer linux.close(fd) + + BUF_SIZE_STEP :: 128 + contents := make([dynamic]u8, 0, BUF_SIZE_STEP, allocator) + + n: int + i: int + for { + resize(&contents, i + BUF_SIZE_STEP) + n, errno = linux.read(fd, contents[i:i+BUF_SIZE_STEP]) + if errno != .NONE { + delete(contents) + return nil, _get_platform_error(errno) + } + if n < BUF_SIZE_STEP { + break + } + i += BUF_SIZE_STEP + } + + resize(&contents, i + n) + + return contents[:], nil } @(private="package") diff --git a/core/os/os2/heap_linux.odin b/core/os/os2/heap_linux.odin index bb4acba13..11cf5ab41 100644 --- a/core/os/os2/heap_linux.odin +++ b/core/os/os2/heap_linux.odin @@ -1,7 +1,7 @@ //+private package os2 -import "core:sys/unix" +import "core:sys/linux" import "core:sync" import "core:mem" @@ -97,9 +97,8 @@ CURRENTLY_ACTIVE :: (^^Region)(~uintptr(0)) FREE_LIST_ENTRIES_PER_BLOCK :: BLOCK_SIZE / size_of(u16) -MMAP_FLAGS :: unix.MAP_ANONYMOUS | unix.MAP_PRIVATE -MMAP_PROT :: unix.PROT_READ | unix.PROT_WRITE - +MMAP_FLAGS : linux.Map_Flags : {.ANONYMOUS, .PRIVATE} +MMAP_PROT : linux.Mem_Protection : {.READ, .WRITE} @thread_local _local_region: ^Region global_regions: ^Region @@ -324,11 +323,11 @@ heap_free :: proc(memory: rawptr) { // Regions // _new_region :: proc() -> ^Region #no_bounds_check { - res := unix.sys_mmap(nil, uint(SIZE_OF_REGION), MMAP_PROT, MMAP_FLAGS, -1, 0) - if res < 0 { + ptr, errno := linux.mmap(0, uint(SIZE_OF_REGION), MMAP_PROT, MMAP_FLAGS, -1, 0) + if errno != .NONE { return nil } - new_region := (^Region)(uintptr(res)) + new_region := (^Region)(ptr) new_region.hdr.local_addr = CURRENTLY_ACTIVE new_region.hdr.reset_addr = &_local_region @@ -634,8 +633,8 @@ _region_free_list_remove :: proc(region: ^Region, free_idx: u16) #no_bounds_chec // _direct_mmap_alloc :: proc(size: int) -> rawptr { mmap_size := _round_up_to_nearest(size + BLOCK_SIZE, PAGE_SIZE) - new_allocation := unix.sys_mmap(nil, uint(mmap_size), MMAP_PROT, MMAP_FLAGS, -1, 0) - if new_allocation < 0 && new_allocation > -4096 { + new_allocation, errno := linux.mmap(0, uint(mmap_size), MMAP_PROT, MMAP_FLAGS, -1, 0) + if errno != .NONE { return nil } @@ -655,13 +654,8 @@ _direct_mmap_resize :: proc(alloc: ^Allocation_Header, new_size: int) -> rawptr return mem.ptr_offset(alloc, 1) } - new_allocation := unix.sys_mremap( - alloc, - uint(old_mmap_size), - uint(new_mmap_size), - unix.MREMAP_MAYMOVE, - ) - if new_allocation < 0 && new_allocation > -4096 { + new_allocation, errno := linux.mremap(alloc, uint(old_mmap_size), uint(new_mmap_size), {.MAYMOVE}) + if errno != .NONE { return nil } @@ -702,7 +696,7 @@ _direct_mmap_to_region :: proc(alloc: ^Allocation_Header, new_size: int) -> rawp _direct_mmap_free :: proc(alloc: ^Allocation_Header) { requested := int(alloc.requested & REQUESTED_MASK) mmap_size := _round_up_to_nearest(requested + BLOCK_SIZE, PAGE_SIZE) - unix.sys_munmap(alloc, uint(mmap_size)) + linux.munmap(alloc, uint(mmap_size)) } // diff --git a/core/os/os2/path_linux.odin b/core/os/os2/path_linux.odin index 81176c219..3c08eedee 100644 --- a/core/os/os2/path_linux.odin +++ b/core/os/os2/path_linux.odin @@ -3,104 +3,89 @@ package os2 import "core:strconv" import "base:runtime" -import "core:sys/unix" +import "core:sys/linux" _Path_Separator :: '/' _Path_Separator_String :: "/" _Path_List_Separator :: ':' -_S_IFMT :: 0o170000 // Type of file mask -_S_IFIFO :: 0o010000 // Named pipe (fifo) -_S_IFCHR :: 0o020000 // Character special -_S_IFDIR :: 0o040000 // Directory -_S_IFBLK :: 0o060000 // Block special -_S_IFREG :: 0o100000 // Regular -_S_IFLNK :: 0o120000 // Symbolic link -_S_IFSOCK :: 0o140000 // Socket - -_OPENDIR_FLAGS :: _O_RDONLY|_O_NONBLOCK|_O_DIRECTORY|_O_LARGEFILE|_O_CLOEXEC +_OPENDIR_FLAGS : linux.Open_Flags : {.NONBLOCK, .DIRECTORY, .LARGEFILE, .CLOEXEC} _is_path_separator :: proc(c: byte) -> bool { return c == '/' } _mkdir :: proc(path: string, perm: File_Mode) -> Error { - // NOTE: These modes would require sys_mknod, however, that would require - // additional arguments to this function. + // TODO: These modes would require mknod, however, that would also + // require additional arguments to this function.. if perm & (File_Mode_Named_Pipe | File_Mode_Device | File_Mode_Char_Device | File_Mode_Sym_Link) != 0 { return .Invalid_Argument } TEMP_ALLOCATOR_GUARD() path_cstr := temp_cstring(path) or_return - return _ok_or_error(unix.sys_mkdir(path_cstr, uint(perm & 0o777))) + return _get_platform_error(linux.mkdir(path_cstr, transmute(linux.Mode)(u32(perm) & 0o777))) } _mkdir_all :: proc(path: string, perm: File_Mode) -> Error { - _mkdirat :: proc(dfd: int, path: []u8, perm: int, has_created: ^bool) -> Error { - if len(path) == 0 { - return _ok_or_error(unix.sys_close(dfd)) - } + mkdirat :: proc(dfd: linux.Fd, path: []u8, perm: int, has_created: ^bool) -> Error { i: int - for /**/; i < len(path) - 1 && path[i] != '/'; i += 1 {} + for ; i < len(path) - 1 && path[i] != '/'; i += 1 {} + if i == 0 { + return _get_platform_error(linux.close(dfd)) + } path[i] = 0 - new_dfd := unix.sys_openat(dfd, cstring(&path[0]), _OPENDIR_FLAGS) - switch new_dfd { - case -ENOENT: - if res := unix.sys_mkdirat(dfd, cstring(&path[0]), uint(perm)); res < 0 { - return _get_platform_error(res) + new_dfd, errno := linux.openat(dfd, cstring(&path[0]), _OPENDIR_FLAGS) + #partial switch errno { + case .ENOENT: + if errno = linux.mkdirat(dfd, cstring(&path[0]), transmute(linux.Mode)(u32(perm))); errno != .NONE { + return _get_platform_error(errno) } has_created^ = true - if new_dfd = unix.sys_openat(dfd, cstring(&path[0]), _OPENDIR_FLAGS); new_dfd < 0 { - return _get_platform_error(new_dfd) + if new_dfd, errno = linux.openat(dfd, cstring(&path[0]), _OPENDIR_FLAGS); errno != .NONE { + return _get_platform_error(errno) } fallthrough - case 0: - if res := unix.sys_close(dfd); res < 0 { - return _get_platform_error(res) + case .NONE: + if errno = linux.close(dfd); errno != .NONE { + return _get_platform_error(errno) } // skip consecutive '/' for i += 1; i < len(path) && path[i] == '/'; i += 1 {} - return _mkdirat(new_dfd, path[i:], perm, has_created) + return mkdirat(new_dfd, path[i:], perm, has_created) case: - return _get_platform_error(new_dfd) + return _get_platform_error(errno) } unreachable() } + // TODO if perm & (File_Mode_Named_Pipe | File_Mode_Device | File_Mode_Char_Device | File_Mode_Sym_Link) != 0 { return .Invalid_Argument } TEMP_ALLOCATOR_GUARD() - // need something we can edit, and use to generate cstrings - allocated: bool - path_bytes: []u8 - if len(path) > _CSTRING_NAME_HEAP_THRESHOLD { - allocated = true - path_bytes = make([]u8, len(path) + 1) - } else { - path_bytes = make([]u8, len(path) + 1, temp_allocator()) - } + path_bytes := make([]u8, len(path) + 1, temp_allocator()) - // NULL terminate the byte slice to make it a valid cstring + // zero terminate the byte slice to make it a valid cstring copy(path_bytes, path) path_bytes[len(path)] = 0 - dfd: int + dfd: linux.Fd + errno: linux.Errno if path_bytes[0] == '/' { - dfd = unix.sys_open("/", _OPENDIR_FLAGS) + dfd, errno = linux.open("/", _OPENDIR_FLAGS) path_bytes = path_bytes[1:] } else { - dfd = unix.sys_open(".", _OPENDIR_FLAGS) + dfd, errno = linux.open(".", _OPENDIR_FLAGS) } - if dfd < 0 { - return _get_platform_error(dfd) + if errno != .NONE { + return _get_platform_error(errno) } has_created: bool - _mkdirat(dfd, path_bytes, int(perm & 0o777), &has_created) or_return + mkdirat(dfd, path_bytes, int(perm & 0o777), &has_created) or_return if has_created { return nil } @@ -119,28 +104,28 @@ dirent64 :: struct { _remove_all :: proc(path: string) -> Error { DT_DIR :: 4 - _remove_all_dir :: proc(dfd: int) -> Error { + remove_all_dir :: proc(dfd: linux.Fd) -> Error { n := 64 buf := make([]u8, n) defer delete(buf) loop: for { - getdents_res := unix.sys_getdents64(dfd, &buf[0], n) - switch getdents_res { - case -EINVAL: + buflen, errno := linux.getdents(dfd, buf[:]) + #partial switch errno { + case .EINVAL: delete(buf) n *= 2 buf = make([]u8, n) continue loop - case -4096..<0: - return _get_platform_error(getdents_res) - case 0: - break loop + case .NONE: + if buflen == 0 { break loop } + case: + return _get_platform_error(errno) } d: ^dirent64 - for i := 0; i < getdents_res; i += int(d.d_reclen) { + for i := 0; i < buflen; i += int(d.d_reclen) { d = (^dirent64)(rawptr(&buf[i])) d_name_cstr := cstring(&d.d_name[0]) @@ -156,23 +141,22 @@ _remove_all :: proc(path: string) -> Error { continue } - unlink_res: int - switch d.d_type { case DT_DIR: - new_dfd := unix.sys_openat(dfd, d_name_cstr, _OPENDIR_FLAGS) - if new_dfd < 0 { - return _get_platform_error(new_dfd) + new_dfd: linux.Fd + new_dfd, errno = linux.openat(dfd, d_name_cstr, _OPENDIR_FLAGS) + if errno != .NONE { + return _get_platform_error(errno) } - defer unix.sys_close(new_dfd) - _remove_all_dir(new_dfd) or_return - unlink_res = unix.sys_unlinkat(dfd, d_name_cstr, int(unix.AT_REMOVEDIR)) + defer linux.close(new_dfd) + remove_all_dir(new_dfd) or_return + errno = linux.unlinkat(dfd, d_name_cstr, {.REMOVEDIR}) case: - unlink_res = unix.sys_unlinkat(dfd, d_name_cstr) + errno = linux.unlinkat(dfd, d_name_cstr, nil) } - if unlink_res < 0 { - return _get_platform_error(unlink_res) + if errno != .NONE { + return _get_platform_error(errno) } } } @@ -182,17 +166,19 @@ _remove_all :: proc(path: string) -> Error { TEMP_ALLOCATOR_GUARD() path_cstr := temp_cstring(path) or_return - fd := unix.sys_open(path_cstr, _OPENDIR_FLAGS) - switch fd { - case -ENOTDIR: - return _ok_or_error(unix.sys_unlink(path_cstr)) - case -4096..<0: - return _get_platform_error(fd) + fd, errno := linux.open(path_cstr, _OPENDIR_FLAGS) + #partial switch errno { + case .NONE: + break + case .ENOTDIR: + return _get_platform_error(linux.unlink(path_cstr)) + case: + return _get_platform_error(errno) } - defer unix.sys_close(fd) - _remove_all_dir(fd) or_return - return _ok_or_error(unix.sys_rmdir(path_cstr)) + defer linux.close(fd) + remove_all_dir(fd) or_return + return _get_platform_error(linux.rmdir(path_cstr)) } _getwd :: proc(allocator: runtime.Allocator) -> (string, Error) { @@ -203,13 +189,12 @@ _getwd :: proc(allocator: runtime.Allocator) -> (string, Error) { PATH_MAX :: 4096 buf := make([dynamic]u8, PATH_MAX, allocator) for { - #no_bounds_check res := unix.sys_getcwd(&buf[0], uint(len(buf))) - - if res >= 0 { - return string_from_null_terminated_bytes(buf[:]), nil + #no_bounds_check n, errno := linux.getcwd(buf[:]) + if errno == .NONE { + return string(buf[:n-1]), nil } - if res != -ERANGE { - return "", _get_platform_error(res) + if errno != .ERANGE { + return "", _get_platform_error(errno) } resize(&buf, len(buf)+PATH_MAX) } @@ -218,16 +203,16 @@ _getwd :: proc(allocator: runtime.Allocator) -> (string, Error) { _setwd :: proc(dir: string) -> Error { dir_cstr := temp_cstring(dir) or_return - return _ok_or_error(unix.sys_chdir(dir_cstr)) + return _get_platform_error(linux.chdir(dir_cstr)) } -_get_full_path :: proc(fd: int, allocator: runtime.Allocator) -> string { +_get_full_path :: proc(fd: linux.Fd, allocator: runtime.Allocator) -> string { PROC_FD_PATH :: "/proc/self/fd/" buf: [32]u8 copy(buf[:], PROC_FD_PATH) - strconv.itoa(buf[len(PROC_FD_PATH):], fd) + strconv.itoa(buf[len(PROC_FD_PATH):], int(fd)) fullpath: string err: Error @@ -236,4 +221,3 @@ _get_full_path :: proc(fd: int, allocator: runtime.Allocator) -> string { } return fullpath } - diff --git a/core/os/os2/pipe_linux.odin b/core/os/os2/pipe_linux.odin index b66ff9663..5d42cca78 100644 --- a/core/os/os2/pipe_linux.odin +++ b/core/os/os2/pipe_linux.odin @@ -1,7 +1,17 @@ //+private package os2 +import "core:sys/linux" + _pipe :: proc() -> (r, w: ^File, err: Error) { - return nil, nil, nil + fds: [2]linux.Fd + errno := linux.pipe2(&fds, {.CLOEXEC}) + if errno != .NONE { + return nil, nil,_get_platform_error(errno) + } + + r = _new_file(uintptr(fds[0])) + w = _new_file(uintptr(fds[1])) + return } diff --git a/core/os/os2/stat_linux.odin b/core/os/os2/stat_linux.odin index dc287cafe..c0b3088b4 100644 --- a/core/os/os2/stat_linux.odin +++ b/core/os/os2/stat_linux.odin @@ -3,108 +3,32 @@ package os2 import "core:time" import "base:runtime" -import "core:sys/unix" +import "core:sys/linux" import "core:path/filepath" -// File type -S_IFMT :: 0o170000 // Type of file mask -S_IFIFO :: 0o010000 // Named pipe (fifo) -S_IFCHR :: 0o020000 // Character special -S_IFDIR :: 0o040000 // Directory -S_IFBLK :: 0o060000 // Block special -S_IFREG :: 0o100000 // Regular -S_IFLNK :: 0o120000 // Symbolic link -S_IFSOCK :: 0o140000 // Socket - -// File mode -// Read, write, execute/search by owner -S_IRWXU :: 0o0700 // RWX mask for owner -S_IRUSR :: 0o0400 // R for owner -S_IWUSR :: 0o0200 // W for owner -S_IXUSR :: 0o0100 // X for owner - - // Read, write, execute/search by group -S_IRWXG :: 0o0070 // RWX mask for group -S_IRGRP :: 0o0040 // R for group -S_IWGRP :: 0o0020 // W for group -S_IXGRP :: 0o0010 // X for group - - // Read, write, execute/search by others -S_IRWXO :: 0o0007 // RWX mask for other -S_IROTH :: 0o0004 // R for other -S_IWOTH :: 0o0002 // W for other -S_IXOTH :: 0o0001 // X for other - -S_ISUID :: 0o4000 // Set user id on execution -S_ISGID :: 0o2000 // Set group id on execution -S_ISVTX :: 0o1000 // Directory restrcted delete - - -S_ISLNK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFLNK } -S_ISREG :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFREG } -S_ISDIR :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFDIR } -S_ISCHR :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFCHR } -S_ISBLK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFBLK } -S_ISFIFO :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFIFO } -S_ISSOCK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFSOCK } - -F_OK :: 0 // Test for file existance -X_OK :: 1 // Test for execute permission -W_OK :: 2 // Test for write permission -R_OK :: 4 // Test for read permission - -@private -Unix_File_Time :: struct { - seconds: i64, - nanoseconds: i64, -} - -@private -_Stat :: struct { - device_id: u64, // ID of device containing file - serial: u64, // File serial number - nlink: u64, // Number of hard links - mode: u32, // Mode of the file - uid: u32, // User ID of the file's owner - gid: u32, // Group ID of the file's group - _padding: i32, // 32 bits of padding - rdev: u64, // Device ID, if device - size: i64, // Size of the file, in bytes - block_size: i64, // Optimal bllocksize for I/O - blocks: i64, // Number of 512-byte blocks allocated - - last_access: Unix_File_Time, // Time of last access - modified: Unix_File_Time, // Time of last modification - status_change: Unix_File_Time, // Time of last status change - - _reserve1, - _reserve2, - _reserve3: i64, -} - - _fstat :: proc(f: ^File, allocator: runtime.Allocator) -> (File_Info, Error) { return _fstat_internal(f.impl.fd, allocator) } -_fstat_internal :: proc(fd: int, allocator: runtime.Allocator) -> (File_Info, Error) { - s: _Stat - result := unix.sys_fstat(fd, &s) - if result < 0 { - return {}, _get_platform_error(result) +_fstat_internal :: proc(fd: linux.Fd, allocator: runtime.Allocator) -> (File_Info, Error) { + s: linux.Stat + errno := linux.fstat(fd, &s) + if errno != .NONE { + return {}, _get_platform_error(errno) } // TODO: As of Linux 4.11, the new statx syscall can retrieve creation_time fi := File_Info { fullpath = _get_full_path(fd, allocator), name = "", - size = s.size, + size = i64(s.size), mode = 0, - is_directory = S_ISDIR(s.mode), - modification_time = time.Time {s.modified.seconds}, - access_time = time.Time {s.last_access.seconds}, - creation_time = time.Time{0}, // regular stat does not provide this + is_directory = linux.S_ISDIR(s.mode), + modification_time = time.Time {i64(s.mtime.time_sec) * i64(time.Second) + i64(s.mtime.time_nsec)}, + access_time = time.Time {i64(s.atime.time_sec) * i64(time.Second) + i64(s.atime.time_nsec)}, + creation_time = time.Time{i64(s.ctime.time_sec) * i64(time.Second) + i64(s.ctime.time_nsec)}, // regular stat does not provide this } + fi.creation_time = fi.modification_time fi.name = filepath.base(fi.fullpath) return fi, nil @@ -115,11 +39,11 @@ _stat :: proc(name: string, allocator: runtime.Allocator) -> (fi: File_Info, err TEMP_ALLOCATOR_GUARD() name_cstr := temp_cstring(name) or_return - fd := unix.sys_open(name_cstr, _O_RDONLY) - if fd < 0 { - return {}, _get_platform_error(fd) + fd, errno := linux.open(name_cstr, {}) + if errno != .NONE { + return {}, _get_platform_error(errno) } - defer unix.sys_close(fd) + defer linux.close(fd) return _fstat_internal(fd, allocator) } @@ -127,11 +51,11 @@ _lstat :: proc(name: string, allocator: runtime.Allocator) -> (fi: File_Info, er TEMP_ALLOCATOR_GUARD() name_cstr := temp_cstring(name) or_return - fd := unix.sys_open(name_cstr, _O_RDONLY | _O_PATH | _O_NOFOLLOW) - if fd < 0 { - return {}, _get_platform_error(fd) + fd, errno := linux.open(name_cstr, {.PATH, .NOFOLLOW}) + if errno != .NONE { + return {}, _get_platform_error(errno) } - defer unix.sys_close(fd) + defer linux.close(fd) return _fstat_internal(fd, allocator) } diff --git a/core/os/os_darwin.odin b/core/os/os_darwin.odin index 702b35689..d29c22900 100644 --- a/core/os/os_darwin.odin +++ b/core/os/os_darwin.odin @@ -555,7 +555,7 @@ open :: proc(path: string, flags: int = O_RDWR, mode: int = 0) -> (Handle, Errno err := fchmod(handle, cast(u16)mode) if err != 0 { _unix_close(handle) - return INVALID_HANDLE, cast(Errno)err + return INVALID_HANDLE, err } } @@ -883,8 +883,8 @@ absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Errno) { } defer _unix_free(path_ptr) - path_cstr := transmute(cstring)path_ptr - path = strings.clone( string(path_cstr) ) + path_cstr := cast(cstring)path_ptr + path = strings.clone(string(path_cstr)) return path, ERROR_NONE } @@ -896,7 +896,7 @@ access :: proc(path: string, mask: int) -> bool { } flush :: proc(fd: Handle) -> Errno { - return cast(Errno)_unix_fsync(fd) + return cast(Errno)_unix_fsync(fd) } lookup_env :: proc(key: string, allocator := context.allocator) -> (value: string, found: bool) { diff --git a/core/os/os_freebsd.odin b/core/os/os_freebsd.odin index 5fd7b3243..2a98a521f 100644 --- a/core/os/os_freebsd.odin +++ b/core/os/os_freebsd.odin @@ -648,8 +648,8 @@ absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Errno) { } defer _unix_free(path_ptr) - path_cstr := transmute(cstring)path_ptr - path = strings.clone( string(path_cstr) ) + + path = strings.clone(string(cstring(path_ptr))) return path, ERROR_NONE } @@ -705,7 +705,9 @@ set_current_directory :: proc(path: string) -> (err: Errno) { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() cstr := strings.clone_to_cstring(path, context.temp_allocator) res := _unix_chdir(cstr) - if res == -1 do return Errno(get_last_error()) + if res == -1 { + return Errno(get_last_error()) + } return ERROR_NONE } @@ -743,7 +745,9 @@ get_page_size :: proc "contextless" () -> int { // NOTE(tetra): The page size never changes, so why do anything complicated // if we don't have to. @static page_size := -1 - if page_size != -1 do return page_size + if page_size != -1 { + return page_size + } page_size = int(_unix_getpagesize()) return page_size diff --git a/core/os/os_linux.odin b/core/os/os_linux.odin index 7e9246235..65eea6760 100644 --- a/core/os/os_linux.odin +++ b/core/os/os_linux.odin @@ -890,8 +890,7 @@ absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Errno) { } defer _unix_free(path_ptr) - path_cstr := transmute(cstring)path_ptr - path = strings.clone( string(path_cstr) ) + path = strings.clone(string(cstring(path_ptr))) return path, ERROR_NONE } diff --git a/core/os/os_netbsd.odin b/core/os/os_netbsd.odin index c0f237bf5..2bda8abf7 100644 --- a/core/os/os_netbsd.odin +++ b/core/os/os_netbsd.odin @@ -658,8 +658,7 @@ absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Errno) { } defer _unix_free(path_ptr) - path_cstr := transmute(cstring)path_ptr - path = strings.clone( string(path_cstr) ) + path = strings.clone(string(cstring(path_ptr))) return path, ERROR_NONE } @@ -715,7 +714,9 @@ set_current_directory :: proc(path: string) -> (err: Errno) { runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() cstr := strings.clone_to_cstring(path, context.temp_allocator) res := _unix_chdir(cstr) - if res == -1 do return Errno(get_last_error()) + if res == -1 { + return Errno(get_last_error()) + } return ERROR_NONE } @@ -756,7 +757,9 @@ get_page_size :: proc() -> int { // NOTE(tetra): The page size never changes, so why do anything complicated // if we don't have to. @static page_size := -1 - if page_size != -1 do return page_size + if page_size != -1 { + return page_size + } page_size = int(_unix_getpagesize()) return page_size diff --git a/core/os/os_openbsd.odin b/core/os/os_openbsd.odin index caffabf14..fa770795c 100644 --- a/core/os/os_openbsd.odin +++ b/core/os/os_openbsd.odin @@ -610,8 +610,7 @@ absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Errno) { } defer _unix_free(path_ptr) - path_cstr := transmute(cstring)path_ptr - path = strings.clone( string(path_cstr) ) + path = strings.clone(string(cstring(path_ptr))) return path, ERROR_NONE } diff --git a/core/os/os_wasi.odin b/core/os/os_wasi.odin index 9bfd87322..8a1acb194 100644 --- a/core/os/os_wasi.odin +++ b/core/os/os_wasi.odin @@ -6,6 +6,8 @@ import "base:runtime" Handle :: distinct i32 Errno :: distinct i32 +INVALID_HANDLE :: -1 + ERROR_NONE :: Errno(wasi.errno_t.SUCCESS) O_RDONLY :: 0x00000 @@ -26,6 +28,16 @@ stdout: Handle = 1 stderr: Handle = 2 current_dir: Handle = 3 +args := _alloc_command_line_arguments() + +_alloc_command_line_arguments :: proc() -> (args: []string) { + args = make([]string, len(runtime.args__)) + for &arg, i in args { + arg = string(runtime.args__[i]) + } + return +} + write :: proc(fd: Handle, data: []byte) -> (int, Errno) { iovs := wasi.ciovec_t(data) n, err := wasi.fd_write(wasi.fd_t(fd), {iovs}) diff --git a/core/os/os_windows.odin b/core/os/os_windows.odin index edec5fcb1..0f3b2a34b 100644 --- a/core/os/os_windows.odin +++ b/core/os/os_windows.odin @@ -178,8 +178,8 @@ WINDOWS_11_BUILD_CUTOFF :: 22_000 get_windows_version_w :: proc() -> win32.OSVERSIONINFOEXW { osvi : win32.OSVERSIONINFOEXW osvi.dwOSVersionInfoSize = size_of(win32.OSVERSIONINFOEXW) - win32.RtlGetVersion(&osvi) - return osvi + win32.RtlGetVersion(&osvi) + return osvi } is_windows_xp :: proc() -> bool { diff --git a/core/path/filepath/path.odin b/core/path/filepath/path.odin index 59a0f7f1c..c3dfa2bb1 100644 --- a/core/path/filepath/path.odin +++ b/core/path/filepath/path.odin @@ -432,7 +432,7 @@ rel :: proc(base_path, target_path: string, allocator := context.allocator) -> ( then `"."` is returned. */ dir :: proc(path: string, allocator := context.allocator) -> string { - context.allocator = allocator + context.allocator = allocator vol := volume_name(path) i := len(path) - 1 for i >= len(vol) && !is_separator(path[i]) { diff --git a/core/reflect/types.odin b/core/reflect/types.odin index f242dfd5c..04dd8a52d 100644 --- a/core/reflect/types.odin +++ b/core/reflect/types.odin @@ -114,7 +114,7 @@ are_types_identical :: proc(a, b: ^Type_Info) -> bool { case Type_Info_Struct: y := b.variant.(Type_Info_Struct) or_return - switch { + switch { case len(x.types) != len(y.types), x.is_packed != y.is_packed, x.is_raw_union != y.is_raw_union, @@ -122,7 +122,7 @@ are_types_identical :: proc(a, b: ^Type_Info) -> bool { x.soa_kind != y.soa_kind, x.soa_base_type != y.soa_base_type, x.soa_len != y.soa_len: - return false + return false } for _, i in x.types { xn, yn := x.names[i], y.names[i] diff --git a/core/slice/slice.odin b/core/slice/slice.odin index 06f08fda2..043e51aa5 100644 --- a/core/slice/slice.odin +++ b/core/slice/slice.odin @@ -156,8 +156,7 @@ linear_search_proc :: proc(array: $A/[]$T, f: proc(T) -> bool) -> (index: int, f */ @(require_results) binary_search :: proc(array: $A/[]$T, key: T) -> (index: int, found: bool) - where intrinsics.type_is_ordered(T) #no_bounds_check -{ + where intrinsics.type_is_ordered(T) #no_bounds_check { return binary_search_by(array, key, cmp_proc(T)) } @@ -712,7 +711,7 @@ enumerated_array :: proc(ptr: ^$T) -> []intrinsics.type_elem_type(T) @(require_results) enum_slice_to_bitset :: proc(enums: []$E, $T: typeid/bit_set[E]) -> (bits: T) where intrinsics.type_is_enum(E), intrinsics.type_bit_set_elem_type(T) == E { for v in enums { - bits |= {v} + bits += {v} } return } diff --git a/core/strings/builder.odin b/core/strings/builder.odin index 3c5bc5793..6bb0b2018 100644 --- a/core/strings/builder.odin +++ b/core/strings/builder.odin @@ -24,7 +24,7 @@ Builder :: struct { buf: [dynamic]byte, } /* -Produces a Builder with a default length of 0 and cap of 16 +Produces an empty Builder *Allocates Using Provided Allocator* @@ -39,7 +39,7 @@ builder_make_none :: proc(allocator := context.allocator, loc := #caller_locatio return Builder{buf=make([dynamic]byte, allocator, loc) or_return }, nil } /* -Produces a Builder with a specified length and cap of max(16,len) byte buffer +Produces a Builder with specified length and capacity `len`. *Allocates Using Provided Allocator* @@ -55,7 +55,7 @@ builder_make_len :: proc(len: int, allocator := context.allocator, loc := #calle return Builder{buf=make([dynamic]byte, len, allocator, loc) or_return }, nil } /* -Produces a Builder with a specified length and cap +Produces a Builder with specified length `len` and capacity `cap`. *Allocates Using Provided Allocator* @@ -103,7 +103,7 @@ builder_make :: proc{ builder_make_len_cap, } /* -Initializes a Builder with a length of 0 and cap of 16 +Initializes an empty Builder It replaces the existing `buf` *Allocates Using Provided Allocator* @@ -121,7 +121,7 @@ builder_init_none :: proc(b: ^Builder, allocator := context.allocator, loc := #c return b, nil } /* -Initializes a Builder with a specified length and cap, which is max(len,16) +Initializes a Builder with specified length and capacity `len`. It replaces the existing `buf` *Allocates Using Provided Allocator* @@ -140,7 +140,7 @@ builder_init_len :: proc(b: ^Builder, len: int, allocator := context.allocator, return b, nil } /* -Initializes a Builder with a specified length and cap +Initializes a Builder with specified length `len` and capacity `cap`. It replaces the existing `buf` Inputs: @@ -723,11 +723,11 @@ write_f32 :: proc(b: ^Builder, f: f32, fmt: byte, always_signed := false) -> (n: return write_string(b, s) } /* -Writes a f32 value to the Builder and returns the number of characters written +Writes a f64 value to the Builder and returns the number of characters written Inputs: - b: A pointer to the Builder -- f: The f32 value to be appended +- f: The f64 value to be appended - fmt: The format byte - always_signed: Optional boolean flag to always include the sign diff --git a/core/strings/intern.odin b/core/strings/intern.odin index 88eea3c50..4c270980c 100644 --- a/core/strings/intern.odin +++ b/core/strings/intern.odin @@ -37,7 +37,7 @@ Returns: intern_init :: proc(m: ^Intern, allocator := context.allocator, map_allocator := context.allocator, loc := #caller_location) -> (err: mem.Allocator_Error) { m.allocator = allocator m.entries = make(map[string]^Intern_Entry, 16, map_allocator, loc) or_return - return nil + return nil } /* Frees the map and all its content allocated using the `.allocator`. diff --git a/core/sync/chan/chan.odin b/core/sync/chan/chan.odin index 0c3f4a725..0c98124de 100644 --- a/core/sync/chan/chan.odin +++ b/core/sync/chan/chan.odin @@ -304,7 +304,7 @@ try_recv_raw :: proc "contextless" (c: ^Raw_Chan, msg_out: rawptr) -> bool { if sync.atomic_load(&c.closed) || sync.atomic_load(&c.w_waiting) == 0 { - return false + return false } mem.copy(msg_out, c.unbuffered_data, int(c.msg_size)) diff --git a/core/sync/primitives_atomic.odin b/core/sync/primitives_atomic.odin index 1b7cdfe35..2cf25ac11 100644 --- a/core/sync/primitives_atomic.odin +++ b/core/sync/primitives_atomic.odin @@ -169,7 +169,7 @@ atomic_rw_mutex_shared_unlock :: proc "contextless" (rw: ^Atomic_RW_Mutex) { if (state & Atomic_RW_Mutex_State_Reader_Mask == Atomic_RW_Mutex_State_Reader) && (state & Atomic_RW_Mutex_State_Is_Writing != 0) { - atomic_sema_post(&rw.sema) + atomic_sema_post(&rw.sema) } } diff --git a/core/sys/darwin/CoreFoundation/CFString.odin b/core/sys/darwin/CoreFoundation/CFString.odin index 4a167c604..6ad3c5bfc 100644 --- a/core/sys/darwin/CoreFoundation/CFString.odin +++ b/core/sys/darwin/CoreFoundation/CFString.odin @@ -192,7 +192,7 @@ StringCopyToOdinString :: proc( max := StringGetMaximumSizeForEncoding(length, StringEncoding(StringBuiltInEncodings.UTF8)) buf, err := make([]byte, max, allocator) - if err != nil do return + if err != nil { return } raw_str := runtime.Raw_String { data = raw_data(buf), diff --git a/core/sys/darwin/xnu_system_call_numbers.odin b/core/sys/darwin/xnu_system_call_numbers.odin index 429d18964..39d902c79 100644 --- a/core/sys/darwin/xnu_system_call_numbers.odin +++ b/core/sys/darwin/xnu_system_call_numbers.odin @@ -1,558 +1,558 @@ package darwin unix_offset_syscall :: proc "contextless" (number: System_Call_Number) -> uintptr { - return uintptr(number) + uintptr(0x2000000) + return uintptr(number) + uintptr(0x2000000) } System_Call_Number :: enum uintptr { - /* 0 syscall */ - exit = 1, - fork = 2, - read = 3, - write = 4, - open = 5, - close = 6, - wait4 = 7, - /* 8 old creat */ - link = 9, - unlink = 10, - /* 11 old execv */ - chdir = 12, - fchdir = 13, - mknod = 14, - chmod = 15, - chown = 16, - /* 17 old break */ - getfsstat = 18, - /* 19 old lseek */ - getpid = 20, - /* 21 old mount */ - /* 22 old umount */ - setuid = 23, - getuid = 24, - geteuid = 25, - ptrace = 26, - recvmsg = 27, - sendmsg = 28, - recvfrom = 29, - accept = 30, - getpeername = 31, - getsockname = 32, - access = 33, - chflags = 34, - fchflags = 35, - sync = 36, - kill = 37, - /* 38 old stat */ - getppid = 39, - /* 40 old lstat */ - dup = 41, - pipe = 42, - getegid = 43, - /* 44 old profil */ - /* 45 old ktrace */ - sigaction = 46, - getgid = 47, - sigprocmask = 48, - getlogin = 49, - setlogin = 50, - acct = 51, - sigpending = 52, - sigaltstack = 53, - ioctl = 54, - reboot = 55, - revoke = 56, - symlink = 57, - readlink = 58, - execve = 59, - umask = 60, - chroot = 61, - /* 62 old fstat */ - /* 63 used internally and reserved */ - /* getpagesize = 64, invalid */ - msync = 65, - vfork = 66, - /* 67 old vread */ - /* 68 old vwrite */ - /* 69 old sbrk */ - /* 70 old sstk */ - /* 71 old mmap */ - /* 72 old vadvise */ - munmap = 73, - mprotect = 74, - madvise = 75, - /* 76 old vhangup */ - /* 77 old vlimit */ - mincore = 78, - getgroups = 79, - setgroups = 80, - getpgrp = 81, - setpgid = 82, - setitimer = 83, - /* 84 old wait */ - swapon = 85, - getitimer = 86, - /* 87 old gethostname */ - /* 88 old sethostname */ - getdtablesize = 89, - dup2 = 90, - /* 91 old getdopt */ - fcntl = 92, - select = 93, - /* 94 old setdopt */ - fsync = 95, - setpriority = 96, - socket = 97, - connect = 98, - /* 99 old accept */ - getpriority = 100, - /* 101 old send */ - /* 102 old recv */ - /* 103 old sigreturn */ - bind = 104, - setsockopt = 105, - listen = 106, - /* 107 old vtimes */ - /* 108 old sigvec */ - /* 109 old sigblock */ - /* 110 old sigsetmask */ - sigsuspend = 111, - /* 112 old sigstack */ - /* 113 old recvmsg */ - /* 114 old sendmsg */ - /* 115 old vtrace */ - gettimeofday = 116, - getrusage = 117, - getsockopt = 118, - /* 119 old resuba */ - readv = 120, - writev = 121, - settimeofday = 122, - fchown = 123, - fchmod = 124, - /* 125 old recvfrom */ - setreuid = 126, - setregid = 127, - rename = 128, - /* 129 old truncate */ - /* 130 old ftruncate */ - flock = 131, - mkfifo = 132, - sendto = 133, - shutdown = 134, - socketpair = 135, - mkdir = 136, - rmdir = 137, - utimes = 138, - futimes = 139, - adjtime = 140, - /* 141 old getpeername */ - gethostuuid = 142, - /* 143 old sethostid */ - /* 144 old getrlimit */ - /* 145 old setrlimit */ - /* 146 old killpg */ - setsid = 147, - /* 148 old setquota */ - /* 149 old qquota */ - /* 150 old getsockname */ - getpgid = 151, - setprivexec = 152, - pread = 153, - pwrite = 154, - nfssvc = 155, - /* 156 old getdirentries */ - statfs = 157, - fstatfs = 158, - unmount = 159, - /* 160 old async_daemon */ - getfh = 161, - /* 162 old getdomainname */ - /* 163 old setdomainname */ - /* 164 */ - quotactl = 165, - /* 166 old exportfs */ - mount = 167, - /* 168 old ustat */ - csops = 169, - csops_audittoken = 170, - /* 171 old wait3 */ - /* 172 old rpause */ - waitid = 173, - /* 174 old getdents */ - /* 175 old gc_control */ - /* 176 old add_profil */ - kdebug_typefilter = 177, - kdebug_trace_string = 178, - kdebug_trace64 = 179, - kdebug_trace = 180, - setgid = 181, - setegid = 182, - seteuid = 183, - sigreturn = 184, - /* 185 old chud */ - thread_selfcounts = 186, - fdatasync = 187, - stat = 188, - fstat = 189, - lstat = 190, - pathconf = 191, - fpathconf = 192, - /* 193 old getfsstat */ - getrlimit = 194, - setrlimit = 195, - getdirentries = 196, - mmap = 197, - /* 198 old __syscall */ - lseek = 199, - truncate = 200, - ftruncate = 201, - sysctl = 202, - mlock = 203, - munlock = 204, - undelete = 205, - /* 206 old ATsocket */ - /* 207 old ATgetmsg */ - /* 208 old ATputmsg */ - /* 209 old ATsndreq */ - /* 210 old ATsndrsp */ - /* 211 old ATgetreq */ - /* 212 old ATgetrsp */ - /* 213 Reserved for AppleTalk */ - /* 214 */ - /* 215 */ - open_dprotected_np = 216, - fsgetpath_ext = 217, - /* 218 old lstatv */ - /* 219 old fstatv */ - getattrlist = 220, - setattrlist = 221, - getdirentriesattr = 222, - exchangedata = 223, - /* 224 old checkuseraccess or fsgetpath */ - searchfs = 225, - delete = 226, - copyfile = 227, - fgetattrlist = 228, - fsetattrlist = 229, - poll = 230, - /* 231 old watchevent */ - /* 232 old waitevent */ - /* 233 old modwatch */ - getxattr = 234, - fgetxattr = 235, - setxattr = 236, - fsetxattr = 237, - removexattr = 238, - fremovexattr = 239, - listxattr = 240, - flistxattr = 241, - fsctl = 242, - initgroups = 243, - posix_spawn = 244, - ffsctl = 245, - /* 246 */ - nfsclnt = 247, - fhopen = 248, - /* 249 */ - minherit = 250, - semsys = 251, - msgsys = 252, - shmsys = 253, - semctl = 254, - semget = 255, - semop = 256, - /* 257 old semconfig */ - msgctl = 258, - msgget = 259, - msgsnd = 260, - msgrcv = 261, - shmat = 262, - shmctl = 263, - shmdt = 264, - shmget = 265, - shm_open = 266, - shm_unlink = 267, - sem_open = 268, - sem_close = 269, - sem_unlink = 270, - sem_wait = 271, - sem_trywait = 272, - sem_post = 273, - sysctlbyname = 274, - /* 275 old sem_init */ - /* 276 old sem_destroy */ - open_extended = 277, - umask_extended = 278, - stat_extended = 279, - lstat_extended = 280, - fstat_extended = 281, - chmod_extended = 282, - fchmod_extended = 283, - access_extended = 284, - settid = 285, - gettid = 286, - setsgroups = 287, - getsgroups = 288, - setwgroups = 289, - getwgroups = 290, - mkfifo_extended = 291, - mkdir_extended = 292, - identitysvc = 293, - shared_region_check_np = 294, - /* 295 old shared_region_map_np */ - vm_pressure_monitor = 296, - psynch_rw_longrdlock = 297, - psynch_rw_yieldwrlock = 298, - psynch_rw_downgrade = 299, - psynch_rw_upgrade = 300, - psynch_mutexwait = 301, - psynch_mutexdrop = 302, - psynch_cvbroad = 303, - psynch_cvsignal = 304, - psynch_cvwait = 305, - psynch_rw_rdlock = 306, - psynch_rw_wrlock = 307, - psynch_rw_unlock = 308, - psynch_rw_unlock2 = 309, - getsid = 310, - settid_with_pid = 311, - psynch_cvclrprepost = 312, - aio_fsync = 313, - aio_return = 314, - aio_suspend = 315, - aio_cancel = 316, - aio_error = 317, - aio_read = 318, - aio_write = 319, - lio_listio = 320, - /* 321 old __pthread_cond_wait */ - iopolicysys = 322, - process_policy = 323, - mlockall = 324, - munlockall = 325, - /* 326 */ - issetugid = 327, - __pthread_kill = 328, - __pthread_sigmask = 329, - __sigwait = 330, - __disable_threadsignal = 331, - __pthread_markcancel = 332, - __pthread_canceled = 333, - __semwait_signal = 334, - /* 335 old utrace */ - proc_info = 336, - sendfile = 337, - stat64 = 338, - fstat64 = 339, - lstat64 = 340, - stat64_extended = 341, - lstat64_extended = 342, - fstat64_extended = 343, - getdirentries64 = 344, - statfs64 = 345, - fstatfs64 = 346, - getfsstat64 = 347, - __pthread_chdir = 348, - __pthread_fchdir = 349, - audit = 350, - auditon = 351, - /* 352 */ - getauid = 353, - setauid = 354, - /* 355 old getaudit */ - /* 356 old setaudit */ - getaudit_addr = 357, - setaudit_addr = 358, - auditctl = 359, - bsdthread_create = 360, - bsdthread_terminate = 361, - kqueue = 362, - kevent = 363, - lchown = 364, - /* 365 old stack_snapshot */ - bsdthread_register = 366, - workq_open = 367, - workq_kernreturn = 368, - kevent64 = 369, - __old_semwait_signal = 370, - __old_semwait_signal_nocancel = 371, - thread_selfid = 372, - ledger = 373, - kevent_qos = 374, - kevent_id = 375, - /* 376 */ - /* 377 */ - /* 378 */ - /* 379 */ - __mac_execve = 380, - __mac_syscall = 381, - __mac_get_file = 382, - __mac_set_file = 383, - __mac_get_link = 384, - __mac_set_link = 385, - __mac_get_proc = 386, - __mac_set_proc = 387, - __mac_get_fd = 388, - __mac_set_fd = 389, - __mac_get_pid = 390, - /* 391 */ - /* 392 */ - /* 393 */ - pselect = 394, - pselect_nocancel = 395, - read_nocancel = 396, - write_nocancel = 397, - open_nocancel = 398, - close_nocancel = 399, - wait4_nocancel = 400, - recvmsg_nocancel = 401, - sendmsg_nocancel = 402, - recvfrom_nocancel = 403, - accept_nocancel = 404, - msync_nocancel = 405, - fcntl_nocancel = 406, - select_nocancel = 407, - fsync_nocancel = 408, - connect_nocancel = 409, - sigsuspend_nocancel = 410, - readv_nocancel = 411, - writev_nocancel = 412, - sendto_nocancel = 413, - pread_nocancel = 414, - pwrite_nocancel = 415, - waitid_nocancel = 416, - poll_nocancel = 417, - msgsnd_nocancel = 418, - msgrcv_nocancel = 419, - sem_wait_nocancel = 420, - aio_suspend_nocancel = 421, - __sigwait_nocancel = 422, - __semwait_signal_nocancel = 423, - __mac_mount = 424, - __mac_get_mount = 425, - __mac_getfsstat = 426, - fsgetpath = 427, - audit_session_self = 428, - audit_session_join = 429, - fileport_makeport = 430, - fileport_makefd = 431, - audit_session_port = 432, - pid_suspend = 433, - pid_resume = 434, - pid_hibernate = 435, - pid_shutdown_sockets = 436, - /* 437 old shared_region_slide_np */ - shared_region_map_and_slide_np = 438, - kas_info = 439, - memorystatus_control = 440, - guarded_open_np = 441, - guarded_close_np = 442, - guarded_kqueue_np = 443, - change_fdguard_np = 444, - usrctl = 445, - proc_rlimit_control = 446, - connectx = 447, - disconnectx = 448, - peeloff = 449, - socket_delegate = 450, - telemetry = 451, - proc_uuid_policy = 452, - memorystatus_get_level = 453, - system_override = 454, - vfs_purge = 455, - sfi_ctl = 456, - sfi_pidctl = 457, - coalition = 458, - coalition_info = 459, - necp_match_policy = 460, - getattrlistbulk = 461, - clonefileat = 462, - openat = 463, - openat_nocancel = 464, - renameat = 465, - faccessat = 466, - fchmodat = 467, - fchownat = 468, - fstatat = 469, - fstatat64 = 470, - linkat = 471, - unlinkat = 472, - readlinkat = 473, - symlinkat = 474, - mkdirat = 475, - getattrlistat = 476, - proc_trace_log = 477, - bsdthread_ctl = 478, - openbyid_np = 479, - recvmsg_x = 480, - sendmsg_x = 481, - thread_selfusage = 482, - csrctl = 483, - guarded_open_dprotected_np = 484, - guarded_write_np = 485, - guarded_pwrite_np = 486, - guarded_writev_np = 487, - renameatx_np = 488, - mremap_encrypted = 489, - netagent_trigger = 490, - stack_snapshot_with_config = 491, - microstackshot = 492, - grab_pgo_data = 493, - persona = 494, - /* 495 */ - mach_eventlink_signal = 496, - mach_eventlink_wait_until = 497, - mach_eventlink_signal_wait_until = 498, - work_interval_ctl = 499, - getentropy = 500, - necp_open = 501, - necp_client_action = 502, - nexus_open = 503, // for those who are intressted http://newosxbook.com/bonus/vol1ch16.html - nexus_register = 504, - nexus_deregister = 505, - nexus_create = 506, - nexus_destroy = 507, - nexus_get_opt = 508, - nexus_set_opt = 509, - channel_open = 510, - channel_get_info = 511, - channel_sync = 512, - channel_get_opt = 513, - channel_set_opt = 514, - ulock_wait = 515, - ulock_wake = 516, - fclonefileat = 517, - fs_snapshot = 518, - register_uexc_handler = 519, - terminate_with_payload = 520, - abort_with_payload = 521, - necp_session_open = 522, - necp_session_action = 523, - setattrlistat = 524, - net_qos_guideline = 525, - fmount = 526, - ntp_adjtime = 527, - ntp_gettime = 528, - os_fault_with_payload = 529, - kqueue_workloop_ctl = 530, - mach_bridge_remote_time = 531, - coalition_ledger = 532, - log_data = 533, - memorystatus_available_memory = 534, - objc_bp_assist_cfg_np = 535, - shared_region_map_and_slide_2_np = 536, - pivot_root = 537, - task_inspect_for_pid = 538, - task_read_for_pid = 539, - preadv = 540, - pwritev = 541, - preadv_nocancel = 542, - pwritev_nocancel = 543, - ulock_wait2 = 544, - proc_info_extended_id = 545, - tracker_action = 546, - debug_syscall_reject = 547, - MAXSYSCALL = 548, - /* invalid = 63, */ + /* 0 syscall */ + exit = 1, + fork = 2, + read = 3, + write = 4, + open = 5, + close = 6, + wait4 = 7, + /* 8 old creat */ + link = 9, + unlink = 10, + /* 11 old execv */ + chdir = 12, + fchdir = 13, + mknod = 14, + chmod = 15, + chown = 16, + /* 17 old break */ + getfsstat = 18, + /* 19 old lseek */ + getpid = 20, + /* 21 old mount */ + /* 22 old umount */ + setuid = 23, + getuid = 24, + geteuid = 25, + ptrace = 26, + recvmsg = 27, + sendmsg = 28, + recvfrom = 29, + accept = 30, + getpeername = 31, + getsockname = 32, + access = 33, + chflags = 34, + fchflags = 35, + sync = 36, + kill = 37, + /* 38 old stat */ + getppid = 39, + /* 40 old lstat */ + dup = 41, + pipe = 42, + getegid = 43, + /* 44 old profil */ + /* 45 old ktrace */ + sigaction = 46, + getgid = 47, + sigprocmask = 48, + getlogin = 49, + setlogin = 50, + acct = 51, + sigpending = 52, + sigaltstack = 53, + ioctl = 54, + reboot = 55, + revoke = 56, + symlink = 57, + readlink = 58, + execve = 59, + umask = 60, + chroot = 61, + /* 62 old fstat */ + /* 63 used internally and reserved */ + /* getpagesize = 64, invalid */ + msync = 65, + vfork = 66, + /* 67 old vread */ + /* 68 old vwrite */ + /* 69 old sbrk */ + /* 70 old sstk */ + /* 71 old mmap */ + /* 72 old vadvise */ + munmap = 73, + mprotect = 74, + madvise = 75, + /* 76 old vhangup */ + /* 77 old vlimit */ + mincore = 78, + getgroups = 79, + setgroups = 80, + getpgrp = 81, + setpgid = 82, + setitimer = 83, + /* 84 old wait */ + swapon = 85, + getitimer = 86, + /* 87 old gethostname */ + /* 88 old sethostname */ + getdtablesize = 89, + dup2 = 90, + /* 91 old getdopt */ + fcntl = 92, + select = 93, + /* 94 old setdopt */ + fsync = 95, + setpriority = 96, + socket = 97, + connect = 98, + /* 99 old accept */ + getpriority = 100, + /* 101 old send */ + /* 102 old recv */ + /* 103 old sigreturn */ + bind = 104, + setsockopt = 105, + listen = 106, + /* 107 old vtimes */ + /* 108 old sigvec */ + /* 109 old sigblock */ + /* 110 old sigsetmask */ + sigsuspend = 111, + /* 112 old sigstack */ + /* 113 old recvmsg */ + /* 114 old sendmsg */ + /* 115 old vtrace */ + gettimeofday = 116, + getrusage = 117, + getsockopt = 118, + /* 119 old resuba */ + readv = 120, + writev = 121, + settimeofday = 122, + fchown = 123, + fchmod = 124, + /* 125 old recvfrom */ + setreuid = 126, + setregid = 127, + rename = 128, + /* 129 old truncate */ + /* 130 old ftruncate */ + flock = 131, + mkfifo = 132, + sendto = 133, + shutdown = 134, + socketpair = 135, + mkdir = 136, + rmdir = 137, + utimes = 138, + futimes = 139, + adjtime = 140, + /* 141 old getpeername */ + gethostuuid = 142, + /* 143 old sethostid */ + /* 144 old getrlimit */ + /* 145 old setrlimit */ + /* 146 old killpg */ + setsid = 147, + /* 148 old setquota */ + /* 149 old qquota */ + /* 150 old getsockname */ + getpgid = 151, + setprivexec = 152, + pread = 153, + pwrite = 154, + nfssvc = 155, + /* 156 old getdirentries */ + statfs = 157, + fstatfs = 158, + unmount = 159, + /* 160 old async_daemon */ + getfh = 161, + /* 162 old getdomainname */ + /* 163 old setdomainname */ + /* 164 */ + quotactl = 165, + /* 166 old exportfs */ + mount = 167, + /* 168 old ustat */ + csops = 169, + csops_audittoken = 170, + /* 171 old wait3 */ + /* 172 old rpause */ + waitid = 173, + /* 174 old getdents */ + /* 175 old gc_control */ + /* 176 old add_profil */ + kdebug_typefilter = 177, + kdebug_trace_string = 178, + kdebug_trace64 = 179, + kdebug_trace = 180, + setgid = 181, + setegid = 182, + seteuid = 183, + sigreturn = 184, + /* 185 old chud */ + thread_selfcounts = 186, + fdatasync = 187, + stat = 188, + fstat = 189, + lstat = 190, + pathconf = 191, + fpathconf = 192, + /* 193 old getfsstat */ + getrlimit = 194, + setrlimit = 195, + getdirentries = 196, + mmap = 197, + /* 198 old __syscall */ + lseek = 199, + truncate = 200, + ftruncate = 201, + sysctl = 202, + mlock = 203, + munlock = 204, + undelete = 205, + /* 206 old ATsocket */ + /* 207 old ATgetmsg */ + /* 208 old ATputmsg */ + /* 209 old ATsndreq */ + /* 210 old ATsndrsp */ + /* 211 old ATgetreq */ + /* 212 old ATgetrsp */ + /* 213 Reserved for AppleTalk */ + /* 214 */ + /* 215 */ + open_dprotected_np = 216, + fsgetpath_ext = 217, + /* 218 old lstatv */ + /* 219 old fstatv */ + getattrlist = 220, + setattrlist = 221, + getdirentriesattr = 222, + exchangedata = 223, + /* 224 old checkuseraccess or fsgetpath */ + searchfs = 225, + delete = 226, + copyfile = 227, + fgetattrlist = 228, + fsetattrlist = 229, + poll = 230, + /* 231 old watchevent */ + /* 232 old waitevent */ + /* 233 old modwatch */ + getxattr = 234, + fgetxattr = 235, + setxattr = 236, + fsetxattr = 237, + removexattr = 238, + fremovexattr = 239, + listxattr = 240, + flistxattr = 241, + fsctl = 242, + initgroups = 243, + posix_spawn = 244, + ffsctl = 245, + /* 246 */ + nfsclnt = 247, + fhopen = 248, + /* 249 */ + minherit = 250, + semsys = 251, + msgsys = 252, + shmsys = 253, + semctl = 254, + semget = 255, + semop = 256, + /* 257 old semconfig */ + msgctl = 258, + msgget = 259, + msgsnd = 260, + msgrcv = 261, + shmat = 262, + shmctl = 263, + shmdt = 264, + shmget = 265, + shm_open = 266, + shm_unlink = 267, + sem_open = 268, + sem_close = 269, + sem_unlink = 270, + sem_wait = 271, + sem_trywait = 272, + sem_post = 273, + sysctlbyname = 274, + /* 275 old sem_init */ + /* 276 old sem_destroy */ + open_extended = 277, + umask_extended = 278, + stat_extended = 279, + lstat_extended = 280, + fstat_extended = 281, + chmod_extended = 282, + fchmod_extended = 283, + access_extended = 284, + settid = 285, + gettid = 286, + setsgroups = 287, + getsgroups = 288, + setwgroups = 289, + getwgroups = 290, + mkfifo_extended = 291, + mkdir_extended = 292, + identitysvc = 293, + shared_region_check_np = 294, + /* 295 old shared_region_map_np */ + vm_pressure_monitor = 296, + psynch_rw_longrdlock = 297, + psynch_rw_yieldwrlock = 298, + psynch_rw_downgrade = 299, + psynch_rw_upgrade = 300, + psynch_mutexwait = 301, + psynch_mutexdrop = 302, + psynch_cvbroad = 303, + psynch_cvsignal = 304, + psynch_cvwait = 305, + psynch_rw_rdlock = 306, + psynch_rw_wrlock = 307, + psynch_rw_unlock = 308, + psynch_rw_unlock2 = 309, + getsid = 310, + settid_with_pid = 311, + psynch_cvclrprepost = 312, + aio_fsync = 313, + aio_return = 314, + aio_suspend = 315, + aio_cancel = 316, + aio_error = 317, + aio_read = 318, + aio_write = 319, + lio_listio = 320, + /* 321 old __pthread_cond_wait */ + iopolicysys = 322, + process_policy = 323, + mlockall = 324, + munlockall = 325, + /* 326 */ + issetugid = 327, + __pthread_kill = 328, + __pthread_sigmask = 329, + __sigwait = 330, + __disable_threadsignal = 331, + __pthread_markcancel = 332, + __pthread_canceled = 333, + __semwait_signal = 334, + /* 335 old utrace */ + proc_info = 336, + sendfile = 337, + stat64 = 338, + fstat64 = 339, + lstat64 = 340, + stat64_extended = 341, + lstat64_extended = 342, + fstat64_extended = 343, + getdirentries64 = 344, + statfs64 = 345, + fstatfs64 = 346, + getfsstat64 = 347, + __pthread_chdir = 348, + __pthread_fchdir = 349, + audit = 350, + auditon = 351, + /* 352 */ + getauid = 353, + setauid = 354, + /* 355 old getaudit */ + /* 356 old setaudit */ + getaudit_addr = 357, + setaudit_addr = 358, + auditctl = 359, + bsdthread_create = 360, + bsdthread_terminate = 361, + kqueue = 362, + kevent = 363, + lchown = 364, + /* 365 old stack_snapshot */ + bsdthread_register = 366, + workq_open = 367, + workq_kernreturn = 368, + kevent64 = 369, + __old_semwait_signal = 370, + __old_semwait_signal_nocancel = 371, + thread_selfid = 372, + ledger = 373, + kevent_qos = 374, + kevent_id = 375, + /* 376 */ + /* 377 */ + /* 378 */ + /* 379 */ + __mac_execve = 380, + __mac_syscall = 381, + __mac_get_file = 382, + __mac_set_file = 383, + __mac_get_link = 384, + __mac_set_link = 385, + __mac_get_proc = 386, + __mac_set_proc = 387, + __mac_get_fd = 388, + __mac_set_fd = 389, + __mac_get_pid = 390, + /* 391 */ + /* 392 */ + /* 393 */ + pselect = 394, + pselect_nocancel = 395, + read_nocancel = 396, + write_nocancel = 397, + open_nocancel = 398, + close_nocancel = 399, + wait4_nocancel = 400, + recvmsg_nocancel = 401, + sendmsg_nocancel = 402, + recvfrom_nocancel = 403, + accept_nocancel = 404, + msync_nocancel = 405, + fcntl_nocancel = 406, + select_nocancel = 407, + fsync_nocancel = 408, + connect_nocancel = 409, + sigsuspend_nocancel = 410, + readv_nocancel = 411, + writev_nocancel = 412, + sendto_nocancel = 413, + pread_nocancel = 414, + pwrite_nocancel = 415, + waitid_nocancel = 416, + poll_nocancel = 417, + msgsnd_nocancel = 418, + msgrcv_nocancel = 419, + sem_wait_nocancel = 420, + aio_suspend_nocancel = 421, + __sigwait_nocancel = 422, + __semwait_signal_nocancel = 423, + __mac_mount = 424, + __mac_get_mount = 425, + __mac_getfsstat = 426, + fsgetpath = 427, + audit_session_self = 428, + audit_session_join = 429, + fileport_makeport = 430, + fileport_makefd = 431, + audit_session_port = 432, + pid_suspend = 433, + pid_resume = 434, + pid_hibernate = 435, + pid_shutdown_sockets = 436, + /* 437 old shared_region_slide_np */ + shared_region_map_and_slide_np = 438, + kas_info = 439, + memorystatus_control = 440, + guarded_open_np = 441, + guarded_close_np = 442, + guarded_kqueue_np = 443, + change_fdguard_np = 444, + usrctl = 445, + proc_rlimit_control = 446, + connectx = 447, + disconnectx = 448, + peeloff = 449, + socket_delegate = 450, + telemetry = 451, + proc_uuid_policy = 452, + memorystatus_get_level = 453, + system_override = 454, + vfs_purge = 455, + sfi_ctl = 456, + sfi_pidctl = 457, + coalition = 458, + coalition_info = 459, + necp_match_policy = 460, + getattrlistbulk = 461, + clonefileat = 462, + openat = 463, + openat_nocancel = 464, + renameat = 465, + faccessat = 466, + fchmodat = 467, + fchownat = 468, + fstatat = 469, + fstatat64 = 470, + linkat = 471, + unlinkat = 472, + readlinkat = 473, + symlinkat = 474, + mkdirat = 475, + getattrlistat = 476, + proc_trace_log = 477, + bsdthread_ctl = 478, + openbyid_np = 479, + recvmsg_x = 480, + sendmsg_x = 481, + thread_selfusage = 482, + csrctl = 483, + guarded_open_dprotected_np = 484, + guarded_write_np = 485, + guarded_pwrite_np = 486, + guarded_writev_np = 487, + renameatx_np = 488, + mremap_encrypted = 489, + netagent_trigger = 490, + stack_snapshot_with_config = 491, + microstackshot = 492, + grab_pgo_data = 493, + persona = 494, + /* 495 */ + mach_eventlink_signal = 496, + mach_eventlink_wait_until = 497, + mach_eventlink_signal_wait_until = 498, + work_interval_ctl = 499, + getentropy = 500, + necp_open = 501, + necp_client_action = 502, + nexus_open = 503, // for those who are intressted http://newosxbook.com/bonus/vol1ch16.html + nexus_register = 504, + nexus_deregister = 505, + nexus_create = 506, + nexus_destroy = 507, + nexus_get_opt = 508, + nexus_set_opt = 509, + channel_open = 510, + channel_get_info = 511, + channel_sync = 512, + channel_get_opt = 513, + channel_set_opt = 514, + ulock_wait = 515, + ulock_wake = 516, + fclonefileat = 517, + fs_snapshot = 518, + register_uexc_handler = 519, + terminate_with_payload = 520, + abort_with_payload = 521, + necp_session_open = 522, + necp_session_action = 523, + setattrlistat = 524, + net_qos_guideline = 525, + fmount = 526, + ntp_adjtime = 527, + ntp_gettime = 528, + os_fault_with_payload = 529, + kqueue_workloop_ctl = 530, + mach_bridge_remote_time = 531, + coalition_ledger = 532, + log_data = 533, + memorystatus_available_memory = 534, + objc_bp_assist_cfg_np = 535, + shared_region_map_and_slide_2_np = 536, + pivot_root = 537, + task_inspect_for_pid = 538, + task_read_for_pid = 539, + preadv = 540, + pwritev = 541, + preadv_nocancel = 542, + pwritev_nocancel = 543, + ulock_wait2 = 544, + proc_info_extended_id = 545, + tracker_action = 546, + debug_syscall_reject = 547, + MAXSYSCALL = 548, + /* invalid = 63, */ } diff --git a/core/sys/info/cpu_intel.odin b/core/sys/info/cpu_intel.odin index 63af853d0..73d4c15e7 100644 --- a/core/sys/info/cpu_intel.odin +++ b/core/sys/info/cpu_intel.odin @@ -117,7 +117,7 @@ init_cpu_name :: proc "c" () { return } - _buf := transmute(^[0x12]u32)&_cpu_name_buf + _buf := (^[0x12]u32)(&_cpu_name_buf) _buf[ 0], _buf[ 1], _buf[ 2], _buf[ 3] = cpuid(0x8000_0002, 0) _buf[ 4], _buf[ 5], _buf[ 6], _buf[ 7] = cpuid(0x8000_0003, 0) _buf[ 8], _buf[ 9], _buf[10], _buf[11] = cpuid(0x8000_0004, 0) diff --git a/core/sys/linux/bits.odin b/core/sys/linux/bits.odin index cfae06013..1e9e5bbbd 100644 --- a/core/sys/linux/bits.odin +++ b/core/sys/linux/bits.odin @@ -48,6 +48,7 @@ Errno :: enum i32 { ENOSYS = 38, ENOTEMPTY = 39, ELOOP = 40, + EUNKNOWN_41 = 41, ENOMSG = 42, EIDRM = 43, ECHRNG = 44, @@ -64,6 +65,7 @@ Errno :: enum i32 { ENOANO = 55, EBADRQC = 56, EBADSLT = 57, + EUNKNOWN_58 = 58, EBFONT = 59, ENOSTR = 60, ENODATA = 61, @@ -150,44 +152,66 @@ Errno :: enum i32 { RDONLY flag is not present, because it has the value of 0, i.e. it is the default, unless WRONLY or RDWR is specified. */ -Open_Flags_Bits :: enum { - WRONLY = 0, - RDWR = 1, - CREAT = 6, - EXCL = 7, - NOCTTY = 8, - TRUNC = 9, - APPEND = 10, - NONBLOCK = 11, - DSYNC = 12, - ASYNC = 13, - DIRECT = 14, - LARGEFILE = 15, - DIRECTORY = 16, - NOFOLLOW = 17, - NOATIME = 18, - CLOEXEC = 19, - PATH = 21, -} +when ODIN_ARCH != .arm64 && ODIN_ARCH != .arm32 { + Open_Flags_Bits :: enum { + WRONLY = 0, + RDWR = 1, + CREAT = 6, + EXCL = 7, + NOCTTY = 8, + TRUNC = 9, + APPEND = 10, + NONBLOCK = 11, + DSYNC = 12, + ASYNC = 13, + DIRECT = 14, + LARGEFILE = 15, + DIRECTORY = 16, + NOFOLLOW = 17, + NOATIME = 18, + CLOEXEC = 19, + PATH = 21, + } + // https://github.com/torvalds/linux/blob/7367539ad4b0f8f9b396baf02110962333719a48/include/uapi/asm-generic/fcntl.h#L19 + #assert(1 << uint(Open_Flags_Bits.WRONLY) == 0o0000000_1) + #assert(1 << uint(Open_Flags_Bits.RDWR) == 0o0000000_2) + #assert(1 << uint(Open_Flags_Bits.CREAT) == 0o00000_100) + #assert(1 << uint(Open_Flags_Bits.EXCL) == 0o00000_200) + #assert(1 << uint(Open_Flags_Bits.NOCTTY) == 0o00000_400) + #assert(1 << uint(Open_Flags_Bits.TRUNC) == 0o0000_1000) + #assert(1 << uint(Open_Flags_Bits.APPEND) == 0o0000_2000) + #assert(1 << uint(Open_Flags_Bits.NONBLOCK) == 0o0000_4000) + #assert(1 << uint(Open_Flags_Bits.DSYNC) == 0o000_10000) + #assert(1 << uint(Open_Flags_Bits.ASYNC) == 0o000_20000) + #assert(1 << uint(Open_Flags_Bits.DIRECT) == 0o000_40000) + #assert(1 << uint(Open_Flags_Bits.LARGEFILE) == 0o00_100000) + #assert(1 << uint(Open_Flags_Bits.DIRECTORY) == 0o00_200000) + #assert(1 << uint(Open_Flags_Bits.NOFOLLOW) == 0o00_400000) + #assert(1 << uint(Open_Flags_Bits.NOATIME) == 0o0_1000000) + #assert(1 << uint(Open_Flags_Bits.CLOEXEC) == 0o0_2000000) + #assert(1 << uint(Open_Flags_Bits.PATH) == 0o_10000000) -// https://github.com/torvalds/linux/blob/7367539ad4b0f8f9b396baf02110962333719a48/include/uapi/asm-generic/fcntl.h#L19 -#assert(1 << uint(Open_Flags_Bits.WRONLY) == 0o0000000_1) -#assert(1 << uint(Open_Flags_Bits.RDWR) == 0o0000000_2) -#assert(1 << uint(Open_Flags_Bits.CREAT) == 0o00000_100) -#assert(1 << uint(Open_Flags_Bits.EXCL) == 0o00000_200) -#assert(1 << uint(Open_Flags_Bits.NOCTTY) == 0o00000_400) -#assert(1 << uint(Open_Flags_Bits.TRUNC) == 0o0000_1000) -#assert(1 << uint(Open_Flags_Bits.APPEND) == 0o0000_2000) -#assert(1 << uint(Open_Flags_Bits.NONBLOCK) == 0o0000_4000) -#assert(1 << uint(Open_Flags_Bits.DSYNC) == 0o000_10000) -#assert(1 << uint(Open_Flags_Bits.ASYNC) == 0o000_20000) -#assert(1 << uint(Open_Flags_Bits.DIRECT) == 0o000_40000) -#assert(1 << uint(Open_Flags_Bits.LARGEFILE) == 0o00_100000) -#assert(1 << uint(Open_Flags_Bits.DIRECTORY) == 0o00_200000) -#assert(1 << uint(Open_Flags_Bits.NOFOLLOW) == 0o00_400000) -#assert(1 << uint(Open_Flags_Bits.NOATIME) == 0o0_1000000) -#assert(1 << uint(Open_Flags_Bits.CLOEXEC) == 0o0_2000000) -#assert(1 << uint(Open_Flags_Bits.PATH) == 0o_10000000) +} else { + Open_Flags_Bits :: enum { + WRONLY = 0, + RDWR = 1, + CREAT = 6, + EXCL = 7, + NOCTTY = 8, + TRUNC = 9, + APPEND = 10, + NONBLOCK = 11, + DSYNC = 12, + ASYNC = 13, + DIRECTORY = 14, + NOFOLLOW = 15, + DIRECT = 16, + LARGEFILE = 17, + NOATIME = 18, + CLOEXEC = 19, + PATH = 21, + } +} /* Bits for FD_Flags bitset @@ -867,7 +891,7 @@ Wait_Option :: enum { WSTOPPED = 1, WEXITED = 2, WCONTINUED = 3, - WNOWAIT = 24, + WNOWAIT = 24, // // For processes created using clone __WNOTHREAD = 29, __WALL = 30, @@ -946,9 +970,22 @@ Sig_Stack_Flag :: enum i32 { AUTODISARM = 31, } +Sig_Action_Flag :: enum u32 { + NOCLDSTOP = 0, + NOCLDWAIT = 1, + SIGINFO = 2, + UNSUPPORTED = 10, + EXPOSE_TAGBITS = 11, + RESTORER = 26, + ONSTACK = 27, + RESTART = 28, + NODEFER = 30, + RESETHAND = 31, +} + /* Type of socket to create - - For TCP you want to use SOCK_STREAM + - For TCP you want to use SOCK_STREAM - For UDP you want to use SOCK_DGRAM Also see `Protocol` */ @@ -1427,16 +1464,16 @@ Futex_Flags_Bits :: enum { Kind of operation on futex, see FUTEX_WAKE_OP */ Futex_Arg_Op :: enum { - SET = 0, /* uaddr2 = oparg; */ - ADD = 1, /* uaddr2 += oparg; */ - OR = 2, /* uaddr2 |= oparg; */ - ANDN = 3, /* uaddr2 &= ~oparg; */ - XOR = 4, /* uaddr2 ^= oparg; */ - PO2_SET = 0, /* uaddr2 = 1< (Errno) { stat :: proc "contextless" (filename: cstring, stat: ^Stat) -> (Errno) { when size_of(int) == 8 { when ODIN_ARCH == .arm64 { - ret := syscall(SYS_fstatat, AT_FDCWD, cast(rawptr) filename, stat) + ret := syscall(SYS_fstatat, AT_FDCWD, cast(rawptr) filename, stat, 0) return Errno(-ret) } else { ret := syscall(SYS_stat, cast(rawptr) filename, stat) @@ -200,10 +200,25 @@ brk :: proc "contextless" (addr: uintptr) -> (Errno) { return Errno(-ret) } +/* + Returns from signal handlers on some archs. +*/ +rt_sigreturn :: proc "c" () -> ! { + intrinsics.syscall(uintptr(SYS_rt_sigreturn)) + unreachable() +} + /* Alter an action taken by a process. */ -rt_sigaction :: proc "contextless" (sig: Signal, sigaction: ^Sig_Action, old_sigaction: ^Sig_Action) -> Errno { +rt_sigaction :: proc "contextless" (sig: Signal, sigaction: ^Sig_Action($T), old_sigaction: ^Sig_Action) -> Errno { + // NOTE(jason): It appears that the restorer is required for i386 and amd64 + when ODIN_ARCH == .i386 || ODIN_ARCH == .amd64 { + sigaction.flags += {.RESTORER} + } + if sigaction != nil && sigaction.restorer == nil && .RESTORER in sigaction.flags { + sigaction.restorer = rt_sigreturn + } ret := syscall(SYS_rt_sigaction, sig, sigaction, old_sigaction, size_of(Sig_Set)) return Errno(-ret) } @@ -1123,7 +1138,7 @@ ftruncate :: proc "contextless" (fd: Fd, length: i64) -> (Errno) { ret := syscall(SYS_ftruncate64, fd, compat64_arg_pair(length)) return Errno(-ret) } else { - ret := syscall(SYS_truncate, fd, compat64_arg_pair(length)) + ret := syscall(SYS_ftruncate, fd, compat64_arg_pair(length)) return Errno(-ret) } } @@ -1231,7 +1246,7 @@ creat :: proc "contextless" (name: cstring, mode: Mode) -> (Fd, Errno) { */ link :: proc "contextless" (target: cstring, linkpath: cstring) -> (Errno) { when ODIN_ARCH == .arm64 { - ret := syscall(SYS_linkat, AT_FDCWD, cast(rawptr) target, AT_FDCWD, cast(rawptr) linkpath) + ret := syscall(SYS_linkat, AT_FDCWD, cast(rawptr) target, AT_FDCWD, cast(rawptr) linkpath, 0) return Errno(-ret) } else { ret := syscall(SYS_link, cast(rawptr) target, cast(rawptr) linkpath) @@ -1261,7 +1276,7 @@ unlink :: proc "contextless" (name: cstring) -> (Errno) { */ symlink :: proc "contextless" (target: cstring, linkpath: cstring) -> (Errno) { when ODIN_ARCH == .arm64 { - ret := syscall(SYS_symlinkat, AT_FDCWD, cast(rawptr) target, cast(rawptr) linkpath) + ret := syscall(SYS_symlinkat, cast(rawptr) target, AT_FDCWD, cast(rawptr) linkpath) return Errno(-ret) } else { ret := syscall(SYS_symlink, cast(rawptr) target, cast(rawptr) linkpath) @@ -1291,7 +1306,7 @@ readlink :: proc "contextless" (name: cstring, buf: []u8) -> (int, Errno) { */ chmod :: proc "contextless" (name: cstring, mode: Mode) -> (Errno) { when ODIN_ARCH == .arm64 { - ret := syscall(SYS_fchmodat, cast(rawptr) name, transmute(u32) mode, 0) + ret := syscall(SYS_fchmodat, AT_FDCWD, cast(rawptr) name, transmute(u32) mode) return Errno(-ret) } else { ret := syscall(SYS_chmod, cast(rawptr) name, transmute(u32) mode) @@ -2226,8 +2241,7 @@ futex_wake :: proc "contextless" (futex: ^Futex, op: Futex_Wake_Type, flags: Fut Returns the total number of waiters that have been woken up plus the number of waiters requeued. */ futex_cmp_requeue :: proc "contextless" (futex: ^Futex, op: Futex_Cmp_Requeue_Type, flags: Futex_Flags, requeue_threshold: u32, - requeue_max: i32, requeue_futex: ^Futex, val: i32) -> (int, Errno) -{ + requeue_max: i32, requeue_futex: ^Futex, val: i32) -> (int, Errno) { futex_flags := cast(u32) op + transmute(u32) flags ret := syscall(SYS_futex, futex, futex_flags, requeue_threshold, requeue_max, requeue_futex, val) return errno_unwrap(ret, int) @@ -2238,8 +2252,7 @@ futex_cmp_requeue :: proc "contextless" (futex: ^Futex, op: Futex_Cmp_Requeue_Ty Returns the total number of waiters that have been woken up. */ futex_requeue :: proc "contextless" (futex: ^Futex, op: Futex_Requeue_Type, flags: Futex_Flags, requeue_threshold: u32, - requeue_max: i32, requeue_futex: ^Futex) -> (int, Errno) -{ + requeue_max: i32, requeue_futex: ^Futex) -> (int, Errno) { futex_flags := cast(u32) op + transmute(u32) flags ret := syscall(SYS_futex, futex, futex_flags, requeue_threshold, requeue_max, requeue_futex) return errno_unwrap(ret, int) @@ -2250,8 +2263,7 @@ futex_requeue :: proc "contextless" (futex: ^Futex, op: Futex_Requeue_Type, flag purpose is to allow implementing conditional values sync primitive, it seems like. */ futex_wake_op :: proc "contextless" (futex: ^Futex, op: Futex_Wake_Op_Type, flags: Futex_Flags, wakeup: i32, - dst_wakeup, dst: ^Futex, futex_op: u32) -> (int, Errno) -{ + dst_wakeup, dst: ^Futex, futex_op: u32) -> (int, Errno) { futex_flags := cast(u32) op + transmute(u32) flags ret := syscall(SYS_futex, futex, futex_flags, wakeup, dst_wakeup, dst, futex_op) return errno_unwrap(ret, int) @@ -2261,8 +2273,7 @@ futex_wake_op :: proc "contextless" (futex: ^Futex, op: Futex_Wake_Op_Type, flag Same as wait, but mask specifies bits that must be equal for the mutex to wake up. */ futex_wait_bitset :: proc "contextless" (futex: ^Futex, op: Futex_Wait_Bitset_Type, flags: Futex_Flags, val: u32, - timeout: ^Time_Spec, mask: u32) -> (int, Errno) -{ + timeout: ^Time_Spec, mask: u32) -> (int, Errno) { futex_flags := cast(u32) op + transmute(u32) flags ret := syscall(SYS_futex, futex, futex_flags, val, timeout, 0, mask) return errno_unwrap(ret, int) @@ -2271,8 +2282,7 @@ futex_wait_bitset :: proc "contextless" (futex: ^Futex, op: Futex_Wait_Bitset_Ty /* Wake up on bitset. */ -futex_wake_bitset :: proc "contextless" (futex: ^Futex, op: Futex_Wake_Bitset_Type, flags: Futex_Flags, n_wakeup: u32, mask: u32) -> (int, Errno) -{ +futex_wake_bitset :: proc "contextless" (futex: ^Futex, op: Futex_Wake_Bitset_Type, flags: Futex_Flags, n_wakeup: u32, mask: u32) -> (int, Errno) { futex_flags := cast(u32) op + transmute(u32) flags ret := syscall(SYS_futex, futex, futex_flags, n_wakeup, 0, 0, mask) return errno_unwrap(ret, int) @@ -2280,7 +2290,7 @@ futex_wake_bitset :: proc "contextless" (futex: ^Futex, op: Futex_Wake_Bitset_Ty // TODO(flysand): Priority inheritance (PI) futicees -futex :: proc { +futex :: proc{ futex_wait, futex_wake, futex_cmp_requeue, @@ -2476,8 +2486,8 @@ tgkill :: proc "contextless" (tgid, tid: Pid, sig: Signal) -> (Errno) { Wait on process, process group or pid file descriptor. Available since Linux 2.6.10. */ -waitid :: proc "contextless" (id_type: Id_Type, id: Id, sig_info: ^Sig_Info, options: Wait_Options) -> (Errno) { - ret := syscall(SYS_waitid, id_type, id, sig_info, transmute(i32) options) +waitid :: proc "contextless" (id_type: Id_Type, id: Id, sig_info: ^Sig_Info, options: Wait_Options, rusage: ^RUsage) -> (Errno) { + ret := syscall(SYS_waitid, id_type, id, sig_info, transmute(i32) options, rusage) return Errno(-ret) } @@ -2504,7 +2514,7 @@ waitid :: proc "contextless" (id_type: Id_Type, id: Id, sig_info: ^Sig_Info, opt Available since Linux 2.6.16. */ openat :: proc "contextless" (fd: Fd, name: cstring, flags: Open_Flags, mode: Mode = {}) -> (Fd, Errno) { - ret := syscall(SYS_openat, fd, AT_FDCWD, transmute(uintptr) name, transmute(u32) mode) + ret := syscall(SYS_openat, fd, transmute(uintptr) name, transmute(u32) flags, transmute(u32) mode) return errno_unwrap(ret, Fd) } @@ -2583,8 +2593,8 @@ linkat :: proc "contextless" (target_dirfd: Fd, oldpath: cstring, link_dirfd: Fd Create a symbolic link at specified dirfd. Available since Linux 2.6.16. */ -symlinkat :: proc "contextless" (dirfd: Fd, target: cstring, linkpath: cstring) -> (Errno) { - ret := syscall(SYS_symlinkat, dirfd, cast(rawptr) target, cast(rawptr) linkpath) +symlinkat :: proc "contextless" (target: cstring, dirfd: Fd, linkpath: cstring) -> (Errno) { + ret := syscall(SYS_symlinkat, cast(rawptr) target, dirfd, cast(rawptr) linkpath) return Errno(-ret) } @@ -2619,13 +2629,13 @@ faccessat :: proc "contextless" (dirfd: Fd, name: cstring, mode: Mode = F_OK) -> Wait for events on a file descriptor. Available since Linux 2.6.16. */ -ppoll :: proc "contextless" (fds: []Poll_Fd, timeout: ^Time_Spec, sigmask: ^Sig_Set) -> (Errno) { +ppoll :: proc "contextless" (fds: []Poll_Fd, timeout: ^Time_Spec, sigmask: ^Sig_Set) -> (i32, Errno) { when size_of(int) == 8 { ret := syscall(SYS_ppoll, raw_data(fds), len(fds), timeout, sigmask, size_of(Sig_Set)) - return Errno(-ret) + return errno_unwrap(ret, i32) } else { ret := syscall(SYS_ppoll_time64, raw_data(fds), len(fds), timeout, sigmask, size_of(Sig_Set)) - return Errno(-ret) + return errno_unwrap(ret, i32) } } @@ -2808,8 +2818,8 @@ getrandom :: proc "contextless" (buf: []u8, flags: Get_Random_Flags) -> (int, Er Execute program relative to a directory file descriptor. Available since Linux 3.19. */ -execveat :: proc "contextless" (dirfd: Fd, name: cstring, argv: [^]cstring, envp: [^]cstring) -> (Errno) { - ret := syscall(SYS_execveat, dirfd, cast(rawptr) name, cast(rawptr) argv, cast(rawptr) envp) +execveat :: proc "contextless" (dirfd: Fd, name: cstring, argv: [^]cstring, envp: [^]cstring, flags: FD_Flags = {}) -> (Errno) { + ret := syscall(SYS_execveat, dirfd, cast(rawptr) name, cast(rawptr) argv, cast(rawptr) envp, transmute(i32) flags) return Errno(-ret) } diff --git a/core/sys/linux/types.odin b/core/sys/linux/types.odin index 5053e1e1c..e3fe67a9b 100644 --- a/core/sys/linux/types.odin +++ b/core/sys/linux/types.odin @@ -18,7 +18,7 @@ Gid :: distinct u32 /* Type for Process IDs, Thread IDs, Thread group ID. */ -Pid :: distinct int +Pid :: distinct i32 /* Type for any of: pid, pidfd, pgid. @@ -89,11 +89,11 @@ FD_Flags :: bit_set[FD_Flags_Bits; i32] Represents file's permission and status bits **Example:** When you're passing a value of this type the recommended usage is: - + ``` linux.Mode{.S_IXOTH, .S_IROTH} | linux.S_IRWXU | linux.S_IRWXG ``` - + This would generate a mode that has full permissions for the file's owner and group, and only "read" and "execute" bits for others. @@ -151,9 +151,9 @@ when ODIN_ARCH == .amd64 { size: i64, blksize: uint, blocks: u64, - atim: Time_Spec, - mtim: Time_Spec, - ctim: Time_Spec, + atime: Time_Spec, + mtime: Time_Spec, + ctime: Time_Spec, ino: Inode, } } @@ -495,16 +495,15 @@ Pid_FD_Flags :: bit_set[Pid_FD_Flags_Bits; i32] // 1. Odin's bitfields start from 0, whereas signals start from 1 // 2. It's unclear how bitfields act in terms of ABI (are they an array of ints or an array of longs?). // it makes a difference because ARM is big endian. -@private _SIGSET_NWORDS :: (1024 / (8 * size_of(uint))) +@private _SIGSET_NWORDS :: (8 / size_of(uint)) Sig_Set :: [_SIGSET_NWORDS]uint @private SI_MAX_SIZE :: 128 -@private SI_ARCH_PREAMBLE :: 3 * size_of(i32) -@private SI_PAD_SIZE :: (SI_MAX_SIZE - SI_ARCH_PREAMBLE) / size_of(i32) -@private SI_TIMER_PAD_SIZE :: size_of(Uid) - size_of(i32) +@private SI_ARCH_PREAMBLE :: 4 * size_of(i32) +@private SI_PAD_SIZE :: SI_MAX_SIZE - SI_ARCH_PREAMBLE Sig_Handler_Fn :: #type proc "c" (sig: Signal) -Sig_Restore_Fn :: #type proc "c" () +Sig_Restore_Fn :: #type proc "c" () -> ! Sig_Info :: struct #packed { signo: Signal, @@ -518,8 +517,9 @@ Sig_Info :: struct #packed { uid: Uid, /* sender's uid */ }, using _timer: struct { - timerid: i32, /* timer id */ + timerid: i32, /* timer id */ overrun: i32, /* overrun count */ + value: Sig_Val, /* timer value */ }, /* POSIX.1b signals */ using _rt: struct { @@ -528,8 +528,8 @@ Sig_Info :: struct #packed { }, /* SIGCHLD */ using _sigchld: struct { - _pid1: Pid, /* which child */ - _uid1: Uid, /* sender's uid */ + _pid1: Pid, /* which child */ + _uid1: Uid, /* sender's uid */ status: i32, /* exit code */ utime: uint, stime: uint, //clock_t @@ -537,7 +537,24 @@ Sig_Info :: struct #packed { /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */ using _sigfault: struct { addr: rawptr, /* faulting insn/memory ref. */ - addr_lsb: i16, /* LSB of the reported address */ + using _: struct #raw_union { + trapno: i32, /* Trap number that caused signal */ + addr_lsb: i16, /* LSB of the reported address */ + using _addr_bnd: struct { + _pad2: u64, + lower: rawptr, /* lower bound during fault */ + upper: rawptr, /* upper bound during fault */ + }, + using _addr_pkey: struct { + _pad3: u64, + pkey: u32, /* protection key on PTE that faulted */ + }, + using _perf: struct { + perf_data: u64, + perf_type: u32, + perf_flags: u32, + }, + }, }, /* SIGPOLL */ using _sigpoll: struct { @@ -547,12 +564,43 @@ Sig_Info :: struct #packed { /* SIGSYS */ using _sigsys: struct { call_addr: rawptr, /* calling user insn */ - syscall: i32, /* triggering system call number */ - arch: u32, /* AUDIT_ARCH_* of syscall */ + syscall: i32, /* triggering system call number */ + arch: u32, /* AUDIT_ARCH_* of syscall */ }, }, } +#assert(size_of(Sig_Info) == 128) +when ODIN_ARCH == .amd64 || ODIN_ARCH == .arm64 { + #assert(offset_of(Sig_Info, signo) == 0x00) + #assert(offset_of(Sig_Info, errno) == 0x04) + #assert(offset_of(Sig_Info, code) == 0x08) + #assert(offset_of(Sig_Info, pid) == 0x10) + #assert(offset_of(Sig_Info, uid) == 0x14) + #assert(offset_of(Sig_Info, timerid) == 0x10) + #assert(offset_of(Sig_Info, overrun) == 0x14) + #assert(offset_of(Sig_Info, value) == 0x18) + #assert(offset_of(Sig_Info, status) == 0x18) + #assert(offset_of(Sig_Info, utime) == 0x20) + #assert(offset_of(Sig_Info, stime) == 0x28) + #assert(offset_of(Sig_Info, addr) == 0x10) + #assert(offset_of(Sig_Info, addr_lsb) == 0x18) + #assert(offset_of(Sig_Info, trapno) == 0x18) + #assert(offset_of(Sig_Info, lower) == 0x20) + #assert(offset_of(Sig_Info, upper) == 0x28) + #assert(offset_of(Sig_Info, pkey) == 0x20) + #assert(offset_of(Sig_Info, perf_data) == 0x18) + #assert(offset_of(Sig_Info, perf_type) == 0x20) + #assert(offset_of(Sig_Info, perf_flags) == 0x24) + #assert(offset_of(Sig_Info, band) == 0x10) + #assert(offset_of(Sig_Info, fd) == 0x18) + #assert(offset_of(Sig_Info, call_addr) == 0x10) + #assert(offset_of(Sig_Info, syscall) == 0x18) + #assert(offset_of(Sig_Info, arch) == 0x1C) +} else { + // TODO +} + SIGEV_MAX_SIZE :: 64 SIGEV_PAD_SIZE :: ((SIGEV_MAX_SIZE-size_of(i32)*2+size_of(Sig_Val))/size_of(i32)) @@ -583,12 +631,20 @@ Sig_Stack :: struct { size: uintptr, } +Sig_Action_Special :: enum uint { + SIG_DFL = 0, + SIG_IGN = 1, + SIG_ERR = ~uint(0), +} + +Sig_Action_Flags :: bit_set[Sig_Action_Flag; uint] Sig_Action :: struct($T: typeid) { using _u: struct #raw_union { handler: Sig_Handler_Fn, sigaction: #type proc "c" (sig: Signal, si: ^Sig_Info, ctx: ^T), + special: Sig_Action_Special, }, - flags: uint, + flags: Sig_Action_Flags, restorer: Sig_Restore_Fn, mask: Sig_Set, } @@ -733,7 +789,7 @@ RLimit :: struct { /* Structure representing how much of each resource got used. -*/ +*/ RUsage :: struct { utime: Time_Val, stime: Time_Val, @@ -813,7 +869,7 @@ when size_of(int) == 8 || ODIN_ARCH == .i386 { cpid: Pid, lpid: Pid, nattach: uint, - _: [2]uint, + _: [2]uint, } } diff --git a/core/sys/linux/wrappers.odin b/core/sys/linux/wrappers.odin index 13073315d..7a30c3bde 100644 --- a/core/sys/linux/wrappers.odin +++ b/core/sys/linux/wrappers.odin @@ -48,7 +48,7 @@ WCOREDUMP :: #force_inline proc "contextless" (s: u32) -> bool { return 1 << ((cast(uint)(sig) - 1) % (8*size_of(uint))) } @private _sigword :: proc "contextless" (sig: Signal) -> (uint) { - return (cast(uint)sig - 1) / (8*size_of(uint)) + return (cast(uint)sig - 1) / (8*size_of(uint)) } // TODO: sigaddset etc @@ -85,13 +85,13 @@ dirent_iterate_buf :: proc "contextless" (buf: []u8, offs: ^int) -> (d: ^Dirent, /// Obtain the name of dirent as a string /// The lifetime of the string is bound to the lifetime of the provided dirent structure dirent_name :: proc "contextless" (dirent: ^Dirent) -> string #no_bounds_check { - str := transmute([^]u8) &dirent.name + str := ([^]u8)(&dirent.name) // Note(flysand): The string size calculated above applies only to the ideal case // we subtract 1 byte from the string size, because a null terminator is guaranteed // to be present. But! That said, the dirents are aligned to 8 bytes and the padding // between the null terminator and the start of the next struct may be not initialized // which means we also have to scan these garbage bytes. - str_size := (cast(int) dirent.reclen) - 1 - cast(int) offset_of(Dirent, name) + str_size := int(dirent.reclen) - 1 - cast(int)offset_of(Dirent, name) // This skips *only* over the garbage, since if we're not garbage we're at nul terminator, // which skips this loop for str[str_size] != 0 { @@ -115,7 +115,6 @@ futex_op :: proc "contextless" (arg_op: Futex_Arg_Op, cmp_op: Futex_Cmp_Op, op_a /// Helper function for constructing the config for caches perf_cache_config :: #force_inline proc "contextless" (id: Perf_Hardware_Cache_Id, op: Perf_Hardware_Cache_Op_Id, - res: Perf_Hardware_Cache_Result_Id) -> u64 -{ + res: Perf_Hardware_Cache_Result_Id) -> u64 { return u64(id) | (u64(op) << 8) | (u64(res) << 16) } \ No newline at end of file diff --git a/core/sys/windows/tlhelp.odin b/core/sys/windows/tlhelp.odin new file mode 100644 index 000000000..7e224dd05 --- /dev/null +++ b/core/sys/windows/tlhelp.odin @@ -0,0 +1,101 @@ +//+build windows +package sys_windows + +foreign import kernel32 "system:Kernel32.lib" + +@(default_calling_convention="system") +foreign kernel32 { + CreateToolhelp32Snapshot :: proc (dwFlags: DWORD, th32ProcessID: DWORD) -> HANDLE --- + Process32FirstW :: proc (hSnapshot: HANDLE, lppe: LPPROCESSENTRY32W) -> BOOL --- + Process32NextW :: proc (hSnapshot: HANDLE, lppe: LPPROCESSENTRY32W) -> BOOL --- + Thread32First :: proc (hSnapshot: HANDLE, lpte: LPTHREADENTRY32) -> BOOL --- + Thread32Next :: proc (hSnapshot: HANDLE, lpte: LPTHREADENTRY32) -> BOOL --- + Module32FirstW :: proc (hSnapshot: HANDLE, lpme: LPMODULEENTRY32W) -> BOOL --- + Module32NextW :: proc (hSnapshot: HANDLE, lpme: LPMODULEENTRY32W) -> BOOL --- + Heap32ListFirst :: proc (hSnapshot: HANDLE, lphl: LPHEAPLIST32) -> BOOL --- + Heap32ListNext :: proc (hSnapshot: HANDLE, lphl: LPHEAPLIST32) -> BOOL --- + Heap32First :: proc (lphe: LPHEAPENTRY32, th32ProcessID: DWORD, th32HeapID: ULONG_PTR) -> BOOL --- + Heap32Next :: proc (lphe: LPHEAPENTRY32) -> BOOL --- + Toolhelp32ReadProcessMemory :: proc ( + th32ProcessID: DWORD, + lpBaseAddress: LPCVOID, + lpBuffer: LPVOID, + cbRead: SIZE_T, + lpNumberOfBytesRead: ^SIZE_T, + ) -> BOOL --- +} + +MAX_MODULE_NAME32 :: 255 + +TH32CS_INHERIT :: 0x80000000 +TH32CS_SNAPHEAPLIST :: 0x00000001 +TH32CS_SNAPPROCESS :: 0x00000002 +TH32CS_SNAPTHREAD :: 0x00000004 +TH32CS_SNAPMODULE :: 0x00000008 +TH32CS_SNAPMODULE32 :: 0x00000010 +TH32CS_SNAPALL :: TH32CS_SNAPHEAPLIST | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD | TH32CS_SNAPMODULE + +PROCESSENTRY32W :: struct { + dwSize: DWORD, + cntUsage: DWORD, + th32ProcessID: DWORD, + th32DefaultHeapID: ULONG_PTR, + th32ModuleID: DWORD, + cntThreads: DWORD, + th32ParentProcessID: DWORD, + pcPriClassBase: LONG, + dwFlags: DWORD, + szExeFile: [MAX_PATH]WCHAR, +} + +LPPROCESSENTRY32W :: ^PROCESSENTRY32W + +THREADENTRY32 :: struct { + dwSize: DWORD, + cntUsage: DWORD, + th32ThreadID: DWORD, + th32OwnerProcessID: DWORD, + tpBasePri: LONG, + tpDeltaPri: LONG, + dwFlags: DWORD, +} + +LPTHREADENTRY32 :: ^THREADENTRY32 + +MODULEENTRY32W :: struct { + dwSize: DWORD, + th32ModuleID: DWORD, + th32ProcessID: DWORD, + GlblcntUsage: DWORD, + ProccntUsage: DWORD, + modBaseAddr: BYTE, + modBaseSize: DWORD, + hModule: HMODULE, + szModule: [MAX_MODULE_NAME32 + 1]WCHAR, + szExePath: [MAX_PATH]WCHAR, +} + +LPMODULEENTRY32W :: ^MODULEENTRY32W + +HEAPLIST32 :: struct { + dwSize: SIZE_T, + th32ProcessID: DWORD, + th32HeapID: ULONG_PTR, + dwFlags: DWORD, +} + +LPHEAPLIST32 :: ^HEAPLIST32 + +HEAPENTRY32 :: struct { + dwSize: SIZE_T, + hHandle: HANDLE, + dwAddress: ULONG_PTR, + dwBlockSize: SIZE_T, + dwFlags: DWORD, + dwLockCount: DWORD, + dwResvd: DWORD, + th32ProcessID: DWORD, + th32HeapID: ULONG_PTR, +} + +LPHEAPENTRY32 :: ^HEAPENTRY32 diff --git a/core/testing/runner.odin b/core/testing/runner.odin index 3510856c7..fa7c2ffd2 100644 --- a/core/testing/runner.odin +++ b/core/testing/runner.odin @@ -51,12 +51,11 @@ get_log_level :: #force_inline proc() -> runtime.Logger_Level { // Always use .Debug in `-debug` mode. return .Debug } else { - when LOG_LEVEL == "debug" { return .Debug } - else when LOG_LEVEL == "info" { return .Info } - else when LOG_LEVEL == "warning" { return .Warning } - else when LOG_LEVEL == "error" { return .Error } - else when LOG_LEVEL == "fatal" { return .Fatal } - else { + when LOG_LEVEL == "debug" { return .Debug } else + when LOG_LEVEL == "info" { return .Info } else + when LOG_LEVEL == "warning" { return .Warning } else + when LOG_LEVEL == "error" { return .Error } else + when LOG_LEVEL == "fatal" { return .Fatal } else { #panic("Unknown `ODIN_TEST_LOG_LEVEL`: \"" + LOG_LEVEL + "\", possible levels are: \"debug\", \"info\", \"warning\", \"error\", or \"fatal\".") } } @@ -198,8 +197,11 @@ runner :: proc(internal_tests: []Internal_Test) -> bool { } } + // `-vet` needs parameters to be shadowed by themselves first as an + // explicit declaration, to allow the next line to work. + internal_tests := internal_tests // Intentional shadow with user-specified tests. - internal_tests := select_internal_tests[:] + internal_tests = select_internal_tests[:] } total_failure_count := 0 diff --git a/core/testing/signal_handler.odin b/core/testing/signal_handler.odin index 891f6bbb6..0b06852ce 100644 --- a/core/testing/signal_handler.odin +++ b/core/testing/signal_handler.odin @@ -9,6 +9,7 @@ Stop_Reason :: enum { Illegal_Instruction, Arithmetic_Error, Segmentation_Fault, + Unhandled_Trap, } test_assertion_failure_proc :: proc(prefix, message: string, loc: runtime.Source_Code_Location) -> ! { diff --git a/core/testing/signal_handler_libc.odin b/core/testing/signal_handler_libc.odin index 0ab34776e..d89d84fae 100644 --- a/core/testing/signal_handler_libc.odin +++ b/core/testing/signal_handler_libc.odin @@ -19,6 +19,11 @@ import "core:os" @(private="file", thread_local) local_test_index: libc.sig_atomic_t +// Windows does not appear to have a SIGTRAP, so this is defined here, instead +// of in the libc package, just so there's no confusion about it being +// available there. +SIGTRAP :: 5 + @(private="file") stop_runner_callback :: proc "c" (sig: libc.int) { prev := intrinsics.atomic_add(&stop_runner_flag, 1) @@ -110,6 +115,10 @@ _setup_signal_handler :: proc() { // For tests: // Catch asserts and panics. libc.signal(libc.SIGILL, stop_test_callback) + when ODIN_OS == .Linux || ODIN_OS == .FreeBSD || ODIN_OS == .Haiku || ODIN_OS == .OpenBSD || ODIN_OS == .NetBSD || ODIN_OS == .Darwin { + // Catch panics on Darwin and unhandled calls to `debug_trap`. + libc.signal(SIGTRAP, stop_test_callback) + } // Catch arithmetic errors. libc.signal(libc.SIGFPE, stop_test_callback) // Catch segmentation faults (illegal memory access). @@ -141,6 +150,7 @@ _should_stop_test :: proc() -> (test_index: int, reason: Stop_Reason, ok: bool) case libc.SIGFPE: reason = .Arithmetic_Error case libc.SIGILL: reason = .Illegal_Instruction case libc.SIGSEGV: reason = .Segmentation_Fault + case SIGTRAP: reason = .Unhandled_Trap } ok = true } diff --git a/core/thread/thread.odin b/core/thread/thread.odin index 55f73d106..80e60d6cf 100644 --- a/core/thread/thread.odin +++ b/core/thread/thread.odin @@ -6,6 +6,8 @@ import "base:intrinsics" _ :: intrinsics +IS_SUPPORTED :: _IS_SUPPORTED + Thread_Proc :: #type proc(^Thread) MAX_USER_ARGUMENTS :: 8 @@ -58,7 +60,9 @@ Thread :: struct { creation_allocator: mem.Allocator, } -#assert(size_of(Thread{}.user_index) == size_of(uintptr)) +when IS_SUPPORTED { + #assert(size_of(Thread{}.user_index) == size_of(uintptr)) +} Thread_Priority :: enum { Normal, diff --git a/core/thread/thread_js.odin b/core/thread/thread_js.odin deleted file mode 100644 index 4f5b5b086..000000000 --- a/core/thread/thread_js.odin +++ /dev/null @@ -1,47 +0,0 @@ -//+build js -package thread - -import "base:intrinsics" -import "core:sync" -import "core:mem" - -Thread_Os_Specific :: struct {} - -_thread_priority_map := [Thread_Priority]i32{ - .Normal = 0, - .Low = -2, - .High = +2, -} - -_create :: proc(procedure: Thread_Proc, priority := Thread_Priority.Normal) -> ^Thread { - unimplemented("core:thread procedure not supported on js target") -} - -_start :: proc(t: ^Thread) { - unimplemented("core:thread procedure not supported on js target") -} - -_is_done :: proc(t: ^Thread) -> bool { - unimplemented("core:thread procedure not supported on js target") -} - -_join :: proc(t: ^Thread) { - unimplemented("core:thread procedure not supported on js target") -} - -_join_multiple :: proc(threads: ..^Thread) { - unimplemented("core:thread procedure not supported on js target") -} - -_destroy :: proc(thread: ^Thread) { - unimplemented("core:thread procedure not supported on js target") -} - -_terminate :: proc(using thread : ^Thread, exit_code: int) { - unimplemented("core:thread procedure not supported on js target") -} - -_yield :: proc() { - unimplemented("core:thread procedure not supported on js target") -} - diff --git a/core/thread/thread_other.odin b/core/thread/thread_other.odin new file mode 100644 index 000000000..34bbfda08 --- /dev/null +++ b/core/thread/thread_other.odin @@ -0,0 +1,47 @@ +//+build js, wasi, orca +package thread + +import "base:intrinsics" + +_IS_SUPPORTED :: false + +Thread_Os_Specific :: struct {} + +_thread_priority_map := [Thread_Priority]i32{ + .Normal = 0, + .Low = -2, + .High = +2, +} + +_create :: proc(procedure: Thread_Proc, priority := Thread_Priority.Normal) -> ^Thread { + unimplemented("core:thread procedure not supported on target") +} + +_start :: proc(t: ^Thread) { + unimplemented("core:thread procedure not supported on target") +} + +_is_done :: proc(t: ^Thread) -> bool { + unimplemented("core:thread procedure not supported on target") +} + +_join :: proc(t: ^Thread) { + unimplemented("core:thread procedure not supported on target") +} + +_join_multiple :: proc(threads: ..^Thread) { + unimplemented("core:thread procedure not supported on target") +} + +_destroy :: proc(thread: ^Thread) { + unimplemented("core:thread procedure not supported on target") +} + +_terminate :: proc(using thread : ^Thread, exit_code: int) { + unimplemented("core:thread procedure not supported on target") +} + +_yield :: proc() { + unimplemented("core:thread procedure not supported on target") +} + diff --git a/core/thread/thread_unix.odin b/core/thread/thread_unix.odin index 5291917da..363f50862 100644 --- a/core/thread/thread_unix.odin +++ b/core/thread/thread_unix.odin @@ -6,6 +6,8 @@ import "core:sync" import "core:sys/unix" import "core:time" +_IS_SUPPORTED :: true + CAS :: sync.atomic_compare_exchange_strong // NOTE(tetra): Aligned here because of core/unix/pthread_linux.odin/pthread_t. @@ -23,10 +25,8 @@ _create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread { __unix_thread_entry_proc :: proc "c" (t: rawptr) -> rawptr { t := (^Thread)(t) - when ODIN_OS != .Darwin { - // We need to give the thread a moment to start up before we enable cancellation. - can_set_thread_cancel_state := unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_ENABLE, nil) == 0 - } + // We need to give the thread a moment to start up before we enable cancellation. + can_set_thread_cancel_state := unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_ENABLE, nil) == 0 sync.lock(&t.mutex) @@ -42,12 +42,10 @@ _create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread { return nil } - when ODIN_OS != .Darwin { - // Enable thread's cancelability. - if can_set_thread_cancel_state { - unix.pthread_setcanceltype (unix.PTHREAD_CANCEL_ASYNCHRONOUS, nil) - unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_ENABLE, nil) - } + // Enable thread's cancelability. + if can_set_thread_cancel_state { + unix.pthread_setcanceltype (unix.PTHREAD_CANCEL_ASYNCHRONOUS, nil) + unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_ENABLE, nil) } { @@ -169,10 +167,17 @@ _destroy :: proc(t: ^Thread) { } _terminate :: proc(t: ^Thread, exit_code: int) { - // `pthread_cancel` is unreliable on Darwin for unknown reasons. - when ODIN_OS != .Darwin { - unix.pthread_cancel(t.unix_thread) - } + // NOTE(Feoramund): For thread cancellation to succeed on BSDs and + // possibly Darwin systems, the thread must call one of the pthread + // cancelation points at some point after this. + // + // The most obvious one of these is `pthread_cancel`, but there is an + // entire list of functions that act as cancelation points available in the + // pthreads manual page. + // + // This is in contrast to behavior I have seen on Linux where the thread is + // just terminated. + unix.pthread_cancel(t.unix_thread) } _yield :: proc() { diff --git a/core/thread/thread_windows.odin b/core/thread/thread_windows.odin index 314ef5842..8da75a2d9 100644 --- a/core/thread/thread_windows.odin +++ b/core/thread/thread_windows.odin @@ -6,6 +6,8 @@ import "base:intrinsics" import "core:sync" import win32 "core:sys/windows" +_IS_SUPPORTED :: true + Thread_Os_Specific :: struct { win32_thread: win32.HANDLE, win32_thread_id: win32.DWORD, diff --git a/core/unicode/letter.odin b/core/unicode/letter.odin index af345f733..e6d0261c6 100644 --- a/core/unicode/letter.odin +++ b/core/unicode/letter.odin @@ -242,7 +242,7 @@ is_enclosing_mark :: proc(r: rune) -> bool { 0x20DD ..= 0x20E0, 0x20E2 ..= 0x20E4, 0xA670 ..= 0xA672: - return true + return true } return false diff --git a/core/unicode/tools/generate_entity_table.odin b/core/unicode/tools/generate_entity_table.odin index ec8106cbe..16baa1adf 100644 --- a/core/unicode/tools/generate_entity_table.odin +++ b/core/unicode/tools/generate_entity_table.odin @@ -142,7 +142,7 @@ generate_encoding_entity_table :: proc() { /* Generate table. */ - fmt.wprintln(w, "package unicode_entity") + fmt.wprintln(w, "package encoding_unicode_entity") fmt.wprintln(w, "") fmt.wprintln(w, GENERATED) fmt.wprintln(w, "") @@ -195,12 +195,12 @@ named_xml_entity_to_rune :: proc(name: string) -> (decoded: rune, ok: bool) { e := entity_map[v] - fmt.wprintf(w, "\t\t\tcase \"%v\":", e.name) + fmt.wprintf(w, "\t\tcase \"%v\":", e.name) for i := len(e.name); i < max_name_length; i += 1 { fmt.wprintf(w, " ") } fmt.wprintf(w, " // %v\n", e.description) - fmt.wprintf(w, "\t\t\t\treturn %v, true\n", rune_to_string(e.codepoint)) + fmt.wprintf(w, "\t\t\treturn %v, true\n", rune_to_string(e.codepoint)) should_close = true } diff --git a/core/unicode/utf8/grapheme.odin b/core/unicode/utf8/grapheme.odin index 911165af9..50d1789ab 100644 --- a/core/unicode/utf8/grapheme.odin +++ b/core/unicode/utf8/grapheme.odin @@ -240,8 +240,7 @@ decode_grapheme_clusters :: proc( // GB8: (LVT | T) × T if is_hangul_syllable_leading(this_rune) || is_hangul_syllable_lv(this_rune) || - is_hangul_syllable_lvt(this_rune) - { + is_hangul_syllable_lvt(this_rune) { if !is_hangul_syllable_leading(last_rune) { grapheme_count += 1 } @@ -251,8 +250,7 @@ decode_grapheme_clusters :: proc( 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) - { + is_hangul_syllable_lv(last_rune) { continue } grapheme_count += 1 @@ -263,8 +261,7 @@ decode_grapheme_clusters :: proc( 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) - { + is_hangul_syllable_vowel(last_rune) { continue } grapheme_count += 1 @@ -285,8 +282,7 @@ decode_grapheme_clusters :: proc( if 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) ) - { + is_indic_conjunct_break_consonant(last_rune) ) { continue_sequence = true continue } @@ -294,8 +290,7 @@ decode_grapheme_clusters :: proc( 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) ) - { + is_indic_conjunct_break_consonant(last_rune) ) { continue_sequence = true continue } @@ -306,8 +301,7 @@ decode_grapheme_clusters :: proc( // (Support for GB11.) if current_sequence == .Emoji && ( is_gcb_extend_class(last_rune) || - is_emoji_extended_pictographic(last_rune) ) - { + is_emoji_extended_pictographic(last_rune) ) { continue_sequence = true } @@ -336,8 +330,7 @@ decode_grapheme_clusters :: proc( 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) - { + is_indic_conjunct_break_linker(last_rune) { continue_sequence = true } else { grapheme_count += 1 @@ -353,8 +346,7 @@ decode_grapheme_clusters :: proc( 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) - { + is_indic_conjunct_break_linker(last_rune) { continue_sequence = true } else { grapheme_count += 1 @@ -366,8 +358,7 @@ decode_grapheme_clusters :: proc( 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) - { + is_indic_conjunct_break_linker(last_rune) { continue_sequence = true } else { grapheme_count += 1 diff --git a/examples/all/all_main.odin b/examples/all/all_main.odin index 5202d72be..eefb29aa8 100644 --- a/examples/all/all_main.odin +++ b/examples/all/all_main.odin @@ -49,25 +49,30 @@ import tuplehash "core:crypto/tuplehash" import x25519 "core:crypto/x25519" import pe "core:debug/pe" +import trace "core:debug/trace" import dynlib "core:dynlib" import net "core:net" +import ansi "core:encoding/ansi" import base32 "core:encoding/base32" import base64 "core:encoding/base64" +import cbor "core:encoding/cbor" import csv "core:encoding/csv" +import endian "core:encoding/endian" import hxa "core:encoding/hxa" import json "core:encoding/json" import varint "core:encoding/varint" import xml "core:encoding/xml" -import endian "core:encoding/endian" -import cbor "core:encoding/cbor" +import uuid "core:encoding/uuid" +import uuid_legacy "core:encoding/uuid/legacy" import fmt "core:fmt" import hash "core:hash" import xxhash "core:hash/xxhash" import image "core:image" +import bmp "core:image/bmp" import netpbm "core:image/netpbm" import png "core:image/png" import qoi "core:image/qoi" @@ -89,6 +94,7 @@ import ease "core:math/ease" import cmplx "core:math/cmplx" import mem "core:mem" +import tlsf "core:mem/tlsf" import virtual "core:mem/virtual" import ast "core:odin/ast" @@ -103,6 +109,8 @@ import os "core:os" import slashpath "core:path/slashpath" import filepath "core:path/filepath" +import relative "core:relative" + import reflect "core:reflect" import runtime "base:runtime" import simd "core:simd" @@ -113,11 +121,13 @@ import strconv "core:strconv" import strings "core:strings" import sync "core:sync" import testing "core:testing" -import scanner "core:text/scanner" + +import edit "core:text/edit" import i18n "core:text/i18n" import match "core:text/match" +import scanner "core:text/scanner" import table "core:text/table" -import edit "core:text/edit" + import thread "core:thread" import time "core:time" import datetime "core:time/datetime" @@ -174,8 +184,10 @@ _ :: sm3 _ :: tuplehash _ :: x25519 _ :: pe +_ :: trace _ :: dynlib _ :: net +_ :: ansi _ :: base32 _ :: base64 _ :: csv @@ -189,6 +201,7 @@ _ :: fmt _ :: hash _ :: xxhash _ :: image +_ :: bmp _ :: netpbm _ :: png _ :: qoi @@ -207,6 +220,7 @@ _ :: rand _ :: ease _ :: cmplx _ :: mem +_ :: tlsf _ :: virtual _ :: ast _ :: doc_format @@ -216,6 +230,7 @@ _ :: os _ :: spall _ :: slashpath _ :: filepath +_ :: relative _ :: reflect _ :: runtime _ :: simd @@ -237,6 +252,8 @@ _ :: datetime _ :: flags _ :: sysinfo _ :: unicode +_ :: uuid +_ :: uuid_legacy _ :: utf8 _ :: utf8string _ :: utf16 diff --git a/examples/demo/demo.odin b/examples/demo/demo.odin index b3c627808..0ad9f4ab0 100644 --- a/examples/demo/demo.odin +++ b/examples/demo/demo.odin @@ -1140,6 +1140,7 @@ prefix_table := [?]string{ print_mutex := b64(false) +@(disabled=!thread.IS_SUPPORTED) threading_example :: proc() { fmt.println("\n# threading_example") @@ -2275,7 +2276,7 @@ arbitrary_precision_mathematics :: proc() { } fmt.printf(as) if print_extra_info { - fmt.printf(" (base: %v, bits: %v, digits: %v)", base, cb, a.used) + fmt.printf(" (base: %v, bits: %v, digits: %v)", base, cb, a.used) } if newline { fmt.println() @@ -2550,6 +2551,50 @@ matrix_type :: proc() { // matrix_minor(m) } +bit_field_type :: proc() { + fmt.println("\n# bit_field type") + // A `bit_field` is a record type in Odin that is akin to a bit-packed struct. + // IMPORTNAT NOTE: `bit_field` is NOT equivalent to `bit_set` as it has different sematics and use cases. + + { + // `bit_field` fields are accessed by using a dot: + Foo :: bit_field u16 { // backing type must be an integer or array of integers + x: i32 | 3, // signed integers will be signed extended on use + y: u16 | 2 + 3, // general expressions + z: My_Enum | SOME_CONSTANT, // ability to define the bit-width elsewhere + w: bool | 2 when SOME_CONSTANT > 10 else 1, + } + + v := Foo{} + v.x = 3 // truncates the value to fit into 3 bits + fmt.println(v.x) // accessing will convert `v.x` to an `i32` and do an appropriate sign extension + + + My_Enum :: enum u8 {A, B, C, D} + SOME_CONSTANT :: 7 + } + + { + // A `bit_field` is different from a struct in that you must specify the backing type. + // This backing type must be an integer or a fixed-length array of integers. + // This is useful if ther eneeds to be a specific alignment or access pattern for the record. + + Bar :: bit_field u32 {} + Baz :: bit_field [4]u8 {} + } + + // IMPORTANT NOTES: + // * If _all_ of the fields in a bit_field are 1-bit in size and they are all booleans, + // please consider using a `bit_set` instead. + // * Odin's `bit_field` and C's bit-fields might not be compatible + // * Odin's `bit_field`s have a well defined layout (Least-Significant-Bit) + // * C's bit-fields on `struct`s are undefined and are not portable across targets and compilers + // * A `bit_field`'s field type can only be one of the following: + // * Integer + // * Boolean + // * Enum +} + main :: proc() { /* For More Odin Examples - https://github.com/odin-lang/examples @@ -2595,5 +2640,6 @@ main :: proc() { or_break_and_or_continue_operators() arbitrary_precision_mathematics() matrix_type() + bit_field_type() } } diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 0495cf3b5..c3b4f2506 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -106,468 +106,7 @@ gb_global String target_arch_names[TargetArch_COUNT] = { str_lit("wasm64p32"), }; -// 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,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,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,emeraldrapids,generic,geode,goldmont,goldmont-plus,goldmont_plus,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,meteorlake,mic_avx512,nehalem,nocona,opteron,opteron-sse3,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"), - // TargetArch_i386: - str_lit("alderlake,amdfam10,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,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,emeraldrapids,generic,geode,goldmont,goldmont-plus,goldmont_plus,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,meteorlake,mic_avx512,nehalem,nocona,opteron,opteron-sse3,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"), - // 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-a53,cortex-a55,cortex-a57,cortex-a7,cortex-a710,cortex-a72,cortex-a73,cortex-a75,cortex-a76,cortex-a76ae,cortex-a77,cortex-a78,cortex-a78c,cortex-a8,cortex-a9,cortex-m0,cortex-m0plus,cortex-m1,cortex-m23,cortex-m3,cortex-m33,cortex-m35p,cortex-m4,cortex-m55,cortex-m7,cortex-m85,cortex-r4,cortex-r4f,cortex-r5,cortex-r52,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,strongarm,strongarm110,strongarm1100,strongarm1110,swift,xscale"), - // TargetArch_arm64: - str_lit("a64fx,ampere1,ampere1a,apple-a10,apple-a11,apple-a12,apple-a13,apple-a14,apple-a15,apple-a16,apple-a7,apple-a8,apple-a9,apple-latest,apple-m1,apple-m2,apple-s4,apple-s5,carmel,cortex-a34,cortex-a35,cortex-a510,cortex-a53,cortex-a55,cortex-a57,cortex-a65,cortex-a65ae,cortex-a710,cortex-a715,cortex-a72,cortex-a73,cortex-a75,cortex-a76,cortex-a76ae,cortex-a77,cortex-a78,cortex-a78c,cortex-r82,cortex-x1,cortex-x1c,cortex-x2,cortex-x3,cyclone,exynos-m3,exynos-m4,exynos-m5,falkor,generic,kryo,neoverse-512tvb,neoverse-e1,neoverse-n1,neoverse-n2,neoverse-v1,neoverse-v2,saphira,thunderx,thunderx2t99,thunderx3t110,thunderxt81,thunderxt83,thunderxt88,tsv110"), - // TargetArch_wasm32: - str_lit("bleeding-edge,generic,mvp"), - // TargetArch_wasm64p32: - str_lit("bleeding-edge,generic,mvp"), -}; - -// 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,3dnow,3dnowa,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,avx512er,avx512f,avx512fp16,avx512ifma,avx512pf,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vp2intersect,avx512vpopcntdq,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,branchfusion,cldemote,clflushopt,clwb,clzero,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,ermsb,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-gather,fast-hops,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,invpcid,kl,lea-sp,lea-uses-ag,lvi-cfi,lvi-load-hardening,lwp,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,mwaitx,no-bypass-delay,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pad-short-functions,pclmul,pconfig,pku,popcnt,prefer-128-bit,prefer-256-bit,prefer-mask-registers,prefer-movmsk-over-vtest,prefer-no-gather,prefer-no-scatter,prefetchi,prefetchwt1,prfchw,ptwrite,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,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,widekl,x87,xop,xsave,xsavec,xsaveopt,xsaves"), - // TargetArch_i386: - str_lit("16bit-mode,32bit-mode,3dnow,3dnowa,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,avx512er,avx512f,avx512fp16,avx512ifma,avx512pf,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vp2intersect,avx512vpopcntdq,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,branchfusion,cldemote,clflushopt,clwb,clzero,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,ermsb,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-gather,fast-hops,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,invpcid,kl,lea-sp,lea-uses-ag,lvi-cfi,lvi-load-hardening,lwp,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,mwaitx,no-bypass-delay,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pad-short-functions,pclmul,pconfig,pku,popcnt,prefer-128-bit,prefer-256-bit,prefer-mask-registers,prefer-movmsk-over-vtest,prefer-no-gather,prefer-no-scatter,prefetchi,prefetchwt1,prfchw,ptwrite,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,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,widekl,x87,xop,xsave,xsavec,xsaveopt,xsaves"), - // 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,aapcs-frame-chain-leaf,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,atomics-32,avoid-movs-shop,avoid-partial-cpsr,bf16,big-endian-instructions,cde,cdecp0,cdecp1,cdecp2,cdecp3,cdecp4,cdecp5,cdecp6,cdecp7,cheap-predicable-cpsr,clrbhb,cortex-a710,cortex-a78,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,m7,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,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,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,a35,a510,a53,a55,a57,a64fx,a65,a710,a715,a72,a73,a75,a76,a77,a78,a78c,aes,aggressive-fma,all,alternate-sextload-cvt-f32-pattern,altnzcv,am,ampere1,ampere1a,amvs,apple-a10,apple-a11,apple-a12,apple-a13,apple-a14,apple-a15,apple-a16,apple-a7,apple-a7-sysreg,arith-bcc-fusion,arith-cbz-fusion,ascend-store-address,b16b16,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,complxnum,cortex-r82,cortex-x1,cortex-x2,cortex-x3,crc,crypto,cssc,custom-cheap-as-move,d128,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,enable-select-opt,ete,exynos-cheap-as-move,exynosm3,exynosm4,f32mm,f64mm,falkor,fgt,fix-cortex-a53-835769,flagm,fmv,force-32bit-jump-tables,fp-armv8,fp16fml,fptoint,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,lor,ls64,lse,lse128,lse2,lsl-fast,mec,mops,mpam,mte,neon,neoverse512tvb,neoversee1,neoversen1,neoversen2,neoversev1,neoversev2,nmi,no-bti-at-return-twice,no-neg-immediates,no-sve-fp-ld1r,no-zcz-fp,nv,outline-atomics,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,prfm-slc-target,rand,ras,rasv2,rcpc,rcpc-immo,rcpc3,rdm,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-x30,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-f16f16,sme-f64f64,sme-i16i64,sme2,sme2p1,spe,spe-eef,specres2,specrestrict,ssbs,strict-align,sve,sve2,sve2-aes,sve2-bitperm,sve2-sha3,sve2-sm4,sve2p1,tagged-globals,the,thunderx,thunderx2t99,thunderx3t110,thunderxt81,thunderxt83,thunderxt88,tlb-rmi,tme,tpidr-el1,tpidr-el2,tpidr-el3,tpidrro-el0,tracev8.4,trbe,tsv110,uaops,use-experimental-zeroing-pseudos,use-postra-scheduler,use-reciprocal-square-root,use-scalar-inc-vl,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,v9a,vh,wfxt,xs,zcm,zcz,zcz-fp-workaround,zcz-gp"), - // TargetArch_wasm32: - str_lit("atomics,bulk-memory,exception-handling,extended-const,multivalue,mutable-globals,nontrapping-fptoint,reference-types,relaxed-simd,sign-ext,simd128,tail-call"), - // TargetArch_wasm64p32: - str_lit("atomics,bulk-memory,exception-handling,extended-const,multivalue,mutable-globals,nontrapping-fptoint,reference-types,relaxed-simd,sign-ext,simd128,tail-call"), -}; - -// Generated with the featuregen script in `misc/featuregen` -gb_global int target_microarch_counts[TargetArch_COUNT] = { - // TargetArch_Invalid: - 0, - // TargetArch_amd64: - 120, - // TargetArch_i386: - 120, - // TargetArch_arm32: - 90, - // TargetArch_arm64: - 63, - // TargetArch_wasm32: - 3, - // TargetArch_wasm64p32: - 3, -}; - -// 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,cldemote,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("3dnow,3dnowa,64bit,64bit-mode,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,lzcnt,mmx,nopl,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4a,vzeroupper,x87") }, - { str_lit("athlon"), str_lit("3dnow,3dnowa,64bit-mode,cmov,cx8,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("athlon-4"), str_lit("3dnow,3dnowa,64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("athlon-fx"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("athlon-mp"), str_lit("3dnow,3dnowa,64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("athlon-tbird"), str_lit("3dnow,3dnowa,64bit-mode,cmov,cx8,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("athlon-xp"), str_lit("3dnow,3dnowa,64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("athlon64"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("athlon64-sse3"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,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,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-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-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("3dnow,3dnowa,64bit,64bit-mode,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,lzcnt,mmx,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,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,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,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,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,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-scalar-shift-masks,fast-vector-shift-masks,fxsr,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-lzcnt,fast-movbe,fast-scalar-shift-masks,fast-vector-shift-masks,fxsr,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("3dnow,64bit-mode,mmx,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("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,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,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,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("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("3dnow,3dnowa,64bit-mode,cx8,mmx,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-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-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-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("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,fast-movbe,fma,fsgsbase,fxsr,gfni,hreset,invpcid,kl,lzcnt,mmx,movbe,movdir64b,movdiri,no-bypass-delay,nopl,pclmul,pconfig,pku,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,uintr,use-glm-div-sqrt-costs,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,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,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,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("3dnow,64bit-mode,cx8,mmx,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("k6-3"), str_lit("3dnow,64bit-mode,cx8,mmx,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("k8"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("k8-sse3"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,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,avx512er,avx512f,avx512pf,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prefetchwt1,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,avx512er,avx512f,avx512pf,avx512vpopcntdq,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prefetchwt1,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("meteorlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avxvnni,bmi,bmi2,cldemote,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,avx512er,avx512f,avx512pf,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prefetchwt1,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,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("3dnow,3dnowa,64bit,64bit-mode,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("opteron-sse3"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, - { 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,cldemote,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,fast-movbe,fma,fsgsbase,fxsr,gfni,hreset,invpcid,kl,lzcnt,mmx,movbe,movdir64b,movdiri,no-bypass-delay,nopl,pclmul,pconfig,pku,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,uintr,use-glm-div-sqrt-costs,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-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-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-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,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("3dnow,64bit-mode,mmx,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-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,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-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,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-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,invpcid,lzcnt,macrofusion,mmx,movbe,mwaitx,nopl,pclmul,pku,popcnt,prfchw,rdpid,rdpru,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,slow-shld,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-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,invpcid,lzcnt,macrofusion,mmx,movbe,mwaitx,nopl,pclmul,pku,popcnt,prfchw,rdpid,rdpru,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,shstk,slow-shld,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,cldemote,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,3dnow,3dnowa,64bit,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,lzcnt,mmx,nopl,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4a,vzeroupper,x87") }, - { str_lit("athlon"), str_lit("32bit-mode,3dnow,3dnowa,cmov,cx8,mmx,nopl,slow-shld,slow-unaligned-mem-16,vzeroupper,x87") }, - { str_lit("athlon-4"), str_lit("32bit-mode,3dnow,3dnowa,cmov,cx8,fxsr,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,vzeroupper,x87") }, - { str_lit("athlon-fx"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("athlon-mp"), str_lit("32bit-mode,3dnow,3dnowa,cmov,cx8,fxsr,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,vzeroupper,x87") }, - { str_lit("athlon-tbird"), str_lit("32bit-mode,3dnow,3dnowa,cmov,cx8,mmx,nopl,slow-shld,slow-unaligned-mem-16,vzeroupper,x87") }, - { str_lit("athlon-xp"), str_lit("32bit-mode,3dnow,3dnowa,cmov,cx8,fxsr,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,vzeroupper,x87") }, - { str_lit("athlon64"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("athlon64-sse3"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,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,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-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-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,3dnow,3dnowa,64bit,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,lzcnt,mmx,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,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,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,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,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,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-scalar-shift-masks,fast-vector-shift-masks,fxsr,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-lzcnt,fast-movbe,fast-scalar-shift-masks,fast-vector-shift-masks,fxsr,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,3dnow,mmx,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("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,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,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,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("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,3dnow,3dnowa,cx8,mmx,slow-unaligned-mem-16,vzeroupper,x87") }, - { str_lit("goldmont"), str_lit("32bit-mode,64bit,aes,clflushopt,cmov,crc32,cx16,cx8,false-deps-popcnt,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-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-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("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,fast-movbe,fma,fsgsbase,fxsr,gfni,hreset,invpcid,kl,lzcnt,mmx,movbe,movdir64b,movdiri,no-bypass-delay,nopl,pclmul,pconfig,pku,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,uintr,use-glm-div-sqrt-costs,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,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,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,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,3dnow,cx8,mmx,slow-unaligned-mem-16,vzeroupper,x87") }, - { str_lit("k6-3"), str_lit("32bit-mode,3dnow,cx8,mmx,slow-unaligned-mem-16,vzeroupper,x87") }, - { str_lit("k8"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("k8-sse3"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,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,avx512er,avx512f,avx512pf,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prefetchwt1,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,avx512er,avx512f,avx512pf,avx512vpopcntdq,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prefetchwt1,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("meteorlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avxvnni,bmi,bmi2,cldemote,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,avx512er,avx512f,avx512pf,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prefetchwt1,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,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,3dnow,3dnowa,64bit,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, - { str_lit("opteron-sse3"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, - { 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,cldemote,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,fast-movbe,fma,fsgsbase,fxsr,gfni,hreset,invpcid,kl,lzcnt,mmx,movbe,movdir64b,movdiri,no-bypass-delay,nopl,pclmul,pconfig,pku,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,uintr,use-glm-div-sqrt-costs,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-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-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-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,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,3dnow,mmx,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-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,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-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,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-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,invpcid,lzcnt,macrofusion,mmx,movbe,mwaitx,nopl,pclmul,pku,popcnt,prfchw,rdpid,rdpru,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,slow-shld,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-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,invpcid,lzcnt,macrofusion,mmx,movbe,mwaitx,nopl,pclmul,pku,popcnt,prfchw,rdpid,rdpru,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,shstk,slow-shld,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,neon,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,neon,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,neon,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,neon,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-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,neon,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-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,neon,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,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,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-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,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,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,db,dsp,fp-armv8d16,fp-armv8d16sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,lob,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-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,neon,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,fp64,fpregs,fpregs64,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("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,neon,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,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,addr-lsl-fast,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,fuse-address,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,addr-lsl-fast,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,fuse-address,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("apple-a10"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,apple-a10,arith-bcc-fusion,arith-cbz-fusion,crc,crypto,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,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,crypto,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,zcz,zcz-gp") }, - { str_lit("apple-a12"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,apple-a12,arith-bcc-fusion,arith-cbz-fusion,ccidx,ccpp,complxnum,crc,crypto,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,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,ccidx,ccpp,complxnum,crc,crypto,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,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,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,el2vmsa,el3,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,fuse-adrp-add,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,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,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,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,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,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,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,zcz,zcz-gp") }, - { str_lit("apple-a7"), str_lit("aes,alternate-sextload-cvt-f32-pattern,apple-a7,apple-a7-sysreg,arith-bcc-fusion,arith-cbz-fusion,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fuse-aes,fuse-crypto-eor,neon,perfmon,sha2,store-pair-suppress,v8a,zcm,zcz,zcz-fp-workaround,zcz-gp") }, - { str_lit("apple-a8"), str_lit("aes,alternate-sextload-cvt-f32-pattern,apple-a7,apple-a7-sysreg,arith-bcc-fusion,arith-cbz-fusion,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fuse-aes,fuse-crypto-eor,neon,perfmon,sha2,store-pair-suppress,v8a,zcm,zcz,zcz-fp-workaround,zcz-gp") }, - { str_lit("apple-a9"), str_lit("aes,alternate-sextload-cvt-f32-pattern,apple-a7,apple-a7-sysreg,arith-bcc-fusion,arith-cbz-fusion,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fuse-aes,fuse-crypto-eor,neon,perfmon,sha2,store-pair-suppress,v8a,zcm,zcz,zcz-fp-workaround,zcz-gp") }, - { str_lit("apple-latest"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,altnzcv,am,amvs,apple-a16,arith-bcc-fusion,arith-cbz-fusion,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,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,zcz,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,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,el2vmsa,el3,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,fuse-adrp-add,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,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,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,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,zcz,zcz-gp") }, - { str_lit("apple-s4"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,apple-a12,arith-bcc-fusion,arith-cbz-fusion,ccidx,ccpp,complxnum,crc,crypto,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,zcz,zcz-gp") }, - { str_lit("apple-s5"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,apple-a12,arith-bcc-fusion,arith-cbz-fusion,ccidx,ccpp,complxnum,crc,crypto,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,zcz,zcz-gp") }, - { str_lit("carmel"), str_lit("CONTEXTIDREL2,aes,carmel,ccpp,crc,crypto,el2vmsa,el3,fp-armv8,fullfp16,lor,lse,neon,pan,pan-rwv,ras,rdm,sha2,uaops,v8.1a,v8.2a,v8a,vh") }, - { str_lit("cortex-a34"), str_lit("a35,aes,crc,crypto,el2vmsa,el3,fp-armv8,neon,perfmon,sha2,v8a") }, - { str_lit("cortex-a35"), str_lit("a35,aes,crc,crypto,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,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, - { str_lit("cortex-a53"), str_lit("a53,aes,balance-fp-ops,crc,crypto,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,crypto,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,aes,balance-fp-ops,crc,crypto,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,crypto,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,crypto,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,addr-lsl-fast,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,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, - { str_lit("cortex-a715"), str_lit("CONTEXTIDREL2,a715,addr-lsl-fast,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,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,spe,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, - { str_lit("cortex-a72"), str_lit("a72,aes,crc,crypto,el2vmsa,el3,enable-select-opt,fp-armv8,fuse-adrp-add,fuse-aes,fuse-literals,neon,perfmon,predictable-select-expensive,sha2,v8a") }, - { str_lit("cortex-a73"), str_lit("a73,aes,crc,crypto,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,aes,ccpp,crc,crypto,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-fast,aes,alu-lsl-fast,ccpp,crc,crypto,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-fast,aes,alu-lsl-fast,ccpp,crc,crypto,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-fast,aes,alu-lsl-fast,ccpp,cmp-bcc-fusion,crc,crypto,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-fast,aes,alu-lsl-fast,ccpp,cmp-bcc-fusion,crc,crypto,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-fast,aes,alu-lsl-fast,ccpp,cmp-bcc-fusion,crc,crypto,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,ccidx,ccpp,complxnum,cortex-r82,crc,dit,dotprod,flagm,fp-armv8,fp16fml,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-fast,aes,alu-lsl-fast,ccpp,cmp-bcc-fusion,cortex-x1,crc,crypto,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-fast,aes,alu-lsl-fast,ccpp,cmp-bcc-fusion,cortex-x1,crc,crypto,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,addr-lsl-fast,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,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, - { str_lit("cortex-x3"), str_lit("CONTEXTIDREL2,addr-lsl-fast,altnzcv,alu-lsl-fast,am,bf16,bti,ccdp,ccidx,ccpp,complxnum,cortex-x3,crc,dit,dotprod,el2vmsa,el3,enable-select-opt,ete,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,spe,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, - { str_lit("cyclone"), str_lit("aes,alternate-sextload-cvt-f32-pattern,apple-a7,apple-a7-sysreg,arith-bcc-fusion,arith-cbz-fusion,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fuse-aes,fuse-crypto-eor,neon,perfmon,sha2,store-pair-suppress,v8a,zcm,zcz,zcz-fp-workaround,zcz-gp") }, - { str_lit("exynos-m3"), str_lit("addr-lsl-fast,aes,alu-lsl-fast,crc,crypto,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,addr-lsl-fast,aes,alu-lsl-fast,arith-bcc-fusion,arith-cbz-fusion,ccpp,crc,crypto,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,addr-lsl-fast,aes,alu-lsl-fast,arith-bcc-fusion,arith-cbz-fusion,ccpp,crc,crypto,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("addr-lsl-fast,aes,alu-lsl-fast,crc,crypto,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("generic"), str_lit("enable-select-opt,ete,fp-armv8,fuse-adrp-add,fuse-aes,neon,trbe,use-postra-scheduler") }, - { str_lit("kryo"), str_lit("addr-lsl-fast,aes,alu-lsl-fast,crc,crypto,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,addr-lsl-fast,aes,alu-lsl-fast,am,bf16,ccdp,ccidx,ccpp,complxnum,crc,crypto,dit,dotprod,el2vmsa,el3,enable-select-opt,flagm,fp-armv8,fp16fml,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,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,crypto,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-fast,aes,alu-lsl-fast,ccpp,crc,crypto,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,addr-lsl-fast,altnzcv,alu-lsl-fast,am,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,dit,dotprod,el2vmsa,el3,enable-select-opt,ete,flagm,fp-armv8,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,neoversen2,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, - { str_lit("neoverse-v1"), str_lit("CONTEXTIDREL2,addr-lsl-fast,aes,alu-lsl-fast,am,bf16,ccdp,ccidx,ccpp,complxnum,crc,crypto,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,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,addr-lsl-fast,altnzcv,alu-lsl-fast,am,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,dit,dotprod,el2vmsa,el3,enable-select-opt,ete,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,neoversev2,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,rand,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,spe,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, - { str_lit("saphira"), str_lit("CONTEXTIDREL2,addr-lsl-fast,aes,alu-lsl-fast,am,ccidx,ccpp,complxnum,crc,crypto,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,crypto,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,crypto,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,crypto,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,crypto,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,crypto,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,crypto,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,crypto,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,mutable-globals,nontrapping-fptoint,sign-ext,simd128,tail-call") }, - { str_lit("generic"), str_lit("mutable-globals,sign-ext") }, - { str_lit("mvp"), str_lit("") }, - // TargetArch_wasm64p32: - { str_lit("bleeding-edge"), str_lit("atomics,bulk-memory,mutable-globals,nontrapping-fptoint,sign-ext,simd128,tail-call") }, - { str_lit("generic"), str_lit("mutable-globals,sign-ext") }, - { str_lit("mvp"), str_lit("") }, -}; +#include "build_settings_microarch.cpp" gb_global String target_endian_names[TargetEndian_COUNT] = { str_lit("little"), @@ -742,10 +281,12 @@ enum VetFlags : u64 { VetFlag_UnusedVariables = 1u<<5, VetFlag_UnusedImports = 1u<<6, VetFlag_Deprecated = 1u<<7, + VetFlag_Cast = 1u<<8, + VetFlag_Tabs = 1u<<9, VetFlag_Unused = VetFlag_UnusedVariables|VetFlag_UnusedImports, - VetFlag_All = VetFlag_Unused|VetFlag_Shadowing|VetFlag_UsingStmt|VetFlag_Deprecated, + VetFlag_All = VetFlag_Unused|VetFlag_Shadowing|VetFlag_UsingStmt|VetFlag_Deprecated|VetFlag_Cast, VetFlag_Using = VetFlag_UsingStmt|VetFlag_UsingParam, }; @@ -769,6 +310,10 @@ u64 get_vet_flag_from_name(String const &name) { return VetFlag_Semicolon; } else if (name == "deprecated") { return VetFlag_Deprecated; + } else if (name == "cast") { + return VetFlag_Cast; + } else if (name == "tabs") { + return VetFlag_Tabs; } return VetFlag_NONE; } @@ -862,6 +407,8 @@ struct BuildContext { bool keep_object_files; bool disallow_do; + StringSet custom_attributes; + bool strict_style; bool ignore_warnings; @@ -873,6 +420,7 @@ struct BuildContext { bool ignore_lazy; bool ignore_llvm_build; + bool ignore_panic; bool ignore_microsoft_magic; bool linker_map_file; @@ -1882,6 +1430,8 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta bc->thread_count = gb_max(bc->affinity.thread_count, 1); } + string_set_init(&bc->custom_attributes); + bc->ODIN_VENDOR = str_lit("odin"); bc->ODIN_VERSION = ODIN_VERSION; bc->ODIN_ROOT = odin_root_dir(); @@ -2053,10 +1603,12 @@ gb_internal void init_build_context(TargetMetrics *cross_target, Subtarget subta gbString link_flags = gb_string_make(heap_allocator(), " "); // link_flags = gb_string_appendc(link_flags, "--export-all "); // link_flags = gb_string_appendc(link_flags, "--export-table "); - link_flags = gb_string_appendc(link_flags, "--allow-undefined "); // if (bc->metrics.arch == TargetArch_wasm64) { // link_flags = gb_string_appendc(link_flags, "-mwasm64 "); // } + if (bc->metrics.os != TargetOs_orca) { + link_flags = gb_string_appendc(link_flags, "--allow-undefined "); + } if (bc->no_entry_point || bc->metrics.os == TargetOs_orca) { link_flags = gb_string_appendc(link_flags, "--no-entry "); } diff --git a/src/build_settings_microarch.cpp b/src/build_settings_microarch.cpp new file mode 100644 index 000000000..02b507031 --- /dev/null +++ b/src/build_settings_microarch.cpp @@ -0,0 +1,462 @@ +// 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,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,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,emeraldrapids,generic,geode,goldmont,goldmont-plus,goldmont_plus,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,meteorlake,mic_avx512,nehalem,nocona,opteron,opteron-sse3,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"), + // TargetArch_i386: + str_lit("alderlake,amdfam10,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,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,emeraldrapids,generic,geode,goldmont,goldmont-plus,goldmont_plus,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,meteorlake,mic_avx512,nehalem,nocona,opteron,opteron-sse3,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"), + // 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-a53,cortex-a55,cortex-a57,cortex-a7,cortex-a710,cortex-a72,cortex-a73,cortex-a75,cortex-a76,cortex-a76ae,cortex-a77,cortex-a78,cortex-a78c,cortex-a8,cortex-a9,cortex-m0,cortex-m0plus,cortex-m1,cortex-m23,cortex-m3,cortex-m33,cortex-m35p,cortex-m4,cortex-m55,cortex-m7,cortex-m85,cortex-r4,cortex-r4f,cortex-r5,cortex-r52,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,strongarm,strongarm110,strongarm1100,strongarm1110,swift,xscale"), + // TargetArch_arm64: + str_lit("a64fx,ampere1,ampere1a,apple-a10,apple-a11,apple-a12,apple-a13,apple-a14,apple-a15,apple-a16,apple-a7,apple-a8,apple-a9,apple-latest,apple-m1,apple-m2,apple-s4,apple-s5,carmel,cortex-a34,cortex-a35,cortex-a510,cortex-a53,cortex-a55,cortex-a57,cortex-a65,cortex-a65ae,cortex-a710,cortex-a715,cortex-a72,cortex-a73,cortex-a75,cortex-a76,cortex-a76ae,cortex-a77,cortex-a78,cortex-a78c,cortex-r82,cortex-x1,cortex-x1c,cortex-x2,cortex-x3,cyclone,exynos-m3,exynos-m4,exynos-m5,falkor,generic,kryo,neoverse-512tvb,neoverse-e1,neoverse-n1,neoverse-n2,neoverse-v1,neoverse-v2,saphira,thunderx,thunderx2t99,thunderx3t110,thunderxt81,thunderxt83,thunderxt88,tsv110"), + // TargetArch_wasm32: + str_lit("bleeding-edge,generic,mvp"), + // TargetArch_wasm64p32: + str_lit("bleeding-edge,generic,mvp"), +}; + +// 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,3dnow,3dnowa,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,avx512er,avx512f,avx512fp16,avx512ifma,avx512pf,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vp2intersect,avx512vpopcntdq,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,branchfusion,cldemote,clflushopt,clwb,clzero,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,ermsb,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-gather,fast-hops,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,invpcid,kl,lea-sp,lea-uses-ag,lvi-cfi,lvi-load-hardening,lwp,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,mwaitx,no-bypass-delay,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pad-short-functions,pclmul,pconfig,pku,popcnt,prefer-128-bit,prefer-256-bit,prefer-mask-registers,prefer-movmsk-over-vtest,prefer-no-gather,prefer-no-scatter,prefetchi,prefetchwt1,prfchw,ptwrite,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,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,widekl,x87,xop,xsave,xsavec,xsaveopt,xsaves"), + // TargetArch_i386: + str_lit("16bit-mode,32bit-mode,3dnow,3dnowa,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,avx512er,avx512f,avx512fp16,avx512ifma,avx512pf,avx512vbmi,avx512vbmi2,avx512vl,avx512vnni,avx512vp2intersect,avx512vpopcntdq,avxifma,avxneconvert,avxvnni,avxvnniint16,avxvnniint8,bmi,bmi2,branchfusion,cldemote,clflushopt,clwb,clzero,cmov,cmpccxadd,crc32,cx16,cx8,enqcmd,ermsb,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-gather,fast-hops,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,invpcid,kl,lea-sp,lea-uses-ag,lvi-cfi,lvi-load-hardening,lwp,lzcnt,macrofusion,mmx,movbe,movdir64b,movdiri,mwaitx,no-bypass-delay,no-bypass-delay-blend,no-bypass-delay-mov,no-bypass-delay-shuffle,nopl,pad-short-functions,pclmul,pconfig,pku,popcnt,prefer-128-bit,prefer-256-bit,prefer-mask-registers,prefer-movmsk-over-vtest,prefer-no-gather,prefer-no-scatter,prefetchi,prefetchwt1,prfchw,ptwrite,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,vaes,vpclmulqdq,vzeroupper,waitpkg,wbnoinvd,widekl,x87,xop,xsave,xsavec,xsaveopt,xsaves"), + // 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,aapcs-frame-chain-leaf,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,atomics-32,avoid-movs-shop,avoid-partial-cpsr,bf16,big-endian-instructions,cde,cdecp0,cdecp1,cdecp2,cdecp3,cdecp4,cdecp5,cdecp6,cdecp7,cheap-predicable-cpsr,clrbhb,cortex-a710,cortex-a78,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,m7,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,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,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,a35,a510,a53,a55,a57,a64fx,a65,a710,a715,a72,a73,a75,a76,a77,a78,a78c,aes,aggressive-fma,all,alternate-sextload-cvt-f32-pattern,altnzcv,am,ampere1,ampere1a,amvs,apple-a10,apple-a11,apple-a12,apple-a13,apple-a14,apple-a15,apple-a16,apple-a7,apple-a7-sysreg,arith-bcc-fusion,arith-cbz-fusion,ascend-store-address,b16b16,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,complxnum,cortex-r82,cortex-x1,cortex-x2,cortex-x3,crc,crypto,cssc,custom-cheap-as-move,d128,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,enable-select-opt,ete,exynos-cheap-as-move,exynosm3,exynosm4,f32mm,f64mm,falkor,fgt,fix-cortex-a53-835769,flagm,fmv,force-32bit-jump-tables,fp-armv8,fp16fml,fptoint,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,lor,ls64,lse,lse128,lse2,lsl-fast,mec,mops,mpam,mte,neon,neoverse512tvb,neoversee1,neoversen1,neoversen2,neoversev1,neoversev2,nmi,no-bti-at-return-twice,no-neg-immediates,no-sve-fp-ld1r,no-zcz-fp,nv,outline-atomics,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,prfm-slc-target,rand,ras,rasv2,rcpc,rcpc-immo,rcpc3,rdm,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-x30,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-f16f16,sme-f64f64,sme-i16i64,sme2,sme2p1,spe,spe-eef,specres2,specrestrict,ssbs,strict-align,sve,sve2,sve2-aes,sve2-bitperm,sve2-sha3,sve2-sm4,sve2p1,tagged-globals,the,thunderx,thunderx2t99,thunderx3t110,thunderxt81,thunderxt83,thunderxt88,tlb-rmi,tme,tpidr-el1,tpidr-el2,tpidr-el3,tpidrro-el0,tracev8.4,trbe,tsv110,uaops,use-experimental-zeroing-pseudos,use-postra-scheduler,use-reciprocal-square-root,use-scalar-inc-vl,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,v9a,vh,wfxt,xs,zcm,zcz,zcz-fp-workaround,zcz-gp"), + // TargetArch_wasm32: + str_lit("atomics,bulk-memory,exception-handling,extended-const,multivalue,mutable-globals,nontrapping-fptoint,reference-types,relaxed-simd,sign-ext,simd128,tail-call"), + // TargetArch_wasm64p32: + str_lit("atomics,bulk-memory,exception-handling,extended-const,multivalue,mutable-globals,nontrapping-fptoint,reference-types,relaxed-simd,sign-ext,simd128,tail-call"), +}; + +// Generated with the featuregen script in `misc/featuregen` +gb_global int target_microarch_counts[TargetArch_COUNT] = { + // TargetArch_Invalid: + 0, + // TargetArch_amd64: + 120, + // TargetArch_i386: + 120, + // TargetArch_arm32: + 90, + // TargetArch_arm64: + 63, + // TargetArch_wasm32: + 3, + // TargetArch_wasm64p32: + 3, +}; + +// 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,cldemote,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("3dnow,3dnowa,64bit,64bit-mode,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,lzcnt,mmx,nopl,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4a,vzeroupper,x87") }, + { str_lit("athlon"), str_lit("3dnow,3dnowa,64bit-mode,cmov,cx8,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("athlon-4"), str_lit("3dnow,3dnowa,64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("athlon-fx"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("athlon-mp"), str_lit("3dnow,3dnowa,64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("athlon-tbird"), str_lit("3dnow,3dnowa,64bit-mode,cmov,cx8,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("athlon-xp"), str_lit("3dnow,3dnowa,64bit-mode,cmov,cx8,fxsr,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("athlon64"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("athlon64-sse3"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,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,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-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-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("3dnow,3dnowa,64bit,64bit-mode,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,lzcnt,mmx,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,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,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,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,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,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-scalar-shift-masks,fast-vector-shift-masks,fxsr,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-lzcnt,fast-movbe,fast-scalar-shift-masks,fast-vector-shift-masks,fxsr,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("3dnow,64bit-mode,mmx,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("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,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,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,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("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("3dnow,3dnowa,64bit-mode,cx8,mmx,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-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-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-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("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,fast-movbe,fma,fsgsbase,fxsr,gfni,hreset,invpcid,kl,lzcnt,mmx,movbe,movdir64b,movdiri,no-bypass-delay,nopl,pclmul,pconfig,pku,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,uintr,use-glm-div-sqrt-costs,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,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,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,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("3dnow,64bit-mode,cx8,mmx,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("k6-3"), str_lit("3dnow,64bit-mode,cx8,mmx,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("k8"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("k8-sse3"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,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,avx512er,avx512f,avx512pf,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prefetchwt1,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,avx512er,avx512f,avx512pf,avx512vpopcntdq,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prefetchwt1,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("meteorlake"), str_lit("64bit,64bit-mode,adx,aes,allow-light-256-bit,avx,avx2,avxvnni,bmi,bmi2,cldemote,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,avx512er,avx512f,avx512pf,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prefetchwt1,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,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("3dnow,3dnowa,64bit,64bit-mode,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("opteron-sse3"), str_lit("3dnow,3dnowa,64bit,64bit-mode,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, + { 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,cldemote,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,fast-movbe,fma,fsgsbase,fxsr,gfni,hreset,invpcid,kl,lzcnt,mmx,movbe,movdir64b,movdiri,no-bypass-delay,nopl,pclmul,pconfig,pku,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,uintr,use-glm-div-sqrt-costs,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-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-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-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,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("3dnow,64bit-mode,mmx,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-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,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-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,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-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,invpcid,lzcnt,macrofusion,mmx,movbe,mwaitx,nopl,pclmul,pku,popcnt,prfchw,rdpid,rdpru,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,slow-shld,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-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,invpcid,lzcnt,macrofusion,mmx,movbe,mwaitx,nopl,pclmul,pku,popcnt,prfchw,rdpid,rdpru,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,shstk,slow-shld,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,cldemote,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,3dnow,3dnowa,64bit,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,lzcnt,mmx,nopl,popcnt,prfchw,sahf,sbb-dep-breaking,slow-shld,sse,sse2,sse3,sse4a,vzeroupper,x87") }, + { str_lit("athlon"), str_lit("32bit-mode,3dnow,3dnowa,cmov,cx8,mmx,nopl,slow-shld,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("athlon-4"), str_lit("32bit-mode,3dnow,3dnowa,cmov,cx8,fxsr,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,vzeroupper,x87") }, + { str_lit("athlon-fx"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("athlon-mp"), str_lit("32bit-mode,3dnow,3dnowa,cmov,cx8,fxsr,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,vzeroupper,x87") }, + { str_lit("athlon-tbird"), str_lit("32bit-mode,3dnow,3dnowa,cmov,cx8,mmx,nopl,slow-shld,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("athlon-xp"), str_lit("32bit-mode,3dnow,3dnowa,cmov,cx8,fxsr,mmx,nopl,slow-shld,slow-unaligned-mem-16,sse,vzeroupper,x87") }, + { str_lit("athlon64"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("athlon64-sse3"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,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,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-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-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,3dnow,3dnowa,64bit,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,lzcnt,mmx,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,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,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,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,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,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-scalar-shift-masks,fast-vector-shift-masks,fxsr,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-lzcnt,fast-movbe,fast-scalar-shift-masks,fast-vector-shift-masks,fxsr,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,3dnow,mmx,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("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,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,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,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("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,3dnow,3dnowa,cx8,mmx,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("goldmont"), str_lit("32bit-mode,64bit,aes,clflushopt,cmov,crc32,cx16,cx8,false-deps-popcnt,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-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-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("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,fast-movbe,fma,fsgsbase,fxsr,gfni,hreset,invpcid,kl,lzcnt,mmx,movbe,movdir64b,movdiri,no-bypass-delay,nopl,pclmul,pconfig,pku,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,uintr,use-glm-div-sqrt-costs,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,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,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,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,3dnow,cx8,mmx,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("k6-3"), str_lit("32bit-mode,3dnow,cx8,mmx,slow-unaligned-mem-16,vzeroupper,x87") }, + { str_lit("k8"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("k8-sse3"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,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,avx512er,avx512f,avx512pf,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prefetchwt1,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,avx512er,avx512f,avx512pf,avx512vpopcntdq,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prefetchwt1,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("meteorlake"), str_lit("32bit-mode,64bit,adx,aes,allow-light-256-bit,avx,avx2,avxvnni,bmi,bmi2,cldemote,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,avx512er,avx512f,avx512pf,bmi,bmi2,cmov,crc32,cx16,cx8,evex512,f16c,fast-gather,fast-movbe,fma,fsgsbase,fxsr,idivq-to-divl,lzcnt,mmx,movbe,nopl,pclmul,popcnt,prefer-mask-registers,prefetchwt1,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,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,3dnow,3dnowa,64bit,cmov,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,vzeroupper,x87") }, + { str_lit("opteron-sse3"), str_lit("32bit-mode,3dnow,3dnowa,64bit,cmov,cx16,cx8,fast-scalar-shift-masks,fxsr,mmx,nopl,sbb-dep-breaking,slow-shld,slow-unaligned-mem-16,sse,sse2,sse3,vzeroupper,x87") }, + { 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,cldemote,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,fast-movbe,fma,fsgsbase,fxsr,gfni,hreset,invpcid,kl,lzcnt,mmx,movbe,movdir64b,movdiri,no-bypass-delay,nopl,pclmul,pconfig,pku,popcnt,prfchw,ptwrite,rdpid,rdrnd,rdseed,sahf,serialize,sha,shstk,slow-incdec,slow-lea,slow-two-mem-ops,sse,sse2,sse3,sse4.1,sse4.2,ssse3,uintr,use-glm-div-sqrt-costs,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-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-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-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,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,3dnow,mmx,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-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,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-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fxsr,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-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,invpcid,lzcnt,macrofusion,mmx,movbe,mwaitx,nopl,pclmul,pku,popcnt,prfchw,rdpid,rdpru,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,slow-shld,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-lzcnt,fast-movbe,fast-scalar-fsqrt,fast-scalar-shift-masks,fast-variable-perlane-shuffle,fast-vector-fsqrt,fma,fsgsbase,fsrm,fxsr,gfni,invpcid,lzcnt,macrofusion,mmx,movbe,mwaitx,nopl,pclmul,pku,popcnt,prfchw,rdpid,rdpru,rdrnd,rdseed,sahf,sbb-dep-breaking,sha,shstk,slow-shld,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,neon,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,neon,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,neon,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,neon,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-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,neon,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-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,neon,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,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,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-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,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,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,db,dsp,fp-armv8d16,fp-armv8d16sp,fp16,fp64,fpregs,fpregs16,fpregs64,fullfp16,hwdiv,lob,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-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,neon,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,fp64,fpregs,fpregs64,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("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,neon,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,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,addr-lsl-fast,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,fuse-address,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,addr-lsl-fast,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,fuse-address,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("apple-a10"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,apple-a10,arith-bcc-fusion,arith-cbz-fusion,crc,crypto,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,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,crypto,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,zcz,zcz-gp") }, + { str_lit("apple-a12"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,apple-a12,arith-bcc-fusion,arith-cbz-fusion,ccidx,ccpp,complxnum,crc,crypto,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,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,ccidx,ccpp,complxnum,crc,crypto,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,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,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,el2vmsa,el3,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,fuse-adrp-add,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,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,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,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,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,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,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,zcz,zcz-gp") }, + { str_lit("apple-a7"), str_lit("aes,alternate-sextload-cvt-f32-pattern,apple-a7,apple-a7-sysreg,arith-bcc-fusion,arith-cbz-fusion,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fuse-aes,fuse-crypto-eor,neon,perfmon,sha2,store-pair-suppress,v8a,zcm,zcz,zcz-fp-workaround,zcz-gp") }, + { str_lit("apple-a8"), str_lit("aes,alternate-sextload-cvt-f32-pattern,apple-a7,apple-a7-sysreg,arith-bcc-fusion,arith-cbz-fusion,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fuse-aes,fuse-crypto-eor,neon,perfmon,sha2,store-pair-suppress,v8a,zcm,zcz,zcz-fp-workaround,zcz-gp") }, + { str_lit("apple-a9"), str_lit("aes,alternate-sextload-cvt-f32-pattern,apple-a7,apple-a7-sysreg,arith-bcc-fusion,arith-cbz-fusion,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fuse-aes,fuse-crypto-eor,neon,perfmon,sha2,store-pair-suppress,v8a,zcm,zcz,zcz-fp-workaround,zcz-gp") }, + { str_lit("apple-latest"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,altnzcv,am,amvs,apple-a16,arith-bcc-fusion,arith-cbz-fusion,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,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,zcz,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,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,el2vmsa,el3,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,fuse-adrp-add,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,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,ccidx,ccpp,complxnum,crc,crypto,disable-latency-sched-heuristic,dit,dotprod,ecv,el2vmsa,el3,fgt,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-address,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,zcz,zcz-gp") }, + { str_lit("apple-s4"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,apple-a12,arith-bcc-fusion,arith-cbz-fusion,ccidx,ccpp,complxnum,crc,crypto,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,zcz,zcz-gp") }, + { str_lit("apple-s5"), str_lit("CONTEXTIDREL2,aes,alternate-sextload-cvt-f32-pattern,apple-a12,arith-bcc-fusion,arith-cbz-fusion,ccidx,ccpp,complxnum,crc,crypto,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,zcz,zcz-gp") }, + { str_lit("carmel"), str_lit("CONTEXTIDREL2,aes,carmel,ccpp,crc,crypto,el2vmsa,el3,fp-armv8,fullfp16,lor,lse,neon,pan,pan-rwv,ras,rdm,sha2,uaops,v8.1a,v8.2a,v8a,vh") }, + { str_lit("cortex-a34"), str_lit("a35,aes,crc,crypto,el2vmsa,el3,fp-armv8,neon,perfmon,sha2,v8a") }, + { str_lit("cortex-a35"), str_lit("a35,aes,crc,crypto,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,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, + { str_lit("cortex-a53"), str_lit("a53,aes,balance-fp-ops,crc,crypto,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,crypto,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,aes,balance-fp-ops,crc,crypto,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,crypto,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,crypto,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,addr-lsl-fast,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,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, + { str_lit("cortex-a715"), str_lit("CONTEXTIDREL2,a715,addr-lsl-fast,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,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,spe,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, + { str_lit("cortex-a72"), str_lit("a72,aes,crc,crypto,el2vmsa,el3,enable-select-opt,fp-armv8,fuse-adrp-add,fuse-aes,fuse-literals,neon,perfmon,predictable-select-expensive,sha2,v8a") }, + { str_lit("cortex-a73"), str_lit("a73,aes,crc,crypto,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,aes,ccpp,crc,crypto,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-fast,aes,alu-lsl-fast,ccpp,crc,crypto,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-fast,aes,alu-lsl-fast,ccpp,crc,crypto,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-fast,aes,alu-lsl-fast,ccpp,cmp-bcc-fusion,crc,crypto,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-fast,aes,alu-lsl-fast,ccpp,cmp-bcc-fusion,crc,crypto,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-fast,aes,alu-lsl-fast,ccpp,cmp-bcc-fusion,crc,crypto,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,ccidx,ccpp,complxnum,cortex-r82,crc,dit,dotprod,flagm,fp-armv8,fp16fml,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-fast,aes,alu-lsl-fast,ccpp,cmp-bcc-fusion,cortex-x1,crc,crypto,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-fast,aes,alu-lsl-fast,ccpp,cmp-bcc-fusion,cortex-x1,crc,crypto,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,addr-lsl-fast,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,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, + { str_lit("cortex-x3"), str_lit("CONTEXTIDREL2,addr-lsl-fast,altnzcv,alu-lsl-fast,am,bf16,bti,ccdp,ccidx,ccpp,complxnum,cortex-x3,crc,dit,dotprod,el2vmsa,el3,enable-select-opt,ete,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,spe,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, + { str_lit("cyclone"), str_lit("aes,alternate-sextload-cvt-f32-pattern,apple-a7,apple-a7-sysreg,arith-bcc-fusion,arith-cbz-fusion,crypto,disable-latency-sched-heuristic,el2vmsa,el3,fp-armv8,fuse-aes,fuse-crypto-eor,neon,perfmon,sha2,store-pair-suppress,v8a,zcm,zcz,zcz-fp-workaround,zcz-gp") }, + { str_lit("exynos-m3"), str_lit("addr-lsl-fast,aes,alu-lsl-fast,crc,crypto,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,addr-lsl-fast,aes,alu-lsl-fast,arith-bcc-fusion,arith-cbz-fusion,ccpp,crc,crypto,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,addr-lsl-fast,aes,alu-lsl-fast,arith-bcc-fusion,arith-cbz-fusion,ccpp,crc,crypto,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("addr-lsl-fast,aes,alu-lsl-fast,crc,crypto,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("generic"), str_lit("enable-select-opt,ete,fp-armv8,fuse-adrp-add,fuse-aes,neon,trbe,use-postra-scheduler") }, + { str_lit("kryo"), str_lit("addr-lsl-fast,aes,alu-lsl-fast,crc,crypto,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,addr-lsl-fast,aes,alu-lsl-fast,am,bf16,ccdp,ccidx,ccpp,complxnum,crc,crypto,dit,dotprod,el2vmsa,el3,enable-select-opt,flagm,fp-armv8,fp16fml,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,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,crypto,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-fast,aes,alu-lsl-fast,ccpp,crc,crypto,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,addr-lsl-fast,altnzcv,alu-lsl-fast,am,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,dit,dotprod,el2vmsa,el3,enable-select-opt,ete,flagm,fp-armv8,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,neoversen2,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, + { str_lit("neoverse-v1"), str_lit("CONTEXTIDREL2,addr-lsl-fast,aes,alu-lsl-fast,am,bf16,ccdp,ccidx,ccpp,complxnum,crc,crypto,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,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,addr-lsl-fast,altnzcv,alu-lsl-fast,am,bf16,bti,ccdp,ccidx,ccpp,complxnum,crc,dit,dotprod,el2vmsa,el3,enable-select-opt,ete,flagm,fp-armv8,fp16fml,fptoint,fullfp16,fuse-adrp-add,fuse-aes,i8mm,jsconv,lor,lse,lse2,mec,mpam,mte,neon,neoversev2,nv,pan,pan-rwv,pauth,perfmon,predictable-select-expensive,predres,rand,ras,rcpc,rcpc-immo,rdm,rme,sb,sel2,spe,specrestrict,ssbs,sve,sve2,sve2-bitperm,tlb-rmi,tracev8.4,trbe,uaops,use-postra-scheduler,use-scalar-inc-vl,v8.1a,v8.2a,v8.3a,v8.4a,v8.5a,v8a,v9a,vh") }, + { str_lit("saphira"), str_lit("CONTEXTIDREL2,addr-lsl-fast,aes,alu-lsl-fast,am,ccidx,ccpp,complxnum,crc,crypto,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,crypto,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,crypto,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,crypto,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,crypto,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,crypto,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,crypto,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,crypto,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,mutable-globals,nontrapping-fptoint,sign-ext,simd128,tail-call") }, + { str_lit("generic"), str_lit("mutable-globals,sign-ext") }, + { str_lit("mvp"), str_lit("") }, + // TargetArch_wasm64p32: + { str_lit("bleeding-edge"), str_lit("atomics,bulk-memory,mutable-globals,nontrapping-fptoint,sign-ext,simd128,tail-call") }, + { str_lit("generic"), str_lit("mutable-globals,sign-ext") }, + { str_lit("mvp"), str_lit("") }, +}; \ No newline at end of file diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index a8299d0f5..c1729333f 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -1726,11 +1726,13 @@ gb_internal bool check_builtin_procedure_directive(CheckerContext *c, Operand *o gb_string_free(str); return false; } - error(call, "Compile time panic: %.*s", LIT(operand->value.value_string)); - if (c->proc_name != "") { - gbString str = type_to_string(c->curr_proc_sig); - error_line("\tCalled within '%.*s' :: %s\n", LIT(c->proc_name), str); - gb_string_free(str); + if (!build_context.ignore_panic) { + error(call, "Compile time panic: %.*s", LIT(operand->value.value_string)); + if (c->proc_name != "") { + gbString str = type_to_string(c->curr_proc_sig); + error_line("\tCalled within '%.*s' :: %s\n", LIT(c->proc_name), str); + gb_string_free(str); + } } operand->type = t_invalid; operand->mode = Addressing_NoValue; @@ -5851,6 +5853,31 @@ gb_internal bool check_builtin_procedure(CheckerContext *c, Operand *operand, As operand->mode = Addressing_Constant; operand->type = t_untyped_integer; break; + case BuiltinProc_type_struct_has_implicit_padding: + operand->value = exact_value_bool(false); + if (operand->mode != Addressing_Type) { + error(operand->expr, "Expected a struct type for '%.*s'", LIT(builtin_name)); + } else if (!is_type_struct(operand->type) && !is_type_soa_struct(operand->type)) { + error(operand->expr, "Expected a struct type for '%.*s'", LIT(builtin_name)); + } else { + Type *bt = base_type(operand->type); + if (bt->Struct.is_packed) { + operand->value = exact_value_bool(false); + } else if (bt->Struct.fields.count != 0) { + i64 size = type_size_of(bt); + Type *field_type = nullptr; + i64 last_offset = type_offset_of(bt, bt->Struct.fields.count-1, &field_type); + if (last_offset+type_size_of(field_type) < size) { + operand->value = exact_value_bool(true); + } else { + i64 packed_size = type_size_of_struct_pretend_is_packed(bt); + operand->value = exact_value_bool(packed_size < size); + } + } + } + operand->mode = Addressing_Constant; + operand->type = t_untyped_bool; + break; case BuiltinProc_type_proc_parameter_count: operand->value = exact_value_i64(0); diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 818556951..883cfcba9 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -709,7 +709,7 @@ gb_internal Entity *init_entity_foreign_library(CheckerContext *ctx, Entity *e) } if (ident == nullptr) { - error(e->token, "foreign entiies must declare which library they are from"); + error(e->token, "foreign entities must declare which library they are from"); } else if (ident->kind != Ast_Ident) { error(ident, "foreign library names must be an identifier"); } else { @@ -1320,8 +1320,8 @@ gb_internal void check_global_variable_decl(CheckerContext *ctx, Entity *&e, Ast error(e->token, "A foreign variable declaration cannot have a default value"); } init_entity_foreign_library(ctx, e); - if (is_arch_wasm()) { - error(e->token, "A foreign variable declaration are not allowed for the '%.*s' architecture", LIT(target_arch_names[build_context.metrics.arch])); + if (is_arch_wasm() && e->Variable.foreign_library != nullptr) { + error(e->token, "A foreign variable declaration can not be scoped to a module and must be declared in a 'foreign {' (without a library) block"); } } if (ac.link_name.len > 0) { diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 507ae68d9..ece7f4a8e 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -1435,6 +1435,16 @@ gb_internal bool is_polymorphic_type_assignable(CheckerContext *c, Type *poly, T if (!is_polymorphic_type_assignable(c, poly->BitSet.elem, source->BitSet.elem, true, modify_type)) { return false; } + + // For generic types like bit_set[$T] the upper and lower of the poly type will be zeroes since + // it could not figure that stuff out when the poly type was created. + if (poly->BitSet.upper == 0 && modify_type) { + poly->BitSet.upper = source->BitSet.upper; + } + if (poly->BitSet.lower == 0 && modify_type) { + poly->BitSet.lower = source->BitSet.lower; + } + if (poly->BitSet.underlying == nullptr) { if (modify_type) { poly->BitSet.underlying = source->BitSet.underlying; @@ -3310,7 +3320,7 @@ gb_internal bool check_cast_internal(CheckerContext *c, Operand *x, Type *type) } -gb_internal void check_cast(CheckerContext *c, Operand *x, Type *type) { +gb_internal void check_cast(CheckerContext *c, Operand *x, Type *type, bool forbid_identical = false) { if (!is_operand_value(*x)) { error(x->expr, "Only values can be casted"); x->mode = Addressing_Invalid; @@ -3382,27 +3392,37 @@ gb_internal void check_cast(CheckerContext *c, Operand *x, Type *type) { add_package_dependency(c, "runtime", "gnu_f2h_ieee", REQUIRE); } } + // If we check polymorphic procedures, we risk erring on + // identical casts that cannot be foreseen or otherwise + // forbidden, so just skip them. + if (forbid_identical && check_vet_flags(c) & VetFlag_Cast && + (c->curr_proc_sig == nullptr || !is_type_polymorphic(c->curr_proc_sig))) { + Type *src_exact = x->type; + Type *dst_exact = type; + + if (src_exact != nullptr && + dst_exact != nullptr && + are_types_identical(src_exact, dst_exact) + ) { + gbString oper_str = expr_to_string(x->expr); + gbString to_type = type_to_string(dst_exact); + error(x->expr, "Unneeded cast of '%s' to identical type '%s'", oper_str, to_type); + gb_string_free(oper_str); + gb_string_free(to_type); + } + } } x->type = type; } -gb_internal bool check_transmute(CheckerContext *c, Ast *node, Operand *o, Type *t) { +gb_internal bool check_transmute(CheckerContext *c, Ast *node, Operand *o, Type *t, bool forbid_identical = false) { if (!is_operand_value(*o)) { error(o->expr, "'transmute' can only be applied to values"); o->mode = Addressing_Invalid; return false; } - // if (o->mode == Addressing_Constant) { - // gbString expr_str = expr_to_string(o->expr); - // error(o->expr, "Cannot transmute a constant expression: '%s'", expr_str); - // gb_string_free(expr_str); - // o->mode = Addressing_Invalid; - // o->expr = node; - // return false; - // } - Type *src_t = o->type; Type *dst_t = t; Type *src_bt = base_type(src_t); @@ -3485,6 +3505,36 @@ gb_internal bool check_transmute(CheckerContext *c, Ast *node, Operand *o, Type return true; } } + } else { + // If we check polymorphic procedures, we risk erring on + // identical casts that cannot be foreseen or otherwise + // forbidden, so just skip them. + if (forbid_identical && check_vet_flags(c) & VetFlag_Cast && + (c->curr_proc_sig == nullptr || !is_type_polymorphic(c->curr_proc_sig))) { + if (are_types_identical(src_t, dst_t)) { + gbString oper_str = expr_to_string(o->expr); + gbString to_type = type_to_string(dst_t); + error(o->expr, "Unneeded transmute of '%s' to identical type '%s'", oper_str, to_type); + gb_string_free(oper_str); + gb_string_free(to_type); + } else if (is_type_internally_pointer_like(src_t) && + is_type_internally_pointer_like(dst_t)) { + error(o->expr, "Use of 'transmute' where 'cast' would be preferred since the types are pointer-like"); + } else if (are_types_identical(src_bt, dst_bt)) { + gbString oper_str = expr_to_string(o->expr); + gbString to_type = type_to_string(dst_t); + error(o->expr, "Unneeded transmute of '%s' to identical type '%s'", oper_str, to_type); + gb_string_free(oper_str); + gb_string_free(to_type); + } else if (is_type_integer(src_t) && is_type_integer(dst_t) && + types_have_same_internal_endian(src_t, dst_t)) { + gbString oper_type = type_to_string(src_t); + gbString to_type = type_to_string(dst_t); + error(o->expr, "Use of 'transmute' where 'cast' would be preferred since both are integers of the same endianness, from '%s' to '%s'", oper_type, to_type); + gb_string_free(to_type); + gb_string_free(oper_type); + } + } } o->mode = Addressing_Value; @@ -4431,9 +4481,14 @@ gb_internal void convert_to_typed(CheckerContext *c, Operand *operand, Type *tar defer (gb_string_free(type_str)); if (valid_count == 1) { + Type *new_type = t->Union.variants[first_success_index]; + target_type = new_type; + if (is_type_union(new_type)) { + convert_to_typed(c, operand, new_type); + break; + } + operand->type = new_type; operand->mode = Addressing_Value; - operand->type = t->Union.variants[first_success_index]; - target_type = t->Union.variants[first_success_index]; break; } else if (valid_count > 1) { ERROR_BLOCK(); @@ -6113,7 +6168,9 @@ gb_internal CallArgumentError check_call_arguments_internal(CheckerContext *c, A Type *t = elem; if (is_type_polymorphic(t)) { - error(call, "Ambiguous call to a polymorphic variadic procedure with no variadic input %s", type_to_string(final_proc_type)); + if (show_error) { + error(call, "Ambiguous call to a polymorphic variadic procedure with no variadic input %s", type_to_string(final_proc_type)); + } err = CallArgumentError_AmbiguousPolymorphicVariadic; } @@ -6745,9 +6802,73 @@ gb_internal CallArgumentData check_call_arguments_proc_group(CheckerContext *c, if (procs.count > 0) { error_line("Did you mean to use one of the following:\n"); } + + // Try to reduce the list further for `$T: typeid` like parameters + bool *possibly_ignore = gb_alloc_array(temporary_allocator(), bool, procs.count); + isize possibly_ignore_set = 0; + + if (true) { + // NOTE(bill): This currently only checks for #soa types + for_array(i, procs) { + Entity *proc = procs[i]; + Type *t = base_type(proc->type); + if (t == nullptr || t->kind != Type_Proc) { + continue; + } + + TypeProc *pt = &t->Proc; + if (pt->param_count == 0) { + continue; + } + + for_array(j, pt->params->Tuple.variables) { + Entity *v = pt->params->Tuple.variables[j]; + if (v->kind != Entity_TypeName) { + continue; + } + + Type *dst_t = base_type(v->type); + while (dst_t->kind == Type_Generic && dst_t->Generic.specialized) { + dst_t = dst_t->Generic.specialized; + } + + if (j >= positional_operands.count) { + continue; + } + Operand const &o = positional_operands[j]; + if (o.mode != Addressing_Type) { + continue; + } + Type *t = base_type(o.type); + if (t->kind == dst_t->kind) { + continue; + } + Type *st = base_type(type_deref(o.type)); + Type *dt = base_type(type_deref(dst_t)); + if (st->kind == dt->kind) { + continue; + } + if (is_type_soa_struct(st)) { + possibly_ignore[i] = true; + possibly_ignore_set += 1; + continue; + } + } + } + } + + if (possibly_ignore_set == procs.count) { + possibly_ignore_set = 0; + } + + isize max_name_length = 0; isize max_type_length = 0; - for (Entity *proc : procs) { + for_array(i, procs) { + if (possibly_ignore_set != 0 && possibly_ignore[i]) { + continue; + } + Entity *proc = procs[i]; Type *t = base_type(proc->type); if (t == t_invalid) continue; String prefix = {}; @@ -6777,7 +6898,11 @@ gb_internal CallArgumentData check_call_arguments_proc_group(CheckerContext *c, } spaces[max_spaces] = 0; - for (Entity *proc : procs) { + for_array(i, procs) { + if (possibly_ignore_set != 0 && possibly_ignore[i]) { + continue; + } + Entity *proc = procs[i]; TokenPos pos = proc->token.pos; Type *t = base_type(proc->type); if (t == t_invalid) continue; @@ -9002,12 +9127,16 @@ gb_internal ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast * type = nullptr; // [?]Type - if (type_expr->kind == Ast_ArrayType && type_expr->ArrayType.count != nullptr) { + if (type_expr->kind == Ast_ArrayType) { Ast *count = type_expr->ArrayType.count; - if (count->kind == Ast_UnaryExpr && - count->UnaryExpr.op.kind == Token_Question) { - type = alloc_type_array(check_type(c, type_expr->ArrayType.elem), -1); - is_to_be_determined_array_count = true; + if (count != nullptr) { + if (count->kind == Ast_UnaryExpr && + count->UnaryExpr.op.kind == Token_Question) { + type = alloc_type_array(check_type(c, type_expr->ArrayType.elem), -1); + is_to_be_determined_array_count = true; + } + } else { + type = alloc_type_slice(check_type(c, type_expr->ArrayType.elem)); } if (cl->elems.count > 0) { if (type_expr->ArrayType.tag != nullptr) { @@ -9020,8 +9149,7 @@ gb_internal ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast * } } } - } - if (type_expr->kind == Ast_DynamicArrayType && type_expr->DynamicArrayType.tag != nullptr) { + } else if (type_expr->kind == Ast_DynamicArrayType && type_expr->DynamicArrayType.tag != nullptr) { if (cl->elems.count > 0) { Ast *tag = type_expr->DynamicArrayType.tag; GB_ASSERT(tag->kind == Ast_BasicDirective); @@ -9060,6 +9188,12 @@ gb_internal ExprKind check_compound_literal(CheckerContext *c, Operand *o, Ast * if (cl->elems.count == 0) { break; // NOTE(bill): No need to init } + + if (t->Struct.soa_kind != StructSoa_None) { + error(node, "#soa arrays are not supported for compound literals"); + break; + } + if (t->Struct.is_raw_union) { if (cl->elems.count > 0) { // NOTE: unions cannot be constant @@ -10712,10 +10846,10 @@ gb_internal ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast if (o->mode != Addressing_Invalid) { switch (tc->token.kind) { case Token_transmute: - check_transmute(c, node, o, type); + check_transmute(c, node, o, type, true); break; case Token_cast: - check_cast(c, o, type); + check_cast(c, o, type, true); break; default: error(node, "Invalid AST: Invalid casting expression"); @@ -11361,6 +11495,9 @@ gb_internal gbString write_expr_to_string(gbString str, Ast *node, bool shorthan case_end; case_ast_node(pt, PointerType, node); + if (pt->tag) { + str = write_expr_to_string(str, pt->tag, false); + } str = gb_string_append_rune(str, '^'); str = write_expr_to_string(str, pt->type, shorthand); case_end; @@ -11371,6 +11508,9 @@ gb_internal gbString write_expr_to_string(gbString str, Ast *node, bool shorthan case_end; case_ast_node(at, ArrayType, node); + if (at->tag) { + str = write_expr_to_string(str, at->tag, false); + } str = gb_string_append_rune(str, '['); if (at->count != nullptr && at->count->kind == Ast_UnaryExpr && @@ -11384,6 +11524,9 @@ gb_internal gbString write_expr_to_string(gbString str, Ast *node, bool shorthan case_end; case_ast_node(at, DynamicArrayType, node); + if (at->tag) { + str = write_expr_to_string(str, at->tag, false); + } str = gb_string_appendc(str, "[dynamic]"); str = write_expr_to_string(str, at->elem, shorthand); case_end; diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index f2e3b0242..edf2fae39 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1258,6 +1258,20 @@ gb_internal void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags error_line("\tSuggestion: Was '#partial switch' wanted?\n"); } } + + if (build_context.strict_style) { + Token stok = ss->token; + for_array(i, bs->stmts) { + Ast *stmt = bs->stmts[i]; + if (stmt->kind != Ast_CaseClause) { + continue; + } + Token ctok = stmt->CaseClause.token; + if (ctok.pos.column > stok.pos.column) { + error(ctok, "With '-strict-style', 'case' statements must share the same column as the 'switch' token"); + } + } + } } diff --git a/src/check_type.cpp b/src/check_type.cpp index c56c8a739..7fd9b379a 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -335,7 +335,7 @@ bool check_constant_parameter_value(Type *type, Ast *expr) { gb_internal Type *check_record_polymorphic_params(CheckerContext *ctx, Ast *polymorphic_params, bool *is_polymorphic_, - Ast *node, Array *poly_operands) { + Array *poly_operands) { Type *polymorphic_params_type = nullptr; GB_ASSERT(is_polymorphic_ != nullptr); @@ -643,13 +643,14 @@ gb_internal void check_struct_type(CheckerContext *ctx, Type *struct_type, Ast * context = str_lit("struct #raw_union"); } + struct_type->Struct.node = node; struct_type->Struct.scope = ctx->scope; struct_type->Struct.is_packed = st->is_packed; struct_type->Struct.is_no_copy = st->is_no_copy; struct_type->Struct.polymorphic_params = check_record_polymorphic_params( ctx, st->polymorphic_params, &struct_type->Struct.is_polymorphic, - node, poly_operands + poly_operands ); wait_signal_set(&struct_type->Struct.polymorphic_wait_signal); @@ -696,11 +697,12 @@ gb_internal void check_union_type(CheckerContext *ctx, Type *union_type, Ast *no ast_node(ut, UnionType, node); + union_type->Union.node = node; union_type->Union.scope = ctx->scope; union_type->Union.polymorphic_params = check_record_polymorphic_params( ctx, ut->polymorphic_params, &union_type->Union.is_polymorphic, - node, poly_operands + poly_operands ); wait_signal_set(&union_type->Union.polymorphic_wait_signal); diff --git a/src/checker.cpp b/src/checker.cpp index fdf5a8b7d..734659510 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -346,6 +346,7 @@ gb_internal Scope *scope_of_node(Ast *node) { gb_internal void check_open_scope(CheckerContext *c, Ast *node) { node = unparen_expr(node); + GB_ASSERT(node != nullptr); GB_ASSERT(node->kind == Ast_Invalid || is_ast_stmt(node) || is_ast_type(node)); @@ -3899,10 +3900,11 @@ gb_internal void check_decl_attributes(CheckerContext *c, Array const &at } if (!proc(c, elem, name, value, ac)) { - if (!build_context.ignore_unknown_attributes) { + if (!build_context.ignore_unknown_attributes && + !string_set_exists(&build_context.custom_attributes, name)) { ERROR_BLOCK(); error(elem, "Unknown attribute element name '%.*s'", LIT(name)); - error_line("\tDid you forget to use build flag '-ignore-unknown-attributes'?\n"); + error_line("\tDid you forget to use the build flag '-ignore-unknown-attributes' or '-custom-attribute:%.*s'?\n", LIT(name)); } } } diff --git a/src/checker_builtin_procs.hpp b/src/checker_builtin_procs.hpp index a2b8a5361..a90c52e61 100644 --- a/src/checker_builtin_procs.hpp +++ b/src/checker_builtin_procs.hpp @@ -277,6 +277,7 @@ BuiltinProc__type_simple_boolean_end, BuiltinProc_type_bit_set_underlying_type, BuiltinProc_type_struct_field_count, + BuiltinProc_type_struct_has_implicit_padding, BuiltinProc_type_proc_parameter_count, BuiltinProc_type_proc_return_count, @@ -593,7 +594,8 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = { {STR_LIT("type_bit_set_elem_type"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_bit_set_underlying_type"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, - {STR_LIT("type_struct_field_count"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("type_struct_field_count"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, + {STR_LIT("type_struct_has_implicit_padding"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_proc_parameter_count"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, {STR_LIT("type_proc_return_count"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics}, diff --git a/src/error.cpp b/src/error.cpp index 03d96219b..f95123f15 100644 --- a/src/error.cpp +++ b/src/error.cpp @@ -237,6 +237,7 @@ enum TerminalColour { TerminalColour_Blue, TerminalColour_Purple, TerminalColour_Black, + TerminalColour_Grey, }; gb_internal void terminal_set_colours(TerminalStyle style, TerminalColour foreground) { @@ -256,6 +257,7 @@ gb_internal void terminal_set_colours(TerminalStyle style, TerminalColour foregr case TerminalColour_Blue: error_out("\x1b[%s;34m", ss); break; case TerminalColour_Purple: error_out("\x1b[%s;35m", ss); break; case TerminalColour_Black: error_out("\x1b[%s;30m", ss); break; + case TerminalColour_Grey: error_out("\x1b[%s;90m", ss); break; } } } @@ -272,85 +274,234 @@ gb_internal isize show_error_on_line(TokenPos const &pos, TokenPos end) { return -1; } - i32 offset = 0; - gbString the_line = get_file_line_as_string(pos, &offset); + i32 error_start_index_bytes = 0; + gbString the_line = get_file_line_as_string(pos, &error_start_index_bytes); defer (gb_string_free(the_line)); - if (the_line != nullptr) { - char const *line_text = the_line; - isize line_len = gb_string_length(the_line); - - // TODO(bill): This assumes ASCII - - enum { - MAX_LINE_LENGTH = 80, - MAX_TAB_WIDTH = 8, - ELLIPSIS_PADDING = 8, // `... ...` - MAX_LINE_LENGTH_PADDED = MAX_LINE_LENGTH-MAX_TAB_WIDTH-ELLIPSIS_PADDING, - }; - - i32 error_length = gb_max(end.offset - pos.offset, 1); - - error_out("\t"); - - terminal_set_colours(TerminalStyle_Bold, TerminalColour_White); - - - isize squiggle_extra = 0; - - if (line_len > MAX_LINE_LENGTH_PADDED) { - i32 left = MAX_TAB_WIDTH; - i32 diff = gb_max(offset-left, 0); - if (diff > 0) { - line_text += diff; - line_len -= diff; - offset = left + ELLIPSIS_PADDING/2; - } - if (line_len > MAX_LINE_LENGTH_PADDED) { - line_len = MAX_LINE_LENGTH_PADDED; - if (error_length > line_len-left) { - error_length = cast(i32)line_len - left; - squiggle_extra = 1; - } - } - if (diff > 0) { - error_out("... %.*s ...", cast(i32)line_len, line_text); - } else { - error_out("%.*s ...", cast(i32)line_len, line_text); - } - } else { - error_out("%.*s", cast(i32)line_len, line_text); - } - error_out("\n\t"); - - for (i32 i = 0; i < offset; i++) { - error_out(" "); - } - - terminal_set_colours(TerminalStyle_Bold, TerminalColour_Green); - - error_out("^"); - if (end.file_id == pos.file_id) { - if (end.line > pos.line) { - for (i32 i = offset; i < line_len; i++) { - error_out("~"); - } - } else if (end.line == pos.line && end.column > pos.column) { - for (i32 i = 1; i < error_length-1+squiggle_extra; i++) { - error_out("~"); - } - if (error_length > 1 && squiggle_extra == 0) { - error_out("^"); - } - } - } - + if (the_line == nullptr || gb_string_length(the_line) == 0) { + terminal_set_colours(TerminalStyle_Normal, TerminalColour_Grey); + error_out("\t( empty line )\n"); terminal_reset_colours(); - error_out("\n"); - return offset; + if (the_line == nullptr) { + return -1; + } else { + return cast(isize)error_start_index_bytes; + } } - return -1; + + // These two will be used like an Odin slice later. + char const *line_text = the_line; + i32 line_length_bytes = cast(i32)gb_string_length(the_line); + + ucg_grapheme* graphemes; + i32 line_length_runes = 0; + i32 line_length_graphemes = 0; + i32 line_width = 0; + + int ucg_result = ucg_decode_grapheme_clusters( + permanent_allocator(), (const uint8_t*)line_text, line_length_bytes, + &graphemes, &line_length_runes, &line_length_graphemes, &line_width); + + if (ucg_result < 0) { + // There was a UTF-8 parsing error. + // Insert a dummy grapheme so the start of the invalid rune can be pointed at. + graphemes = (ucg_grapheme*)gb_resize(permanent_allocator(), + graphemes, + sizeof(ucg_grapheme) * (line_length_graphemes), + sizeof(ucg_grapheme) * (1 + line_length_graphemes)); + + ucg_grapheme append = { + error_start_index_bytes, + line_length_runes, + 1, + }; + + graphemes[line_length_graphemes] = append; + } + + // The units below are counted in visual, monospace cells. + enum { + MAX_LINE_LENGTH = 80, + MAX_TAB_WIDTH = 8, + ELLIPSIS_PADDING = 8, // `... ...` + MIN_LEFT_VIEW = 8, + + // A rough estimate of how many characters we'll insert, at most: + MAX_INSERTED_WIDTH = MAX_TAB_WIDTH + ELLIPSIS_PADDING, + + MAX_LINE_LENGTH_PADDED = MAX_LINE_LENGTH - MAX_INSERTED_WIDTH, + }; + + i32 error_start_index_graphemes = 0; + for (i32 i = 0; i < line_length_graphemes; i += 1) { + if (graphemes[i].byte_index == error_start_index_bytes) { + error_start_index_graphemes = i; + break; + } + } + + if (error_start_index_graphemes == 0 && error_start_index_bytes != 0 && line_length_graphemes != 0) { + // The error index in graphemes was not found, but we did find a valid Unicode string. + // + // This is an edge case where the error is sitting on a newline or the + // end of the line, as that is the only location we could not have checked. + error_start_index_graphemes = line_length_graphemes; + } + + error_out("\t"); + + bool show_right_ellipsis = false; + + i32 squiggle_padding = 0; + i32 window_open_bytes = 0; + i32 window_close_bytes = 0; + if (line_width > MAX_LINE_LENGTH_PADDED) { + // Now that we know the line is over the length limit, we have to + // compose a visual window in which to display the error. + i32 window_size_left = 0; + i32 window_size_right = 0; + i32 window_open_graphemes = 0; + + for (i32 i = error_start_index_graphemes - 1; i > 0; i -= 1) { + window_size_left += graphemes[i].width; + if (window_size_left >= MIN_LEFT_VIEW) { + window_open_graphemes = i; + window_open_bytes = graphemes[i].byte_index; + break; + } + } + + for (i32 i = error_start_index_graphemes; i < line_length_graphemes; i += 1) { + window_size_right += graphemes[i].width; + if (window_size_right >= MAX_LINE_LENGTH_PADDED - MIN_LEFT_VIEW) { + window_close_bytes = graphemes[i].byte_index; + break; + } + } + if (window_close_bytes == 0) { + // The window ends at the end of the line. + window_close_bytes = line_length_bytes; + } + + if (window_size_right < MAX_LINE_LENGTH_PADDED - MIN_LEFT_VIEW) { + // Hit the end of the string early on the right side; expand backwards. + for (i32 i = window_open_graphemes - 1; i > 0; i -= 1) { + window_size_left += graphemes[i].width; + if (window_size_left + window_size_right >= MAX_LINE_LENGTH_PADDED) { + window_open_graphemes = i; + window_open_bytes = graphemes[i].byte_index; + break; + } + } + } + + GB_ASSERT_MSG(window_close_bytes >= window_open_bytes, "Error line truncation window has wrong byte indices. (open, close: %i, %i)", window_open_bytes, window_close_bytes); + + if (window_close_bytes != line_length_bytes) { + show_right_ellipsis = true; + } + + // Close the window, going left. + line_length_bytes = window_close_bytes; + + // Adjust the slice of text. In Odin, this would be: + // `line_text = line_text[window_left_bytes:]` + line_text += window_open_bytes; + line_length_bytes -= window_open_bytes; + GB_ASSERT_MSG(line_length_bytes >= 0, "Bounds-checking error: line_length_bytes"); + + if (window_open_bytes > 0) { + error_out("... "); + squiggle_padding += 4; + } + } else { + // No truncation needed. + window_open_bytes = 0; + window_close_bytes = line_length_bytes; + } + + for (i32 i = error_start_index_graphemes; i > 0; i -= 1) { + if (graphemes[i].byte_index == window_open_bytes) { + break; + } + squiggle_padding += graphemes[i].width; + } + + // Start printing code. + + terminal_set_colours(TerminalStyle_Normal, TerminalColour_White); + error_out("%.*s", line_length_bytes, line_text); + + i32 squiggle_length = 0; + bool trailing_squiggle = false; + + if (end.file_id == pos.file_id) { + // The error has an endpoint. + + if (end.line > pos.line) { + // Error goes to next line. + // Always show the ellipsis in this case + show_right_ellipsis = true; + + for (i32 i = error_start_index_graphemes; i < line_length_graphemes; i += 1) { + squiggle_length += graphemes[i].width; + trailing_squiggle = true; + } + + } else if (end.line == pos.line && end.column > pos.column) { + // Error terminates before line end. + i32 adjusted_end_index = graphemes[error_start_index_graphemes].byte_index + end.column - pos.column; + + for (i32 i = error_start_index_graphemes; i < line_length_graphemes; i += 1) { + if (graphemes[i].byte_index >= adjusted_end_index) { + break; + } else if (graphemes[i].byte_index >= window_close_bytes) { + trailing_squiggle = true; + break; + } + squiggle_length += graphemes[i].width; + } + } + } else { + // The error is at one spot; no range known. + squiggle_length = 1; + } + + if (show_right_ellipsis) { + error_out(" ..."); + } + + error_out("\n\t"); + + for (i32 i = squiggle_padding; i > 0; i -= 1) { + error_out(" "); + } + + terminal_set_colours(TerminalStyle_Bold, TerminalColour_Green); + + if (squiggle_length > 0) { + error_out("^"); + squiggle_length -= 1; + } + for (/**/; squiggle_length > 1; squiggle_length -= 1) { + error_out("~"); + } + if (squiggle_length > 0) { + if (trailing_squiggle) { + error_out("~ ..."); + } else { + error_out("^"); + } + } + + // NOTE(Feoramund): Specifically print a newline, then reset colours, + // instead of the other way around. Otherwise the printing mechanism + // will collapse the newline for reasons currently beyond my ken. + error_out("\n"); + terminal_reset_colours(); + + return squiggle_padding; } gb_internal void error_out_empty(void) { diff --git a/src/linker.cpp b/src/linker.cpp index 9eed14ea9..371736743 100644 --- a/src/linker.cpp +++ b/src/linker.cpp @@ -70,11 +70,23 @@ gb_internal i32 linker_stage(LinkerData *gen) { if (is_arch_wasm()) { timings_start_section(timings, str_lit("wasm-ld")); + gbString lib_str = gb_string_make(heap_allocator(), ""); + gbString extra_orca_flags = gb_string_make(temporary_allocator(), ""); gbString inputs = gb_string_make(temporary_allocator(), ""); inputs = gb_string_append_fmt(inputs, "\"%.*s.o\"", LIT(output_filename)); + + for (Entity *e : gen->foreign_libraries) { + GB_ASSERT(e->kind == Entity_LibraryName); + // NOTE(bill): Add these before the linking values + String extra_linker_flags = string_trim_whitespace(e->LibraryName.extra_linker_flags); + if (extra_linker_flags.len != 0) { + lib_str = gb_string_append_fmt(lib_str, " %.*s", LIT(extra_linker_flags)); + } + } + if (build_context.metrics.os == TargetOs_orca) { gbString orca_sdk_path = gb_string_make(temporary_allocator(), ""); if (!system_exec_command_line_app_output("orca sdk-path", &orca_sdk_path)) { @@ -93,16 +105,18 @@ gb_internal i32 linker_stage(LinkerData *gen) { #if defined(GB_SYSTEM_WINDOWS) result = system_exec_command_line_app("wasm-ld", - "\"%.*s\\bin\\wasm-ld\" %s -o \"%.*s\" %.*s %.*s %s", + "\"%.*s\\bin\\wasm-ld\" %s -o \"%.*s\" %.*s %.*s %s %s", LIT(build_context.ODIN_ROOT), inputs, LIT(output_filename), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags), + lib_str, extra_orca_flags); #else result = system_exec_command_line_app("wasm-ld", - "wasm-ld %s -o \"%.*s\" %.*s %.*s %s", + "wasm-ld %s -o \"%.*s\" %.*s %.*s %s %s", inputs, LIT(output_filename), LIT(build_context.link_flags), LIT(build_context.extra_linker_flags), + lib_str, extra_orca_flags); #endif return result; @@ -578,9 +592,16 @@ gb_internal i32 linker_stage(LinkerData *gen) { } } - gbString link_command_line = gb_string_make(heap_allocator(), "clang -Wno-unused-command-line-argument "); + // Link using `clang`, unless overridden by `ODIN_CLANG_PATH` environment variable. + const char* clang_path = gb_get_env("ODIN_CLANG_PATH", permanent_allocator()); + if (clang_path == NULL) { + clang_path = "clang"; + } + + gbString link_command_line = gb_string_make(heap_allocator(), clang_path); defer (gb_string_free(link_command_line)); + link_command_line = gb_string_appendc(link_command_line, " -Wno-unused-command-line-argument "); link_command_line = gb_string_appendc(link_command_line, object_files); link_command_line = gb_string_append_fmt(link_command_line, " -o \"%.*s\" ", LIT(output_filename)); link_command_line = gb_string_append_fmt(link_command_line, " %s ", platform_lib_str); diff --git a/src/llvm_abi.cpp b/src/llvm_abi.cpp index 1f7a39447..b2e485d01 100644 --- a/src/llvm_abi.cpp +++ b/src/llvm_abi.cpp @@ -1239,9 +1239,9 @@ namespace lbAbiWasm { gb_internal LB_ABI_INFO(abi_info) { lbFunctionType *ft = gb_alloc_item(permanent_allocator(), lbFunctionType); ft->ctx = c; + ft->calling_convention = calling_convention; ft->args = compute_arg_types(c, arg_types, arg_count, calling_convention, original_type); ft->ret = compute_return_type(ft, c, return_type, return_is_defined, return_is_tuple); - ft->calling_convention = calling_convention; return ft; } @@ -1378,14 +1378,14 @@ namespace lbAbiWasm { } else if (lb_is_type_kind(return_type, LLVMStructTypeKind) || lb_is_type_kind(return_type, LLVMArrayTypeKind)) { if (type_can_be_direct(return_type, ft->calling_convention)) { return lb_arg_type_direct(return_type); - } - - i64 sz = lb_sizeof(return_type); - switch (sz) { - case 1: return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 8), nullptr, nullptr); - case 2: return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 16), nullptr, nullptr); - case 4: return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 32), nullptr, nullptr); - case 8: return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 64), nullptr, nullptr); + } else if (ft->calling_convention != ProcCC_CDecl) { + i64 sz = lb_sizeof(return_type); + switch (sz) { + case 1: return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 8), nullptr, nullptr); + case 2: return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 16), nullptr, nullptr); + case 4: return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 32), nullptr, nullptr); + case 8: return lb_arg_type_direct(return_type, LLVMIntTypeInContext(c, 64), nullptr, nullptr); + } } LB_ABI_MODIFY_RETURN_IF_TUPLE_MACRO(); diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 04c4ce244..92c8138c5 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -3217,8 +3217,6 @@ gb_internal bool lb_generate_code(lbGenerator *gen) { LLVMSetDLLStorageClass(g.value, LLVMDLLImportStorageClass); LLVMSetExternallyInitialized(g.value, true); lb_add_foreign_library_path(m, e->Variable.foreign_library); - - lb_set_wasm_import_attributes(g.value, e, name); } else { LLVMSetInitializer(g.value, LLVMConstNull(lb_type(m, e->type))); } diff --git a/src/llvm_backend_expr.cpp b/src/llvm_backend_expr.cpp index a23f8cfbe..bcacc0537 100644 --- a/src/llvm_backend_expr.cpp +++ b/src/llvm_backend_expr.cpp @@ -1127,12 +1127,21 @@ gb_internal lbValue lb_emit_arith(lbProcedure *p, TokenKind op, lbValue lhs, lbV switch (op) { case Token_Add: - real = lb_emit_arith(p, Token_Add, a, c, ft); - imag = lb_emit_arith(p, Token_Add, b, d, ft); - break; case Token_Sub: - real = lb_emit_arith(p, Token_Sub, a, c, ft); - imag = lb_emit_arith(p, Token_Sub, b, d, ft); + if (type_size_of(ft) == 2) { + a = lb_emit_conv(p, a, t_f32); + b = lb_emit_conv(p, b, t_f32); + c = lb_emit_conv(p, c, t_f32); + d = lb_emit_conv(p, d, t_f32); + real = lb_emit_arith(p, op, a, c, t_f32); + imag = lb_emit_arith(p, op, b, d, t_f32); + + real = lb_emit_conv(p, real, ft); + imag = lb_emit_conv(p, imag, ft); + } else { + real = lb_emit_arith(p, op, a, c, ft); + imag = lb_emit_arith(p, op, b, d, ft); + } break; case Token_Mul: { lbValue x = lb_emit_arith(p, Token_Mul, a, c, ft); @@ -1156,6 +1165,11 @@ gb_internal lbValue lb_emit_arith(lbProcedure *p, TokenKind op, lbValue lhs, lbV Type *ft = base_complex_elem_type(type); if (op == Token_Add || op == Token_Sub) { + Type *immediate_type = ft; + if (type_size_of(ft) == 2) { + immediate_type = t_f32; + } + lbAddr res = lb_add_local_generated(p, type, false); // NOTE: initialized in full later lbValue x0 = lb_emit_struct_ev(p, lhs, 0); lbValue x1 = lb_emit_struct_ev(p, lhs, 1); @@ -1167,15 +1181,39 @@ gb_internal lbValue lb_emit_arith(lbProcedure *p, TokenKind op, lbValue lhs, lbV lbValue y2 = lb_emit_struct_ev(p, rhs, 2); lbValue y3 = lb_emit_struct_ev(p, rhs, 3); - lbValue z0 = lb_emit_arith(p, op, x0, y0, ft); - lbValue z1 = lb_emit_arith(p, op, x1, y1, ft); - lbValue z2 = lb_emit_arith(p, op, x2, y2, ft); - lbValue z3 = lb_emit_arith(p, op, x3, y3, ft); + if (immediate_type != ft) { + x0 = lb_emit_conv(p, x0, immediate_type); + x1 = lb_emit_conv(p, x1, immediate_type); + x2 = lb_emit_conv(p, x2, immediate_type); + x3 = lb_emit_conv(p, x3, immediate_type); - lb_emit_store(p, lb_emit_struct_ep(p, res.addr, 0), z0); - lb_emit_store(p, lb_emit_struct_ep(p, res.addr, 1), z1); - lb_emit_store(p, lb_emit_struct_ep(p, res.addr, 2), z2); - lb_emit_store(p, lb_emit_struct_ep(p, res.addr, 3), z3); + y0 = lb_emit_conv(p, y0, immediate_type); + y1 = lb_emit_conv(p, y1, immediate_type); + y2 = lb_emit_conv(p, y2, immediate_type); + y3 = lb_emit_conv(p, y3, immediate_type); + } + + lbValue z0 = lb_emit_arith(p, op, x0, y0, immediate_type); + lbValue z1 = lb_emit_arith(p, op, x1, y1, immediate_type); + lbValue z2 = lb_emit_arith(p, op, x2, y2, immediate_type); + lbValue z3 = lb_emit_arith(p, op, x3, y3, immediate_type); + + lbValue d0 = lb_emit_struct_ep(p, res.addr, 0); + lbValue d1 = lb_emit_struct_ep(p, res.addr, 1); + lbValue d2 = lb_emit_struct_ep(p, res.addr, 2); + lbValue d3 = lb_emit_struct_ep(p, res.addr, 3); + + if (immediate_type != ft) { + d0 = lb_emit_conv(p, d0, ft); + d1 = lb_emit_conv(p, d1, ft); + d2 = lb_emit_conv(p, d2, ft); + d3 = lb_emit_conv(p, d3, ft); + } + + lb_emit_store(p, d0, z0); + lb_emit_store(p, d1, z1); + lb_emit_store(p, d2, z2); + lb_emit_store(p, d3, z3); return lb_addr_load(p, res); } else if (op == Token_Mul) { @@ -2044,13 +2082,6 @@ gb_internal lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) { } if (is_type_union(dst)) { - for (Type *vt : dst->Union.variants) { - if (are_types_identical(vt, src_type)) { - lbAddr parent = lb_add_local_generated(p, t, true); - lb_emit_store_union_variant(p, parent.addr, value, vt); - return lb_addr_load(p, parent); - } - } if (dst->Union.variants.count == 1) { Type *vt = dst->Union.variants[0]; if (internal_check_is_assignable_to(src_type, vt)) { @@ -2060,6 +2091,50 @@ gb_internal lbValue lb_emit_conv(lbProcedure *p, lbValue value, Type *t) { return lb_addr_load(p, parent); } } + for (Type *vt : dst->Union.variants) { + if (are_types_identical(src_type, vt)) { + lbAddr parent = lb_add_local_generated(p, t, true); + lb_emit_store_union_variant(p, parent.addr, value, vt); + return lb_addr_load(p, parent); + } + } + ValidIndexAndScore *valids = gb_alloc_array(temporary_allocator(), ValidIndexAndScore, dst->Union.variants.count); + isize valid_count = 0; + isize first_success_index = -1; + for_array(i, dst->Union.variants) { + Type *vt = dst->Union.variants[i]; + i64 score = 0; + if (internal_check_is_assignable_to(src_type, vt)) { + valids[valid_count].index = i; + valids[valid_count].score = score; + valid_count += 1; + if (first_success_index < 0) { + first_success_index = i; + } + } + } + if (valid_count > 1) { + gb_sort_array(valids, valid_count, valid_index_and_score_cmp); + i64 best_score = valids[0].score; + for (isize i = 1; i < valid_count; i++) { + auto v = valids[i]; + if (best_score > v.score) { + valid_count = i; + break; + } + best_score = v.score; + } + first_success_index = valids[0].index; + } + + if (valid_count == 1) { + Type *vt = dst->Union.variants[first_success_index]; + value = lb_emit_conv(p, value, vt); + lbAddr parent = lb_add_local_generated(p, t, true); + lb_emit_store_union_variant(p, parent.addr, value, vt); + return lb_addr_load(p, parent); + } + } // NOTE(bill): This has to be done before 'Pointer <-> Pointer' as it's @@ -3283,13 +3358,8 @@ gb_internal lbValue lb_build_expr_internal(lbProcedure *p, Ast *expr) { Type *type = type_of_expr(expr); GB_ASSERT_MSG(tv.mode != Addressing_Invalid, "invalid expression '%s' (tv.mode = %d, tv.type = %s) @ %s\n Current Proc: %.*s : %s", expr_to_string(expr), tv.mode, type_to_string(tv.type), token_pos_to_string(expr_pos), LIT(p->name), type_to_string(p->type)); - if (tv.value.kind != ExactValue_Invalid) { - // NOTE(bill): The commented out code below is just for debug purposes only - // if (is_type_untyped(type)) { - // gb_printf_err("%s %s : %s @ %p\n", token_pos_to_string(expr_pos), expr_to_string(expr), type_to_string(expr->tav.type), expr); - // GB_PANIC("%s\n", type_to_string(tv.type)); - // } + if (tv.value.kind != ExactValue_Invalid) { // NOTE(bill): Short on constant values return lb_const_value(p->module, type, tv.value); } else if (tv.mode == Addressing_Type) { diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 03d0f8b32..c2ae5de74 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -1162,7 +1162,7 @@ gb_internal lbValue lb_addr_load(lbProcedure *p, lbAddr const &addr) { lbValue copy_size = byte_size; lbValue src_offset = lb_emit_conv(p, src, t_u8_ptr); src_offset = lb_emit_ptr_offset(p, src_offset, byte_offset); - if (addr.bitfield.bit_offset + dst_byte_size <= total_bitfield_bit_size) { + if (addr.bitfield.bit_offset + 8*dst_byte_size <= total_bitfield_bit_size) { do_mask = true; copy_size = lb_const_int(p->module, t_uintptr, dst_byte_size); } diff --git a/src/llvm_backend_proc.cpp b/src/llvm_backend_proc.cpp index 958b4fd38..68ba4f74e 100644 --- a/src/llvm_backend_proc.cpp +++ b/src/llvm_backend_proc.cpp @@ -233,7 +233,7 @@ gb_internal lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool i if (p->is_foreign) { - lb_set_wasm_import_attributes(p->value, entity, p->name); + lb_set_wasm_procedure_import_attributes(p->value, entity, p->name); } diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index 94153e233..98ed0c57e 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -2018,7 +2018,7 @@ gb_internal LLVMValueRef llvm_get_inline_asm(LLVMTypeRef func_type, String const } -gb_internal void lb_set_wasm_import_attributes(LLVMValueRef value, Entity *entity, String import_name) { +gb_internal void lb_set_wasm_procedure_import_attributes(LLVMValueRef value, Entity *entity, String import_name) { if (!is_arch_wasm()) { return; } diff --git a/src/main.cpp b/src/main.cpp index 1896dd0b7..dca2b7fc8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -300,7 +300,10 @@ enum BuildFlagKind { BuildFlag_VetUsingParam, BuildFlag_VetStyle, BuildFlag_VetSemicolon, + BuildFlag_VetCast, + BuildFlag_VetTabs, + BuildFlag_CustomAttribute, BuildFlag_IgnoreUnknownAttributes, BuildFlag_ExtraLinkerFlags, BuildFlag_ExtraAssemblerFlags, @@ -343,6 +346,7 @@ enum BuildFlagKind { // internal use only BuildFlag_InternalIgnoreLazy, BuildFlag_InternalIgnoreLLVMBuild, + BuildFlag_InternalIgnorePanic, BuildFlag_Tilde, @@ -498,7 +502,10 @@ gb_internal bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_VetUsingParam, str_lit("vet-using-param"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_VetStyle, str_lit("vet-style"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_VetSemicolon, str_lit("vet-semicolon"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_VetCast, str_lit("vet-cast"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_VetTabs, str_lit("vet-tabs"), BuildFlagParam_None, Command__does_check); + add_flag(&build_flags, BuildFlag_CustomAttribute, str_lit("custom-attribute"), BuildFlagParam_String, Command__does_check, true); add_flag(&build_flags, BuildFlag_IgnoreUnknownAttributes, str_lit("ignore-unknown-attributes"), BuildFlagParam_None, Command__does_check); add_flag(&build_flags, BuildFlag_ExtraLinkerFlags, str_lit("extra-linker-flags"), BuildFlagParam_String, Command__does_build); add_flag(&build_flags, BuildFlag_ExtraAssemblerFlags, str_lit("extra-assembler-flags"), BuildFlagParam_String, Command__does_build); @@ -539,6 +546,7 @@ gb_internal bool parse_build_flags(Array args) { add_flag(&build_flags, BuildFlag_InternalIgnoreLazy, str_lit("internal-ignore-lazy"), BuildFlagParam_None, Command_all); add_flag(&build_flags, BuildFlag_InternalIgnoreLLVMBuild, str_lit("internal-ignore-llvm-build"),BuildFlagParam_None, Command_all); + add_flag(&build_flags, BuildFlag_InternalIgnorePanic, str_lit("internal-ignore-panic"), BuildFlagParam_None, Command_all); #if ALLOW_TILDE add_flag(&build_flags, BuildFlag_Tilde, str_lit("tilde"), BuildFlagParam_None, Command__does_build); @@ -1150,6 +1158,31 @@ gb_internal bool parse_build_flags(Array args) { case BuildFlag_VetUsingParam: build_context.vet_flags |= VetFlag_UsingParam; break; case BuildFlag_VetStyle: build_context.vet_flags |= VetFlag_Style; break; case BuildFlag_VetSemicolon: build_context.vet_flags |= VetFlag_Semicolon; break; + case BuildFlag_VetCast: build_context.vet_flags |= VetFlag_Cast; break; + case BuildFlag_VetTabs: build_context.vet_flags |= VetFlag_Tabs; break; + + case BuildFlag_CustomAttribute: + { + GB_ASSERT(value.kind == ExactValue_String); + String val = value.value_string; + String_Iterator it = {val, 0}; + for (;;) { + String attr = string_split_iterator(&it, ','); + if (attr.len == 0) { + break; + } + + attr = string_trim_whitespace(attr); + if (!string_is_valid_identifier(attr)) { + gb_printf_err("-custom-attribute '%.*s' must be a valid identifier\n", LIT(attr)); + bad_flags = true; + continue; + } + + string_set_add(&build_context.custom_attributes, attr); + } + } + break; case BuildFlag_IgnoreUnknownAttributes: build_context.ignore_unknown_attributes = true; @@ -1324,6 +1357,9 @@ gb_internal bool parse_build_flags(Array args) { case BuildFlag_InternalIgnoreLLVMBuild: build_context.ignore_llvm_build = true; break; + case BuildFlag_InternalIgnorePanic: + build_context.ignore_panic = true; + break; case BuildFlag_Tilde: build_context.tilde_backend = true; break; @@ -2218,9 +2254,26 @@ gb_internal void print_show_help(String const arg0, String const &command) { print_usage_line(1, "-vet-semicolon"); print_usage_line(2, "Errs on unneeded semicolons."); print_usage_line(0, ""); + + print_usage_line(1, "-vet-cast"); + print_usage_line(2, "Errs on casting a value to its own type or using `transmute` rather than `cast`."); + print_usage_line(0, ""); + + print_usage_line(1, "-vet-tabs"); + print_usage_line(2, "Errs when the use of tabs has not been used for indentation."); + print_usage_line(0, ""); } if (check) { + print_usage_line(1, "-custom-attribute:"); + print_usage_line(2, "Add a custom attribute which will be ignored if it is unknown."); + print_usage_line(2, "This can be used with metaprogramming tools."); + print_usage_line(2, "Examples:"); + print_usage_line(3, "-custom-attribute:my_tag"); + print_usage_line(3, "-custom-attribute:my_tag,the_other_thing"); + print_usage_line(3, "-custom-attribute:my_tag -custom-attribute:the_other_thing"); + print_usage_line(0, ""); + print_usage_line(1, "-ignore-unknown-attributes"); print_usage_line(2, "Ignores unknown attributes."); print_usage_line(2, "This can be used with metaprogramming tools."); @@ -2303,9 +2356,13 @@ gb_internal void print_show_help(String const arg0, String const &command) { print_usage_line(0, ""); print_usage_line(1, "-strict-style"); + print_usage_line(2, "This enforces parts of same style as the Odin compiler, prefer '-vet-style -vet-semicolon' if you do not want to match it exactly."); + print_usage_line(2, ""); print_usage_line(2, "Errs on unneeded tokens, such as unneeded semicolons."); print_usage_line(2, "Errs on missing trailing commas followed by a newline."); print_usage_line(2, "Errs on deprecated syntax."); + print_usage_line(2, "Errs when the attached-brace style in not adhered to (also known as 1TBS)."); + print_usage_line(2, "Errs when 'case' labels are not in the same column as the associated 'switch' token."); print_usage_line(0, ""); print_usage_line(1, "-ignore-warnings"); diff --git a/src/parser.cpp b/src/parser.cpp index 1272de4fc..cc12432e0 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -35,22 +35,48 @@ gb_internal gbString get_file_line_as_string(TokenPos const &pos, i32 *offset_) if (file == nullptr) { return nullptr; } - isize offset = pos.offset; - u8 *start = file->tokenizer.start; u8 *end = file->tokenizer.end; if (start == end) { return nullptr; } + + isize offset = pos.offset; + if (pos.line != 0 && offset == 0) { + for (i32 i = 1; i < pos.line; i++) { + while (start+offset < end) { + u8 c = start[offset++]; + if (c == '\n') { + break; + } + } + } + for (i32 i = 1; i < pos.column; i++) { + u8 *ptr = start+offset; + u8 c = *ptr; + if (c & 0x80) { + offset += utf8_decode(ptr, end-ptr, nullptr); + } else { + offset++; + } + } + } + + isize len = end-start; if (len < offset) { return nullptr; } - u8 *pos_offset = start+offset; u8 *line_start = pos_offset; u8 *line_end = pos_offset; + + if (offset > 0 && *line_start == '\n') { + // Prevent an error token that starts at the boundary of a line that + // leads to an empty line from advancing off its line. + line_start -= 1; + } while (line_start >= start) { if (*line_start == '\n') { line_start += 1; @@ -58,6 +84,11 @@ gb_internal gbString get_file_line_as_string(TokenPos const &pos, i32 *offset_) } line_start -= 1; } + if (line_start == start - 1) { + // Prevent an error on the first line from stepping behind the boundary + // of the text. + line_start += 1; + } while (line_end < end) { if (*line_end == '\n') { @@ -70,6 +101,7 @@ gb_internal gbString get_file_line_as_string(TokenPos const &pos, i32 *offset_) if (offset_) *offset_ = cast(i32)(pos_offset - the_line.text); + return gb_string_make_length(heap_allocator(), the_line.text, the_line.len); } @@ -718,7 +750,17 @@ gb_internal ExactValue exact_value_from_token(AstFile *f, Token const &token) { } ExactValue value = exact_value_from_basic_literal(token.kind, s); if (value.kind == ExactValue_Invalid) { - syntax_error(token, "Invalid token literal"); + switch (token.kind) { + case Token_Integer: + syntax_error(token, "Invalid integer literal"); + break; + case Token_Float: + syntax_error(token, "Invalid float literal"); + break; + default: + syntax_error(token, "Invalid token literal"); + break; + } } return value; } @@ -1455,7 +1497,7 @@ gb_internal bool skip_possible_newline(AstFile *f) { return false; } -gb_internal bool skip_possible_newline_for_literal(AstFile *f) { +gb_internal bool skip_possible_newline_for_literal(AstFile *f, bool ignore_strict_style=false) { Token curr = f->curr_token; if (token_is_newline(curr)) { Token next = peek_token(f); @@ -1463,6 +1505,10 @@ gb_internal bool skip_possible_newline_for_literal(AstFile *f) { switch (next.kind) { case Token_OpenBrace: case Token_else: + if (build_context.strict_style && !ignore_strict_style) { + syntax_error(next, "With '-strict-style' the attached brace style (1TBS) is enforced"); + } + /*fallthrough*/ case Token_where: advance_token(f); return true; @@ -2486,7 +2532,7 @@ gb_internal Ast *parse_operand(AstFile *f, bool lhs) { return type; } - skip_possible_newline_for_literal(f); + skip_possible_newline_for_literal(f, where_token.kind == Token_where); if (allow_token(f, Token_Uninit)) { if (where_token.kind != Token_Invalid) { @@ -4468,6 +4514,9 @@ gb_internal bool parse_control_statement_semicolon_separator(AstFile *f) { } + + + gb_internal Ast *parse_if_stmt(AstFile *f) { if (f->curr_proc == nullptr) { syntax_error(f->curr_token, "You cannot use an if statement in the file scope"); @@ -4510,7 +4559,11 @@ gb_internal Ast *parse_if_stmt(AstFile *f) { body = parse_block_stmt(f, false); } - skip_possible_newline_for_literal(f); + bool ignore_strict_style = false; + if (token.pos.line == ast_end_token(body).pos.line) { + ignore_strict_style = true; + } + skip_possible_newline_for_literal(f, ignore_strict_style); if (f->curr_token.kind == Token_else) { Token else_token = expect_token(f, Token_else); switch (f->curr_token.kind) { @@ -4542,9 +4595,12 @@ gb_internal Ast *parse_when_stmt(AstFile *f) { isize prev_level = f->expr_level; f->expr_level = -1; + bool prev_allow_in_expr = f->allow_in_expr; + f->allow_in_expr = true; cond = parse_expr(f, false); + f->allow_in_expr = prev_allow_in_expr; f->expr_level = prev_level; if (cond == nullptr) { @@ -4559,7 +4615,11 @@ gb_internal Ast *parse_when_stmt(AstFile *f) { body = parse_block_stmt(f, true); } - skip_possible_newline_for_literal(f); + bool ignore_strict_style = false; + if (token.pos.line == ast_end_token(body).pos.line) { + ignore_strict_style = true; + } + skip_possible_newline_for_literal(f, ignore_strict_style); if (f->curr_token.kind == Token_else) { Token else_token = expect_token(f, Token_else); switch (f->curr_token.kind) { @@ -5245,12 +5305,53 @@ gb_internal Ast *parse_stmt(AstFile *f) { return ast_bad_stmt(f, token, f->curr_token); } + + +gb_internal u64 check_vet_flags(AstFile *file) { + if (file && file->vet_flags_set) { + return file->vet_flags; + } + return build_context.vet_flags; +} + + +gb_internal void parse_enforce_tabs(AstFile *f) { + Token prev = f->prev_token; + Token curr = f->curr_token; + if (prev.pos.line < curr.pos.line) { + u8 *start = f->tokenizer.start+prev.pos.offset; + u8 *end = f->tokenizer.start+curr.pos.offset; + u8 *it = end; + while (it > start) { + if (*it == '\n') { + it++; + break; + } + it--; + } + + isize len = end-it; + for (isize i = 0; i < len; i++) { + if (it[i] == ' ') { + syntax_error(curr, "With '-vet-tabs', tabs must be used for indentation"); + break; + } + } + } +} + gb_internal Array parse_stmt_list(AstFile *f) { auto list = array_make(ast_allocator(f)); while (f->curr_token.kind != Token_case && f->curr_token.kind != Token_CloseBrace && f->curr_token.kind != Token_EOF) { + + // Checks to see if tabs have been used for indentation + if (check_vet_flags(f) & VetFlag_Tabs) { + parse_enforce_tabs(f); + } + Ast *stmt = parse_stmt(f); if (stmt && stmt->kind != Ast_EmptyStmt) { array_add(&list, stmt); @@ -5407,6 +5508,7 @@ gb_internal WORKER_TASK_PROC(parser_worker_proc) { gb_internal void parser_add_file_to_process(Parser *p, AstPackage *pkg, FileInfo fi, TokenPos pos) { ImportedFile f = {pkg, fi, pos, p->file_to_process_count++}; + f.pos.file_id = cast(i32)(f.index+1); auto wd = gb_alloc_item(permanent_allocator(), ParserWorkerData); wd->parser = p; wd->imported_file = f; @@ -5443,6 +5545,7 @@ gb_internal WORKER_TASK_PROC(foreign_file_worker_proc) { gb_internal void parser_add_foreign_file_to_process(Parser *p, AstPackage *pkg, AstForeignFileKind kind, FileInfo fi, TokenPos pos) { // TODO(bill): Use a better allocator ImportedFile f = {pkg, fi, pos, p->file_to_process_count++}; + f.pos.file_id = cast(i32)(f.index+1); auto wd = gb_alloc_item(permanent_allocator(), ForeignFileWorkerData); wd->parser = p; wd->imported_file = f; diff --git a/src/tilde.cpp b/src/tilde.cpp index 4fc7d1c9b..f6fed0f9a 100644 --- a/src/tilde.cpp +++ b/src/tilde.cpp @@ -363,7 +363,6 @@ gb_internal bool cg_global_variables_create(cgModule *m, Array if (is_foreign) { linkage = TB_LINKAGE_PUBLIC; // lb_add_foreign_library_path(m, e->Variable.foreign_library); - // lb_set_wasm_import_attributes(g.value, e, name); } else if (is_export) { linkage = TB_LINKAGE_PUBLIC; } diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index f7751d840..4425bee29 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -432,7 +432,10 @@ gb_internal gb_inline i32 digit_value(Rune r) { return 16; // NOTE(bill): Larger than highest possible } -gb_internal gb_inline void scan_mantissa(Tokenizer *t, i32 base) { +gb_internal gb_inline void scan_mantissa(Tokenizer *t, i32 base, bool force_base) { + if (!force_base) { + base = 16; // always check for any possible letter + } while (digit_value(t->curr_rune) < base || t->curr_rune == '_') { advance_to_next_rune(t); } @@ -457,7 +460,7 @@ gb_internal void scan_number_to_token(Tokenizer *t, Token *token, bool seen_deci token->string.len += 1; token->pos.column -= 1; token->kind = Token_Float; - scan_mantissa(t, 10); + scan_mantissa(t, 10, true); goto exponent; } @@ -467,44 +470,50 @@ gb_internal void scan_number_to_token(Tokenizer *t, Token *token, bool seen_deci switch (t->curr_rune) { case 'b': // Binary advance_to_next_rune(t); - scan_mantissa(t, 2); + scan_mantissa(t, 2, false); if (t->curr - prev <= 2) { + tokenizer_err(t, "Invalid binary integer"); token->kind = Token_Invalid; } goto end; case 'o': // Octal advance_to_next_rune(t); - scan_mantissa(t, 8); + scan_mantissa(t, 8, false); if (t->curr - prev <= 2) { + tokenizer_err(t, "Invalid octal integer"); token->kind = Token_Invalid; } goto end; case 'd': // Decimal advance_to_next_rune(t); - scan_mantissa(t, 10); + scan_mantissa(t, 10, false); if (t->curr - prev <= 2) { + tokenizer_err(t, "Invalid explicitly decimal integer"); token->kind = Token_Invalid; } goto end; case 'z': // Dozenal advance_to_next_rune(t); - scan_mantissa(t, 12); + scan_mantissa(t, 12, false); if (t->curr - prev <= 2) { + tokenizer_err(t, "Invalid dozenal integer"); token->kind = Token_Invalid; } goto end; case 'x': // Hexadecimal advance_to_next_rune(t); - scan_mantissa(t, 16); + scan_mantissa(t, 16, false); if (t->curr - prev <= 2) { + tokenizer_err(t, "Invalid hexadecimal integer"); token->kind = Token_Invalid; } goto end; case 'h': // Hexadecimal Float token->kind = Token_Float; advance_to_next_rune(t); - scan_mantissa(t, 16); + scan_mantissa(t, 16, false); if (t->curr - prev <= 2) { + tokenizer_err(t, "Invalid hexadecimal float"); token->kind = Token_Invalid; } else { u8 *start = prev+2; @@ -527,12 +536,12 @@ gb_internal void scan_number_to_token(Tokenizer *t, Token *token, bool seen_deci } goto end; default: - scan_mantissa(t, 10); + scan_mantissa(t, 10, true); goto fraction; } } - scan_mantissa(t, 10); + scan_mantissa(t, 10, true); fraction: @@ -544,7 +553,7 @@ fraction: advance_to_next_rune(t); token->kind = Token_Float; - scan_mantissa(t, 10); + scan_mantissa(t, 10, true); } exponent: @@ -554,7 +563,7 @@ exponent: if (t->curr_rune == '-' || t->curr_rune == '+') { advance_to_next_rune(t); } - scan_mantissa(t, 10); + scan_mantissa(t, 10, false); } switch (t->curr_rune) { @@ -777,7 +786,6 @@ gb_internal void tokenizer_get_token(Tokenizer *t, Token *token, int repeat=0) { case '`': // Raw String Literal case '"': // String Literal { - bool has_carriage_return = false; i32 success; Rune quote = curr_rune; token->kind = Token_String; @@ -807,9 +815,6 @@ gb_internal void tokenizer_get_token(Tokenizer *t, Token *token, int repeat=0) { if (r == quote) { break; } - if (r == '\r') { - has_carriage_return = true; - } } } token->string.len = t->curr - token->string.text; diff --git a/src/types.cpp b/src/types.cpp index 97e8267a3..c3a5fb539 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -2366,6 +2366,7 @@ gb_internal bool type_has_nil(Type *t) { return false; } + gb_internal bool elem_type_can_be_constant(Type *t) { t = base_type(t); if (t == t_invalid) { @@ -3224,7 +3225,7 @@ gb_internal Selection lookup_field_with_selection(Type *type_, String field_name } } if (type->kind == Type_Struct) { - wait_signal_until_available(&type->Struct.fields_wait_signal); + // wait_signal_until_available(&type->Struct.fields_wait_signal); isize field_count = type->Struct.fields.count; if (field_count != 0) for_array(i, type->Struct.fields) { Entity *f = type->Struct.fields[i]; @@ -3254,7 +3255,7 @@ gb_internal Selection lookup_field_with_selection(Type *type_, String field_name } if (type->kind == Type_Struct) { - wait_signal_until_available(&type->Struct.fields_wait_signal); + // wait_signal_until_available(&type->Struct.fields_wait_signal); Scope *s = type->Struct.scope; if (s != nullptr) { Entity *found = scope_lookup_current(s, field_name); diff --git a/src/ucg/ucg.c b/src/ucg/ucg.c new file mode 100644 index 000000000..c3e270e1a --- /dev/null +++ b/src/ucg/ucg.c @@ -0,0 +1,686 @@ +/* + * SPDX-FileCopyrightText: (c) 2024 Feoramund + * SPDX-License-Identifier: BSD-3-Clause + */ + + +// +// NOTE(Feoramund): This is my UCG library, adapted for use within the Odin compiler. +// Most of the comments have been let alone and may not strictly apply anymore. +// +// 1. The UCG allocator interface was replaced by gbAllocator. +// 2. The UCG UTF-8 decoder was replaced with the one already in the compiler. +// 3. Non-essential code was stripped. +// 4. Some types were changed for compatibility. +// + + +/* This is the data that is allocated when an allocator is passed to + * ucg_decode_grapheme_clusters. */ +typedef struct { + i32 byte_index; + i32 rune_index; + i32 width; +} ucg_grapheme; + + +/* #include "ucg.h" */ +#include "ucg_tables.h" + +#define UCG_TABLE_LEN(t) (sizeof(t) / sizeof(int32_t)) + +#define ZERO_WIDTH_SPACE 0x200B +#define ZERO_WIDTH_NON_JOINER 0x200C +#define ZERO_WIDTH_JOINER 0x200D +#define WORD_JOINER 0x2060 + +int ucg_binary_search(int32_t value, const int32_t* table, int length, int stride) { + GB_ASSERT(table != NULL); + GB_ASSERT(length > 0); + GB_ASSERT(stride > 0); + + int n = length; + int t = 0; + for (/**/; n > 1; /**/) { + int m = n / 2; + int p = t + m * stride; + if (value >= table[p]) { + t = p; + n = n - m; + } else { + n = m; + } + } + if (n != 0 && value >= table[t]) { + return t; + } + return -1; +} + +// +// The procedures below are accurate as of Unicode 15.1.0. +// + +bool ucg_is_control(int32_t r) { + if (r <= 0x1F || (0x7F <= r && r <= 0x9F)) { + return true; + } + return false; +} + +// Emoji_Modifier +bool ucg_is_emoji_modifier(int32_t r) { + return 0x1F3FB <= r && r <= 0x1F3FF; +} + +// Regional_Indicator +bool ucg_is_regional_indicator(int32_t r) { + return 0x1F1E6 <= r && r <= 0x1F1FF; +} + +// General_Category=Enclosing_Mark +bool ucg_is_enclosing_mark(int32_t r) { + switch (r) { + case 0x0488: + case 0x0489: + case 0x1ABE: + return true; + } + + if (0x20DD <= r && r <= 0x20E0) { return true; } + if (0x20E2 <= r && r <= 0x20E4) { return true; } + if (0xA670 <= r && r <= 0xA672) { return true; } + + return false; +} + +// Prepended_Concatenation_Mark +bool ucg_is_prepended_concatenation_mark(int32_t r) { + switch (r) { + case 0x006DD: + case 0x0070F: + case 0x008E2: + case 0x110BD: + case 0x110CD: + return true; + } + + if (0x00600 <= r && r <= 0x00605) { return true; } + if (0x00890 <= r && r <= 0x00891) { return true; } + + return false; +} + +// General_Category=Spacing_Mark +bool ucg_is_spacing_mark(int32_t r) { + intptr_t p = ucg_binary_search(r, ucg_spacing_mark_ranges, UCG_TABLE_LEN(ucg_spacing_mark_ranges)/2, 2); + if (p >= 0 && ucg_spacing_mark_ranges[p] <= r && r <= ucg_spacing_mark_ranges[p+1]) { + return true; + } + return false; +} + +// General_Category=Nonspacing_Mark +bool ucg_is_nonspacing_mark(int32_t r) { + intptr_t p = ucg_binary_search(r, ucg_nonspacing_mark_ranges, UCG_TABLE_LEN(ucg_nonspacing_mark_ranges)/2, 2); + if (p >= 0 && ucg_nonspacing_mark_ranges[p] <= r && r <= ucg_nonspacing_mark_ranges[p+1]) { + return true; + } + return false; +} + +// Extended_Pictographic +bool ucg_is_emoji_extended_pictographic(int32_t r) { + intptr_t p = ucg_binary_search(r, ucg_emoji_extended_pictographic_ranges, UCG_TABLE_LEN(ucg_emoji_extended_pictographic_ranges)/2, 2); + if (p >= 0 && ucg_emoji_extended_pictographic_ranges[p] <= r && r <= ucg_emoji_extended_pictographic_ranges[p+1]) { + return true; + } + return false; +} + +// Grapheme_Extend +bool ucg_is_grapheme_extend(int32_t r) { + intptr_t p = ucg_binary_search(r, ucg_grapheme_extend_ranges, UCG_TABLE_LEN(ucg_grapheme_extend_ranges)/2, 2); + if (p >= 0 && ucg_grapheme_extend_ranges[p] <= r && r <= ucg_grapheme_extend_ranges[p+1]) { + return true; + } + return false; +} + + +// Hangul_Syllable_Type=Leading_Jamo +bool ucg_is_hangul_syllable_leading(int32_t r) { + return (0x1100 <= r && r <= 0x115F) || (0xA960 <= r && r <= 0xA97C); +} + +// Hangul_Syllable_Type=Vowel_Jamo +bool ucg_is_hangul_syllable_vowel(int32_t r) { + return (0x1160 <= r && r <= 0x11A7) || (0xD7B0 <= r && r <= 0xD7C6); +} + +// Hangul_Syllable_Type=Trailing_Jamo +bool ucg_is_hangul_syllable_trailing(int32_t r) { + return (0x11A8 <= r && r <= 0x11FF) || (0xD7CB <= r && r <= 0xD7FB); +} + +// Hangul_Syllable_Type=LV_Syllable +bool ucg_is_hangul_syllable_lv(int32_t r) { + intptr_t p = ucg_binary_search(r, ucg_hangul_syllable_lv_singlets, UCG_TABLE_LEN(ucg_hangul_syllable_lv_singlets), 1); + if (p >= 0 && r == ucg_hangul_syllable_lv_singlets[p]) { + return true; + } + return false; +} + +// Hangul_Syllable_Type=LVT_Syllable +bool ucg_is_hangul_syllable_lvt(int32_t r) { + intptr_t p = ucg_binary_search(r, ucg_hangul_syllable_lvt_ranges, UCG_TABLE_LEN(ucg_hangul_syllable_lvt_ranges)/2, 2); + if (p >= 0 && ucg_hangul_syllable_lvt_ranges[p] <= r && r <= ucg_hangul_syllable_lvt_ranges[p+1]) { + return true; + } + return false; +} + + +// Indic_Syllabic_Category=Consonant_Preceding_Repha +bool ucg_is_indic_consonant_preceding_repha(int32_t r) { + switch (r) { + case 0x00D4E: + case 0x11941: + case 0x11D46: + case 0x11F02: + return true; + } + return false; +} + +// Indic_Syllabic_Category=Consonant_Prefixed +bool ucg_is_indic_consonant_prefixed(int32_t r) { + switch (r) { + case 0x1193F: + case 0x11A3A: + return true; + } + + if (0x111C2 <= r && r <= 0x111C3) { return true; } + if (0x11A84 <= r && r <= 0x11A89) { return true; } + + return false; +} + +// Indic_Conjunct_Break=Linker +bool ucg_is_indic_conjunct_break_linker(int32_t r) { + switch (r) { + case 0x094D: + case 0x09CD: + case 0x0ACD: + case 0x0B4D: + case 0x0C4D: + case 0x0D4D: + return true; + } + return false; +} + +// Indic_Conjunct_Break=Consonant +bool ucg_is_indic_conjunct_break_consonant(int32_t r) { + intptr_t p = ucg_binary_search(r, ucg_indic_conjunct_break_consonant_ranges, UCG_TABLE_LEN(ucg_indic_conjunct_break_consonant_ranges)/2, 2); + if (p >= 0 && ucg_indic_conjunct_break_consonant_ranges[p] <= r && r <= ucg_indic_conjunct_break_consonant_ranges[p+1]) { + return true; + } + return false; +} + +// Indic_Conjunct_Break=Extend +bool ucg_is_indic_conjunct_break_extend(int32_t r) { + intptr_t p = ucg_binary_search(r, ucg_indic_conjunct_break_extend_ranges, UCG_TABLE_LEN(ucg_indic_conjunct_break_extend_ranges)/2, 2); + if (p >= 0 && ucg_indic_conjunct_break_extend_ranges[p] <= r && r <= ucg_indic_conjunct_break_extend_ranges[p+1]) { + return true; + } + return false; +} + + +/* +``` +Indic_Syllabic_Category = Consonant_Preceding_Repha, or +Indic_Syllabic_Category = Consonant_Prefixed, or +Prepended_Concatenation_Mark = Yes +``` +*/ +bool ucg_is_gcb_prepend_class(int32_t r) { + return ucg_is_indic_consonant_preceding_repha(r) || ucg_is_indic_consonant_prefixed(r) || ucg_is_prepended_concatenation_mark(r); +} + +/* +``` +Grapheme_Extend = Yes, or +Emoji_Modifier = Yes + +This includes: +General_Category = Nonspacing_Mark +General_Category = Enclosing_Mark +U+200C ZERO WIDTH NON-JOINER + +plus a few General_Category = Spacing_Mark needed for canonical equivalence. +``` +*/ +bool ucg_is_gcb_extend_class(int32_t r) { + return ucg_is_grapheme_extend(r) || ucg_is_emoji_modifier(r); +} + +// Return values: +// +// - 2 if East_Asian_Width=F or W, or +// - 0 if non-printable / zero-width, or +// - 1 in all other cases. +// +int ucg_normalized_east_asian_width(int32_t r) { + if (ucg_is_control(r)) { + return 0; + } else if (r <= 0x10FF) { + // Easy early out for low runes. + return 1; + } + + switch (r) { + // This is a different interpretation of the BOM which occurs in the middle of text. + case 0xFEFF: /* ZERO_WIDTH_NO_BREAK_SPACE */ + case ZERO_WIDTH_SPACE: + case ZERO_WIDTH_NON_JOINER: + case ZERO_WIDTH_JOINER: + case WORD_JOINER: + return 0; + } + + intptr_t p = ucg_binary_search(r, ucg_normalized_east_asian_width_ranges, UCG_TABLE_LEN(ucg_normalized_east_asian_width_ranges)/3, 3); + if (p >= 0 && ucg_normalized_east_asian_width_ranges[p] <= r && r <= ucg_normalized_east_asian_width_ranges[p+1]) { + return (int)ucg_normalized_east_asian_width_ranges[p+2]; + } + return 1; +} + +// +// End of Unicode 15.1.0 block. +// + +enum grapheme_cluster_sequence { + None, + Indic, + Emoji, + Regional, +}; + +typedef struct { + ucg_grapheme* graphemes; + i32 rune_count; + i32 grapheme_count; + i32 width; + + int32_t last_rune; + bool last_rune_breaks_forward; + + i32 last_width; + i32 last_grapheme_count; + + bool bypass_next_rune; + + int regional_indicator_counter; + + enum grapheme_cluster_sequence current_sequence; + bool continue_sequence; +} ucg_decoder_state; + + +void _ucg_decode_grapheme_clusters_deferred_step( + gbAllocator allocator, + ucg_decoder_state* state, + i32 byte_index, + int32_t this_rune +) { + // "Break at the start and end of text, unless the text is empty." + // + // GB1: sot ÷ Any + // GB2: Any ÷ eot + if (state->rune_count == 0 && state->grapheme_count == 0) { + state->grapheme_count += 1; + } + + if (state->grapheme_count > state->last_grapheme_count) { + state->width += ucg_normalized_east_asian_width(this_rune); + + /* if (allocator != NULL) { */ + state->graphemes = (ucg_grapheme*)gb_resize(allocator, + state->graphemes, + sizeof(ucg_grapheme) * (state->grapheme_count), + sizeof(ucg_grapheme) * (1 + state->grapheme_count)); + + ucg_grapheme append = { + byte_index, + state->rune_count, + state->width - state->last_width, + }; + + state->graphemes[state->grapheme_count - 1] = append; + /* } */ + + state->last_grapheme_count = state->grapheme_count; + state->last_width = state->width; + } + + state->last_rune = this_rune; + state->rune_count += 1; + + if (!state->continue_sequence) { + state->current_sequence = None; + state->regional_indicator_counter = 0; + } + state->continue_sequence = false; +} + +int ucg_decode_grapheme_clusters( + gbAllocator allocator, + const uint8_t* str, + int str_len, + + ucg_grapheme** out_graphemes, + i32* out_rune_count, + i32* out_grapheme_count, + i32* out_width +) { + // 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 for more information. + // + // + // [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 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. + + ucg_decoder_state state = {0}; + +#define UCG_DEFERRED_DECODE_STEP() (_ucg_decode_grapheme_clusters_deferred_step(allocator, &state, byte_index, this_rune)) + + for (i32 byte_index = 0, bytes_advanced = 0; byte_index < str_len; byte_index += bytes_advanced) { + int32_t this_rune = GB_RUNE_INVALID; + bytes_advanced = (i32)(utf8_decode(str+byte_index, str_len-byte_index, &this_rune)); + if (this_rune == GB_RUNE_INVALID || bytes_advanced == 0) { + // There was a Unicode parsing error; bail out. + if (out_graphemes != NULL) { *out_graphemes = state.graphemes; } + if (out_rune_count != NULL) { *out_rune_count = state.rune_count; } + if (out_grapheme_count != NULL) { *out_grapheme_count = state.grapheme_count; } + if (out_width != NULL) { *out_width = state.width; } + + // Return an error code. + return -1; + } + + // "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' && state.last_rune == '\r') { + state.last_rune_breaks_forward = false; + state.bypass_next_rune = false; + UCG_DEFERRED_DECODE_STEP(); continue; + } + + if (ucg_is_control(this_rune)) { + state.grapheme_count += 1; + state.last_rune_breaks_forward = true; + state.bypass_next_rune = true; + UCG_DEFERRED_DECODE_STEP(); continue; + } + + // (This check is for rules that work forwards, instead of backwards.) + if (state.bypass_next_rune) { + if (state.last_rune_breaks_forward) { + state.grapheme_count += 1; + state.last_rune_breaks_forward = false; + } + + state.bypass_next_rune = false; + UCG_DEFERRED_DECODE_STEP(); continue; + } + + // (Optimization 1: Prevent low runes from proceeding further.) + // + // * 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) { + state.grapheme_count += 1; + UCG_DEFERRED_DECODE_STEP(); continue; + } + + // (Optimization 2: Check if the rune is in the Hangul space before getting specific.) + if (0x1100 <= this_rune && this_rune <= 0xD7FB) { + // "Do not break Hangul syllable sequences." + // + // GB6: L × (L | V | LV | LVT) + // GB7: (LV | V) × (V | T) + // GB8: (LVT | T) × T + if (ucg_is_hangul_syllable_leading(this_rune) || + ucg_is_hangul_syllable_lv(this_rune) || + ucg_is_hangul_syllable_lvt(this_rune)) + { + if (!ucg_is_hangul_syllable_leading(state.last_rune)) { + state.grapheme_count += 1; + } + UCG_DEFERRED_DECODE_STEP(); continue; + } + + if (ucg_is_hangul_syllable_vowel(this_rune)) { + if (ucg_is_hangul_syllable_leading(state.last_rune) || + ucg_is_hangul_syllable_vowel(state.last_rune) || + ucg_is_hangul_syllable_lv(state.last_rune)) + { + UCG_DEFERRED_DECODE_STEP(); continue; + } + state.grapheme_count += 1; + UCG_DEFERRED_DECODE_STEP(); continue; + } + + if (ucg_is_hangul_syllable_trailing(this_rune)) { + if (ucg_is_hangul_syllable_trailing(state.last_rune) || + ucg_is_hangul_syllable_lvt(state.last_rune) || + ucg_is_hangul_syllable_lv(state.last_rune) || + ucg_is_hangul_syllable_vowel(state.last_rune)) + { + UCG_DEFERRED_DECODE_STEP(); continue; + } + state.grapheme_count += 1; + UCG_DEFERRED_DECODE_STEP(); continue; + } + } + + // "Do not break before extending characters or ZWJ." + // + // GB9: × (Extend | ZWJ) + if (this_rune == ZERO_WIDTH_JOINER) { + state.continue_sequence = true; + UCG_DEFERRED_DECODE_STEP(); continue; + } + + if (ucg_is_gcb_extend_class(this_rune)) { + // (Support for GB9c.) + if (state.current_sequence == Indic) { + if (ucg_is_indic_conjunct_break_extend(this_rune) && ( + ucg_is_indic_conjunct_break_linker(state.last_rune) || + ucg_is_indic_conjunct_break_consonant(state.last_rune) )) + { + state.continue_sequence = true; + UCG_DEFERRED_DECODE_STEP(); continue; + } + + if (ucg_is_indic_conjunct_break_linker(this_rune) && ( + ucg_is_indic_conjunct_break_linker(state.last_rune) || + ucg_is_indic_conjunct_break_extend(state.last_rune) || + ucg_is_indic_conjunct_break_consonant(state.last_rune) )) + { + state.continue_sequence = true; + UCG_DEFERRED_DECODE_STEP(); continue; + } + + UCG_DEFERRED_DECODE_STEP(); continue; + } + + // (Support for GB11.) + if (state.current_sequence == Emoji && ( + ucg_is_gcb_extend_class(state.last_rune) || + ucg_is_emoji_extended_pictographic(state.last_rune) )) + { + state.continue_sequence = true; + } + + UCG_DEFERRED_DECODE_STEP(); continue; + } + + // _The GB9a and GB9b rules only apply to extended grapheme clusters:_ + // "Do not break before SpacingMarks, or after Prepend characters." + // + // GB9a: × SpacingMark + // GB9b: Prepend × + if (ucg_is_spacing_mark(this_rune)) { + UCG_DEFERRED_DECODE_STEP(); continue; + } + + if (ucg_is_gcb_prepend_class(this_rune)) { + state.grapheme_count += 1; + state.bypass_next_rune = true; + UCG_DEFERRED_DECODE_STEP(); continue; + } + + // _The GB9c rule only applies to extended grapheme clusters:_ + // "Do not break within certain combinations with Indic_Conjunct_Break (InCB)=Linker." + // + // GB9c: \p{InCB=Consonant} [ \p{InCB=Extend} \p{InCB=Linker} ]* \p{InCB=Linker} [ \p{InCB=Extend} \p{InCB=Linker} ]* × \p{InCB=Consonant} + if (ucg_is_indic_conjunct_break_consonant(this_rune)) { + if (state.current_sequence == Indic) { + if (state.last_rune == ZERO_WIDTH_JOINER || + ucg_is_indic_conjunct_break_linker(state.last_rune)) + { + state.continue_sequence = true; + } else { + state.grapheme_count += 1; + } + } else { + state.grapheme_count += 1; + state.current_sequence = Indic; + state.continue_sequence = true; + } + UCG_DEFERRED_DECODE_STEP(); continue; + } + + if (ucg_is_indic_conjunct_break_extend(this_rune)) { + if (state.current_sequence == Indic) { + if (ucg_is_indic_conjunct_break_consonant(state.last_rune) || + ucg_is_indic_conjunct_break_linker(state.last_rune)) + { + state.continue_sequence = true; + } else { + state.grapheme_count += 1; + } + } + UCG_DEFERRED_DECODE_STEP(); continue; + } + + if (ucg_is_indic_conjunct_break_linker(this_rune)) { + if (state.current_sequence == Indic) { + if (ucg_is_indic_conjunct_break_extend(state.last_rune) || + ucg_is_indic_conjunct_break_linker(state.last_rune)) + { + state.continue_sequence = true; + } else { + state.grapheme_count += 1; + } + } + UCG_DEFERRED_DECODE_STEP(); continue; + } + + // + // (Curiously, there is no GB10.) + // + + // "Do not break within emoji modifier sequences or emoji zwj sequences." + // + // GB11: \p{Extended_Pictographic} Extend* ZWJ × \p{Extended_Pictographic} + if (ucg_is_emoji_extended_pictographic(this_rune)) { + if (state.current_sequence != Emoji || state.last_rune != ZERO_WIDTH_JOINER) { + state.grapheme_count += 1; + } + state.current_sequence = Emoji; + state.continue_sequence = true; + UCG_DEFERRED_DECODE_STEP(); continue; + } + + // "Do not break within emoji flag sequences. + // That is, do not break between regional indicator (RI) symbols + // if there is an odd number of RI characters before the break point." + // + // GB12: sot (RI RI)* RI × RI + // GB13: [^RI] (RI RI)* RI × RI + if (ucg_is_regional_indicator(this_rune)) { + if ((state.regional_indicator_counter & 1) == 0) { + state.grapheme_count += 1; + } + + state.current_sequence = Regional; + state.continue_sequence = true; + state.regional_indicator_counter += 1; + + UCG_DEFERRED_DECODE_STEP(); continue; + } + + // "Otherwise, break everywhere." + // + // GB999: Any ÷ Any + state.grapheme_count += 1; + UCG_DEFERRED_DECODE_STEP(); + } + +#undef UCG_DEFERRED_DECODE_STEP + + if (out_graphemes != NULL) { *out_graphemes = state.graphemes; } + if (out_rune_count != NULL) { *out_rune_count = state.rune_count; } + if (out_grapheme_count != NULL) { *out_grapheme_count = state.grapheme_count; } + if (out_width != NULL) { *out_width = state.width; } + + return 0; +} + +#undef UCG_TABLE_LEN +#undef ZERO_WIDTH_SPACE +#undef ZERO_WIDTH_NON_JOINER +#undef ZERO_WIDTH_JOINER +#undef WORD_JOINER diff --git a/src/ucg/ucg_tables.h b/src/ucg/ucg_tables.h new file mode 100644 index 000000000..a33f9f898 --- /dev/null +++ b/src/ucg/ucg_tables.h @@ -0,0 +1,2629 @@ +/* + * SPDX-FileCopyrightText: (c) 2024 Feoramund + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef _UCG_TABLES_INCLUDED +#define _UCG_TABLES_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +// +// The tables below are accurate as of Unicode 15.1.0. +// + +static const int32_t ucg_spacing_mark_ranges[] = { + 0x0903, 0x0903, + 0x093B, 0x093B, + 0x093E, 0x0940, + 0x0949, 0x094C, + 0x094E, 0x094F, + 0x0982, 0x0983, + 0x09BE, 0x09C0, + 0x09C7, 0x09C8, + 0x09CB, 0x09CC, + 0x09D7, 0x09D7, + 0x0A03, 0x0A03, + 0x0A3E, 0x0A40, + 0x0A83, 0x0A83, + 0x0ABE, 0x0AC0, + 0x0AC9, 0x0AC9, + 0x0ACB, 0x0ACC, + 0x0B02, 0x0B03, + 0x0B3E, 0x0B3E, + 0x0B40, 0x0B40, + 0x0B47, 0x0B48, + 0x0B4B, 0x0B4C, + 0x0B57, 0x0B57, + 0x0BBE, 0x0BBF, + 0x0BC1, 0x0BC2, + 0x0BC6, 0x0BC8, + 0x0BCA, 0x0BCC, + 0x0BD7, 0x0BD7, + 0x0C01, 0x0C03, + 0x0C41, 0x0C44, + 0x0C82, 0x0C83, + 0x0CBE, 0x0CBE, + 0x0CC0, 0x0CC4, + 0x0CC7, 0x0CC8, + 0x0CCA, 0x0CCB, + 0x0CD5, 0x0CD6, + 0x0CF3, 0x0CF3, + 0x0D02, 0x0D03, + 0x0D3E, 0x0D40, + 0x0D46, 0x0D48, + 0x0D4A, 0x0D4C, + 0x0D57, 0x0D57, + 0x0D82, 0x0D83, + 0x0DCF, 0x0DD1, + 0x0DD8, 0x0DDF, + 0x0DF2, 0x0DF3, + 0x0F3E, 0x0F3F, + 0x0F7F, 0x0F7F, + 0x102B, 0x102C, + 0x1031, 0x1031, + 0x1038, 0x1038, + 0x103B, 0x103C, + 0x1056, 0x1057, + 0x1062, 0x1064, + 0x1067, 0x106D, + 0x1083, 0x1084, + 0x1087, 0x108C, + 0x108F, 0x108F, + 0x109A, 0x109C, + 0x1715, 0x1715, + 0x1734, 0x1734, + 0x17B6, 0x17B6, + 0x17BE, 0x17C5, + 0x17C7, 0x17C8, + 0x1923, 0x1926, + 0x1929, 0x192B, + 0x1930, 0x1931, + 0x1933, 0x1938, + 0x1A19, 0x1A1A, + 0x1A55, 0x1A55, + 0x1A57, 0x1A57, + 0x1A61, 0x1A61, + 0x1A63, 0x1A64, + 0x1A6D, 0x1A72, + 0x1B04, 0x1B04, + 0x1B35, 0x1B35, + 0x1B3B, 0x1B3B, + 0x1B3D, 0x1B41, + 0x1B43, 0x1B44, + 0x1B82, 0x1B82, + 0x1BA1, 0x1BA1, + 0x1BA6, 0x1BA7, + 0x1BAA, 0x1BAA, + 0x1BE7, 0x1BE7, + 0x1BEA, 0x1BEC, + 0x1BEE, 0x1BEE, + 0x1BF2, 0x1BF3, + 0x1C24, 0x1C2B, + 0x1C34, 0x1C35, + 0x1CE1, 0x1CE1, + 0x1CF7, 0x1CF7, + 0x302E, 0x302F, + 0xA823, 0xA824, + 0xA827, 0xA827, + 0xA880, 0xA881, + 0xA8B4, 0xA8C3, + 0xA952, 0xA953, + 0xA983, 0xA983, + 0xA9B4, 0xA9B5, + 0xA9BA, 0xA9BB, + 0xA9BE, 0xA9C0, + 0xAA2F, 0xAA30, + 0xAA33, 0xAA34, + 0xAA4D, 0xAA4D, + 0xAA7B, 0xAA7B, + 0xAA7D, 0xAA7D, + 0xAAEB, 0xAAEB, + 0xAAEE, 0xAAEF, + 0xAAF5, 0xAAF5, + 0xABE3, 0xABE4, + 0xABE6, 0xABE7, + 0xABE9, 0xABEA, + 0xABEC, 0xABEC, + 0x11000, 0x11000, + 0x11002, 0x11002, + 0x11082, 0x11082, + 0x110B0, 0x110B2, + 0x110B7, 0x110B8, + 0x1112C, 0x1112C, + 0x11145, 0x11146, + 0x11182, 0x11182, + 0x111B3, 0x111B5, + 0x111BF, 0x111C0, + 0x111CE, 0x111CE, + 0x1122C, 0x1122E, + 0x11232, 0x11233, + 0x11235, 0x11235, + 0x112E0, 0x112E2, + 0x11302, 0x11303, + 0x1133E, 0x1133F, + 0x11341, 0x11344, + 0x11347, 0x11348, + 0x1134B, 0x1134D, + 0x11357, 0x11357, + 0x11362, 0x11363, + 0x11435, 0x11437, + 0x11440, 0x11441, + 0x11445, 0x11445, + 0x114B0, 0x114B2, + 0x114B9, 0x114B9, + 0x114BB, 0x114BE, + 0x114C1, 0x114C1, + 0x115AF, 0x115B1, + 0x115B8, 0x115BB, + 0x115BE, 0x115BE, + 0x11630, 0x11632, + 0x1163B, 0x1163C, + 0x1163E, 0x1163E, + 0x116AC, 0x116AC, + 0x116AE, 0x116AF, + 0x116B6, 0x116B6, + 0x11720, 0x11721, + 0x11726, 0x11726, + 0x1182C, 0x1182E, + 0x11838, 0x11838, + 0x11930, 0x11935, + 0x11937, 0x11938, + 0x1193D, 0x1193D, + 0x11940, 0x11940, + 0x11942, 0x11942, + 0x119D1, 0x119D3, + 0x119DC, 0x119DF, + 0x119E4, 0x119E4, + 0x11A39, 0x11A39, + 0x11A57, 0x11A58, + 0x11A97, 0x11A97, + 0x11C2F, 0x11C2F, + 0x11C3E, 0x11C3E, + 0x11CA9, 0x11CA9, + 0x11CB1, 0x11CB1, + 0x11CB4, 0x11CB4, + 0x11D8A, 0x11D8E, + 0x11D93, 0x11D94, + 0x11D96, 0x11D96, + 0x11EF5, 0x11EF6, + 0x11F03, 0x11F03, + 0x11F34, 0x11F35, + 0x11F3E, 0x11F3F, + 0x11F41, 0x11F41, + 0x16F51, 0x16F87, + 0x16FF0, 0x16FF1, + 0x1D165, 0x1D166, + 0x1D16D, 0x1D172, +}; + +static const int32_t ucg_nonspacing_mark_ranges[] = { + 0x0300, 0x036F, + 0x0483, 0x0487, + 0x0591, 0x05BD, + 0x05BF, 0x05BF, + 0x05C1, 0x05C2, + 0x05C4, 0x05C5, + 0x05C7, 0x05C7, + 0x0610, 0x061A, + 0x064B, 0x065F, + 0x0670, 0x0670, + 0x06D6, 0x06DC, + 0x06DF, 0x06E4, + 0x06E7, 0x06E8, + 0x06EA, 0x06ED, + 0x0711, 0x0711, + 0x0730, 0x074A, + 0x07A6, 0x07B0, + 0x07EB, 0x07F3, + 0x07FD, 0x07FD, + 0x0816, 0x0819, + 0x081B, 0x0823, + 0x0825, 0x0827, + 0x0829, 0x082D, + 0x0859, 0x085B, + 0x0898, 0x089F, + 0x08CA, 0x08E1, + 0x08E3, 0x0902, + 0x093A, 0x093A, + 0x093C, 0x093C, + 0x0941, 0x0948, + 0x094D, 0x094D, + 0x0951, 0x0957, + 0x0962, 0x0963, + 0x0981, 0x0981, + 0x09BC, 0x09BC, + 0x09C1, 0x09C4, + 0x09CD, 0x09CD, + 0x09E2, 0x09E3, + 0x09FE, 0x09FE, + 0x0A01, 0x0A02, + 0x0A3C, 0x0A3C, + 0x0A41, 0x0A42, + 0x0A47, 0x0A48, + 0x0A4B, 0x0A4D, + 0x0A51, 0x0A51, + 0x0A70, 0x0A71, + 0x0A75, 0x0A75, + 0x0A81, 0x0A82, + 0x0ABC, 0x0ABC, + 0x0AC1, 0x0AC5, + 0x0AC7, 0x0AC8, + 0x0ACD, 0x0ACD, + 0x0AE2, 0x0AE3, + 0x0AFA, 0x0AFF, + 0x0B01, 0x0B01, + 0x0B3C, 0x0B3C, + 0x0B3F, 0x0B3F, + 0x0B41, 0x0B44, + 0x0B4D, 0x0B4D, + 0x0B55, 0x0B56, + 0x0B62, 0x0B63, + 0x0B82, 0x0B82, + 0x0BC0, 0x0BC0, + 0x0BCD, 0x0BCD, + 0x0C00, 0x0C00, + 0x0C04, 0x0C04, + 0x0C3C, 0x0C3C, + 0x0C3E, 0x0C40, + 0x0C46, 0x0C48, + 0x0C4A, 0x0C4D, + 0x0C55, 0x0C56, + 0x0C62, 0x0C63, + 0x0C81, 0x0C81, + 0x0CBC, 0x0CBC, + 0x0CBF, 0x0CBF, + 0x0CC6, 0x0CC6, + 0x0CCC, 0x0CCD, + 0x0CE2, 0x0CE3, + 0x0D00, 0x0D01, + 0x0D3B, 0x0D3C, + 0x0D41, 0x0D44, + 0x0D4D, 0x0D4D, + 0x0D62, 0x0D63, + 0x0D81, 0x0D81, + 0x0DCA, 0x0DCA, + 0x0DD2, 0x0DD4, + 0x0DD6, 0x0DD6, + 0x0E31, 0x0E31, + 0x0E34, 0x0E3A, + 0x0E47, 0x0E4E, + 0x0EB1, 0x0EB1, + 0x0EB4, 0x0EBC, + 0x0EC8, 0x0ECE, + 0x0F18, 0x0F19, + 0x0F35, 0x0F35, + 0x0F37, 0x0F37, + 0x0F39, 0x0F39, + 0x0F71, 0x0F7E, + 0x0F80, 0x0F84, + 0x0F86, 0x0F87, + 0x0F8D, 0x0F97, + 0x0F99, 0x0FBC, + 0x0FC6, 0x0FC6, + 0x102D, 0x1030, + 0x1032, 0x1037, + 0x1039, 0x103A, + 0x103D, 0x103E, + 0x1058, 0x1059, + 0x105E, 0x1060, + 0x1071, 0x1074, + 0x1082, 0x1082, + 0x1085, 0x1086, + 0x108D, 0x108D, + 0x109D, 0x109D, + 0x135D, 0x135F, + 0x1712, 0x1714, + 0x1732, 0x1733, + 0x1752, 0x1753, + 0x1772, 0x1773, + 0x17B4, 0x17B5, + 0x17B7, 0x17BD, + 0x17C6, 0x17C6, + 0x17C9, 0x17D3, + 0x17DD, 0x17DD, + 0x180B, 0x180D, + 0x180F, 0x180F, + 0x1885, 0x1886, + 0x18A9, 0x18A9, + 0x1920, 0x1922, + 0x1927, 0x1928, + 0x1932, 0x1932, + 0x1939, 0x193B, + 0x1A17, 0x1A18, + 0x1A1B, 0x1A1B, + 0x1A56, 0x1A56, + 0x1A58, 0x1A5E, + 0x1A60, 0x1A60, + 0x1A62, 0x1A62, + 0x1A65, 0x1A6C, + 0x1A73, 0x1A7C, + 0x1A7F, 0x1A7F, + 0x1AB0, 0x1ABD, + 0x1ABF, 0x1ACE, + 0x1B00, 0x1B03, + 0x1B34, 0x1B34, + 0x1B36, 0x1B3A, + 0x1B3C, 0x1B3C, + 0x1B42, 0x1B42, + 0x1B6B, 0x1B73, + 0x1B80, 0x1B81, + 0x1BA2, 0x1BA5, + 0x1BA8, 0x1BA9, + 0x1BAB, 0x1BAD, + 0x1BE6, 0x1BE6, + 0x1BE8, 0x1BE9, + 0x1BED, 0x1BED, + 0x1BEF, 0x1BF1, + 0x1C2C, 0x1C33, + 0x1C36, 0x1C37, + 0x1CD0, 0x1CD2, + 0x1CD4, 0x1CE0, + 0x1CE2, 0x1CE8, + 0x1CED, 0x1CED, + 0x1CF4, 0x1CF4, + 0x1CF8, 0x1CF9, + 0x1DC0, 0x1DFF, + 0x20D0, 0x20DC, + 0x20E1, 0x20E1, + 0x20E5, 0x20F0, + 0x2CEF, 0x2CF1, + 0x2D7F, 0x2D7F, + 0x2DE0, 0x2DFF, + 0x302A, 0x302D, + 0x3099, 0x309A, + 0xA66F, 0xA66F, + 0xA674, 0xA67D, + 0xA69E, 0xA69F, + 0xA6F0, 0xA6F1, + 0xA802, 0xA802, + 0xA806, 0xA806, + 0xA80B, 0xA80B, + 0xA825, 0xA826, + 0xA82C, 0xA82C, + 0xA8C4, 0xA8C5, + 0xA8E0, 0xA8F1, + 0xA8FF, 0xA8FF, + 0xA926, 0xA92D, + 0xA947, 0xA951, + 0xA980, 0xA982, + 0xA9B3, 0xA9B3, + 0xA9B6, 0xA9B9, + 0xA9BC, 0xA9BD, + 0xA9E5, 0xA9E5, + 0xAA29, 0xAA2E, + 0xAA31, 0xAA32, + 0xAA35, 0xAA36, + 0xAA43, 0xAA43, + 0xAA4C, 0xAA4C, + 0xAA7C, 0xAA7C, + 0xAAB0, 0xAAB0, + 0xAAB2, 0xAAB4, + 0xAAB7, 0xAAB8, + 0xAABE, 0xAABF, + 0xAAC1, 0xAAC1, + 0xAAEC, 0xAAED, + 0xAAF6, 0xAAF6, + 0xABE5, 0xABE5, + 0xABE8, 0xABE8, + 0xABED, 0xABED, + 0xFB1E, 0xFB1E, + 0xFE00, 0xFE0F, + 0xFE20, 0xFE2F, + 0x101FD, 0x101FD, + 0x102E0, 0x102E0, + 0x10376, 0x1037A, + 0x10A01, 0x10A03, + 0x10A05, 0x10A06, + 0x10A0C, 0x10A0F, + 0x10A38, 0x10A3A, + 0x10A3F, 0x10A3F, + 0x10AE5, 0x10AE6, + 0x10D24, 0x10D27, + 0x10EAB, 0x10EAC, + 0x10EFD, 0x10EFF, + 0x10F46, 0x10F50, + 0x10F82, 0x10F85, + 0x11001, 0x11001, + 0x11038, 0x11046, + 0x11070, 0x11070, + 0x11073, 0x11074, + 0x1107F, 0x11081, + 0x110B3, 0x110B6, + 0x110B9, 0x110BA, + 0x110C2, 0x110C2, + 0x11100, 0x11102, + 0x11127, 0x1112B, + 0x1112D, 0x11134, + 0x11173, 0x11173, + 0x11180, 0x11181, + 0x111B6, 0x111BE, + 0x111C9, 0x111CC, + 0x111CF, 0x111CF, + 0x1122F, 0x11231, + 0x11234, 0x11234, + 0x11236, 0x11237, + 0x1123E, 0x1123E, + 0x11241, 0x11241, + 0x112DF, 0x112DF, + 0x112E3, 0x112EA, + 0x11300, 0x11301, + 0x1133B, 0x1133C, + 0x11340, 0x11340, + 0x11366, 0x1136C, + 0x11370, 0x11374, + 0x11438, 0x1143F, + 0x11442, 0x11444, + 0x11446, 0x11446, + 0x1145E, 0x1145E, + 0x114B3, 0x114B8, + 0x114BA, 0x114BA, + 0x114BF, 0x114C0, + 0x114C2, 0x114C3, + 0x115B2, 0x115B5, + 0x115BC, 0x115BD, + 0x115BF, 0x115C0, + 0x115DC, 0x115DD, + 0x11633, 0x1163A, + 0x1163D, 0x1163D, + 0x1163F, 0x11640, + 0x116AB, 0x116AB, + 0x116AD, 0x116AD, + 0x116B0, 0x116B5, + 0x116B7, 0x116B7, + 0x1171D, 0x1171F, + 0x11722, 0x11725, + 0x11727, 0x1172B, + 0x1182F, 0x11837, + 0x11839, 0x1183A, + 0x1193B, 0x1193C, + 0x1193E, 0x1193E, + 0x11943, 0x11943, + 0x119D4, 0x119D7, + 0x119DA, 0x119DB, + 0x119E0, 0x119E0, + 0x11A01, 0x11A0A, + 0x11A33, 0x11A38, + 0x11A3B, 0x11A3E, + 0x11A47, 0x11A47, + 0x11A51, 0x11A56, + 0x11A59, 0x11A5B, + 0x11A8A, 0x11A96, + 0x11A98, 0x11A99, + 0x11C30, 0x11C36, + 0x11C38, 0x11C3D, + 0x11C3F, 0x11C3F, + 0x11C92, 0x11CA7, + 0x11CAA, 0x11CB0, + 0x11CB2, 0x11CB3, + 0x11CB5, 0x11CB6, + 0x11D31, 0x11D36, + 0x11D3A, 0x11D3A, + 0x11D3C, 0x11D3D, + 0x11D3F, 0x11D45, + 0x11D47, 0x11D47, + 0x11D90, 0x11D91, + 0x11D95, 0x11D95, + 0x11D97, 0x11D97, + 0x11EF3, 0x11EF4, + 0x11F00, 0x11F01, + 0x11F36, 0x11F3A, + 0x11F40, 0x11F40, + 0x11F42, 0x11F42, + 0x13440, 0x13440, + 0x13447, 0x13455, + 0x16AF0, 0x16AF4, + 0x16B30, 0x16B36, + 0x16F4F, 0x16F4F, + 0x16F8F, 0x16F92, + 0x16FE4, 0x16FE4, + 0x1BC9D, 0x1BC9E, + 0x1CF00, 0x1CF2D, + 0x1CF30, 0x1CF46, + 0x1D167, 0x1D169, + 0x1D17B, 0x1D182, + 0x1D185, 0x1D18B, + 0x1D1AA, 0x1D1AD, + 0x1D242, 0x1D244, + 0x1DA00, 0x1DA36, + 0x1DA3B, 0x1DA6C, + 0x1DA75, 0x1DA75, + 0x1DA84, 0x1DA84, + 0x1DA9B, 0x1DA9F, + 0x1DAA1, 0x1DAAF, + 0x1E000, 0x1E006, + 0x1E008, 0x1E018, + 0x1E01B, 0x1E021, + 0x1E023, 0x1E024, + 0x1E026, 0x1E02A, + 0x1E08F, 0x1E08F, + 0x1E130, 0x1E136, + 0x1E2AE, 0x1E2AE, + 0x1E2EC, 0x1E2EF, + 0x1E4EC, 0x1E4EF, + 0x1E8D0, 0x1E8D6, + 0x1E944, 0x1E94A, + 0xE0100, 0xE01EF, +}; + +static const int32_t ucg_emoji_extended_pictographic_ranges[] = { + 0x00A9, 0x00A9, + 0x00AE, 0x00AE, + 0x203C, 0x203C, + 0x2049, 0x2049, + 0x2122, 0x2122, + 0x2139, 0x2139, + 0x2194, 0x2199, + 0x21A9, 0x21AA, + 0x231A, 0x231B, + 0x2328, 0x2328, + 0x2388, 0x2388, + 0x23CF, 0x23CF, + 0x23E9, 0x23EC, + 0x23ED, 0x23EE, + 0x23EF, 0x23EF, + 0x23F0, 0x23F0, + 0x23F1, 0x23F2, + 0x23F3, 0x23F3, + 0x23F8, 0x23FA, + 0x24C2, 0x24C2, + 0x25AA, 0x25AB, + 0x25B6, 0x25B6, + 0x25C0, 0x25C0, + 0x25FB, 0x25FE, + 0x2600, 0x2601, + 0x2602, 0x2603, + 0x2604, 0x2604, + 0x2605, 0x2605, + 0x2607, 0x260D, + 0x260E, 0x260E, + 0x260F, 0x2610, + 0x2611, 0x2611, + 0x2612, 0x2612, + 0x2614, 0x2615, + 0x2616, 0x2617, + 0x2618, 0x2618, + 0x2619, 0x261C, + 0x261D, 0x261D, + 0x261E, 0x261F, + 0x2620, 0x2620, + 0x2621, 0x2621, + 0x2622, 0x2623, + 0x2624, 0x2625, + 0x2626, 0x2626, + 0x2627, 0x2629, + 0x262A, 0x262A, + 0x262B, 0x262D, + 0x262E, 0x262E, + 0x262F, 0x262F, + 0x2630, 0x2637, + 0x2638, 0x2639, + 0x263A, 0x263A, + 0x263B, 0x263F, + 0x2640, 0x2640, + 0x2641, 0x2641, + 0x2642, 0x2642, + 0x2643, 0x2647, + 0x2648, 0x2653, + 0x2654, 0x265E, + 0x265F, 0x265F, + 0x2660, 0x2660, + 0x2661, 0x2662, + 0x2663, 0x2663, + 0x2664, 0x2664, + 0x2665, 0x2666, + 0x2667, 0x2667, + 0x2668, 0x2668, + 0x2669, 0x267A, + 0x267B, 0x267B, + 0x267C, 0x267D, + 0x267E, 0x267E, + 0x267F, 0x267F, + 0x2680, 0x2685, + 0x2690, 0x2691, + 0x2692, 0x2692, + 0x2693, 0x2693, + 0x2694, 0x2694, + 0x2695, 0x2695, + 0x2696, 0x2697, + 0x2698, 0x2698, + 0x2699, 0x2699, + 0x269A, 0x269A, + 0x269B, 0x269C, + 0x269D, 0x269F, + 0x26A0, 0x26A1, + 0x26A2, 0x26A6, + 0x26A7, 0x26A7, + 0x26A8, 0x26A9, + 0x26AA, 0x26AB, + 0x26AC, 0x26AF, + 0x26B0, 0x26B1, + 0x26B2, 0x26BC, + 0x26BD, 0x26BE, + 0x26BF, 0x26C3, + 0x26C4, 0x26C5, + 0x26C6, 0x26C7, + 0x26C8, 0x26C8, + 0x26C9, 0x26CD, + 0x26CE, 0x26CE, + 0x26CF, 0x26CF, + 0x26D0, 0x26D0, + 0x26D1, 0x26D1, + 0x26D2, 0x26D2, + 0x26D3, 0x26D3, + 0x26D4, 0x26D4, + 0x26D5, 0x26E8, + 0x26E9, 0x26E9, + 0x26EA, 0x26EA, + 0x26EB, 0x26EF, + 0x26F0, 0x26F1, + 0x26F2, 0x26F3, + 0x26F4, 0x26F4, + 0x26F5, 0x26F5, + 0x26F6, 0x26F6, + 0x26F7, 0x26F9, + 0x26FA, 0x26FA, + 0x26FB, 0x26FC, + 0x26FD, 0x26FD, + 0x26FE, 0x2701, + 0x2702, 0x2702, + 0x2703, 0x2704, + 0x2705, 0x2705, + 0x2708, 0x270C, + 0x270D, 0x270D, + 0x270E, 0x270E, + 0x270F, 0x270F, + 0x2710, 0x2711, + 0x2712, 0x2712, + 0x2714, 0x2714, + 0x2716, 0x2716, + 0x271D, 0x271D, + 0x2721, 0x2721, + 0x2728, 0x2728, + 0x2733, 0x2734, + 0x2744, 0x2744, + 0x2747, 0x2747, + 0x274C, 0x274C, + 0x274E, 0x274E, + 0x2753, 0x2755, + 0x2757, 0x2757, + 0x2763, 0x2763, + 0x2764, 0x2764, + 0x2765, 0x2767, + 0x2795, 0x2797, + 0x27A1, 0x27A1, + 0x27B0, 0x27B0, + 0x27BF, 0x27BF, + 0x2934, 0x2935, + 0x2B05, 0x2B07, + 0x2B1B, 0x2B1C, + 0x2B50, 0x2B50, + 0x2B55, 0x2B55, + 0x3030, 0x3030, + 0x303D, 0x303D, + 0x3297, 0x3297, + 0x3299, 0x3299, + 0x1F000, 0x1F003, + 0x1F004, 0x1F004, + 0x1F005, 0x1F0CE, + 0x1F0CF, 0x1F0CF, + 0x1F0D0, 0x1F0FF, + 0x1F10D, 0x1F10F, + 0x1F12F, 0x1F12F, + 0x1F16C, 0x1F16F, + 0x1F170, 0x1F171, + 0x1F17E, 0x1F17F, + 0x1F18E, 0x1F18E, + 0x1F191, 0x1F19A, + 0x1F1AD, 0x1F1E5, + 0x1F201, 0x1F202, + 0x1F203, 0x1F20F, + 0x1F21A, 0x1F21A, + 0x1F22F, 0x1F22F, + 0x1F232, 0x1F23A, + 0x1F23C, 0x1F23F, + 0x1F249, 0x1F24F, + 0x1F250, 0x1F251, + 0x1F252, 0x1F2FF, + 0x1F300, 0x1F30C, + 0x1F30D, 0x1F30E, + 0x1F30F, 0x1F30F, + 0x1F310, 0x1F310, + 0x1F311, 0x1F311, + 0x1F312, 0x1F312, + 0x1F313, 0x1F315, + 0x1F316, 0x1F318, + 0x1F319, 0x1F319, + 0x1F31A, 0x1F31A, + 0x1F31B, 0x1F31B, + 0x1F31C, 0x1F31C, + 0x1F31D, 0x1F31E, + 0x1F31F, 0x1F320, + 0x1F321, 0x1F321, + 0x1F322, 0x1F323, + 0x1F324, 0x1F32C, + 0x1F32D, 0x1F32F, + 0x1F330, 0x1F331, + 0x1F332, 0x1F333, + 0x1F334, 0x1F335, + 0x1F336, 0x1F336, + 0x1F337, 0x1F34A, + 0x1F34B, 0x1F34B, + 0x1F34C, 0x1F34F, + 0x1F350, 0x1F350, + 0x1F351, 0x1F37B, + 0x1F37C, 0x1F37C, + 0x1F37D, 0x1F37D, + 0x1F37E, 0x1F37F, + 0x1F380, 0x1F393, + 0x1F394, 0x1F395, + 0x1F396, 0x1F397, + 0x1F398, 0x1F398, + 0x1F399, 0x1F39B, + 0x1F39C, 0x1F39D, + 0x1F39E, 0x1F39F, + 0x1F3A0, 0x1F3C4, + 0x1F3C5, 0x1F3C5, + 0x1F3C6, 0x1F3C6, + 0x1F3C7, 0x1F3C7, + 0x1F3C8, 0x1F3C8, + 0x1F3C9, 0x1F3C9, + 0x1F3CA, 0x1F3CA, + 0x1F3CB, 0x1F3CE, + 0x1F3CF, 0x1F3D3, + 0x1F3D4, 0x1F3DF, + 0x1F3E0, 0x1F3E3, + 0x1F3E4, 0x1F3E4, + 0x1F3E5, 0x1F3F0, + 0x1F3F1, 0x1F3F2, + 0x1F3F3, 0x1F3F3, + 0x1F3F4, 0x1F3F4, + 0x1F3F5, 0x1F3F5, + 0x1F3F6, 0x1F3F6, + 0x1F3F7, 0x1F3F7, + 0x1F3F8, 0x1F3FA, + 0x1F400, 0x1F407, + 0x1F408, 0x1F408, + 0x1F409, 0x1F40B, + 0x1F40C, 0x1F40E, + 0x1F40F, 0x1F410, + 0x1F411, 0x1F412, + 0x1F413, 0x1F413, + 0x1F414, 0x1F414, + 0x1F415, 0x1F415, + 0x1F416, 0x1F416, + 0x1F417, 0x1F429, + 0x1F42A, 0x1F42A, + 0x1F42B, 0x1F43E, + 0x1F43F, 0x1F43F, + 0x1F440, 0x1F440, + 0x1F441, 0x1F441, + 0x1F442, 0x1F464, + 0x1F465, 0x1F465, + 0x1F466, 0x1F46B, + 0x1F46C, 0x1F46D, + 0x1F46E, 0x1F4AC, + 0x1F4AD, 0x1F4AD, + 0x1F4AE, 0x1F4B5, + 0x1F4B6, 0x1F4B7, + 0x1F4B8, 0x1F4EB, + 0x1F4EC, 0x1F4ED, + 0x1F4EE, 0x1F4EE, + 0x1F4EF, 0x1F4EF, + 0x1F4F0, 0x1F4F4, + 0x1F4F5, 0x1F4F5, + 0x1F4F6, 0x1F4F7, + 0x1F4F8, 0x1F4F8, + 0x1F4F9, 0x1F4FC, + 0x1F4FD, 0x1F4FD, + 0x1F4FE, 0x1F4FE, + 0x1F4FF, 0x1F502, + 0x1F503, 0x1F503, + 0x1F504, 0x1F507, + 0x1F508, 0x1F508, + 0x1F509, 0x1F509, + 0x1F50A, 0x1F514, + 0x1F515, 0x1F515, + 0x1F516, 0x1F52B, + 0x1F52C, 0x1F52D, + 0x1F52E, 0x1F53D, + 0x1F546, 0x1F548, + 0x1F549, 0x1F54A, + 0x1F54B, 0x1F54E, + 0x1F54F, 0x1F54F, + 0x1F550, 0x1F55B, + 0x1F55C, 0x1F567, + 0x1F568, 0x1F56E, + 0x1F56F, 0x1F570, + 0x1F571, 0x1F572, + 0x1F573, 0x1F579, + 0x1F57A, 0x1F57A, + 0x1F57B, 0x1F586, + 0x1F587, 0x1F587, + 0x1F588, 0x1F589, + 0x1F58A, 0x1F58D, + 0x1F58E, 0x1F58F, + 0x1F590, 0x1F590, + 0x1F591, 0x1F594, + 0x1F595, 0x1F596, + 0x1F597, 0x1F5A3, + 0x1F5A4, 0x1F5A4, + 0x1F5A5, 0x1F5A5, + 0x1F5A6, 0x1F5A7, + 0x1F5A8, 0x1F5A8, + 0x1F5A9, 0x1F5B0, + 0x1F5B1, 0x1F5B2, + 0x1F5B3, 0x1F5BB, + 0x1F5BC, 0x1F5BC, + 0x1F5BD, 0x1F5C1, + 0x1F5C2, 0x1F5C4, + 0x1F5C5, 0x1F5D0, + 0x1F5D1, 0x1F5D3, + 0x1F5D4, 0x1F5DB, + 0x1F5DC, 0x1F5DE, + 0x1F5DF, 0x1F5E0, + 0x1F5E1, 0x1F5E1, + 0x1F5E2, 0x1F5E2, + 0x1F5E3, 0x1F5E3, + 0x1F5E4, 0x1F5E7, + 0x1F5E8, 0x1F5E8, + 0x1F5E9, 0x1F5EE, + 0x1F5EF, 0x1F5EF, + 0x1F5F0, 0x1F5F2, + 0x1F5F3, 0x1F5F3, + 0x1F5F4, 0x1F5F9, + 0x1F5FA, 0x1F5FA, + 0x1F5FB, 0x1F5FF, + 0x1F600, 0x1F600, + 0x1F601, 0x1F606, + 0x1F607, 0x1F608, + 0x1F609, 0x1F60D, + 0x1F60E, 0x1F60E, + 0x1F60F, 0x1F60F, + 0x1F610, 0x1F610, + 0x1F611, 0x1F611, + 0x1F612, 0x1F614, + 0x1F615, 0x1F615, + 0x1F616, 0x1F616, + 0x1F617, 0x1F617, + 0x1F618, 0x1F618, + 0x1F619, 0x1F619, + 0x1F61A, 0x1F61A, + 0x1F61B, 0x1F61B, + 0x1F61C, 0x1F61E, + 0x1F61F, 0x1F61F, + 0x1F620, 0x1F625, + 0x1F626, 0x1F627, + 0x1F628, 0x1F62B, + 0x1F62C, 0x1F62C, + 0x1F62D, 0x1F62D, + 0x1F62E, 0x1F62F, + 0x1F630, 0x1F633, + 0x1F634, 0x1F634, + 0x1F635, 0x1F635, + 0x1F636, 0x1F636, + 0x1F637, 0x1F640, + 0x1F641, 0x1F644, + 0x1F645, 0x1F64F, + 0x1F680, 0x1F680, + 0x1F681, 0x1F682, + 0x1F683, 0x1F685, + 0x1F686, 0x1F686, + 0x1F687, 0x1F687, + 0x1F688, 0x1F688, + 0x1F689, 0x1F689, + 0x1F68A, 0x1F68B, + 0x1F68C, 0x1F68C, + 0x1F68D, 0x1F68D, + 0x1F68E, 0x1F68E, + 0x1F68F, 0x1F68F, + 0x1F690, 0x1F690, + 0x1F691, 0x1F693, + 0x1F694, 0x1F694, + 0x1F695, 0x1F695, + 0x1F696, 0x1F696, + 0x1F697, 0x1F697, + 0x1F698, 0x1F698, + 0x1F699, 0x1F69A, + 0x1F69B, 0x1F6A1, + 0x1F6A2, 0x1F6A2, + 0x1F6A3, 0x1F6A3, + 0x1F6A4, 0x1F6A5, + 0x1F6A6, 0x1F6A6, + 0x1F6A7, 0x1F6AD, + 0x1F6AE, 0x1F6B1, + 0x1F6B2, 0x1F6B2, + 0x1F6B3, 0x1F6B5, + 0x1F6B6, 0x1F6B6, + 0x1F6B7, 0x1F6B8, + 0x1F6B9, 0x1F6BE, + 0x1F6BF, 0x1F6BF, + 0x1F6C0, 0x1F6C0, + 0x1F6C1, 0x1F6C5, + 0x1F6C6, 0x1F6CA, + 0x1F6CB, 0x1F6CB, + 0x1F6CC, 0x1F6CC, + 0x1F6CD, 0x1F6CF, + 0x1F6D0, 0x1F6D0, + 0x1F6D1, 0x1F6D2, + 0x1F6D3, 0x1F6D4, + 0x1F6D5, 0x1F6D5, + 0x1F6D6, 0x1F6D7, + 0x1F6D8, 0x1F6DB, + 0x1F6DC, 0x1F6DC, + 0x1F6DD, 0x1F6DF, + 0x1F6E0, 0x1F6E5, + 0x1F6E6, 0x1F6E8, + 0x1F6E9, 0x1F6E9, + 0x1F6EA, 0x1F6EA, + 0x1F6EB, 0x1F6EC, + 0x1F6ED, 0x1F6EF, + 0x1F6F0, 0x1F6F0, + 0x1F6F1, 0x1F6F2, + 0x1F6F3, 0x1F6F3, + 0x1F6F4, 0x1F6F6, + 0x1F6F7, 0x1F6F8, + 0x1F6F9, 0x1F6F9, + 0x1F6FA, 0x1F6FA, + 0x1F6FB, 0x1F6FC, + 0x1F6FD, 0x1F6FF, + 0x1F774, 0x1F77F, + 0x1F7D5, 0x1F7DF, + 0x1F7E0, 0x1F7EB, + 0x1F7EC, 0x1F7EF, + 0x1F7F0, 0x1F7F0, + 0x1F7F1, 0x1F7FF, + 0x1F80C, 0x1F80F, + 0x1F848, 0x1F84F, + 0x1F85A, 0x1F85F, + 0x1F888, 0x1F88F, + 0x1F8AE, 0x1F8FF, + 0x1F90C, 0x1F90C, + 0x1F90D, 0x1F90F, + 0x1F910, 0x1F918, + 0x1F919, 0x1F91E, + 0x1F91F, 0x1F91F, + 0x1F920, 0x1F927, + 0x1F928, 0x1F92F, + 0x1F930, 0x1F930, + 0x1F931, 0x1F932, + 0x1F933, 0x1F93A, + 0x1F93C, 0x1F93E, + 0x1F93F, 0x1F93F, + 0x1F940, 0x1F945, + 0x1F947, 0x1F94B, + 0x1F94C, 0x1F94C, + 0x1F94D, 0x1F94F, + 0x1F950, 0x1F95E, + 0x1F95F, 0x1F96B, + 0x1F96C, 0x1F970, + 0x1F971, 0x1F971, + 0x1F972, 0x1F972, + 0x1F973, 0x1F976, + 0x1F977, 0x1F978, + 0x1F979, 0x1F979, + 0x1F97A, 0x1F97A, + 0x1F97B, 0x1F97B, + 0x1F97C, 0x1F97F, + 0x1F980, 0x1F984, + 0x1F985, 0x1F991, + 0x1F992, 0x1F997, + 0x1F998, 0x1F9A2, + 0x1F9A3, 0x1F9A4, + 0x1F9A5, 0x1F9AA, + 0x1F9AB, 0x1F9AD, + 0x1F9AE, 0x1F9AF, + 0x1F9B0, 0x1F9B9, + 0x1F9BA, 0x1F9BF, + 0x1F9C0, 0x1F9C0, + 0x1F9C1, 0x1F9C2, + 0x1F9C3, 0x1F9CA, + 0x1F9CB, 0x1F9CB, + 0x1F9CC, 0x1F9CC, + 0x1F9CD, 0x1F9CF, + 0x1F9D0, 0x1F9E6, + 0x1F9E7, 0x1F9FF, + 0x1FA00, 0x1FA6F, + 0x1FA70, 0x1FA73, + 0x1FA74, 0x1FA74, + 0x1FA75, 0x1FA77, + 0x1FA78, 0x1FA7A, + 0x1FA7B, 0x1FA7C, + 0x1FA7D, 0x1FA7F, + 0x1FA80, 0x1FA82, + 0x1FA83, 0x1FA86, + 0x1FA87, 0x1FA88, + 0x1FA89, 0x1FA8F, + 0x1FA90, 0x1FA95, + 0x1FA96, 0x1FAA8, + 0x1FAA9, 0x1FAAC, + 0x1FAAD, 0x1FAAF, + 0x1FAB0, 0x1FAB6, + 0x1FAB7, 0x1FABA, + 0x1FABB, 0x1FABD, + 0x1FABE, 0x1FABE, + 0x1FABF, 0x1FABF, + 0x1FAC0, 0x1FAC2, + 0x1FAC3, 0x1FAC5, + 0x1FAC6, 0x1FACD, + 0x1FACE, 0x1FACF, + 0x1FAD0, 0x1FAD6, + 0x1FAD7, 0x1FAD9, + 0x1FADA, 0x1FADB, + 0x1FADC, 0x1FADF, + 0x1FAE0, 0x1FAE7, + 0x1FAE8, 0x1FAE8, + 0x1FAE9, 0x1FAEF, + 0x1FAF0, 0x1FAF6, + 0x1FAF7, 0x1FAF8, + 0x1FAF9, 0x1FAFF, + 0x1FC00, 0x1FFFD, +}; + +static const int32_t ucg_grapheme_extend_ranges[] = { + 0x0300, 0x036F, + 0x0483, 0x0487, + 0x0488, 0x0489, + 0x0591, 0x05BD, + 0x05BF, 0x05BF, + 0x05C1, 0x05C2, + 0x05C4, 0x05C5, + 0x05C7, 0x05C7, + 0x0610, 0x061A, + 0x064B, 0x065F, + 0x0670, 0x0670, + 0x06D6, 0x06DC, + 0x06DF, 0x06E4, + 0x06E7, 0x06E8, + 0x06EA, 0x06ED, + 0x0711, 0x0711, + 0x0730, 0x074A, + 0x07A6, 0x07B0, + 0x07EB, 0x07F3, + 0x07FD, 0x07FD, + 0x0816, 0x0819, + 0x081B, 0x0823, + 0x0825, 0x0827, + 0x0829, 0x082D, + 0x0859, 0x085B, + 0x0898, 0x089F, + 0x08CA, 0x08E1, + 0x08E3, 0x0902, + 0x093A, 0x093A, + 0x093C, 0x093C, + 0x0941, 0x0948, + 0x094D, 0x094D, + 0x0951, 0x0957, + 0x0962, 0x0963, + 0x0981, 0x0981, + 0x09BC, 0x09BC, + 0x09BE, 0x09BE, + 0x09C1, 0x09C4, + 0x09CD, 0x09CD, + 0x09D7, 0x09D7, + 0x09E2, 0x09E3, + 0x09FE, 0x09FE, + 0x0A01, 0x0A02, + 0x0A3C, 0x0A3C, + 0x0A41, 0x0A42, + 0x0A47, 0x0A48, + 0x0A4B, 0x0A4D, + 0x0A51, 0x0A51, + 0x0A70, 0x0A71, + 0x0A75, 0x0A75, + 0x0A81, 0x0A82, + 0x0ABC, 0x0ABC, + 0x0AC1, 0x0AC5, + 0x0AC7, 0x0AC8, + 0x0ACD, 0x0ACD, + 0x0AE2, 0x0AE3, + 0x0AFA, 0x0AFF, + 0x0B01, 0x0B01, + 0x0B3C, 0x0B3C, + 0x0B3E, 0x0B3E, + 0x0B3F, 0x0B3F, + 0x0B41, 0x0B44, + 0x0B4D, 0x0B4D, + 0x0B55, 0x0B56, + 0x0B57, 0x0B57, + 0x0B62, 0x0B63, + 0x0B82, 0x0B82, + 0x0BBE, 0x0BBE, + 0x0BC0, 0x0BC0, + 0x0BCD, 0x0BCD, + 0x0BD7, 0x0BD7, + 0x0C00, 0x0C00, + 0x0C04, 0x0C04, + 0x0C3C, 0x0C3C, + 0x0C3E, 0x0C40, + 0x0C46, 0x0C48, + 0x0C4A, 0x0C4D, + 0x0C55, 0x0C56, + 0x0C62, 0x0C63, + 0x0C81, 0x0C81, + 0x0CBC, 0x0CBC, + 0x0CBF, 0x0CBF, + 0x0CC2, 0x0CC2, + 0x0CC6, 0x0CC6, + 0x0CCC, 0x0CCD, + 0x0CD5, 0x0CD6, + 0x0CE2, 0x0CE3, + 0x0D00, 0x0D01, + 0x0D3B, 0x0D3C, + 0x0D3E, 0x0D3E, + 0x0D41, 0x0D44, + 0x0D4D, 0x0D4D, + 0x0D57, 0x0D57, + 0x0D62, 0x0D63, + 0x0D81, 0x0D81, + 0x0DCA, 0x0DCA, + 0x0DCF, 0x0DCF, + 0x0DD2, 0x0DD4, + 0x0DD6, 0x0DD6, + 0x0DDF, 0x0DDF, + 0x0E31, 0x0E31, + 0x0E34, 0x0E3A, + 0x0E47, 0x0E4E, + 0x0EB1, 0x0EB1, + 0x0EB4, 0x0EBC, + 0x0EC8, 0x0ECE, + 0x0F18, 0x0F19, + 0x0F35, 0x0F35, + 0x0F37, 0x0F37, + 0x0F39, 0x0F39, + 0x0F71, 0x0F7E, + 0x0F80, 0x0F84, + 0x0F86, 0x0F87, + 0x0F8D, 0x0F97, + 0x0F99, 0x0FBC, + 0x0FC6, 0x0FC6, + 0x102D, 0x1030, + 0x1032, 0x1037, + 0x1039, 0x103A, + 0x103D, 0x103E, + 0x1058, 0x1059, + 0x105E, 0x1060, + 0x1071, 0x1074, + 0x1082, 0x1082, + 0x1085, 0x1086, + 0x108D, 0x108D, + 0x109D, 0x109D, + 0x135D, 0x135F, + 0x1712, 0x1714, + 0x1732, 0x1733, + 0x1752, 0x1753, + 0x1772, 0x1773, + 0x17B4, 0x17B5, + 0x17B7, 0x17BD, + 0x17C6, 0x17C6, + 0x17C9, 0x17D3, + 0x17DD, 0x17DD, + 0x180B, 0x180D, + 0x180F, 0x180F, + 0x1885, 0x1886, + 0x18A9, 0x18A9, + 0x1920, 0x1922, + 0x1927, 0x1928, + 0x1932, 0x1932, + 0x1939, 0x193B, + 0x1A17, 0x1A18, + 0x1A1B, 0x1A1B, + 0x1A56, 0x1A56, + 0x1A58, 0x1A5E, + 0x1A60, 0x1A60, + 0x1A62, 0x1A62, + 0x1A65, 0x1A6C, + 0x1A73, 0x1A7C, + 0x1A7F, 0x1A7F, + 0x1AB0, 0x1ABD, + 0x1ABE, 0x1ABE, + 0x1ABF, 0x1ACE, + 0x1B00, 0x1B03, + 0x1B34, 0x1B34, + 0x1B35, 0x1B35, + 0x1B36, 0x1B3A, + 0x1B3C, 0x1B3C, + 0x1B42, 0x1B42, + 0x1B6B, 0x1B73, + 0x1B80, 0x1B81, + 0x1BA2, 0x1BA5, + 0x1BA8, 0x1BA9, + 0x1BAB, 0x1BAD, + 0x1BE6, 0x1BE6, + 0x1BE8, 0x1BE9, + 0x1BED, 0x1BED, + 0x1BEF, 0x1BF1, + 0x1C2C, 0x1C33, + 0x1C36, 0x1C37, + 0x1CD0, 0x1CD2, + 0x1CD4, 0x1CE0, + 0x1CE2, 0x1CE8, + 0x1CED, 0x1CED, + 0x1CF4, 0x1CF4, + 0x1CF8, 0x1CF9, + 0x1DC0, 0x1DFF, + 0x200C, 0x200C, + 0x20D0, 0x20DC, + 0x20DD, 0x20E0, + 0x20E1, 0x20E1, + 0x20E2, 0x20E4, + 0x20E5, 0x20F0, + 0x2CEF, 0x2CF1, + 0x2D7F, 0x2D7F, + 0x2DE0, 0x2DFF, + 0x302A, 0x302D, + 0x302E, 0x302F, + 0x3099, 0x309A, + 0xA66F, 0xA66F, + 0xA670, 0xA672, + 0xA674, 0xA67D, + 0xA69E, 0xA69F, + 0xA6F0, 0xA6F1, + 0xA802, 0xA802, + 0xA806, 0xA806, + 0xA80B, 0xA80B, + 0xA825, 0xA826, + 0xA82C, 0xA82C, + 0xA8C4, 0xA8C5, + 0xA8E0, 0xA8F1, + 0xA8FF, 0xA8FF, + 0xA926, 0xA92D, + 0xA947, 0xA951, + 0xA980, 0xA982, + 0xA9B3, 0xA9B3, + 0xA9B6, 0xA9B9, + 0xA9BC, 0xA9BD, + 0xA9E5, 0xA9E5, + 0xAA29, 0xAA2E, + 0xAA31, 0xAA32, + 0xAA35, 0xAA36, + 0xAA43, 0xAA43, + 0xAA4C, 0xAA4C, + 0xAA7C, 0xAA7C, + 0xAAB0, 0xAAB0, + 0xAAB2, 0xAAB4, + 0xAAB7, 0xAAB8, + 0xAABE, 0xAABF, + 0xAAC1, 0xAAC1, + 0xAAEC, 0xAAED, + 0xAAF6, 0xAAF6, + 0xABE5, 0xABE5, + 0xABE8, 0xABE8, + 0xABED, 0xABED, + 0xFB1E, 0xFB1E, + 0xFE00, 0xFE0F, + 0xFE20, 0xFE2F, + 0xFF9E, 0xFF9F, + 0x101FD, 0x101FD, + 0x102E0, 0x102E0, + 0x10376, 0x1037A, + 0x10A01, 0x10A03, + 0x10A05, 0x10A06, + 0x10A0C, 0x10A0F, + 0x10A38, 0x10A3A, + 0x10A3F, 0x10A3F, + 0x10AE5, 0x10AE6, + 0x10D24, 0x10D27, + 0x10EAB, 0x10EAC, + 0x10EFD, 0x10EFF, + 0x10F46, 0x10F50, + 0x10F82, 0x10F85, + 0x11001, 0x11001, + 0x11038, 0x11046, + 0x11070, 0x11070, + 0x11073, 0x11074, + 0x1107F, 0x11081, + 0x110B3, 0x110B6, + 0x110B9, 0x110BA, + 0x110C2, 0x110C2, + 0x11100, 0x11102, + 0x11127, 0x1112B, + 0x1112D, 0x11134, + 0x11173, 0x11173, + 0x11180, 0x11181, + 0x111B6, 0x111BE, + 0x111C9, 0x111CC, + 0x111CF, 0x111CF, + 0x1122F, 0x11231, + 0x11234, 0x11234, + 0x11236, 0x11237, + 0x1123E, 0x1123E, + 0x11241, 0x11241, + 0x112DF, 0x112DF, + 0x112E3, 0x112EA, + 0x11300, 0x11301, + 0x1133B, 0x1133C, + 0x1133E, 0x1133E, + 0x11340, 0x11340, + 0x11357, 0x11357, + 0x11366, 0x1136C, + 0x11370, 0x11374, + 0x11438, 0x1143F, + 0x11442, 0x11444, + 0x11446, 0x11446, + 0x1145E, 0x1145E, + 0x114B0, 0x114B0, + 0x114B3, 0x114B8, + 0x114BA, 0x114BA, + 0x114BD, 0x114BD, + 0x114BF, 0x114C0, + 0x114C2, 0x114C3, + 0x115AF, 0x115AF, + 0x115B2, 0x115B5, + 0x115BC, 0x115BD, + 0x115BF, 0x115C0, + 0x115DC, 0x115DD, + 0x11633, 0x1163A, + 0x1163D, 0x1163D, + 0x1163F, 0x11640, + 0x116AB, 0x116AB, + 0x116AD, 0x116AD, + 0x116B0, 0x116B5, + 0x116B7, 0x116B7, + 0x1171D, 0x1171F, + 0x11722, 0x11725, + 0x11727, 0x1172B, + 0x1182F, 0x11837, + 0x11839, 0x1183A, + 0x11930, 0x11930, + 0x1193B, 0x1193C, + 0x1193E, 0x1193E, + 0x11943, 0x11943, + 0x119D4, 0x119D7, + 0x119DA, 0x119DB, + 0x119E0, 0x119E0, + 0x11A01, 0x11A0A, + 0x11A33, 0x11A38, + 0x11A3B, 0x11A3E, + 0x11A47, 0x11A47, + 0x11A51, 0x11A56, + 0x11A59, 0x11A5B, + 0x11A8A, 0x11A96, + 0x11A98, 0x11A99, + 0x11C30, 0x11C36, + 0x11C38, 0x11C3D, + 0x11C3F, 0x11C3F, + 0x11C92, 0x11CA7, + 0x11CAA, 0x11CB0, + 0x11CB2, 0x11CB3, + 0x11CB5, 0x11CB6, + 0x11D31, 0x11D36, + 0x11D3A, 0x11D3A, + 0x11D3C, 0x11D3D, + 0x11D3F, 0x11D45, + 0x11D47, 0x11D47, + 0x11D90, 0x11D91, + 0x11D95, 0x11D95, + 0x11D97, 0x11D97, + 0x11EF3, 0x11EF4, + 0x11F00, 0x11F01, + 0x11F36, 0x11F3A, + 0x11F40, 0x11F40, + 0x11F42, 0x11F42, + 0x13440, 0x13440, + 0x13447, 0x13455, + 0x16AF0, 0x16AF4, + 0x16B30, 0x16B36, + 0x16F4F, 0x16F4F, + 0x16F8F, 0x16F92, + 0x16FE4, 0x16FE4, + 0x1BC9D, 0x1BC9E, + 0x1CF00, 0x1CF2D, + 0x1CF30, 0x1CF46, + 0x1D165, 0x1D165, + 0x1D167, 0x1D169, + 0x1D16E, 0x1D172, + 0x1D17B, 0x1D182, + 0x1D185, 0x1D18B, + 0x1D1AA, 0x1D1AD, + 0x1D242, 0x1D244, + 0x1DA00, 0x1DA36, + 0x1DA3B, 0x1DA6C, + 0x1DA75, 0x1DA75, + 0x1DA84, 0x1DA84, + 0x1DA9B, 0x1DA9F, + 0x1DAA1, 0x1DAAF, + 0x1E000, 0x1E006, + 0x1E008, 0x1E018, + 0x1E01B, 0x1E021, + 0x1E023, 0x1E024, + 0x1E026, 0x1E02A, + 0x1E08F, 0x1E08F, + 0x1E130, 0x1E136, + 0x1E2AE, 0x1E2AE, + 0x1E2EC, 0x1E2EF, + 0x1E4EC, 0x1E4EF, + 0x1E8D0, 0x1E8D6, + 0x1E944, 0x1E94A, + 0xE0020, 0xE007F, + 0xE0100, 0xE01EF, +}; + +static const int32_t ucg_hangul_syllable_lv_singlets[] = { + 0xAC00, + 0xAC1C, + 0xAC38, + 0xAC54, + 0xAC70, + 0xAC8C, + 0xACA8, + 0xACC4, + 0xACE0, + 0xACFC, + 0xAD18, + 0xAD34, + 0xAD50, + 0xAD6C, + 0xAD88, + 0xADA4, + 0xADC0, + 0xADDC, + 0xADF8, + 0xAE14, + 0xAE30, + 0xAE4C, + 0xAE68, + 0xAE84, + 0xAEA0, + 0xAEBC, + 0xAED8, + 0xAEF4, + 0xAF10, + 0xAF2C, + 0xAF48, + 0xAF64, + 0xAF80, + 0xAF9C, + 0xAFB8, + 0xAFD4, + 0xAFF0, + 0xB00C, + 0xB028, + 0xB044, + 0xB060, + 0xB07C, + 0xB098, + 0xB0B4, + 0xB0D0, + 0xB0EC, + 0xB108, + 0xB124, + 0xB140, + 0xB15C, + 0xB178, + 0xB194, + 0xB1B0, + 0xB1CC, + 0xB1E8, + 0xB204, + 0xB220, + 0xB23C, + 0xB258, + 0xB274, + 0xB290, + 0xB2AC, + 0xB2C8, + 0xB2E4, + 0xB300, + 0xB31C, + 0xB338, + 0xB354, + 0xB370, + 0xB38C, + 0xB3A8, + 0xB3C4, + 0xB3E0, + 0xB3FC, + 0xB418, + 0xB434, + 0xB450, + 0xB46C, + 0xB488, + 0xB4A4, + 0xB4C0, + 0xB4DC, + 0xB4F8, + 0xB514, + 0xB530, + 0xB54C, + 0xB568, + 0xB584, + 0xB5A0, + 0xB5BC, + 0xB5D8, + 0xB5F4, + 0xB610, + 0xB62C, + 0xB648, + 0xB664, + 0xB680, + 0xB69C, + 0xB6B8, + 0xB6D4, + 0xB6F0, + 0xB70C, + 0xB728, + 0xB744, + 0xB760, + 0xB77C, + 0xB798, + 0xB7B4, + 0xB7D0, + 0xB7EC, + 0xB808, + 0xB824, + 0xB840, + 0xB85C, + 0xB878, + 0xB894, + 0xB8B0, + 0xB8CC, + 0xB8E8, + 0xB904, + 0xB920, + 0xB93C, + 0xB958, + 0xB974, + 0xB990, + 0xB9AC, + 0xB9C8, + 0xB9E4, + 0xBA00, + 0xBA1C, + 0xBA38, + 0xBA54, + 0xBA70, + 0xBA8C, + 0xBAA8, + 0xBAC4, + 0xBAE0, + 0xBAFC, + 0xBB18, + 0xBB34, + 0xBB50, + 0xBB6C, + 0xBB88, + 0xBBA4, + 0xBBC0, + 0xBBDC, + 0xBBF8, + 0xBC14, + 0xBC30, + 0xBC4C, + 0xBC68, + 0xBC84, + 0xBCA0, + 0xBCBC, + 0xBCD8, + 0xBCF4, + 0xBD10, + 0xBD2C, + 0xBD48, + 0xBD64, + 0xBD80, + 0xBD9C, + 0xBDB8, + 0xBDD4, + 0xBDF0, + 0xBE0C, + 0xBE28, + 0xBE44, + 0xBE60, + 0xBE7C, + 0xBE98, + 0xBEB4, + 0xBED0, + 0xBEEC, + 0xBF08, + 0xBF24, + 0xBF40, + 0xBF5C, + 0xBF78, + 0xBF94, + 0xBFB0, + 0xBFCC, + 0xBFE8, + 0xC004, + 0xC020, + 0xC03C, + 0xC058, + 0xC074, + 0xC090, + 0xC0AC, + 0xC0C8, + 0xC0E4, + 0xC100, + 0xC11C, + 0xC138, + 0xC154, + 0xC170, + 0xC18C, + 0xC1A8, + 0xC1C4, + 0xC1E0, + 0xC1FC, + 0xC218, + 0xC234, + 0xC250, + 0xC26C, + 0xC288, + 0xC2A4, + 0xC2C0, + 0xC2DC, + 0xC2F8, + 0xC314, + 0xC330, + 0xC34C, + 0xC368, + 0xC384, + 0xC3A0, + 0xC3BC, + 0xC3D8, + 0xC3F4, + 0xC410, + 0xC42C, + 0xC448, + 0xC464, + 0xC480, + 0xC49C, + 0xC4B8, + 0xC4D4, + 0xC4F0, + 0xC50C, + 0xC528, + 0xC544, + 0xC560, + 0xC57C, + 0xC598, + 0xC5B4, + 0xC5D0, + 0xC5EC, + 0xC608, + 0xC624, + 0xC640, + 0xC65C, + 0xC678, + 0xC694, + 0xC6B0, + 0xC6CC, + 0xC6E8, + 0xC704, + 0xC720, + 0xC73C, + 0xC758, + 0xC774, + 0xC790, + 0xC7AC, + 0xC7C8, + 0xC7E4, + 0xC800, + 0xC81C, + 0xC838, + 0xC854, + 0xC870, + 0xC88C, + 0xC8A8, + 0xC8C4, + 0xC8E0, + 0xC8FC, + 0xC918, + 0xC934, + 0xC950, + 0xC96C, + 0xC988, + 0xC9A4, + 0xC9C0, + 0xC9DC, + 0xC9F8, + 0xCA14, + 0xCA30, + 0xCA4C, + 0xCA68, + 0xCA84, + 0xCAA0, + 0xCABC, + 0xCAD8, + 0xCAF4, + 0xCB10, + 0xCB2C, + 0xCB48, + 0xCB64, + 0xCB80, + 0xCB9C, + 0xCBB8, + 0xCBD4, + 0xCBF0, + 0xCC0C, + 0xCC28, + 0xCC44, + 0xCC60, + 0xCC7C, + 0xCC98, + 0xCCB4, + 0xCCD0, + 0xCCEC, + 0xCD08, + 0xCD24, + 0xCD40, + 0xCD5C, + 0xCD78, + 0xCD94, + 0xCDB0, + 0xCDCC, + 0xCDE8, + 0xCE04, + 0xCE20, + 0xCE3C, + 0xCE58, + 0xCE74, + 0xCE90, + 0xCEAC, + 0xCEC8, + 0xCEE4, + 0xCF00, + 0xCF1C, + 0xCF38, + 0xCF54, + 0xCF70, + 0xCF8C, + 0xCFA8, + 0xCFC4, + 0xCFE0, + 0xCFFC, + 0xD018, + 0xD034, + 0xD050, + 0xD06C, + 0xD088, + 0xD0A4, + 0xD0C0, + 0xD0DC, + 0xD0F8, + 0xD114, + 0xD130, + 0xD14C, + 0xD168, + 0xD184, + 0xD1A0, + 0xD1BC, + 0xD1D8, + 0xD1F4, + 0xD210, + 0xD22C, + 0xD248, + 0xD264, + 0xD280, + 0xD29C, + 0xD2B8, + 0xD2D4, + 0xD2F0, + 0xD30C, + 0xD328, + 0xD344, + 0xD360, + 0xD37C, + 0xD398, + 0xD3B4, + 0xD3D0, + 0xD3EC, + 0xD408, + 0xD424, + 0xD440, + 0xD45C, + 0xD478, + 0xD494, + 0xD4B0, + 0xD4CC, + 0xD4E8, + 0xD504, + 0xD520, + 0xD53C, + 0xD558, + 0xD574, + 0xD590, + 0xD5AC, + 0xD5C8, + 0xD5E4, + 0xD600, + 0xD61C, + 0xD638, + 0xD654, + 0xD670, + 0xD68C, + 0xD6A8, + 0xD6C4, + 0xD6E0, + 0xD6FC, + 0xD718, + 0xD734, + 0xD750, + 0xD76C, + 0xD788, +}; + +static const int32_t ucg_hangul_syllable_lvt_ranges[] = { + 0xAC01, 0xAC1B, + 0xAC1D, 0xAC37, + 0xAC39, 0xAC53, + 0xAC55, 0xAC6F, + 0xAC71, 0xAC8B, + 0xAC8D, 0xACA7, + 0xACA9, 0xACC3, + 0xACC5, 0xACDF, + 0xACE1, 0xACFB, + 0xACFD, 0xAD17, + 0xAD19, 0xAD33, + 0xAD35, 0xAD4F, + 0xAD51, 0xAD6B, + 0xAD6D, 0xAD87, + 0xAD89, 0xADA3, + 0xADA5, 0xADBF, + 0xADC1, 0xADDB, + 0xADDD, 0xADF7, + 0xADF9, 0xAE13, + 0xAE15, 0xAE2F, + 0xAE31, 0xAE4B, + 0xAE4D, 0xAE67, + 0xAE69, 0xAE83, + 0xAE85, 0xAE9F, + 0xAEA1, 0xAEBB, + 0xAEBD, 0xAED7, + 0xAED9, 0xAEF3, + 0xAEF5, 0xAF0F, + 0xAF11, 0xAF2B, + 0xAF2D, 0xAF47, + 0xAF49, 0xAF63, + 0xAF65, 0xAF7F, + 0xAF81, 0xAF9B, + 0xAF9D, 0xAFB7, + 0xAFB9, 0xAFD3, + 0xAFD5, 0xAFEF, + 0xAFF1, 0xB00B, + 0xB00D, 0xB027, + 0xB029, 0xB043, + 0xB045, 0xB05F, + 0xB061, 0xB07B, + 0xB07D, 0xB097, + 0xB099, 0xB0B3, + 0xB0B5, 0xB0CF, + 0xB0D1, 0xB0EB, + 0xB0ED, 0xB107, + 0xB109, 0xB123, + 0xB125, 0xB13F, + 0xB141, 0xB15B, + 0xB15D, 0xB177, + 0xB179, 0xB193, + 0xB195, 0xB1AF, + 0xB1B1, 0xB1CB, + 0xB1CD, 0xB1E7, + 0xB1E9, 0xB203, + 0xB205, 0xB21F, + 0xB221, 0xB23B, + 0xB23D, 0xB257, + 0xB259, 0xB273, + 0xB275, 0xB28F, + 0xB291, 0xB2AB, + 0xB2AD, 0xB2C7, + 0xB2C9, 0xB2E3, + 0xB2E5, 0xB2FF, + 0xB301, 0xB31B, + 0xB31D, 0xB337, + 0xB339, 0xB353, + 0xB355, 0xB36F, + 0xB371, 0xB38B, + 0xB38D, 0xB3A7, + 0xB3A9, 0xB3C3, + 0xB3C5, 0xB3DF, + 0xB3E1, 0xB3FB, + 0xB3FD, 0xB417, + 0xB419, 0xB433, + 0xB435, 0xB44F, + 0xB451, 0xB46B, + 0xB46D, 0xB487, + 0xB489, 0xB4A3, + 0xB4A5, 0xB4BF, + 0xB4C1, 0xB4DB, + 0xB4DD, 0xB4F7, + 0xB4F9, 0xB513, + 0xB515, 0xB52F, + 0xB531, 0xB54B, + 0xB54D, 0xB567, + 0xB569, 0xB583, + 0xB585, 0xB59F, + 0xB5A1, 0xB5BB, + 0xB5BD, 0xB5D7, + 0xB5D9, 0xB5F3, + 0xB5F5, 0xB60F, + 0xB611, 0xB62B, + 0xB62D, 0xB647, + 0xB649, 0xB663, + 0xB665, 0xB67F, + 0xB681, 0xB69B, + 0xB69D, 0xB6B7, + 0xB6B9, 0xB6D3, + 0xB6D5, 0xB6EF, + 0xB6F1, 0xB70B, + 0xB70D, 0xB727, + 0xB729, 0xB743, + 0xB745, 0xB75F, + 0xB761, 0xB77B, + 0xB77D, 0xB797, + 0xB799, 0xB7B3, + 0xB7B5, 0xB7CF, + 0xB7D1, 0xB7EB, + 0xB7ED, 0xB807, + 0xB809, 0xB823, + 0xB825, 0xB83F, + 0xB841, 0xB85B, + 0xB85D, 0xB877, + 0xB879, 0xB893, + 0xB895, 0xB8AF, + 0xB8B1, 0xB8CB, + 0xB8CD, 0xB8E7, + 0xB8E9, 0xB903, + 0xB905, 0xB91F, + 0xB921, 0xB93B, + 0xB93D, 0xB957, + 0xB959, 0xB973, + 0xB975, 0xB98F, + 0xB991, 0xB9AB, + 0xB9AD, 0xB9C7, + 0xB9C9, 0xB9E3, + 0xB9E5, 0xB9FF, + 0xBA01, 0xBA1B, + 0xBA1D, 0xBA37, + 0xBA39, 0xBA53, + 0xBA55, 0xBA6F, + 0xBA71, 0xBA8B, + 0xBA8D, 0xBAA7, + 0xBAA9, 0xBAC3, + 0xBAC5, 0xBADF, + 0xBAE1, 0xBAFB, + 0xBAFD, 0xBB17, + 0xBB19, 0xBB33, + 0xBB35, 0xBB4F, + 0xBB51, 0xBB6B, + 0xBB6D, 0xBB87, + 0xBB89, 0xBBA3, + 0xBBA5, 0xBBBF, + 0xBBC1, 0xBBDB, + 0xBBDD, 0xBBF7, + 0xBBF9, 0xBC13, + 0xBC15, 0xBC2F, + 0xBC31, 0xBC4B, + 0xBC4D, 0xBC67, + 0xBC69, 0xBC83, + 0xBC85, 0xBC9F, + 0xBCA1, 0xBCBB, + 0xBCBD, 0xBCD7, + 0xBCD9, 0xBCF3, + 0xBCF5, 0xBD0F, + 0xBD11, 0xBD2B, + 0xBD2D, 0xBD47, + 0xBD49, 0xBD63, + 0xBD65, 0xBD7F, + 0xBD81, 0xBD9B, + 0xBD9D, 0xBDB7, + 0xBDB9, 0xBDD3, + 0xBDD5, 0xBDEF, + 0xBDF1, 0xBE0B, + 0xBE0D, 0xBE27, + 0xBE29, 0xBE43, + 0xBE45, 0xBE5F, + 0xBE61, 0xBE7B, + 0xBE7D, 0xBE97, + 0xBE99, 0xBEB3, + 0xBEB5, 0xBECF, + 0xBED1, 0xBEEB, + 0xBEED, 0xBF07, + 0xBF09, 0xBF23, + 0xBF25, 0xBF3F, + 0xBF41, 0xBF5B, + 0xBF5D, 0xBF77, + 0xBF79, 0xBF93, + 0xBF95, 0xBFAF, + 0xBFB1, 0xBFCB, + 0xBFCD, 0xBFE7, + 0xBFE9, 0xC003, + 0xC005, 0xC01F, + 0xC021, 0xC03B, + 0xC03D, 0xC057, + 0xC059, 0xC073, + 0xC075, 0xC08F, + 0xC091, 0xC0AB, + 0xC0AD, 0xC0C7, + 0xC0C9, 0xC0E3, + 0xC0E5, 0xC0FF, + 0xC101, 0xC11B, + 0xC11D, 0xC137, + 0xC139, 0xC153, + 0xC155, 0xC16F, + 0xC171, 0xC18B, + 0xC18D, 0xC1A7, + 0xC1A9, 0xC1C3, + 0xC1C5, 0xC1DF, + 0xC1E1, 0xC1FB, + 0xC1FD, 0xC217, + 0xC219, 0xC233, + 0xC235, 0xC24F, + 0xC251, 0xC26B, + 0xC26D, 0xC287, + 0xC289, 0xC2A3, + 0xC2A5, 0xC2BF, + 0xC2C1, 0xC2DB, + 0xC2DD, 0xC2F7, + 0xC2F9, 0xC313, + 0xC315, 0xC32F, + 0xC331, 0xC34B, + 0xC34D, 0xC367, + 0xC369, 0xC383, + 0xC385, 0xC39F, + 0xC3A1, 0xC3BB, + 0xC3BD, 0xC3D7, + 0xC3D9, 0xC3F3, + 0xC3F5, 0xC40F, + 0xC411, 0xC42B, + 0xC42D, 0xC447, + 0xC449, 0xC463, + 0xC465, 0xC47F, + 0xC481, 0xC49B, + 0xC49D, 0xC4B7, + 0xC4B9, 0xC4D3, + 0xC4D5, 0xC4EF, + 0xC4F1, 0xC50B, + 0xC50D, 0xC527, + 0xC529, 0xC543, + 0xC545, 0xC55F, + 0xC561, 0xC57B, + 0xC57D, 0xC597, + 0xC599, 0xC5B3, + 0xC5B5, 0xC5CF, + 0xC5D1, 0xC5EB, + 0xC5ED, 0xC607, + 0xC609, 0xC623, + 0xC625, 0xC63F, + 0xC641, 0xC65B, + 0xC65D, 0xC677, + 0xC679, 0xC693, + 0xC695, 0xC6AF, + 0xC6B1, 0xC6CB, + 0xC6CD, 0xC6E7, + 0xC6E9, 0xC703, + 0xC705, 0xC71F, + 0xC721, 0xC73B, + 0xC73D, 0xC757, + 0xC759, 0xC773, + 0xC775, 0xC78F, + 0xC791, 0xC7AB, + 0xC7AD, 0xC7C7, + 0xC7C9, 0xC7E3, + 0xC7E5, 0xC7FF, + 0xC801, 0xC81B, + 0xC81D, 0xC837, + 0xC839, 0xC853, + 0xC855, 0xC86F, + 0xC871, 0xC88B, + 0xC88D, 0xC8A7, + 0xC8A9, 0xC8C3, + 0xC8C5, 0xC8DF, + 0xC8E1, 0xC8FB, + 0xC8FD, 0xC917, + 0xC919, 0xC933, + 0xC935, 0xC94F, + 0xC951, 0xC96B, + 0xC96D, 0xC987, + 0xC989, 0xC9A3, + 0xC9A5, 0xC9BF, + 0xC9C1, 0xC9DB, + 0xC9DD, 0xC9F7, + 0xC9F9, 0xCA13, + 0xCA15, 0xCA2F, + 0xCA31, 0xCA4B, + 0xCA4D, 0xCA67, + 0xCA69, 0xCA83, + 0xCA85, 0xCA9F, + 0xCAA1, 0xCABB, + 0xCABD, 0xCAD7, + 0xCAD9, 0xCAF3, + 0xCAF5, 0xCB0F, + 0xCB11, 0xCB2B, + 0xCB2D, 0xCB47, + 0xCB49, 0xCB63, + 0xCB65, 0xCB7F, + 0xCB81, 0xCB9B, + 0xCB9D, 0xCBB7, + 0xCBB9, 0xCBD3, + 0xCBD5, 0xCBEF, + 0xCBF1, 0xCC0B, + 0xCC0D, 0xCC27, + 0xCC29, 0xCC43, + 0xCC45, 0xCC5F, + 0xCC61, 0xCC7B, + 0xCC7D, 0xCC97, + 0xCC99, 0xCCB3, + 0xCCB5, 0xCCCF, + 0xCCD1, 0xCCEB, + 0xCCED, 0xCD07, + 0xCD09, 0xCD23, + 0xCD25, 0xCD3F, + 0xCD41, 0xCD5B, + 0xCD5D, 0xCD77, + 0xCD79, 0xCD93, + 0xCD95, 0xCDAF, + 0xCDB1, 0xCDCB, + 0xCDCD, 0xCDE7, + 0xCDE9, 0xCE03, + 0xCE05, 0xCE1F, + 0xCE21, 0xCE3B, + 0xCE3D, 0xCE57, + 0xCE59, 0xCE73, + 0xCE75, 0xCE8F, + 0xCE91, 0xCEAB, + 0xCEAD, 0xCEC7, + 0xCEC9, 0xCEE3, + 0xCEE5, 0xCEFF, + 0xCF01, 0xCF1B, + 0xCF1D, 0xCF37, + 0xCF39, 0xCF53, + 0xCF55, 0xCF6F, + 0xCF71, 0xCF8B, + 0xCF8D, 0xCFA7, + 0xCFA9, 0xCFC3, + 0xCFC5, 0xCFDF, + 0xCFE1, 0xCFFB, + 0xCFFD, 0xD017, + 0xD019, 0xD033, + 0xD035, 0xD04F, + 0xD051, 0xD06B, + 0xD06D, 0xD087, + 0xD089, 0xD0A3, + 0xD0A5, 0xD0BF, + 0xD0C1, 0xD0DB, + 0xD0DD, 0xD0F7, + 0xD0F9, 0xD113, + 0xD115, 0xD12F, + 0xD131, 0xD14B, + 0xD14D, 0xD167, + 0xD169, 0xD183, + 0xD185, 0xD19F, + 0xD1A1, 0xD1BB, + 0xD1BD, 0xD1D7, + 0xD1D9, 0xD1F3, + 0xD1F5, 0xD20F, + 0xD211, 0xD22B, + 0xD22D, 0xD247, + 0xD249, 0xD263, + 0xD265, 0xD27F, + 0xD281, 0xD29B, + 0xD29D, 0xD2B7, + 0xD2B9, 0xD2D3, + 0xD2D5, 0xD2EF, + 0xD2F1, 0xD30B, + 0xD30D, 0xD327, + 0xD329, 0xD343, + 0xD345, 0xD35F, + 0xD361, 0xD37B, + 0xD37D, 0xD397, + 0xD399, 0xD3B3, + 0xD3B5, 0xD3CF, + 0xD3D1, 0xD3EB, + 0xD3ED, 0xD407, + 0xD409, 0xD423, + 0xD425, 0xD43F, + 0xD441, 0xD45B, + 0xD45D, 0xD477, + 0xD479, 0xD493, + 0xD495, 0xD4AF, + 0xD4B1, 0xD4CB, + 0xD4CD, 0xD4E7, + 0xD4E9, 0xD503, + 0xD505, 0xD51F, + 0xD521, 0xD53B, + 0xD53D, 0xD557, + 0xD559, 0xD573, + 0xD575, 0xD58F, + 0xD591, 0xD5AB, + 0xD5AD, 0xD5C7, + 0xD5C9, 0xD5E3, + 0xD5E5, 0xD5FF, + 0xD601, 0xD61B, + 0xD61D, 0xD637, + 0xD639, 0xD653, + 0xD655, 0xD66F, + 0xD671, 0xD68B, + 0xD68D, 0xD6A7, + 0xD6A9, 0xD6C3, + 0xD6C5, 0xD6DF, + 0xD6E1, 0xD6FB, + 0xD6FD, 0xD717, + 0xD719, 0xD733, + 0xD735, 0xD74F, + 0xD751, 0xD76B, + 0xD76D, 0xD787, + 0xD789, 0xD7A3, +}; + +static const int32_t ucg_indic_conjunct_break_consonant_ranges[] = { + 0x0915, 0x0939, + 0x0958, 0x095F, + 0x0978, 0x097F, + 0x0995, 0x09A8, + 0x09AA, 0x09B0, + 0x09B2, 0x09B2, + 0x09B6, 0x09B9, + 0x09DC, 0x09DD, + 0x09DF, 0x09DF, + 0x09F0, 0x09F1, + 0x0A95, 0x0AA8, + 0x0AAA, 0x0AB0, + 0x0AB2, 0x0AB3, + 0x0AB5, 0x0AB9, + 0x0AF9, 0x0AF9, + 0x0B15, 0x0B28, + 0x0B2A, 0x0B30, + 0x0B32, 0x0B33, + 0x0B35, 0x0B39, + 0x0B5C, 0x0B5D, + 0x0B5F, 0x0B5F, + 0x0B71, 0x0B71, + 0x0C15, 0x0C28, + 0x0C2A, 0x0C39, + 0x0C58, 0x0C5A, + 0x0D15, 0x0D3A, +}; + +static const int32_t ucg_indic_conjunct_break_extend_ranges[] = { + 0x0300, 0x034E, + 0x0350, 0x036F, + 0x0483, 0x0487, + 0x0591, 0x05BD, + 0x05BF, 0x05BF, + 0x05C1, 0x05C2, + 0x05C4, 0x05C5, + 0x05C7, 0x05C7, + 0x0610, 0x061A, + 0x064B, 0x065F, + 0x0670, 0x0670, + 0x06D6, 0x06DC, + 0x06DF, 0x06E4, + 0x06E7, 0x06E8, + 0x06EA, 0x06ED, + 0x0711, 0x0711, + 0x0730, 0x074A, + 0x07EB, 0x07F3, + 0x07FD, 0x07FD, + 0x0816, 0x0819, + 0x081B, 0x0823, + 0x0825, 0x0827, + 0x0829, 0x082D, + 0x0859, 0x085B, + 0x0898, 0x089F, + 0x08CA, 0x08E1, + 0x08E3, 0x08FF, + 0x093C, 0x093C, + 0x0951, 0x0954, + 0x09BC, 0x09BC, + 0x09FE, 0x09FE, + 0x0A3C, 0x0A3C, + 0x0ABC, 0x0ABC, + 0x0B3C, 0x0B3C, + 0x0C3C, 0x0C3C, + 0x0C55, 0x0C56, + 0x0CBC, 0x0CBC, + 0x0D3B, 0x0D3C, + 0x0E38, 0x0E3A, + 0x0E48, 0x0E4B, + 0x0EB8, 0x0EBA, + 0x0EC8, 0x0ECB, + 0x0F18, 0x0F19, + 0x0F35, 0x0F35, + 0x0F37, 0x0F37, + 0x0F39, 0x0F39, + 0x0F71, 0x0F72, + 0x0F74, 0x0F74, + 0x0F7A, 0x0F7D, + 0x0F80, 0x0F80, + 0x0F82, 0x0F84, + 0x0F86, 0x0F87, + 0x0FC6, 0x0FC6, + 0x1037, 0x1037, + 0x1039, 0x103A, + 0x108D, 0x108D, + 0x135D, 0x135F, + 0x1714, 0x1714, + 0x17D2, 0x17D2, + 0x17DD, 0x17DD, + 0x18A9, 0x18A9, + 0x1939, 0x193B, + 0x1A17, 0x1A18, + 0x1A60, 0x1A60, + 0x1A75, 0x1A7C, + 0x1A7F, 0x1A7F, + 0x1AB0, 0x1ABD, + 0x1ABF, 0x1ACE, + 0x1B34, 0x1B34, + 0x1B6B, 0x1B73, + 0x1BAB, 0x1BAB, + 0x1BE6, 0x1BE6, + 0x1C37, 0x1C37, + 0x1CD0, 0x1CD2, + 0x1CD4, 0x1CE0, + 0x1CE2, 0x1CE8, + 0x1CED, 0x1CED, + 0x1CF4, 0x1CF4, + 0x1CF8, 0x1CF9, + 0x1DC0, 0x1DFF, + 0x200D, 0x200D, + 0x20D0, 0x20DC, + 0x20E1, 0x20E1, + 0x20E5, 0x20F0, + 0x2CEF, 0x2CF1, + 0x2D7F, 0x2D7F, + 0x2DE0, 0x2DFF, + 0x302A, 0x302D, + 0x302E, 0x302F, + 0x3099, 0x309A, + 0xA66F, 0xA66F, + 0xA674, 0xA67D, + 0xA69E, 0xA69F, + 0xA6F0, 0xA6F1, + 0xA82C, 0xA82C, + 0xA8E0, 0xA8F1, + 0xA92B, 0xA92D, + 0xA9B3, 0xA9B3, + 0xAAB0, 0xAAB0, + 0xAAB2, 0xAAB4, + 0xAAB7, 0xAAB8, + 0xAABE, 0xAABF, + 0xAAC1, 0xAAC1, + 0xAAF6, 0xAAF6, + 0xABED, 0xABED, + 0xFB1E, 0xFB1E, + 0xFE20, 0xFE2F, + 0x101FD, 0x101FD, + 0x102E0, 0x102E0, + 0x10376, 0x1037A, + 0x10A0D, 0x10A0D, + 0x10A0F, 0x10A0F, + 0x10A38, 0x10A3A, + 0x10A3F, 0x10A3F, + 0x10AE5, 0x10AE6, + 0x10D24, 0x10D27, + 0x10EAB, 0x10EAC, + 0x10EFD, 0x10EFF, + 0x10F46, 0x10F50, + 0x10F82, 0x10F85, + 0x11070, 0x11070, + 0x1107F, 0x1107F, + 0x110BA, 0x110BA, + 0x11100, 0x11102, + 0x11133, 0x11134, + 0x11173, 0x11173, + 0x111CA, 0x111CA, + 0x11236, 0x11236, + 0x112E9, 0x112EA, + 0x1133B, 0x1133C, + 0x11366, 0x1136C, + 0x11370, 0x11374, + 0x11446, 0x11446, + 0x1145E, 0x1145E, + 0x114C3, 0x114C3, + 0x115C0, 0x115C0, + 0x116B7, 0x116B7, + 0x1172B, 0x1172B, + 0x1183A, 0x1183A, + 0x1193E, 0x1193E, + 0x11943, 0x11943, + 0x11A34, 0x11A34, + 0x11A47, 0x11A47, + 0x11A99, 0x11A99, + 0x11D42, 0x11D42, + 0x11D44, 0x11D45, + 0x11D97, 0x11D97, + 0x11F42, 0x11F42, + 0x16AF0, 0x16AF4, + 0x16B30, 0x16B36, + 0x1BC9E, 0x1BC9E, + 0x1D165, 0x1D165, + 0x1D167, 0x1D169, + 0x1D16E, 0x1D172, + 0x1D17B, 0x1D182, + 0x1D185, 0x1D18B, + 0x1D1AA, 0x1D1AD, + 0x1D242, 0x1D244, + 0x1E000, 0x1E006, + 0x1E008, 0x1E018, + 0x1E01B, 0x1E021, + 0x1E023, 0x1E024, + 0x1E026, 0x1E02A, + 0x1E08F, 0x1E08F, + 0x1E130, 0x1E136, + 0x1E2AE, 0x1E2AE, + 0x1E2EC, 0x1E2EF, + 0x1E4EC, 0x1E4EF, + 0x1E8D0, 0x1E8D6, + 0x1E944, 0x1E94A, +}; + +// Fullwidth (F) and Wide (W) are counted as 2. +// Everything else is 1. +// +// Derived from: https://unicode.org/Public/15.1.0/ucd/EastAsianWidth.txt +static const int32_t ucg_normalized_east_asian_width_ranges[] = { + 0x0000, 0x10FF, 1, + 0x1100, 0x115F, 2, + 0x1160, 0x2319, 1, + 0x231A, 0x231B, 2, + 0x231C, 0x2328, 1, + 0x2329, 0x232A, 2, + 0x232B, 0x23E8, 1, + 0x23E9, 0x23EC, 2, + 0x23ED, 0x23EF, 1, + 0x23F0, 0x23F0, 2, + 0x23F1, 0x23F2, 1, + 0x23F3, 0x23F3, 2, + 0x23F4, 0x25FC, 1, + 0x25FD, 0x25FE, 2, + 0x25FF, 0x2613, 1, + 0x2614, 0x2615, 2, + 0x2616, 0x2647, 1, + 0x2648, 0x2653, 2, + 0x2654, 0x267E, 1, + 0x267F, 0x267F, 2, + 0x2680, 0x2692, 1, + 0x2693, 0x2693, 2, + 0x2694, 0x26A0, 1, + 0x26A1, 0x26A1, 2, + 0x26A2, 0x26A9, 1, + 0x26AA, 0x26AB, 2, + 0x26AC, 0x26BC, 1, + 0x26BD, 0x26BE, 2, + 0x26BF, 0x26C3, 1, + 0x26C4, 0x26C5, 2, + 0x26C6, 0x26CD, 1, + 0x26CE, 0x26CE, 2, + 0x26CF, 0x26D3, 1, + 0x26D4, 0x26D4, 2, + 0x26D5, 0x26E9, 1, + 0x26EA, 0x26EA, 2, + 0x26EB, 0x26F1, 1, + 0x26F2, 0x26F3, 2, + 0x26F4, 0x26F4, 1, + 0x26F5, 0x26F5, 2, + 0x26F6, 0x26F9, 1, + 0x26FA, 0x26FA, 2, + 0x26FB, 0x26FC, 1, + 0x26FD, 0x26FD, 2, + 0x26FE, 0x2704, 1, + 0x2705, 0x2705, 2, + 0x2706, 0x2709, 1, + 0x270A, 0x270B, 2, + 0x270C, 0x2727, 1, + 0x2728, 0x2728, 2, + 0x2729, 0x274B, 1, + 0x274C, 0x274C, 2, + 0x274D, 0x274D, 1, + 0x274E, 0x274E, 2, + 0x274F, 0x2752, 1, + 0x2753, 0x2755, 2, + 0x2756, 0x2756, 1, + 0x2757, 0x2757, 2, + 0x2758, 0x2794, 1, + 0x2795, 0x2797, 2, + 0x2798, 0x27AF, 1, + 0x27B0, 0x27B0, 2, + 0x27B1, 0x27BE, 1, + 0x27BF, 0x27BF, 2, + 0x27C0, 0x2B1A, 1, + 0x2B1B, 0x2B1C, 2, + 0x2B1D, 0x2B4F, 1, + 0x2B50, 0x2B50, 2, + 0x2B51, 0x2B54, 1, + 0x2B55, 0x2B55, 2, + 0x2B56, 0x2E5D, 1, + 0x2E80, 0x303E, 2, + 0x303F, 0x303F, 1, + 0x3041, 0x3247, 2, + 0x3248, 0x324F, 1, + 0x3250, 0x4DBF, 2, + 0x4DC0, 0x4DFF, 1, + 0x4E00, 0xA4C6, 2, + 0xA4D0, 0xA95F, 1, + 0xA960, 0xA97C, 2, + 0xA980, 0xABF9, 1, + 0xAC00, 0xD7A3, 2, + 0xD7B0, 0xF8FF, 1, + 0xF900, 0xFAFF, 2, + 0xFB00, 0xFE0F, 1, + 0xFE10, 0xFE19, 2, + 0xFE20, 0xFE2F, 1, + 0xFE30, 0xFE6B, 2, + 0xFE70, 0xFEFF, 1, + 0xFF01, 0xFF60, 2, + 0xFF61, 0xFFDC, 1, + 0xFFE0, 0xFFE6, 2, + 0xFFE8, 0x16F9F, 1, + 0x16FE0, 0x1B2FB, 2, + 0x1BC00, 0x1F003, 1, + 0x1F004, 0x1F004, 2, + 0x1F005, 0x1F0CE, 1, + 0x1F0CF, 0x1F0CF, 2, + 0x1F0D1, 0x1F18D, 1, + 0x1F18E, 0x1F18E, 2, + 0x1F18F, 0x1F190, 1, + 0x1F191, 0x1F19A, 2, + 0x1F19B, 0x1F1FF, 1, + 0x1F200, 0x1F320, 2, + 0x1F321, 0x1F32C, 1, + 0x1F32D, 0x1F335, 2, + 0x1F336, 0x1F336, 1, + 0x1F337, 0x1F37C, 2, + 0x1F37D, 0x1F37D, 1, + 0x1F37E, 0x1F393, 2, + 0x1F394, 0x1F39F, 1, + 0x1F3A0, 0x1F3CA, 2, + 0x1F3CB, 0x1F3CE, 1, + 0x1F3CF, 0x1F3D3, 2, + 0x1F3D4, 0x1F3DF, 1, + 0x1F3E0, 0x1F3F0, 2, + 0x1F3F1, 0x1F3F3, 1, + 0x1F3F4, 0x1F3F4, 2, + 0x1F3F5, 0x1F3F7, 1, + 0x1F3F8, 0x1F43E, 2, + 0x1F43F, 0x1F43F, 1, + 0x1F440, 0x1F440, 2, + 0x1F441, 0x1F441, 1, + 0x1F442, 0x1F4FC, 2, + 0x1F4FD, 0x1F4FE, 1, + 0x1F4FF, 0x1F53D, 2, + 0x1F53E, 0x1F54A, 1, + 0x1F54B, 0x1F54E, 2, + 0x1F54F, 0x1F54F, 1, + 0x1F550, 0x1F567, 2, + 0x1F568, 0x1F579, 1, + 0x1F57A, 0x1F57A, 2, + 0x1F57B, 0x1F594, 1, + 0x1F595, 0x1F596, 2, + 0x1F597, 0x1F5A3, 1, + 0x1F5A4, 0x1F5A4, 2, + 0x1F5A5, 0x1F5FA, 1, + 0x1F5FB, 0x1F64F, 2, + 0x1F650, 0x1F67F, 1, + 0x1F680, 0x1F6C5, 2, + 0x1F6C6, 0x1F6CB, 1, + 0x1F6CC, 0x1F6CC, 2, + 0x1F6CD, 0x1F6CF, 1, + 0x1F6D0, 0x1F6D2, 2, + 0x1F6D3, 0x1F6D4, 1, + 0x1F6D5, 0x1F6DF, 2, + 0x1F6E0, 0x1F6EA, 1, + 0x1F6EB, 0x1F6EC, 2, + 0x1F6F0, 0x1F6F3, 1, + 0x1F6F4, 0x1F6FC, 2, + 0x1F700, 0x1F7D9, 1, + 0x1F7E0, 0x1F7F0, 2, + 0x1F800, 0x1F90B, 1, + 0x1F90C, 0x1F93A, 2, + 0x1F93B, 0x1F93B, 1, + 0x1F93C, 0x1F945, 2, + 0x1F946, 0x1F946, 1, + 0x1F947, 0x1F9FF, 2, + 0x1FA00, 0x1FA6D, 1, + 0x1FA70, 0x1FAF8, 2, + 0x1FB00, 0x1FBF9, 1, + 0x20000, 0x3FFFD, 2, + 0xE0001, 0x10FFFD, 1, +}; + +// +// End of Unicode 15.1.0 block. +// + +#ifdef __cplusplus +} +#endif + +#endif /* _UCG_TABLES_INCLUDED */ diff --git a/src/unicode.cpp b/src/unicode.cpp index c244a323c..665d5b182 100644 --- a/src/unicode.cpp +++ b/src/unicode.cpp @@ -162,3 +162,8 @@ end: if (codepoint_out) *codepoint_out = codepoint; return width; } + +// NOTE(Feoramund): It's down here because I made UCG use the utf8_decode above to avoid duplicating code. +extern "C" { +#include "ucg/ucg.c" +} diff --git a/tests/core/encoding/hxa/test_core_hxa.odin b/tests/core/encoding/hxa/test_core_hxa.odin index 31d40c8b3..a8f3e94f6 100644 --- a/tests/core/encoding/hxa/test_core_hxa.odin +++ b/tests/core/encoding/hxa/test_core_hxa.odin @@ -134,14 +134,11 @@ test_write :: proc(t: ^testing.T) { testing.expectf(t, read_err == read_e, fmt.tprintf("read_err %v != %v", read_err, read_e)) defer hxa.file_destroy(file) - testing.expectf(t, file.magic_number == 0x417848, fmt.tprintf("file.magic_number %v != %v", - file.magic_number, 0x417848)) + testing.expectf(t, file.magic_number == 0x417848, fmt.tprintf("file.magic_number %v != %v", file.magic_number, 0x417848)) testing.expectf(t, file.version == 3, fmt.tprintf("file.version %v != %v", file.version, 3)) - testing.expectf(t, file.internal_node_count == 1, fmt.tprintf("file.internal_node_count %v != %v", - file.internal_node_count, 1)) + testing.expectf(t, file.internal_node_count == 1, fmt.tprintf("file.internal_node_count %v != %v", file.internal_node_count, 1)) - testing.expectf(t, len(file.nodes) == len(w_file.nodes), fmt.tprintf("len(file.nodes) %v != %v", - len(file.nodes), len(w_file.nodes))) + testing.expectf(t, len(file.nodes) == len(w_file.nodes), fmt.tprintf("len(file.nodes) %v != %v", len(file.nodes), len(w_file.nodes))) m := &file.nodes[0].meta_data w_m := &w_file.nodes[0].meta_data @@ -150,20 +147,16 @@ test_write :: proc(t: ^testing.T) { m_v, m_v_ok := m[0].value.([]f64le) testing.expectf(t, m_v_ok, fmt.tprintf("m_v_ok %v != %v", m_v_ok, true)) - testing.expectf(t, len(m_v) == len(n1_m1_value), fmt.tprintf("%v != len(m_v) %v", - len(m_v), len(n1_m1_value))) + testing.expectf(t, len(m_v) == len(n1_m1_value), fmt.tprintf("%v != len(m_v) %v", len(m_v), len(n1_m1_value))) for i := 0; i < len(m_v); i += 1 { - testing.expectf(t, m_v[i] == n1_m1_value[i], fmt.tprintf("m_v[%d] %v != %v", - i, m_v[i], n1_m1_value[i])) + testing.expectf(t, m_v[i] == n1_m1_value[i], fmt.tprintf("m_v[%d] %v != %v", i, m_v[i], n1_m1_value[i])) } v, v_ok := file.nodes[0].content.(hxa.Node_Image) testing.expectf(t, v_ok, fmt.tprintf("v_ok %v != %v", v_ok, true)) testing.expectf(t, v.type == n1_content.type, fmt.tprintf("v.type %v != %v", v.type, n1_content.type)) - testing.expectf(t, len(v.resolution) == 3, fmt.tprintf("len(v.resolution) %v != %v", - len(v.resolution), 3)) - testing.expectf(t, len(v.image_stack) == len(n1_content.image_stack), fmt.tprintf("len(v.image_stack) %v != %v", - len(v.image_stack), len(n1_content.image_stack))) + testing.expectf(t, len(v.resolution) == 3, fmt.tprintf("len(v.resolution) %v != %v", len(v.resolution), 3)) + testing.expectf(t, len(v.image_stack) == len(n1_content.image_stack), fmt.tprintf("len(v.image_stack) %v != %v", len(v.image_stack), len(n1_content.image_stack))) for i := 0; i < len(v.image_stack); i += 1 { testing.expectf(t, v.image_stack[i].name == n1_content.image_stack[i].name, fmt.tprintf("v.image_stack[%d].name %v != %v", @@ -182,8 +175,7 @@ test_write :: proc(t: ^testing.T) { testing.expectf(t, l_ok, fmt.tprintf("l_ok %v != %v", l_ok, true)) testing.expectf(t, len(l) == len(n1_t), fmt.tprintf("len(l) %v != %v", len(l), len(n1_t))) for j := 0; j < len(l); j += 1 { - testing.expectf(t, l[j] == n1_t[j], fmt.tprintf("l[%d] %v (%h) != %v (%h)", - j, l[j], l[j], n1_t[j], n1_t[j])) + testing.expectf(t, l[j] == n1_t[j], fmt.tprintf("l[%d] %v (%h) != %v (%h)", j, l[j], l[j], n1_t[j], n1_t[j])) } case []f64le: l, l_ok := v.image_stack[i].data.([]f64le) diff --git a/tests/core/encoding/uuid/test_core_uuid.odin b/tests/core/encoding/uuid/test_core_uuid.odin new file mode 100644 index 000000000..619534a7f --- /dev/null +++ b/tests/core/encoding/uuid/test_core_uuid.odin @@ -0,0 +1,439 @@ +package test_core_uuid + +import "core:crypto" +import "core:encoding/uuid" +import uuid_legacy "core:encoding/uuid/legacy" +import "core:log" +import "core:slice" +import "core:testing" +import "core:time" + +@(test) +test_version_and_variant :: proc(t: ^testing.T) { + context.random_generator = crypto.random_generator() + + v1 := uuid.generate_v1(0) + v3 := uuid_legacy.generate_v3(uuid.Namespace_DNS, "") + v4 := uuid.generate_v4() + v5 := uuid_legacy.generate_v5(uuid.Namespace_DNS, "") + v6 := uuid.generate_v6() + v7 := uuid.generate_v7() + + _v8_array: [16]u8 = 0xff + v8_int := uuid.stamp_v8(max(u128)) + v8_array := uuid.stamp_v8(_v8_array) + v8_slice := uuid.stamp_v8(_v8_array[:]) + + v8_hash := uuid.generate_v8_hash(uuid.Namespace_DNS, "", .SHA512) + + testing.expect_value(t, uuid.version(v1), 1) + testing.expect_value(t, uuid.variant(v1), uuid.Variant_Type.RFC_4122) + testing.expect_value(t, uuid.version(v3), 3) + testing.expect_value(t, uuid.variant(v3), uuid.Variant_Type.RFC_4122) + testing.expect_value(t, uuid.version(v4), 4) + testing.expect_value(t, uuid.variant(v4), uuid.Variant_Type.RFC_4122) + testing.expect_value(t, uuid.version(v5), 5) + testing.expect_value(t, uuid.variant(v5), uuid.Variant_Type.RFC_4122) + testing.expect_value(t, uuid.version(v6), 6) + testing.expect_value(t, uuid.variant(v6), uuid.Variant_Type.RFC_4122) + testing.expect_value(t, uuid.version(v7), 7) + testing.expect_value(t, uuid.variant(v7), uuid.Variant_Type.RFC_4122) + + testing.expect_value(t, uuid.version(v8_int), 8) + testing.expect_value(t, uuid.variant(v8_int), uuid.Variant_Type.RFC_4122) + testing.expect_value(t, uuid.version(v8_array), 8) + testing.expect_value(t, uuid.variant(v8_array), uuid.Variant_Type.RFC_4122) + testing.expect_value(t, uuid.version(v8_slice), 8) + testing.expect_value(t, uuid.variant(v8_slice), uuid.Variant_Type.RFC_4122) + + testing.expect_value(t, uuid.version(v8_hash), 8) + testing.expect_value(t, uuid.variant(v8_hash), uuid.Variant_Type.RFC_4122) +} + +@(test) +test_timestamps :: proc(t: ^testing.T) { + // This test makes sure that timestamps are recoverable and have not been + // overwritten by neighboring bits, taking into account precision loss. + context.random_generator = crypto.random_generator() + + N :: max(i64) + + max_time := time.Time { N } + + mac: [6]byte + v1 := uuid.generate_v1(0, mac, max_time) + v6 := uuid.generate_v6(0, mac, max_time) + v7 := uuid.generate_v7(max_time) + // The counter version keeps its time in the same place as the basic version, + // this is just for the sake of completeness. + v7_counter := uuid.generate_v7(0, max_time) + + v1_time := uuid.time_v1(v1) + v6_time := uuid.time_v6(v6) + v7_time := uuid.time_v7(v7) + v7_counter_time := uuid.time_v7(v7_counter) + + // I hope the compiler doesn't ever optimize this out. + max_time_hns_resolution := time.Time { N / 100 * 100 } + max_time_ms_resolution := time.Time { N / 1e6 * 1e6 } + + testing.expectf(t, + time.diff(max_time_hns_resolution, v1_time) == 0, + "v1 UUID timestamp is invalid, expected %x, got %x", + max_time_hns_resolution, v1_time) + + testing.expectf(t, + time.diff(max_time_hns_resolution, v6_time) == 0, + "v6 UUID timestamp is invalid, expected %x, got %x", + max_time_hns_resolution, v6_time) + + testing.expectf(t, + time.diff(max_time_ms_resolution, v7_time) == 0, + "v7 UUID timestamp is invalid, expected %x, got %x", + max_time_ms_resolution, v7_time) + + testing.expectf(t, + time.diff(max_time_ms_resolution, v7_counter_time) == 0, + "v7 UUID (with counter) timestamp is invalid, expected %x, got %x", + max_time_ms_resolution, v7_counter_time) +} + +@(test) +test_v8_hash_implementation :: proc(t: ^testing.T) { + // This example and its results are derived from RFC 9562. + // https://www.rfc-editor.org/rfc/rfc9562.html#name-example-of-a-uuidv8-value-n + + id := uuid.generate_v8_hash(uuid.Namespace_DNS, "www.example.com", .SHA256) + id_str := uuid.to_string(id) + defer delete(id_str) + testing.expect_value(t, id_str, "5c146b14-3c52-8afd-938a-375d0df1fbf6") +} + +@(test) +test_legacy_namespaced_uuids :: proc(t: ^testing.T) { + TEST_NAME :: "0123456789ABCDEF0123456789ABCDEF" + + Expected_Result :: struct { + namespace: uuid.Identifier, + v3, v5: string, + } + + Expected_Results := [?]Expected_Result { + { uuid.Namespace_DNS, "80147f37-36db-3b82-b78f-810c3c6504ba", "18394c41-13a2-593f-abf2-a63e163c2860" }, + { uuid.Namespace_URL, "8136789b-8e16-3fbd-800b-1587e2f22521", "07337422-eb77-5fd3-99af-c7f59e641e13" }, + { uuid.Namespace_OID, "adbb95bc-ea50-3226-9a75-20c34a6030f8", "24db9b0f-70b8-53c4-a301-f695ce17276d" }, + { uuid.Namespace_X500, "a8965ad1-0e54-3d65-b933-8b7cca8e8313", "3012bf2d-fac4-5187-9825-493e6636b936" }, + } + + for exp in Expected_Results { + v3 := uuid_legacy.generate_v3(exp.namespace, TEST_NAME) + v5 := uuid_legacy.generate_v5(exp.namespace, TEST_NAME) + + v3_str := uuid.to_string(v3) + defer delete(v3_str) + + v5_str := uuid.to_string(v5) + defer delete(v5_str) + + testing.expect_value(t, v3_str, exp.v3) + testing.expect_value(t, v5_str, exp.v5) + } +} + +@(test) +test_v1 :: proc(t: ^testing.T) { + context.random_generator = crypto.random_generator() + + point_a := time.unix(1, 0) + point_b := time.unix(3, 0) + point_c := time.unix(5, 0) + + CLOCK :: 0x3A1A + mac := [6]u8{0xFF, 0x10, 0xAA, 0x55, 0x01, 0xFF} + + v1_a := uuid.generate_v1(CLOCK, mac, point_a) + v1_b := uuid.generate_v1(CLOCK, mac, point_b) + v1_c := uuid.generate_v1(CLOCK, mac, point_c) + + testing.expect_value(t, uuid.clock_seq(v1_a), CLOCK) + + extracted_mac := uuid.node(v1_a) + for i in 0 ..< len(mac) { + testing.expect(t, mac[i] == extracted_mac[i]) + } + + time_a := uuid.time_v1(v1_a) + time_b := uuid.time_v1(v1_b) + time_c := uuid.time_v1(v1_c) + + log.debugf("A: %02x, %v", v1_a, time_a) + log.debugf("B: %02x, %v", v1_b, time_b) + log.debugf("C: %02x, %v", v1_c, time_c) + + testing.expect(t, time.diff(time_a, time_b) > 0, "The time on the later-generated v1 UUID is earlier than its successor.") + testing.expect(t, time.diff(time_b, time_c) > 0, "The time on the later-generated v1 UUID is earlier than its successor.") + testing.expect(t, time.diff(time_a, time_c) > 0, "The time on the later-generated v1 UUID is earlier than its successor.") +} + +@(test) +test_v6 :: proc(t: ^testing.T) { + context.random_generator = crypto.random_generator() + + point_a := time.unix(1, 0) + point_b := time.unix(3, 0) + point_c := time.unix(5, 0) + + CLOCK :: 0x3A1A + mac := [6]u8{0xFF, 0x10, 0xAA, 0x55, 0x01, 0xFF} + + v6_a := uuid.generate_v6(CLOCK, mac, point_a) + v6_b := uuid.generate_v6(CLOCK, mac, point_b) + v6_c := uuid.generate_v6(CLOCK, mac, point_c) + + testing.expect_value(t, uuid.clock_seq(v6_a), CLOCK) + + extracted_mac := uuid.node(v6_a) + for i in 0 ..< len(mac) { + testing.expect(t, mac[i] == extracted_mac[i]) + } + + time_a := uuid.time_v6(v6_a) + time_b := uuid.time_v6(v6_b) + time_c := uuid.time_v6(v6_c) + + log.debugf("A: %02x, %v", v6_a, time_a) + log.debugf("B: %02x, %v", v6_b, time_b) + log.debugf("C: %02x, %v", v6_c, time_c) + + testing.expect(t, time.diff(time_a, time_b) > 0, "The time on the later-generated v6 UUID is earlier than its successor.") + testing.expect(t, time.diff(time_b, time_c) > 0, "The time on the later-generated v6 UUID is earlier than its successor.") + testing.expect(t, time.diff(time_a, time_c) > 0, "The time on the later-generated v6 UUID is earlier than its successor.") +} + +@(test) +test_v7 :: proc(t: ^testing.T) { + context.random_generator = crypto.random_generator() + + point_a := time.unix(1, 0) + point_b := time.unix(3, 0) + point_c := time.unix(5, 0) + + v7_a := uuid.generate_v7(point_a) + v7_b := uuid.generate_v7(point_b) + v7_c := uuid.generate_v7(point_c) + + time_a := uuid.time_v7(v7_a) + time_b := uuid.time_v7(v7_b) + time_c := uuid.time_v7(v7_c) + + log.debugf("A: %02x, %v", v7_a, time_a) + log.debugf("B: %02x, %v", v7_b, time_b) + log.debugf("C: %02x, %v", v7_c, time_c) + + testing.expect(t, time.diff(time_a, time_b) > 0, "The time on the later-generated v7 UUID is earlier than its successor.") + testing.expect(t, time.diff(time_b, time_c) > 0, "The time on the later-generated v7 UUID is earlier than its successor.") + testing.expect(t, time.diff(time_a, time_c) > 0, "The time on the later-generated v7 UUID is earlier than its successor.") + + v7_with_counter := uuid.generate_v7(0x555) + log.debugf("D: %02x", v7_with_counter) + testing.expect_value(t, uuid.counter_v7(v7_with_counter), 0x555) +} + +@(test) +test_sorting_v1 :: proc(t: ^testing.T) { + // This test is to make sure that the v1 UUIDs do _not_ sort. + // They are incapable of sorting properly by the nature their time bit ordering. + // + // Something is very strange if they do sort correctly. + point_a := time.unix(1, 0) + point_b := time.unix(3, 0) + point_c := time.unix(5, 0) + point_d := time.unix(7, 0) + point_e := time.unix(11, 0) + + mac: [6]byte + v1_a := uuid.generate_v1(0, mac, point_a) + v1_b := uuid.generate_v1(0, mac, point_b) + v1_c := uuid.generate_v1(0, mac, point_c) + v1_d := uuid.generate_v1(0, mac, point_d) + v1_e := uuid.generate_v1(0, mac, point_e) + + sort_test := [5]u128be { + transmute(u128be)v1_e, + transmute(u128be)v1_a, + transmute(u128be)v1_d, + transmute(u128be)v1_b, + transmute(u128be)v1_c, + } + + log.debugf("Before: %x", sort_test) + slice.sort(sort_test[:]) + log.debugf("After: %x", sort_test) + + ERROR :: "v1 UUIDs are sorting by time, despite this not being possible." + + testing.expect(t, sort_test[0] != transmute(u128be)v1_a, ERROR) + testing.expect(t, sort_test[1] != transmute(u128be)v1_b, ERROR) + testing.expect(t, sort_test[2] != transmute(u128be)v1_c, ERROR) + testing.expect(t, sort_test[3] != transmute(u128be)v1_d, ERROR) + testing.expect(t, sort_test[4] != transmute(u128be)v1_e, ERROR) +} + +@(test) +test_sorting_v6 :: proc(t: ^testing.T) { + context.random_generator = crypto.random_generator() + + point_a := time.unix(1, 0) + point_b := time.unix(3, 0) + point_c := time.unix(5, 0) + point_d := time.unix(7, 0) + point_e := time.unix(11, 0) + + mac: [6]byte + v6_a := uuid.generate_v6(0, mac, point_a) + v6_b := uuid.generate_v6(0, mac, point_b) + v6_c := uuid.generate_v6(0, mac, point_c) + v6_d := uuid.generate_v6(0, mac, point_d) + v6_e := uuid.generate_v6(0, mac, point_e) + + sort_test := [5]u128be { + transmute(u128be)v6_e, + transmute(u128be)v6_a, + transmute(u128be)v6_d, + transmute(u128be)v6_b, + transmute(u128be)v6_c, + } + + log.debugf("Before: %x", sort_test) + slice.sort(sort_test[:]) + log.debugf("After: %x", sort_test) + + ERROR :: "v6 UUIDs are failing to sort properly." + + testing.expect(t, sort_test[0] < sort_test[1], ERROR) + testing.expect(t, sort_test[1] < sort_test[2], ERROR) + testing.expect(t, sort_test[2] < sort_test[3], ERROR) + testing.expect(t, sort_test[3] < sort_test[4], ERROR) + + testing.expect(t, sort_test[0] == transmute(u128be)v6_a, ERROR) + testing.expect(t, sort_test[1] == transmute(u128be)v6_b, ERROR) + testing.expect(t, sort_test[2] == transmute(u128be)v6_c, ERROR) + testing.expect(t, sort_test[3] == transmute(u128be)v6_d, ERROR) + testing.expect(t, sort_test[4] == transmute(u128be)v6_e, ERROR) +} + +@(test) +test_sorting_v7 :: proc(t: ^testing.T) { + context.random_generator = crypto.random_generator() + + point_a := time.unix(1, 0) + point_b := time.unix(3, 0) + point_c := time.unix(5, 0) + point_d := time.unix(7, 0) + point_e := time.unix(11, 0) + + v7_a := uuid.generate_v7(point_a) + v7_b := uuid.generate_v7(point_b) + v7_c := uuid.generate_v7(point_c) + v7_d := uuid.generate_v7(point_d) + v7_e := uuid.generate_v7(point_e) + + sort_test := [5]u128be { + transmute(u128be)v7_e, + transmute(u128be)v7_a, + transmute(u128be)v7_d, + transmute(u128be)v7_b, + transmute(u128be)v7_c, + } + + log.debugf("Before: %x", sort_test) + slice.sort(sort_test[:]) + log.debugf("After: %x", sort_test) + + ERROR :: "v7 UUIDs are failing to sort properly." + + testing.expect(t, sort_test[0] < sort_test[1], ERROR) + testing.expect(t, sort_test[1] < sort_test[2], ERROR) + testing.expect(t, sort_test[2] < sort_test[3], ERROR) + testing.expect(t, sort_test[3] < sort_test[4], ERROR) + + testing.expect(t, sort_test[0] == transmute(u128be)v7_a, ERROR) + testing.expect(t, sort_test[1] == transmute(u128be)v7_b, ERROR) + testing.expect(t, sort_test[2] == transmute(u128be)v7_c, ERROR) + testing.expect(t, sort_test[3] == transmute(u128be)v7_d, ERROR) + testing.expect(t, sort_test[4] == transmute(u128be)v7_e, ERROR) +} + +@(test) +test_writing :: proc(t: ^testing.T) { + id: uuid.Identifier + + for &b, i in id { + b = u8(i) + } + + buf: [uuid.EXPECTED_LENGTH]u8 + + s_alloc := uuid.to_string(id) + defer delete(s_alloc) + + s_buf := uuid.to_string(id, buf[:]) + + testing.expect_value(t, s_alloc, "00010203-0405-0607-0809-0a0b0c0d0e0f") + testing.expect_value(t, s_buf, "00010203-0405-0607-0809-0a0b0c0d0e0f") +} + +@(test) +test_reading :: proc(t: ^testing.T) { + id, err := uuid.read("00010203-0405-0607-0809-0a0b0c0d0e0f") + testing.expect_value(t, err, nil) + + for b, i in id { + testing.expect_value(t, b, u8(i)) + } +} + +@(test) +test_reading_errors :: proc(t: ^testing.T) { + { + BAD_STRING :: "|.......@....@....@....@............" + _, err := uuid.read(BAD_STRING) + testing.expect_value(t, err, uuid.Read_Error.Invalid_Separator) + } + + { + BAD_STRING :: "|.......-....-....-....-............" + _, err := uuid.read(BAD_STRING) + testing.expect_value(t, err, uuid.Read_Error.Invalid_Hexadecimal) + } + + { + BAD_STRING :: ".......-....-....-....-............" + _, err := uuid.read(BAD_STRING) + testing.expect_value(t, err, uuid.Read_Error.Invalid_Length) + } + + { + BAD_STRING :: "|.......-....-....-....-............|" + _, err := uuid.read(BAD_STRING) + testing.expect_value(t, err, uuid.Read_Error.Invalid_Length) + } + + { + BAD_STRING :: "00000000-0000-0000-0000-0000000000001" + _, err := uuid.read(BAD_STRING) + testing.expect_value(t, err, uuid.Read_Error.Invalid_Length) + } + + { + BAD_STRING :: "00000000000000000000000000000000" + _, err := uuid.read(BAD_STRING) + testing.expect_value(t, err, uuid.Read_Error.Invalid_Length) + } + + { + OK_STRING :: "00000000-0000-0000-0000-000000000000" + _, err := uuid.read(OK_STRING) + testing.expect_value(t, err, nil) + } +} diff --git a/tests/core/net/test_core_net.odin b/tests/core/net/test_core_net.odin index f806463e9..a8f41082a 100644 --- a/tests/core/net/test_core_net.odin +++ b/tests/core/net/test_core_net.odin @@ -18,6 +18,7 @@ import "core:sync" import "core:time" import "core:thread" import "core:fmt" +import "core:log" @test address_parsing_test :: proc(t: ^testing.T) { @@ -216,6 +217,8 @@ IP_Address_Parsing_Test_Vectors :: []IP_Address_Parsing_Test_Vector{ ENDPOINT_TWO_SERVERS := net.Endpoint{net.IP4_Address{127, 0, 0, 1}, 9991} ENDPOINT_CLOSED_PORT := net.Endpoint{net.IP4_Address{127, 0, 0, 1}, 9992} ENDPOINT_SERVER_SENDS := net.Endpoint{net.IP4_Address{127, 0, 0, 1}, 9993} +ENDPOINT_UDP_ECHO := net.Endpoint{net.IP4_Address{127, 0, 0, 1}, 9994} +ENDPOINT_NONBLOCK := net.Endpoint{net.IP4_Address{127, 0, 0, 1}, 9995} @(test) two_servers_binding_same_endpoint :: proc(t: ^testing.T) { @@ -256,7 +259,7 @@ client_sends_server_data :: proc(t: ^testing.T) { } tcp_client :: proc(thread_data: rawptr) { - r := transmute(^Thread_Data)thread_data + r := cast(^Thread_Data)thread_data defer sync.wait_group_done(r.wg) @@ -271,7 +274,7 @@ client_sends_server_data :: proc(t: ^testing.T) { } tcp_server :: proc(thread_data: rawptr) { - r := transmute(^Thread_Data)thread_data + r := cast(^Thread_Data)thread_data defer sync.wait_group_done(r.wg) @@ -516,6 +519,102 @@ join_url_test :: proc(t: ^testing.T) { } } +@test +test_udp_echo :: proc(t: ^testing.T) { + server, make_server_err := net.make_unbound_udp_socket(.IP4) + if !testing.expect_value(t, make_server_err, nil) { + return + } + defer net.close(server) + + bind_server_err := net.bind(server, ENDPOINT_UDP_ECHO) + if !testing.expect_value(t, bind_server_err, nil) { + return + } + + client, make_client_err := net.make_unbound_udp_socket(.IP4) + if !testing.expect_value(t, make_client_err, nil) { + return + } + defer net.close(client) + + msg := "Hellope world!" + buf: [64]u8 + + bytes_written, send_err := net.send_udp(client, transmute([]u8)msg[:], ENDPOINT_UDP_ECHO) + if !testing.expect_value(t, send_err, nil) { + return + } + if !testing.expect_value(t, bytes_written, len(msg)) { + return + } + + bytes_read, _, read_err := net.recv_udp(server, buf[:]) + if !testing.expect_value(t, read_err, nil) { + return + } + if !testing.expect_value(t, bytes_read, len(msg)) { + return + } + + testing.expect_value(t, msg, transmute(string)buf[:bytes_read]) +} + +@test +test_dns_resolve :: proc(t: ^testing.T) { + // NOTE: This test depends on external factors, so if it fails, an IP + // address may have changed or become unavailable. + + // The net API returns only one address per protocol version, and DNS + // records can store many, so we'll have to check all possibilities. + ep4, ep6, resolve_err := net.resolve("dns.quad9.net") + if !testing.expect_value(t, resolve_err, nil) { + return + } + + ip4, ip4_ok := ep4.address.(net.IP4_Address) + if !testing.expect(t, ip4_ok, "Unable to resolve IP4") { + return + } + + valid_ip4_a := net.IP4_Address{ 9, 9, 9, 9} + valid_ip4_b := net.IP4_Address{149, 112, 112, 112} + if ip4 != valid_ip4_a && ip4 != valid_ip4_b { + log.errorf("DNS resolved to invalid IP4: %v, expected %v or %v", ip4, valid_ip4_a, valid_ip4_b) + } + + ip6, ip6_ok := ep6.address.(net.IP6_Address) + if !testing.expect(t, ip6_ok, "Unable to resolve IP6") { + return + } + + valid_ip6_a := net.IP6_Address{0x2620, 0xfe, 0, 0, 0, 0, 0, 9} + valid_ip6_b := net.IP6_Address{0x2620, 0xfe, 0, 0, 0, 0, 0, 0xfe} + if ip6 != valid_ip6_a && ip6 != valid_ip6_b { + log.errorf("DNS resolved to invalid IP6: %v, expected %v or %v", ip6, valid_ip6_a, valid_ip6_b) + } +} + +@test +test_nonblocking_option :: proc(t: ^testing.T) { + server, listen_err := net.listen_tcp(ENDPOINT_NONBLOCK) + if !testing.expect_value(t, listen_err, nil) { + return + } + defer net.close(server) + + testing.set_fail_timeout(t, 2 * time.Second) + + // If the nonblocking option isn't set correctly in the operating system, + // this should block until the timeout hits. + net.set_blocking(server, false) + + _, _, accept_err := net.accept_tcp(server) + if !testing.expect_value(t, accept_err, net.Accept_Error.Would_Block) { + return + } +} + @(private) address_to_binstr :: proc(address: net.Address) -> (binstr: string) { switch t in address { diff --git a/tests/core/normal.odin b/tests/core/normal.odin index a84420cca..065090be3 100644 --- a/tests/core/normal.odin +++ b/tests/core/normal.odin @@ -17,6 +17,7 @@ download_assets :: proc() { @(require) import "encoding/hex" @(require) import "encoding/hxa" @(require) import "encoding/json" +@(require) import "encoding/uuid" @(require) import "encoding/varint" @(require) import "encoding/xml" @(require) import "flags" diff --git a/tests/core/path/filepath/test_core_filepath.odin b/tests/core/path/filepath/test_core_filepath.odin index 94b9329bb..f0137f69b 100644 --- a/tests/core/path/filepath/test_core_filepath.odin +++ b/tests/core/path/filepath/test_core_filepath.odin @@ -35,12 +35,10 @@ test_split_list_windows :: proc(t: ^testing.T) { assert(i == d.i, fmt.tprintf("wrong data index: i %d != d.i %d\n", i, d.i)) r := filepath.split_list(d.v) defer delete_split(r) - testing.expect(t, len(r) == len(d.e), fmt.tprintf("i:%d %s(%s) len(r) %d != len(d.e) %d", - i, #procedure, d.v, len(r), len(d.e))) + testing.expect(t, len(r) == len(d.e), fmt.tprintf("i:%d %s(%s) len(r) %d != len(d.e) %d", i, #procedure, d.v, len(r), len(d.e))) if len(r) == len(d.e) { for _, j in r { - testing.expect(t, r[j] == d.e[j], fmt.tprintf("i:%d %s(%v) -> %v[%d] != %v", - i, #procedure, d.v, r[j], j, d.e[j])) + testing.expect(t, r[j] == d.e[j], fmt.tprintf("i:%d %s(%v) -> %v[%d] != %v", i, #procedure, d.v, r[j], j, d.e[j])) } } } diff --git a/vendor/ENet/unix.odin b/vendor/ENet/unix.odin index 0bbfce20a..0e3399aeb 100644 --- a/vendor/ENet/unix.odin +++ b/vendor/ENet/unix.odin @@ -23,7 +23,7 @@ import "core:c" } @(private="file") FD_CLR :: #force_inline proc(d: i32, s: ^fd_set) { - s.fds_bits[d / (8 * size_of(c.long))] &= ~(c.ulong(1) << (c.ulong(d) % (8 * size_of(c.ulong)))) + s.fds_bits[d / (8 * size_of(c.long))] &~= c.ulong(1) << (c.ulong(d) % (8 * size_of(c.ulong))) } @(private="file") FD_ISSET :: #force_inline proc(d: i32, s: ^fd_set) -> bool { diff --git a/vendor/ENet/win32.odin b/vendor/ENet/win32.odin index 1df35ee45..d05cf5d99 100644 --- a/vendor/ENet/win32.odin +++ b/vendor/ENet/win32.odin @@ -39,7 +39,9 @@ foreign WinSock2 { return } } - if s.fd_count >= FD_SETSIZE do return + if s.fd_count >= FD_SETSIZE { + return + } s.fd_array[s.fd_count] = fd s.fd_count += 1 } diff --git a/vendor/OpenGL/wrappers.odin b/vendor/OpenGL/wrappers.odin index a04df6987..1eb8fc72f 100644 --- a/vendor/OpenGL/wrappers.odin +++ b/vendor/OpenGL/wrappers.odin @@ -454,20 +454,13 @@ when !GL_DEBUG { BeginQueryIndexed :: proc "c" (target: u32, index: u32, id: u32) { impl_BeginQueryIndexed(target, index, id) } EndQueryIndexed :: proc "c" (target: u32, index: u32) { impl_EndQueryIndexed(target, index) } GetQueryIndexediv :: proc "c" (target: u32, index: u32, pname: u32, params: [^]i32) { impl_GetQueryIndexediv(target, index, pname, params) } - GetTextureHandleARB :: proc "c" (texture: u32) -> u64 - { return impl_GetTextureHandleARB(texture) } - GetTextureSamplerHandleARB :: proc "c" (texture, sampler: u32) -> u64 - { return impl_GetTextureSamplerHandleARB(texture, sampler) } - GetImageHandleARB :: proc "c" (texture: u32, level: i32, layered: bool, layer: i32, format: u32) -> u64 - { return impl_GetImageHandleARB(texture, level, layered, layer, format) } - MakeTextureHandleResidentARB :: proc "c" (handle: u64) - { impl_MakeTextureHandleResidentARB(handle) } - MakeImageHandleResidentARB :: proc "c" (handle: u64, access: u32) - { impl_MakeImageHandleResidentARB(handle, access) } - MakeTextureHandleNonResidentARB:: proc "c" (handle: u64) - { impl_MakeTextureHandleNonResidentARB(handle) } - MakeImageHandleNonResidentARB :: proc "c" (handle: u64) - { impl_MakeImageHandleNonResidentARB(handle) } + GetTextureHandleARB :: proc "c" (texture: u32) -> u64 { return impl_GetTextureHandleARB(texture) } + GetTextureSamplerHandleARB :: proc "c" (texture, sampler: u32) -> u64 { return impl_GetTextureSamplerHandleARB(texture, sampler) } + GetImageHandleARB :: proc "c" (texture: u32, level: i32, layered: bool, layer: i32, format: u32) -> u64 { return impl_GetImageHandleARB(texture, level, layered, layer, format) } + MakeTextureHandleResidentARB :: proc "c" (handle: u64) { impl_MakeTextureHandleResidentARB(handle) } + MakeImageHandleResidentARB :: proc "c" (handle: u64, access: u32) { impl_MakeImageHandleResidentARB(handle, access) } + MakeTextureHandleNonResidentARB:: proc "c" (handle: u64) { impl_MakeTextureHandleNonResidentARB(handle) } + MakeImageHandleNonResidentARB :: proc "c" (handle: u64) { impl_MakeImageHandleNonResidentARB(handle) } // VERSION_4_1 ReleaseShaderCompiler :: proc "c" () { impl_ReleaseShaderCompiler() } @@ -788,17 +781,17 @@ when !GL_DEBUG { { // add input arguments for arg, arg_index in args[num_ret:] { - if arg_index > 0 { fmt.printf(", ") } + if arg_index > 0 { fmt.printf(", ") } - if v, ok := arg.(u32); ok { // TODO: Assumes all u32 are GLenum (they're not, GLbitfield and GLuint are also mapped to u32), fix later by better typing - if err == .INVALID_ENUM { - fmt.printf("INVALID_ENUM=%d", v) + if v, ok := arg.(u32); ok { // TODO: Assumes all u32 are GLenum (they're not, GLbitfield and GLuint are also mapped to u32), fix later by better typing + if err == .INVALID_ENUM { + fmt.printf("INVALID_ENUM=%d", v) + } else { + fmt.printf("GL_%v=%d", GL_Enum(v), v) + } } else { - fmt.printf("GL_%v=%d", GL_Enum(v), v) + fmt.printf("%v", arg) } - } else { - fmt.printf("%v", arg) - } } // add return arguments @@ -817,7 +810,7 @@ when !GL_DEBUG { } // add location - fmt.printf(" in: %s(%d:%d)\n", from_loc.file_path, from_loc.line, from_loc.column) + fmt.printf(" in: %s(%d:%d)\n", from_loc.file_path, from_loc.line, from_loc.column) } } @@ -1265,20 +1258,13 @@ when !GL_DEBUG { BeginQueryIndexed :: proc "c" (target: u32, index: u32, id: u32, loc := #caller_location) { impl_BeginQueryIndexed(target, index, id); debug_helper(loc, 0, target, index, id) } EndQueryIndexed :: proc "c" (target: u32, index: u32, loc := #caller_location) { impl_EndQueryIndexed(target, index); debug_helper(loc, 0, target, index) } GetQueryIndexediv :: proc "c" (target: u32, index: u32, pname: u32, params: [^]i32, loc := #caller_location) { impl_GetQueryIndexediv(target, index, pname, params); debug_helper(loc, 0, target, index, pname, params) } - GetTextureHandleARB :: proc "c" (target: u32, loc := #caller_location) -> u64 - { ret := impl_GetTextureHandleARB(target); debug_helper(loc, 0, target); return ret } - GetTextureSamplerHandleARB :: proc "c" (texture, sampler: u32, loc := #caller_location) -> u64 - { ret := impl_GetTextureSamplerHandleARB(texture, sampler); debug_helper(loc, 0, texture, sampler); return ret } - GetImageHandleARB :: proc "c" (texture: u32, level: i32, layered: bool, layer: i32, format: u32, loc := #caller_location) -> u64 - { ret := impl_GetImageHandleARB(texture, level, layered, layer, format); debug_helper(loc, 0, texture, level, layered, layer, format); return ret } - MakeTextureHandleResidentARB :: proc "c" (handle: u64, loc := #caller_location) - { impl_MakeTextureHandleResidentARB(handle); debug_helper(loc, 0, handle) } - MakeImageHandleResidentARB :: proc "c" (handle: u64, access: u32, loc := #caller_location) - { impl_MakeImageHandleResidentARB(handle, access); debug_helper(loc, 0, handle, access) } - MakeTextureHandleNonResidentARB:: proc "c" (handle: u64, loc := #caller_location) - { impl_MakeTextureHandleNonResidentARB(handle); debug_helper(loc, 0, handle) } - MakeImageHandleNonResidentARB :: proc "c" (handle: u64, loc := #caller_location) - { impl_MakeImageHandleNonResidentARB(handle); debug_helper(loc, 0, handle) } + GetTextureHandleARB :: proc "c" (target: u32, loc := #caller_location) -> u64 { ret := impl_GetTextureHandleARB(target); debug_helper(loc, 0, target); return ret } + GetTextureSamplerHandleARB :: proc "c" (texture, sampler: u32, loc := #caller_location) -> u64 { ret := impl_GetTextureSamplerHandleARB(texture, sampler); debug_helper(loc, 0, texture, sampler); return ret } + GetImageHandleARB :: proc "c" (texture: u32, level: i32, layered: bool, layer: i32, format: u32, loc := #caller_location) -> u64 { ret := impl_GetImageHandleARB(texture, level, layered, layer, format); debug_helper(loc, 0, texture, level, layered, layer, format); return ret } + MakeTextureHandleResidentARB :: proc "c" (handle: u64, loc := #caller_location) { impl_MakeTextureHandleResidentARB(handle); debug_helper(loc, 0, handle) } + MakeImageHandleResidentARB :: proc "c" (handle: u64, access: u32, loc := #caller_location) { impl_MakeImageHandleResidentARB(handle, access); debug_helper(loc, 0, handle, access) } + MakeTextureHandleNonResidentARB:: proc "c" (handle: u64, loc := #caller_location) { impl_MakeTextureHandleNonResidentARB(handle); debug_helper(loc, 0, handle) } + MakeImageHandleNonResidentARB :: proc "c" (handle: u64, loc := #caller_location) { impl_MakeImageHandleNonResidentARB(handle); debug_helper(loc, 0, handle) } diff --git a/vendor/commonmark/cmark.odin b/vendor/commonmark/cmark.odin index 9ad71da3f..50544b9bd 100644 --- a/vendor/commonmark/cmark.odin +++ b/vendor/commonmark/cmark.odin @@ -494,15 +494,15 @@ free_cstring :: proc "c" (str: cstring) { free_rawptr(rawptr(str)) } free_string :: proc "c" (s: string) { - free_rawptr(raw_data(s)) + free_rawptr(raw_data(s)) } free :: proc{free_rawptr, free_cstring} // Wrap CMark allocator as Odin allocator @(private) cmark_allocator_proc :: proc(allocator_data: rawptr, mode: runtime.Allocator_Mode, - size, alignment: int, - old_memory: rawptr, old_size: int, loc := #caller_location) -> (res: []byte, err: runtime.Allocator_Error) { + size, alignment: int, + old_memory: rawptr, old_size: int, loc := #caller_location) -> (res: []byte, err: runtime.Allocator_Error) { cmark_alloc := cast(^Allocator)allocator_data switch mode { diff --git a/vendor/fontstash/fontstash.odin b/vendor/fontstash/fontstash.odin index 70edcd109..9b556a04a 100644 --- a/vendor/fontstash/fontstash.odin +++ b/vendor/fontstash/fontstash.odin @@ -798,10 +798,10 @@ __getVerticalAlign :: proc( case .BOTTOMLEFT: switch av { - case .TOP: res = -font.ascender * f32(pixelSize) / 10 - case .MIDDLE: res = -(font.ascender + font.descender) / 2 * f32(pixelSize) / 10 - case .BASELINE: res = 0 - case .BOTTOM: res = -font.descender * f32(pixelSize) / 10 + case .TOP: res = -font.ascender * f32(pixelSize) / 10 + case .MIDDLE: res = -(font.ascender + font.descender) / 2 * f32(pixelSize) / 10 + case .BASELINE: res = 0 + case .BOTTOM: res = -font.descender * f32(pixelSize) / 10 } } diff --git a/vendor/sdl2/sdl2.odin b/vendor/sdl2/sdl2.odin index 719390adc..73d95e18a 100644 --- a/vendor/sdl2/sdl2.odin +++ b/vendor/sdl2/sdl2.odin @@ -235,8 +235,8 @@ foreign lib { // quit QuitRequested :: #force_inline proc "c" () -> bool { - PumpEvents() - return bool(PeepEvents(nil, 0, .PEEKEVENT, .QUIT, .QUIT) > 0) + PumpEvents() + return bool(PeepEvents(nil, 0, .PEEKEVENT, .QUIT, .QUIT) > 0) } diff --git a/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py b/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py index 65f53758f..a551887ff 100644 --- a/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py +++ b/vendor/vulkan/_gen/create_vulkan_odin_wrapper.py @@ -94,15 +94,13 @@ def convert_type(t, prev_name, curr_name): if t == "": return t + if t.startswith("const"): + t = convert_type(t[6:], prev_name, curr_name) + elif t.endswith("*"): - elem = "" pointer = "^" - if t.startswith("const"): - ttype = t[6:len(t)-1] - elem = convert_type(ttype, prev_name, curr_name) - else: - ttype = t[:len(t)-1] - elem = convert_type(ttype, prev_name, curr_name) + ttype = t[:len(t)-1] + elem = convert_type(ttype, prev_name, curr_name) if curr_name.endswith("s") or curr_name.endswith("Table"): if prev_name.endswith("Count") or prev_name.endswith("Counts"): @@ -625,12 +623,14 @@ def parse_procedures(f): for rt, name, fields in data: proc_name = no_vk(name) - pf = [] prev_name = "" - for type_, fname in re.findall(r"(?:\s*|)(.+?)\s*(\w+)(?:,|$)", fields): + for type_, fname, array_len in re.findall(r"(?:\s*|)(.+?)\s*(\w+)(?:\[(\d+)\])?(?:,|$)", fields): curr_name = fix_arg(fname) - pf.append((do_type(type_, prev_name, curr_name), curr_name)) + ty = do_type(type_, prev_name, curr_name) + if array_len != "": + ty = f"^[{array_len}]{ty}" + pf.append((ty, curr_name)) prev_name = curr_name data_fields = ', '.join(["{}: {}".format(n, t) for t, n in pf if t != ""]) @@ -798,7 +798,7 @@ API_VERSION_1_2 :: (1<<22) | (2<<12) | (0) API_VERSION_1_3 :: (1<<22) | (3<<12) | (0) MAKE_VERSION :: proc(major, minor, patch: u32) -> u32 { - return (major<<22) | (minor<<12) | (patch) +\treturn (major<<22) | (minor<<12) | (patch) } // Base types diff --git a/vendor/vulkan/core.odin b/vendor/vulkan/core.odin index 764156b8d..79b856595 100644 --- a/vendor/vulkan/core.odin +++ b/vendor/vulkan/core.odin @@ -8,7 +8,7 @@ API_VERSION_1_2 :: (1<<22) | (2<<12) | (0) API_VERSION_1_3 :: (1<<22) | (3<<12) | (0) MAKE_VERSION :: proc(major, minor, patch: u32) -> u32 { - return (major<<22) | (minor<<12) | (patch) + return (major<<22) | (minor<<12) | (patch) } // Base types diff --git a/vendor/vulkan/procedures.odin b/vendor/vulkan/procedures.odin index 9a27b4f79..bec421f29 100644 --- a/vendor/vulkan/procedures.odin +++ b/vendor/vulkan/procedures.odin @@ -259,7 +259,7 @@ ProcCmdResolveImage2KHR :: #type proc "system ProcCmdSetAlphaToCoverageEnableEXT :: #type proc "system" (commandBuffer: CommandBuffer, alphaToCoverageEnable: b32) ProcCmdSetAlphaToOneEnableEXT :: #type proc "system" (commandBuffer: CommandBuffer, alphaToOneEnable: b32) ProcCmdSetAttachmentFeedbackLoopEnableEXT :: #type proc "system" (commandBuffer: CommandBuffer, aspectMask: ImageAspectFlags) -ProcCmdSetBlendConstants :: #type proc "system" (commandBuffer: CommandBuffer) +ProcCmdSetBlendConstants :: #type proc "system" (commandBuffer: CommandBuffer, blendConstants: ^[4]f32) ProcCmdSetCheckpointNV :: #type proc "system" (commandBuffer: CommandBuffer, pCheckpointMarker: rawptr) ProcCmdSetCoarseSampleOrderNV :: #type proc "system" (commandBuffer: CommandBuffer, sampleOrderType: CoarseSampleOrderTypeNV, customSampleOrderCount: u32, pCustomSampleOrders: [^]CoarseSampleOrderCustomNV) ProcCmdSetColorBlendAdvancedEXT :: #type proc "system" (commandBuffer: CommandBuffer, firstAttachment: u32, attachmentCount: u32, pColorBlendAdvanced: ^ColorBlendAdvancedEXT) @@ -302,8 +302,8 @@ ProcCmdSetEvent2KHR :: #type proc "system ProcCmdSetExclusiveScissorEnableNV :: #type proc "system" (commandBuffer: CommandBuffer, firstExclusiveScissor: u32, exclusiveScissorCount: u32, pExclusiveScissorEnables: [^]b32) ProcCmdSetExclusiveScissorNV :: #type proc "system" (commandBuffer: CommandBuffer, firstExclusiveScissor: u32, exclusiveScissorCount: u32, pExclusiveScissors: [^]Rect2D) ProcCmdSetExtraPrimitiveOverestimationSizeEXT :: #type proc "system" (commandBuffer: CommandBuffer, extraPrimitiveOverestimationSize: f32) -ProcCmdSetFragmentShadingRateEnumNV :: #type proc "system" (commandBuffer: CommandBuffer, shadingRate: FragmentShadingRateNV) -ProcCmdSetFragmentShadingRateKHR :: #type proc "system" (commandBuffer: CommandBuffer, pFragmentSize: ^Extent2D) +ProcCmdSetFragmentShadingRateEnumNV :: #type proc "system" (commandBuffer: CommandBuffer, shadingRate: FragmentShadingRateNV, combinerOps: ^[2]FragmentShadingRateCombinerOpKHR) +ProcCmdSetFragmentShadingRateKHR :: #type proc "system" (commandBuffer: CommandBuffer, pFragmentSize: ^Extent2D, combinerOps: ^[2]FragmentShadingRateCombinerOpKHR) ProcCmdSetFrontFace :: #type proc "system" (commandBuffer: CommandBuffer, frontFace: FrontFace) ProcCmdSetFrontFaceEXT :: #type proc "system" (commandBuffer: CommandBuffer, frontFace: FrontFace) ProcCmdSetLineRasterizationModeEXT :: #type proc "system" (commandBuffer: CommandBuffer, lineRasterizationMode: LineRasterizationModeEXT) diff --git a/vendor/wgpu/wgpu_native.odin b/vendor/wgpu/wgpu_native.odin index 2b10e3c17..7c106a452 100644 --- a/vendor/wgpu/wgpu_native.odin +++ b/vendor/wgpu/wgpu_native.odin @@ -29,10 +29,9 @@ foreign { RawQueueSubmitForIndex :: proc(queue: Queue, commandCount: uint, commands: [^]CommandBuffer) -> SubmissionIndex --- // Returns true if the queue is empty, or false if there are more queue submissions still in flight. - @(link_name="wgpuDevicePoll") - RawDevicePoll :: proc(device: Device, wait: b32, /* NULLABLE */ wrappedSubmissionIndex: /* const */ ^WrappedSubmissionIndex) -> b32 --- + DevicePoll :: proc(device: Device, wait: b32, /* NULLABLE */ wrappedSubmissionIndex: /* const */ ^WrappedSubmissionIndex = nil) -> b32 --- - SetLogCallback :: proc "odin" (callback: LogCallback) --- + SetLogCallback :: proc(callback: LogCallback, userdata: rawptr) --- SetLogLevel :: proc(level: LogLevel) --- @@ -67,9 +66,3 @@ InstanceEnumerateAdapters :: proc(instance: Instance, options: ^InstanceEnumerat QueueSubmitForIndex :: proc(queue: Queue, commands: []CommandBuffer) -> SubmissionIndex { return RawQueueSubmitForIndex(queue, len(commands), raw_data(commands)) } - -DevicePoll :: proc(device: Device, wait: b32) -> (wrappedSubmissionIndex: WrappedSubmissionIndex, ok: bool) { - ok = bool(RawDevicePoll(device, wait, &wrappedSubmissionIndex)) - return -} - diff --git a/vendor/wgpu/wgpu_native_types.odin b/vendor/wgpu/wgpu_native_types.odin index b0837198f..2133fdd50 100644 --- a/vendor/wgpu/wgpu_native_types.odin +++ b/vendor/wgpu/wgpu_native_types.odin @@ -79,7 +79,7 @@ RequiredLimitsExtras :: struct { } SupportedLimitsExtras :: struct { - using chain: ChainedStruct, + using chain: ChainedStructOut, limits: NativeLimits, } @@ -182,7 +182,7 @@ SurfaceConfigurationExtras :: struct { desiredMaximumFrameLatency: i32, } -LogCallback :: #type proc "odin" (level: LogLevel, message: cstring) +LogCallback :: #type proc "c" (level: LogLevel, message: cstring, userdata: rawptr) // Wrappers