mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 23:58:50 +00:00
Merge tag 'dev-2024-07'
This commit is contained in:
@@ -32,8 +32,8 @@ jobs:
|
|||||||
gmake -C vendor/stb/src
|
gmake -C vendor/stb/src
|
||||||
gmake -C vendor/cgltf/src
|
gmake -C vendor/cgltf/src
|
||||||
gmake -C vendor/miniaudio/src
|
gmake -C vendor/miniaudio/src
|
||||||
./odin check examples/all -vet -strict-style -target:netbsd_amd64
|
./odin check examples/all -vet -strict-style -disallow-do -target:netbsd_amd64
|
||||||
./odin check examples/all -vet -strict-style -target:netbsd_arm64
|
./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/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/core/speed.odin -file -all-packages -o:speed -define:ODIN_TEST_FANCY=false
|
||||||
./odin test tests/vendor -all-packages -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/stb/src
|
||||||
gmake -C vendor/cgltf/src
|
gmake -C vendor/cgltf/src
|
||||||
gmake -C vendor/miniaudio/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/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/core/speed.odin -file -all-packages -o:speed -define:ODIN_TEST_FANCY=false
|
||||||
./odin test tests/vendor -all-packages -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)
|
- name: Download LLVM (MacOS ARM)
|
||||||
if: matrix.os == 'macos-14'
|
if: matrix.os == 'macos-14'
|
||||||
run: |
|
run: |
|
||||||
brew install llvm@17
|
brew install llvm@17 wasmtime
|
||||||
echo "/opt/homebrew/opt/llvm@17/bin" >> $GITHUB_PATH
|
echo "/opt/homebrew/opt/llvm@17/bin" >> $GITHUB_PATH
|
||||||
|
|
||||||
- name: Build Odin
|
- name: Build Odin
|
||||||
@@ -135,18 +135,24 @@ jobs:
|
|||||||
./run.sh
|
./run.sh
|
||||||
|
|
||||||
- name: Odin check examples/all for Linux i386
|
- 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'
|
if: matrix.os == 'ubuntu-latest'
|
||||||
- name: Odin check examples/all for Linux arm64
|
- 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'
|
if: matrix.os == 'ubuntu-latest'
|
||||||
- name: Odin check examples/all for FreeBSD amd64
|
- 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'
|
if: matrix.os == 'ubuntu-latest'
|
||||||
- name: Odin check examples/all for OpenBSD amd64
|
- 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'
|
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:
|
build_windows:
|
||||||
name: Windows Build, Check, and Test
|
name: Windows Build, Check, and Test
|
||||||
runs-on: windows-2022
|
runs-on: windows-2022
|
||||||
|
|||||||
@@ -195,6 +195,7 @@ type_proc_parameter_type :: proc($T: typeid, index: int) -> typeid where type_i
|
|||||||
type_proc_return_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_count :: proc($T: typeid) -> typeid ---
|
||||||
type_polymorphic_record_parameter_value :: proc($T: typeid, index: int) -> $V ---
|
type_polymorphic_record_parameter_value :: proc($T: typeid, index: int) -> $V ---
|
||||||
|
|||||||
@@ -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.
|
// with the old value, and reducing the length of the dynamic array by 1.
|
||||||
//
|
//
|
||||||
// Note: This is an O(1) operation.
|
// 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.
|
// Note: If the index is out of bounds, this procedure will panic.
|
||||||
@builtin
|
@builtin
|
||||||
unordered_remove :: proc(array: ^$D/[dynamic]$T, index: int, loc := #caller_location) #no_bounds_check {
|
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.
|
// `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: 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.
|
// Note: If the index is out of bounds, this procedure will panic.
|
||||||
@builtin
|
@builtin
|
||||||
ordered_remove :: proc(array: ^$D/[dynamic]$T, index: int, loc := #caller_location) #no_bounds_check {
|
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`
|
// `clear` will set the length of a passed dynamic array or map to `0`
|
||||||
@builtin
|
@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`).
|
// `reserve` will try to reserve memory of a passed dynamic array or map to the requested element count (setting the `cap`).
|
||||||
@builtin
|
@builtin
|
||||||
reserve :: proc{reserve_dynamic_array, reserve_map}
|
reserve :: proc{
|
||||||
|
reserve_dynamic_array,
|
||||||
|
reserve_map,
|
||||||
|
|
||||||
|
reserve_soa,
|
||||||
|
}
|
||||||
|
|
||||||
@builtin
|
@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`).
|
// `resize` will try to resize memory of a passed dynamic array to the requested element count (setting the `len`, and possibly `cap`).
|
||||||
@builtin
|
@builtin
|
||||||
resize :: proc{resize_dynamic_array}
|
resize :: proc{
|
||||||
|
resize_dynamic_array,
|
||||||
|
|
||||||
|
resize_soa,
|
||||||
|
}
|
||||||
|
|
||||||
@builtin
|
@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.
|
// Shrinks the capacity of a dynamic array or map down to the current length, or the given capacity.
|
||||||
@builtin
|
@builtin
|
||||||
@@ -268,7 +290,7 @@ new_clone :: proc(data: $T, allocator := context.allocator, loc := #caller_locat
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFAULT_RESERVE_CAPACITY :: 16
|
DEFAULT_DYNAMIC_ARRAY_CAPACITY :: 8
|
||||||
|
|
||||||
@(require_results)
|
@(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 {
|
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`.
|
// Note: Prefer using the procedure group `make`.
|
||||||
@(builtin, require_results)
|
@(builtin, require_results)
|
||||||
make_dynamic_array :: proc($T: typeid/[dynamic]$E, allocator := context.allocator, loc := #caller_location) -> (T, Allocator_Error) #optional_allocator_error {
|
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.
|
// `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.
|
// 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_dynamic_array_len_cap,
|
||||||
make_map,
|
make_map,
|
||||||
make_multi_pointer,
|
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
|
return 1, nil
|
||||||
} else {
|
} else {
|
||||||
if cap(array) < len(array)+1 {
|
if cap(array) < len(array)+1 {
|
||||||
// Same behavior as _append_elems but there's only one arg, so we always just add 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) + 8
|
cap := 2 * cap(array) + DEFAULT_DYNAMIC_ARRAY_CAPACITY
|
||||||
|
|
||||||
// do not 'or_return' here as it could be a partial success
|
// do not 'or_return' here as it could be a partial success
|
||||||
if should_zero {
|
if should_zero {
|
||||||
@@ -473,7 +500,7 @@ _append_elems :: #force_inline proc(array: ^$T/[dynamic]$E, should_zero: bool, l
|
|||||||
return arg_len, nil
|
return arg_len, nil
|
||||||
} else {
|
} else {
|
||||||
if cap(array) < len(array)+arg_len {
|
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
|
// do not 'or_return' here as it could be a partial success
|
||||||
if should_zero {
|
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
|
// 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 append :: proc{
|
||||||
@builtin non_zero_append :: proc{non_zero_append_elem, non_zero_append_elems, non_zero_append_elem_string}
|
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
|
@builtin
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ raw_soa_footer_slice :: proc(array: ^$T/#soa[]$E) -> (footer: ^Raw_SOA_Footer_Sl
|
|||||||
if array == nil {
|
if array == nil {
|
||||||
return 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))
|
footer = (^Raw_SOA_Footer_Slice)(uintptr(array) + field_count*size_of(rawptr))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -64,12 +64,7 @@ raw_soa_footer_dynamic_array :: proc(array: ^$T/#soa[dynamic]$E) -> (footer: ^Ra
|
|||||||
if array == nil {
|
if array == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
field_count: uintptr
|
field_count := uintptr(len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E))
|
||||||
when intrinsics.type_is_array(E) {
|
|
||||||
field_count = len(E)
|
|
||||||
} else {
|
|
||||||
field_count = uintptr(intrinsics.type_struct_field_count(E))
|
|
||||||
}
|
|
||||||
footer = (^Raw_SOA_Footer_Dynamic_Array)(uintptr(array) + field_count*size_of(rawptr))
|
footer = (^Raw_SOA_Footer_Dynamic_Array)(uintptr(array) + field_count*size_of(rawptr))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -98,7 +93,7 @@ make_soa_aligned :: proc($T: typeid/#soa[]$E, length: int, alignment: int, alloc
|
|||||||
ti = type_info_base(ti)
|
ti = type_info_base(ti)
|
||||||
si := &ti.variant.(Type_Info_Struct)
|
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
|
total_size := 0
|
||||||
for i in 0..<field_count {
|
for i in 0..<field_count {
|
||||||
@@ -147,7 +142,7 @@ make_soa_slice :: proc($T: typeid/#soa[]$E, length: int, allocator := context.al
|
|||||||
@(builtin, require_results)
|
@(builtin, require_results)
|
||||||
make_soa_dynamic_array :: proc($T: typeid/#soa[dynamic]$E, allocator := context.allocator, loc := #caller_location) -> (array: T, err: Allocator_Error) #optional_allocator_error {
|
make_soa_dynamic_array :: proc($T: typeid/#soa[dynamic]$E, allocator := context.allocator, loc := #caller_location) -> (array: T, err: Allocator_Error) #optional_allocator_error {
|
||||||
context.allocator = allocator
|
context.allocator = allocator
|
||||||
reserve_soa(&array, DEFAULT_RESERVE_CAPACITY, loc) or_return
|
reserve_soa(&array, 0, loc) or_return
|
||||||
return array, nil
|
return array, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,8 +182,28 @@ resize_soa :: proc(array: ^$T/#soa[dynamic]$E, length: int, loc := #caller_locat
|
|||||||
return nil
|
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
|
@builtin
|
||||||
reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_location) -> Allocator_Error {
|
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 {
|
if array == nil {
|
||||||
return 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)
|
ti = type_info_base(ti)
|
||||||
si := &ti.variant.(Type_Info_Struct)
|
si := &ti.variant.(Type_Info_Struct)
|
||||||
|
|
||||||
field_count: uintptr
|
field_count := uintptr(len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E))
|
||||||
when intrinsics.type_is_array(E) {
|
|
||||||
field_count = len(E)
|
|
||||||
} else {
|
|
||||||
field_count = uintptr(intrinsics.type_struct_field_count(E))
|
|
||||||
}
|
|
||||||
assert(footer.cap == old_cap)
|
assert(footer.cap == old_cap)
|
||||||
|
|
||||||
old_size := 0
|
old_size := 0
|
||||||
@@ -238,7 +248,7 @@ reserve_soa :: proc(array: ^$T/#soa[dynamic]$E, capacity: int, loc := #caller_lo
|
|||||||
old_data := (^rawptr)(array)^
|
old_data := (^rawptr)(array)^
|
||||||
|
|
||||||
new_bytes := array.allocator.procedure(
|
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,
|
nil, old_size, loc,
|
||||||
) or_return
|
) or_return
|
||||||
new_data := raw_data(new_bytes)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@builtin
|
@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 {
|
if array == nil {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if cap(array) <= len(array) + 1 {
|
if cap(array) <= len(array) + 1 {
|
||||||
cap := 2 * cap(array) + 8
|
// Same behavior as append_soa_elems but there's only one arg, so we always just add DEFAULT_DYNAMIC_ARRAY_CAPACITY.
|
||||||
err = reserve_soa(array, cap, loc) // do not 'or_return' here as it could be a partial success
|
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)
|
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_of(T)
|
||||||
ti = type_info_base(ti)
|
ti = type_info_base(ti)
|
||||||
si := &ti.variant.(Type_Info_Struct)
|
si := &ti.variant.(Type_Info_Struct)
|
||||||
field_count: uintptr
|
field_count := uintptr(len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E))
|
||||||
when intrinsics.type_is_array(E) {
|
|
||||||
field_count = len(E)
|
|
||||||
} else {
|
|
||||||
field_count = uintptr(intrinsics.type_struct_field_count(E))
|
|
||||||
}
|
|
||||||
|
|
||||||
data := (^rawptr)(array)^
|
data := (^rawptr)(array)^
|
||||||
|
|
||||||
@@ -326,7 +342,17 @@ append_soa_elem :: proc(array: ^$T/#soa[dynamic]$E, arg: E, loc := #caller_locat
|
|||||||
}
|
}
|
||||||
|
|
||||||
@builtin
|
@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 {
|
if array == nil {
|
||||||
return
|
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 {
|
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)
|
||||||
err = reserve_soa(array, cap, loc) // do not 'or_return' here as it could be a partial success
|
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)
|
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_of(typeid_of(T))
|
||||||
ti = type_info_base(ti)
|
ti = type_info_base(ti)
|
||||||
si := &ti.variant.(Type_Info_Struct)
|
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)^
|
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 {
|
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
|
array := array
|
||||||
ptr := (^rawptr)(&array)^
|
ptr := (^rawptr)(&array)^
|
||||||
free(ptr, allocator, loc) or_return
|
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 {
|
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
|
array := array
|
||||||
ptr := (^rawptr)(&array)^
|
ptr := (^rawptr)(&array)^
|
||||||
footer := raw_soa_footer(&array)
|
footer := raw_soa_footer(&array)
|
||||||
@@ -416,7 +444,8 @@ delete_soa :: proc{
|
|||||||
|
|
||||||
|
|
||||||
clear_soa_dynamic_array :: proc(array: ^$T/#soa[dynamic]$E) {
|
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 := raw_soa_footer(array)
|
||||||
footer.len = 0
|
footer.len = 0
|
||||||
}
|
}
|
||||||
@@ -438,12 +467,7 @@ into_dynamic_soa :: proc(array: $T/#soa[]$E) -> #soa[dynamic]E {
|
|||||||
allocator = nil_allocator(),
|
allocator = nil_allocator(),
|
||||||
}
|
}
|
||||||
|
|
||||||
field_count: uintptr
|
field_count := uintptr(len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E))
|
||||||
when intrinsics.type_is_array(E) {
|
|
||||||
field_count = len(E)
|
|
||||||
} else {
|
|
||||||
field_count = uintptr(intrinsics.type_struct_field_count(E))
|
|
||||||
}
|
|
||||||
|
|
||||||
array := array
|
array := array
|
||||||
dynamic_data := ([^]rawptr)(&d)[:field_count]
|
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)
|
ti = type_info_base(ti)
|
||||||
si := &ti.variant.(Type_Info_Struct)
|
si := &ti.variant.(Type_Info_Struct)
|
||||||
|
|
||||||
field_count: uintptr
|
field_count := uintptr(len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E))
|
||||||
when intrinsics.type_is_array(E) {
|
|
||||||
field_count = len(E)
|
|
||||||
} else {
|
|
||||||
field_count = uintptr(intrinsics.type_struct_field_count(E))
|
|
||||||
}
|
|
||||||
|
|
||||||
data := uintptr(array)
|
data := uintptr(array)
|
||||||
for i in 0..<field_count {
|
for i in 0..<field_count {
|
||||||
@@ -500,12 +519,7 @@ ordered_remove_soa :: proc(array: ^$T/#soa[dynamic]$E, index: int, loc := #calle
|
|||||||
ti = type_info_base(ti)
|
ti = type_info_base(ti)
|
||||||
si := &ti.variant.(Type_Info_Struct)
|
si := &ti.variant.(Type_Info_Struct)
|
||||||
|
|
||||||
field_count: uintptr
|
field_count := uintptr(len(E) when intrinsics.type_is_array(E) else intrinsics.type_struct_field_count(E))
|
||||||
when intrinsics.type_is_array(E) {
|
|
||||||
field_count = len(E)
|
|
||||||
} else {
|
|
||||||
field_count = uintptr(intrinsics.type_struct_field_count(E))
|
|
||||||
}
|
|
||||||
|
|
||||||
data := uintptr(array)
|
data := uintptr(array)
|
||||||
for i in 0..<field_count {
|
for i in 0..<field_count {
|
||||||
|
|||||||
@@ -22,6 +22,11 @@ when !ODIN_TEST && !ODIN_NO_ENTRY_POINT {
|
|||||||
@(link_name="_start", linkage="strong", require, export)
|
@(link_name="_start", linkage="strong", require, export)
|
||||||
_start :: proc "c" () {
|
_start :: proc "c" () {
|
||||||
context = default_context()
|
context = default_context()
|
||||||
|
|
||||||
|
when ODIN_OS == .WASI {
|
||||||
|
_wasi_setup_args()
|
||||||
|
}
|
||||||
|
|
||||||
#force_no_inline _startup_runtime()
|
#force_no_inline _startup_runtime()
|
||||||
intrinsics.__entry_point()
|
intrinsics.__entry_point()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,13 +3,16 @@
|
|||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
_heap_alloc :: proc "contextless" (size: int, zero_memory := true) -> rawptr {
|
_heap_alloc :: proc "contextless" (size: int, zero_memory := true) -> rawptr {
|
||||||
|
context = default_context()
|
||||||
unimplemented("base:runtime 'heap_alloc' procedure is not supported on this platform")
|
unimplemented("base:runtime 'heap_alloc' procedure is not supported on this platform")
|
||||||
}
|
}
|
||||||
|
|
||||||
_heap_resize :: proc "contextless" (ptr: rawptr, new_size: int) -> rawptr {
|
_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")
|
unimplemented("base:runtime 'heap_resize' procedure is not supported on this platform")
|
||||||
}
|
}
|
||||||
|
|
||||||
_heap_free :: proc "contextless" (ptr: rawptr) {
|
_heap_free :: proc "contextless" (ptr: rawptr) {
|
||||||
|
context = default_context()
|
||||||
unimplemented("base:runtime 'heap_free' procedure is not supported on this platform")
|
unimplemented("base:runtime 'heap_free' procedure is not supported on this platform")
|
||||||
}
|
}
|
||||||
|
|||||||
+31
-27
@@ -1,3 +1,4 @@
|
|||||||
|
//+vet !cast
|
||||||
package runtime
|
package runtime
|
||||||
|
|
||||||
import "base:intrinsics"
|
import "base:intrinsics"
|
||||||
@@ -29,7 +30,7 @@ is_power_of_two_int :: #force_inline proc "contextless" (x: int) -> bool {
|
|||||||
return (x & (x-1)) == 0
|
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))
|
assert(is_power_of_two_int(align))
|
||||||
|
|
||||||
p := ptr
|
p := ptr
|
||||||
@@ -47,7 +48,7 @@ is_power_of_two_uint :: #force_inline proc "contextless" (x: uint) -> bool {
|
|||||||
return (x & (x-1)) == 0
|
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))
|
assert(is_power_of_two_uint(align))
|
||||||
|
|
||||||
p := ptr
|
p := ptr
|
||||||
@@ -65,7 +66,7 @@ is_power_of_two_uintptr :: #force_inline proc "contextless" (x: uintptr) -> bool
|
|||||||
return (x & (x-1)) == 0
|
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))
|
assert(is_power_of_two_uintptr(align))
|
||||||
|
|
||||||
p := ptr
|
p := ptr
|
||||||
@@ -642,21 +643,24 @@ abs_quaternion256 :: #force_inline proc "contextless" (x: quaternion256) -> f64
|
|||||||
|
|
||||||
|
|
||||||
quo_complex32 :: proc "contextless" (n, m: complex32) -> complex32 {
|
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)) {
|
e, f: f32
|
||||||
ratio := imag(m) / real(m)
|
|
||||||
denom := real(m) + ratio*imag(m)
|
if abs(mr) >= abs(mi) {
|
||||||
e = (real(n) + imag(n)*ratio) / denom
|
ratio := mi / mr
|
||||||
f = (imag(n) - real(n)*ratio) / denom
|
denom := mr + ratio*mi
|
||||||
|
e = (nr + ni*ratio) / denom
|
||||||
|
f = (ni - nr*ratio) / denom
|
||||||
} else {
|
} else {
|
||||||
ratio := real(m) / imag(m)
|
ratio := mr / mi
|
||||||
denom := imag(m) + ratio*real(m)
|
denom := mi + ratio*mr
|
||||||
e = (real(n)*ratio + imag(n)) / denom
|
e = (nr*ratio + ni) / denom
|
||||||
f = (imag(n)*ratio - real(n)) / 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 {
|
mul_quaternion64 :: proc "contextless" (q, r: quaternion64) -> quaternion64 {
|
||||||
q0, q1, q2, q3 := real(q), imag(q), jmag(q), kmag(q)
|
q0, q1, q2, q3 := f32(real(q)), f32(imag(q)), f32(jmag(q)), f32(kmag(q))
|
||||||
r0, r1, r2, r3 := real(r), imag(r), jmag(r), kmag(r)
|
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
|
t0 := r0*q0 - r1*q1 - r2*q2 - r3*q3
|
||||||
t1 := r0*q1 + r1*q0 - r2*q3 + r3*q2
|
t1 := r0*q1 + r1*q0 - r2*q3 + r3*q2
|
||||||
t2 := r0*q2 + r1*q3 + r2*q0 - r3*q1
|
t2 := r0*q2 + r1*q3 + r2*q0 - r3*q1
|
||||||
t3 := r0*q3 - r1*q2 + r2*q1 + r3*q0
|
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 {
|
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 {
|
quo_quaternion64 :: proc "contextless" (q, r: quaternion64) -> quaternion64 {
|
||||||
q0, q1, q2, q3 := real(q), imag(q), jmag(q), kmag(q)
|
q0, q1, q2, q3 := f32(real(q)), f32(imag(q)), f32(jmag(q)), f32(kmag(q))
|
||||||
r0, r1, r2, r3 := real(r), imag(r), jmag(r), kmag(r)
|
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)
|
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
|
t2 := (r0*q2 - r1*q3 - r2*q0 + r3*q1) * invmag2
|
||||||
t3 := (r0*q3 + r1*q2 + r2*q1 - r3*q0) * 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 {
|
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
|
bn := (b ~ s_b) - s_b
|
||||||
|
|
||||||
r: u128 = ---
|
r: u128 = ---
|
||||||
_ = udivmod128(transmute(u128)an, transmute(u128)bn, &r)
|
_ = udivmod128(u128(an), u128(bn), &r)
|
||||||
return (transmute(i128)r ~ s_a) - s_a
|
return (i128(r) ~ s_a) - s_a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@(link_name="__divmodti4", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE)
|
@(link_name="__divmodti4", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE)
|
||||||
divmodti4 :: proc "c" (a, b: i128, rem: ^i128) -> i128 {
|
divmodti4 :: proc "c" (a, b: i128, rem: ^i128) -> i128 {
|
||||||
u := udivmod128(transmute(u128)a, transmute(u128)b, cast(^u128)rem)
|
u := udivmod128(u128(a), u128(b), (^u128)(rem))
|
||||||
return transmute(i128)u
|
return i128(u)
|
||||||
}
|
}
|
||||||
|
|
||||||
@(link_name="__divti3", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE)
|
@(link_name="__divti3", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE)
|
||||||
divti3 :: proc "c" (a, b: i128) -> i128 {
|
divti3 :: proc "c" (a, b: i128) -> i128 {
|
||||||
u := udivmodti4(transmute(u128)a, transmute(u128)b, nil)
|
u := udivmodti4(u128(a), u128(b), nil)
|
||||||
return transmute(i128)u
|
return i128(u)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@(link_name="__fixdfti", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE)
|
@(link_name="__fixdfti", linkage=RUNTIME_LINKAGE, require=RUNTIME_REQUIRE)
|
||||||
fixdfti :: proc(a: u64) -> i128 {
|
fixdfti :: proc "c" (a: u64) -> i128 {
|
||||||
significandBits :: 52
|
significandBits :: 52
|
||||||
typeWidth :: (size_of(u64)*8)
|
typeWidth :: (size_of(u64)*8)
|
||||||
exponentBits :: (typeWidth - significandBits - 1)
|
exponentBits :: (typeWidth - significandBits - 1)
|
||||||
|
|||||||
@@ -2,10 +2,54 @@
|
|||||||
//+private
|
//+private
|
||||||
package runtime
|
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) {
|
_stderr_write :: proc "contextless" (data: []byte) -> (int, _OS_Errno) {
|
||||||
data_iovec := (wasi.ciovec_t)(data)
|
n: uint
|
||||||
n, err := wasi.fd_write(1, {data_iovec})
|
err := fd_write(1, {data}, &n)
|
||||||
return int(n), _OS_Errno(err)
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ default_random_generator_proc :: proc(data: rawptr, mode: Random_Generator_Mode,
|
|||||||
switch len(p) {
|
switch len(p) {
|
||||||
case size_of(u64):
|
case size_of(u64):
|
||||||
// Fast path for a 64-bit destination.
|
// 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:
|
case:
|
||||||
// All other cases.
|
// All other cases.
|
||||||
pos := i8(0)
|
pos := i8(0)
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ udivmod128 :: proc "c" (a, b: u128, rem: ^u128) -> u128 {
|
|||||||
return u128(n[high] >> _ctz(d[high]))
|
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 sr > U64_BITS - 2 {
|
||||||
if rem != nil {
|
if rem != nil {
|
||||||
rem^ = a
|
rem^ = a
|
||||||
@@ -107,7 +107,7 @@ udivmod128 :: proc "c" (a, b: u128, rem: ^u128) -> u128 {
|
|||||||
r[low] = n[high] >> (sr - U64_BITS)
|
r[low] = n[high] >> (sr - U64_BITS)
|
||||||
}
|
}
|
||||||
} else {
|
} 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 sr > U64_BITS - 1 {
|
||||||
if rem != nil {
|
if rem != nil {
|
||||||
@@ -143,7 +143,7 @@ udivmod128 :: proc "c" (a, b: u128, rem: ^u128) -> u128 {
|
|||||||
r_all = transmute(u128)r
|
r_all = transmute(u128)r
|
||||||
s := i128(b - r_all - 1) >> (U128_BITS - 1)
|
s := i128(b - r_all - 1) >> (U128_BITS - 1)
|
||||||
carry = u32(s & 1)
|
carry = u32(s & 1)
|
||||||
r_all -= b & transmute(u128)s
|
r_all -= b & u128(s)
|
||||||
r = transmute([2]u64)r_all
|
r = transmute([2]u64)r_all
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -495,7 +495,7 @@ claim_more_memory :: proc(a: ^WASM_Allocator, num_bytes: uint) -> bool {
|
|||||||
// we can just extend the spill.
|
// we can just extend the spill.
|
||||||
spill_end := uintptr(raw_data(a.spill)) + uintptr(len(a.spill))
|
spill_end := uintptr(raw_data(a.spill)) + uintptr(len(a.spill))
|
||||||
if spill_end == uintptr(raw_data(allocated)) {
|
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)
|
raw_spill.len += len(allocated)
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, we have to "waste" the previous spill.
|
// 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.
|
// 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
|
// Reset the bit to update latest status so that we do not
|
||||||
// redundantly look at this bucket again.
|
// 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
|
bucket_mask ~= 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -760,7 +760,7 @@ free :: proc(a: ^WASM_Allocator, ptr: rawptr, loc := #caller_location) {
|
|||||||
defer unlock(a)
|
defer unlock(a)
|
||||||
|
|
||||||
size := region.size
|
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_field := ([^]uint)(region)[-1]
|
||||||
prev_region_size := prev_region_size_field & ~uint(FREE_REGION_FLAG)
|
prev_region_size := prev_region_size_field & ~uint(FREE_REGION_FLAG)
|
||||||
|
|||||||
+1
-14
@@ -34,20 +34,7 @@ when ODIN_OS == .Windows {
|
|||||||
SIGTERM :: 15
|
SIGTERM :: 15
|
||||||
}
|
}
|
||||||
|
|
||||||
when ODIN_OS == .Linux || ODIN_OS == .FreeBSD || ODIN_OS == .Haiku || ODIN_OS == .OpenBSD || ODIN_OS == .NetBSD {
|
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))
|
|
||||||
|
|
||||||
SIGABRT :: 6
|
|
||||||
SIGFPE :: 8
|
|
||||||
SIGILL :: 4
|
|
||||||
SIGINT :: 2
|
|
||||||
SIGSEGV :: 11
|
|
||||||
SIGTERM :: 15
|
|
||||||
}
|
|
||||||
|
|
||||||
when ODIN_OS == .Darwin {
|
|
||||||
SIG_ERR :: rawptr(~uintptr(0))
|
SIG_ERR :: rawptr(~uintptr(0))
|
||||||
SIG_DFL :: rawptr(uintptr(0))
|
SIG_DFL :: rawptr(uintptr(0))
|
||||||
SIG_IGN :: rawptr(uintptr(1))
|
SIG_IGN :: rawptr(uintptr(1))
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ decompress_slice_to_output_buffer :: proc(input: []u8, output: []u8, model := DE
|
|||||||
validate_model(model) or_return
|
validate_model(model) or_return
|
||||||
|
|
||||||
for inp < inp_end {
|
for inp < inp_end {
|
||||||
val := transmute(i8)input[inp]
|
val := i8(input[inp])
|
||||||
mark := int(-1)
|
mark := int(-1)
|
||||||
|
|
||||||
for val < 0 {
|
for val < 0 {
|
||||||
@@ -274,12 +274,9 @@ compress_string_to_buffer :: proc(input: string, output: []u8, model := DEFAULT_
|
|||||||
out_ptr := raw_data(output[out:])
|
out_ptr := raw_data(output[out:])
|
||||||
|
|
||||||
switch pack.bytes_packed {
|
switch pack.bytes_packed {
|
||||||
case 4:
|
case 4: intrinsics.unaligned_store((^u32)(out_ptr), code)
|
||||||
intrinsics.unaligned_store(transmute(^u32)out_ptr, code)
|
case 2: intrinsics.unaligned_store((^u16)(out_ptr), u16(code))
|
||||||
case 2:
|
case 1: intrinsics.unaligned_store( (^u8)(out_ptr), u8(code))
|
||||||
intrinsics.unaligned_store(transmute(^u16)out_ptr, u16(code))
|
|
||||||
case 1:
|
|
||||||
intrinsics.unaligned_store(transmute(^u8)out_ptr, u8(code))
|
|
||||||
case:
|
case:
|
||||||
return out, .Unknown_Compression_Method
|
return out, .Unknown_Compression_Method
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
ba.max_index = max(idx, ba.max_index)
|
||||||
|
|
||||||
if set_to{ ba.bits[leg_index] |= 1 << uint(bit_index) }
|
if set_to {
|
||||||
else { ba.bits[leg_index] &= ~(1 << uint(bit_index)) }
|
ba.bits[leg_index] |= 1 << uint(bit_index)
|
||||||
|
} else {
|
||||||
|
ba.bits[leg_index] &~= 1 << uint(bit_index)
|
||||||
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -253,7 +256,7 @@ Inputs:
|
|||||||
- index: Which bit in the array
|
- index: Which bit in the array
|
||||||
*/
|
*/
|
||||||
unsafe_unset :: proc(b: ^Bit_Array, bit: int) #no_bounds_check {
|
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).
|
A helper function to create a Bit Array with optional bias, in case your smallest index is non-zero (including negative).
|
||||||
|
|||||||
@@ -70,8 +70,7 @@ set :: proc(c: ^$C/Cache($Key, $Value), key: Key, value: Value) -> runtime.Alloc
|
|||||||
if c.count == c.capacity {
|
if c.count == c.capacity {
|
||||||
e = c.tail
|
e = c.tail
|
||||||
_remove_node(c, e)
|
_remove_node(c, e)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
c.count += 1
|
c.count += 1
|
||||||
e = new(Node(Key, Value), c.node_allocator) or_return
|
e = new(Node(Key, Value), c.node_allocator) or_return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ pop_front_safe :: proc(q: ^$Q/Queue($T)) -> (elem: T, ok: bool) {
|
|||||||
return
|
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) {
|
push_back_elems :: proc(q: ^$Q/Queue($T), elems: ..T) -> (ok: bool, err: runtime.Allocator_Error) {
|
||||||
n := uint(builtin.len(elems))
|
n := uint(builtin.len(elems))
|
||||||
if space(q^) < int(n) {
|
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 {
|
_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)
|
new_capacity := max(min_capacity, uint(8), uint(builtin.len(q.data))*2)
|
||||||
n := uint(builtin.len(q.data))
|
n := uint(builtin.len(q.data))
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ ge_set_bytes :: proc "contextless" (ge: ^Group_Element, b: []byte) -> bool {
|
|||||||
if len(b) != 32 {
|
if len(b) != 32 {
|
||||||
intrinsics.trap()
|
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
|
// Do the work in a scratch element, so that ge is unchanged on
|
||||||
// failure.
|
// failure.
|
||||||
@@ -169,7 +169,7 @@ ge_bytes :: proc "contextless" (ge: ^Group_Element, dst: []byte) {
|
|||||||
if len(dst) != 32 {
|
if len(dst) != 32 {
|
||||||
intrinsics.trap()
|
intrinsics.trap()
|
||||||
}
|
}
|
||||||
dst_ := transmute(^[32]byte)(raw_data(dst))
|
dst_ := (^[32]byte)(raw_data(dst))
|
||||||
|
|
||||||
// Convert the element to affine (x, y) representation.
|
// Convert the element to affine (x, y) representation.
|
||||||
x, y, z_inv: field.Tight_Field_Element = ---, ---, ---
|
x, y, z_inv: field.Tight_Field_Element = ---, ---, ---
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ sc_set_bytes :: proc "contextless" (sc: ^Scalar, b: []byte) -> bool {
|
|||||||
if len(b) != 32 {
|
if len(b) != 32 {
|
||||||
intrinsics.trap()
|
intrinsics.trap()
|
||||||
}
|
}
|
||||||
b_ := transmute(^[32]byte)(raw_data(b))
|
b_ := (^[32]byte)(raw_data(b))
|
||||||
return field.fe_from_bytes(sc, 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 {
|
if len(b) != 32 {
|
||||||
intrinsics.trap()
|
intrinsics.trap()
|
||||||
}
|
}
|
||||||
b_ := transmute(^[32]byte)(raw_data(b))
|
b_ := (^[32]byte)(raw_data(b))
|
||||||
field.fe_from_bytes_rfc8032(sc, b_)
|
field.fe_from_bytes_rfc8032(sc, b_)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,13 +6,13 @@ import "core:mem"
|
|||||||
fe_relax_cast :: #force_inline proc "contextless" (
|
fe_relax_cast :: #force_inline proc "contextless" (
|
||||||
arg1: ^Tight_Field_Element,
|
arg1: ^Tight_Field_Element,
|
||||||
) -> ^Loose_Field_Element {
|
) -> ^Loose_Field_Element {
|
||||||
return transmute(^Loose_Field_Element)(arg1)
|
return (^Loose_Field_Element)(arg1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fe_tighten_cast :: #force_inline proc "contextless" (
|
fe_tighten_cast :: #force_inline proc "contextless" (
|
||||||
arg1: ^Loose_Field_Element,
|
arg1: ^Loose_Field_Element,
|
||||||
) -> ^Tight_Field_Element {
|
) -> ^Tight_Field_Element {
|
||||||
return transmute(^Tight_Field_Element)(arg1)
|
return (^Tight_Field_Element)(arg1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fe_clear :: proc "contextless" (
|
fe_clear :: proc "contextless" (
|
||||||
|
|||||||
@@ -7,13 +7,13 @@ import "core:mem"
|
|||||||
fe_relax_cast :: #force_inline proc "contextless" (
|
fe_relax_cast :: #force_inline proc "contextless" (
|
||||||
arg1: ^Tight_Field_Element,
|
arg1: ^Tight_Field_Element,
|
||||||
) -> ^Loose_Field_Element {
|
) -> ^Loose_Field_Element {
|
||||||
return transmute(^Loose_Field_Element)(arg1)
|
return (^Loose_Field_Element)(arg1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fe_tighten_cast :: #force_inline proc "contextless" (
|
fe_tighten_cast :: #force_inline proc "contextless" (
|
||||||
arg1: ^Loose_Field_Element,
|
arg1: ^Loose_Field_Element,
|
||||||
) -> ^Tight_Field_Element {
|
) -> ^Tight_Field_Element {
|
||||||
return transmute(^Tight_Field_Element)(arg1)
|
return (^Tight_Field_Element)(arg1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fe_from_bytes :: #force_inline proc "contextless" (
|
fe_from_bytes :: #force_inline proc "contextless" (
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ init_256 :: proc(ctx: ^Context, key, domain_sep: []byte) {
|
|||||||
update :: proc(ctx: ^Context, data: []byte) {
|
update :: proc(ctx: ^Context, data: []byte) {
|
||||||
assert(ctx.is_initialized)
|
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
|
// 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")
|
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.
|
// clone clones the Context other into ctx.
|
||||||
@@ -84,7 +84,7 @@ clone :: proc(ctx, other: ^Context) {
|
|||||||
return
|
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
|
// reset sanitizes the Context. The Context must be re-initialized to
|
||||||
@@ -94,7 +94,7 @@ reset :: proc(ctx: ^Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
shake.reset(transmute(^shake.Context)(ctx))
|
shake.reset((^shake.Context)(ctx))
|
||||||
}
|
}
|
||||||
|
|
||||||
@(private)
|
@(private)
|
||||||
@@ -107,7 +107,7 @@ _init_kmac :: proc(ctx: ^Context, key, s: []byte, sec_strength: int) {
|
|||||||
panic("crypto/kmac: invalid KMAC key, too short")
|
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.init_cshake(ctx_, N_KMAC, s, sec_strength)
|
||||||
_sha3.bytepad(ctx_, [][]byte{key}, _sha3.rate_cshake(sec_strength))
|
_sha3.bytepad(ctx_, [][]byte{key}, _sha3.rate_cshake(sec_strength))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,12 +66,12 @@ init_512 :: proc(ctx: ^Context) {
|
|||||||
@(private)
|
@(private)
|
||||||
_init :: proc(ctx: ^Context) {
|
_init :: proc(ctx: ^Context) {
|
||||||
ctx.dsbyte = _sha3.DS_KECCAK
|
ctx.dsbyte = _sha3.DS_KECCAK
|
||||||
_sha3.init(transmute(^_sha3.Context)(ctx))
|
_sha3.init((^_sha3.Context)(ctx))
|
||||||
}
|
}
|
||||||
|
|
||||||
// update adds more data to the Context.
|
// update adds more data to the Context.
|
||||||
update :: proc(ctx: ^Context, data: []byte) {
|
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
|
// 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,
|
// Iff finalize_clone is set, final will work on a copy of the Context,
|
||||||
// which is useful for for calculating rolling digests.
|
// which is useful for for calculating rolling digests.
|
||||||
final :: proc(ctx: ^Context, hash: []byte, finalize_clone: bool = false) {
|
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 clones the Context other into ctx.
|
||||||
clone :: proc(ctx, other: ^Context) {
|
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
|
// reset sanitizes the Context. The Context must be re-initialized to
|
||||||
// be used again.
|
// be used again.
|
||||||
reset :: proc(ctx: ^Context) {
|
reset :: proc(ctx: ^Context) {
|
||||||
_sha3.reset(transmute(^_sha3.Context)(ctx))
|
_sha3.reset((^_sha3.Context)(ctx))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ ge_set_bytes :: proc "contextless" (ge: ^Group_Element, b: []byte) -> bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
b_ := transmute(^[32]byte)(raw_data(b))
|
b_ := (^[32]byte)(raw_data(b))
|
||||||
|
|
||||||
s: field.Tight_Field_Element = ---
|
s: field.Tight_Field_Element = ---
|
||||||
defer field.fe_clear(&s)
|
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
|
// 2. Return the 32-byte little-endian encoding of s. More
|
||||||
// specifically, this is the encoding of the canonical
|
// specifically, this is the encoding of the canonical
|
||||||
// representation of s as an integer between 0 and p-1, inclusive.
|
// 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_to_bytes(dst_, &tmp)
|
||||||
|
|
||||||
field.fe_clear_vec([]^field.Tight_Field_Element{&u1, &u2, &tmp, &z_inv, &ix0, &iy0, &x, &y})
|
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)
|
@(private)
|
||||||
ge_map :: proc "contextless" (ge: ^Group_Element, b: []byte) {
|
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:
|
// The MAP function is defined on 32-byte strings as:
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ sc_set_bytes_wide :: proc(sc: ^Scalar, b: []byte) {
|
|||||||
panic("crypto/ristretto255: invalid wide input size")
|
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_)
|
grp.sc_set_bytes_wide(sc, b_)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,12 +68,12 @@ init_512 :: proc(ctx: ^Context) {
|
|||||||
@(private)
|
@(private)
|
||||||
_init :: proc(ctx: ^Context) {
|
_init :: proc(ctx: ^Context) {
|
||||||
ctx.dsbyte = _sha3.DS_SHA3
|
ctx.dsbyte = _sha3.DS_SHA3
|
||||||
_sha3.init(transmute(^_sha3.Context)(ctx))
|
_sha3.init((^_sha3.Context)(ctx))
|
||||||
}
|
}
|
||||||
|
|
||||||
// update adds more data to the Context.
|
// update adds more data to the Context.
|
||||||
update :: proc(ctx: ^Context, data: []byte) {
|
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
|
// 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,
|
// Iff finalize_clone is set, final will work on a copy of the Context,
|
||||||
// which is useful for for calculating rolling digests.
|
// which is useful for for calculating rolling digests.
|
||||||
final :: proc(ctx: ^Context, hash: []byte, finalize_clone: bool = false) {
|
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 clones the Context other into ctx.
|
||||||
clone :: proc(ctx, other: ^Context) {
|
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
|
// reset sanitizes the Context. The Context must be re-initialized to
|
||||||
// be used again.
|
// be used again.
|
||||||
reset :: proc(ctx: ^Context) {
|
reset :: proc(ctx: ^Context) {
|
||||||
_sha3.reset(transmute(^_sha3.Context)(ctx))
|
_sha3.reset((^_sha3.Context)(ctx))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,35 +24,35 @@ Context :: distinct _sha3.Context
|
|||||||
|
|
||||||
// init_128 initializes a Context for SHAKE128.
|
// init_128 initializes a Context for SHAKE128.
|
||||||
init_128 :: proc(ctx: ^Context) {
|
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 initializes a Context for SHAKE256.
|
||||||
init_256 :: proc(ctx: ^Context) {
|
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 initializes a Context for cSHAKE128.
|
||||||
init_cshake_128 :: proc(ctx: ^Context, domain_sep: []byte) {
|
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 initializes a Context for cSHAKE256.
|
||||||
init_cshake_256 :: proc(ctx: ^Context, domain_sep: []byte) {
|
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
|
// 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.
|
// after any reads have been done, and attempts to do so will panic.
|
||||||
write :: proc(ctx: ^Context, data: []byte) {
|
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
|
// 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
|
// 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.
|
// been called one or more times, further calls to write will panic.
|
||||||
read :: proc(ctx: ^Context, dst: []byte) {
|
read :: proc(ctx: ^Context, dst: []byte) {
|
||||||
ctx_ := transmute(^_sha3.Context)(ctx)
|
ctx_ := (^_sha3.Context)(ctx)
|
||||||
if !ctx.is_finalized {
|
if !ctx.is_finalized {
|
||||||
_sha3.shake_xof(ctx_)
|
_sha3.shake_xof(ctx_)
|
||||||
}
|
}
|
||||||
@@ -62,11 +62,11 @@ read :: proc(ctx: ^Context, dst: []byte) {
|
|||||||
|
|
||||||
// clone clones the Context other into ctx.
|
// clone clones the Context other into ctx.
|
||||||
clone :: proc(ctx, other: ^Context) {
|
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
|
// reset sanitizes the Context. The Context must be re-initialized to
|
||||||
// be used again.
|
// be used again.
|
||||||
reset :: proc(ctx: ^Context) {
|
reset :: proc(ctx: ^Context) {
|
||||||
_sha3.reset(transmute(^_sha3.Context)(ctx))
|
_sha3.reset((^_sha3.Context)(ctx))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,19 +13,19 @@ Context :: distinct _sha3.Context
|
|||||||
|
|
||||||
// init_128 initializes a Context for TupleHash128 or TupleHashXOF128.
|
// init_128 initializes a Context for TupleHash128 or TupleHashXOF128.
|
||||||
init_128 :: proc(ctx: ^Context, domain_sep: []byte) {
|
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 initializes a Context for TupleHash256 or TupleHashXOF256.
|
||||||
init_256 :: proc(ctx: ^Context, domain_sep: []byte) {
|
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
|
// write_element writes a tuple element into the TupleHash or TupleHashXOF
|
||||||
// instance. This MUST not be called after any reads have been done, and
|
// instance. This MUST not be called after any reads have been done, and
|
||||||
// any attempts to do so will panic.
|
// any attempts to do so will panic.
|
||||||
write_element :: proc(ctx: ^Context, data: []byte) {
|
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
|
// 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,
|
// Iff finalize_clone is set, final will work on a copy of the Context,
|
||||||
// which is useful for for calculating rolling digests.
|
// which is useful for for calculating rolling digests.
|
||||||
final :: proc(ctx: ^Context, hash: []byte, finalize_clone: bool = false) {
|
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
|
// 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
|
// After read has been called one or more times, further calls to
|
||||||
// write_element will panic.
|
// write_element will panic.
|
||||||
read :: proc(ctx: ^Context, dst: []byte) {
|
read :: proc(ctx: ^Context, dst: []byte) {
|
||||||
ctx_ := transmute(^_sha3.Context)(ctx)
|
ctx_ := (^_sha3.Context)(ctx)
|
||||||
if !ctx.is_finalized {
|
if !ctx.is_finalized {
|
||||||
_sha3.encode_byte_len(ctx_, 0, false) // right_encode
|
_sha3.encode_byte_len(ctx_, 0, false) // right_encode
|
||||||
_sha3.shake_xof(ctx_)
|
_sha3.shake_xof(ctx_)
|
||||||
@@ -53,13 +53,13 @@ read :: proc(ctx: ^Context, dst: []byte) {
|
|||||||
|
|
||||||
// clone clones the Context other into ctx.
|
// clone clones the Context other into ctx.
|
||||||
clone :: proc(ctx, other: ^Context) {
|
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
|
// reset sanitizes the Context. The Context must be re-initialized to
|
||||||
// be used again.
|
// be used again.
|
||||||
reset :: proc(ctx: ^Context) {
|
reset :: proc(ctx: ^Context) {
|
||||||
_sha3.reset(transmute(^_sha3.Context)(ctx))
|
_sha3.reset((^_sha3.Context)(ctx))
|
||||||
}
|
}
|
||||||
|
|
||||||
@(private)
|
@(private)
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ _Context :: struct {
|
|||||||
|
|
||||||
@(private="package")
|
@(private="package")
|
||||||
_init :: proc(ctx: ^Context) -> (ok: bool) {
|
_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)
|
ctx.impl.state = backtrace_create_state("odin-debug-trace", 1, nil, ctx)
|
||||||
return ctx.impl.state != nil
|
return ctx.impl.state != nil
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
//+build !windows !linux !darwin
|
//+build !windows !linux !darwin
|
||||||
package debug_trace
|
package debug_trace
|
||||||
|
|
||||||
|
import "base:runtime"
|
||||||
|
|
||||||
_Context :: struct {
|
_Context :: struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -10,9 +12,9 @@ _init :: proc(ctx: ^Context) -> (ok: bool) {
|
|||||||
_destroy :: proc(ctx: ^Context) -> bool {
|
_destroy :: proc(ctx: ^Context) -> bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
_frames :: proc(ctx: ^Context, skip: uint, allocator: runtime.Allocator) -> []Frame {
|
_frames :: proc(ctx: ^Context, skip: uint, frames_buffer: []Frame) -> []Frame {
|
||||||
return nil
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -233,7 +233,7 @@ encode_into_encoder :: proc(e: Encoder, v: Value, loc := #caller_location) -> En
|
|||||||
|
|
||||||
if .Self_Described_CBOR in e.flags {
|
if .Self_Described_CBOR in e.flags {
|
||||||
_encode_u64(e, TAG_SELF_DESCRIBED_CBOR, .Tag) or_return
|
_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 {
|
switch v_spec in v {
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ marshal_into_encoder :: proc(e: Encoder, v: any, loc := #caller_location) -> (e
|
|||||||
|
|
||||||
if .Self_Described_CBOR in e.flags {
|
if .Self_Described_CBOR in e.flags {
|
||||||
err_conv(_encode_u64(e, TAG_SELF_DESCRIBED_CBOR, .Tag)) or_return
|
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 {
|
if v == nil {
|
||||||
|
|||||||
@@ -95,7 +95,6 @@ tag_register_number :: proc(impl: Tag_Implementation, nr: Tag_Number, id: string
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Controls initialization of default tag implementations.
|
// 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)
|
INITIALIZE_DEFAULT_TAGS :: #config(CBOR_INITIALIZE_DEFAULT_TAGS, !ODIN_DEFAULT_TO_PANIC_ALLOCATOR && !ODIN_DEFAULT_TO_NIL_ALLOCATOR)
|
||||||
|
|
||||||
@(private, init, disabled=!INITIALIZE_DEFAULT_TAGS)
|
@(private, init, disabled=!INITIALIZE_DEFAULT_TAGS)
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
|
|||||||
case runtime.Type_Info_Array:
|
case runtime.Type_Info_Array:
|
||||||
opt_write_start(w, opt, '[') or_return
|
opt_write_start(w, opt, '[') or_return
|
||||||
for i in 0..<info.count {
|
for i in 0..<info.count {
|
||||||
opt_write_iteration(w, opt, i) or_return
|
opt_write_iteration(w, opt, i == 0) or_return
|
||||||
data := uintptr(v.data) + uintptr(i*info.elem_size)
|
data := uintptr(v.data) + uintptr(i*info.elem_size)
|
||||||
marshal_to_writer(w, any{rawptr(data), info.elem.id}, opt) or_return
|
marshal_to_writer(w, any{rawptr(data), info.elem.id}, opt) or_return
|
||||||
}
|
}
|
||||||
@@ -248,7 +248,7 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
|
|||||||
case runtime.Type_Info_Enumerated_Array:
|
case runtime.Type_Info_Enumerated_Array:
|
||||||
opt_write_start(w, opt, '[') or_return
|
opt_write_start(w, opt, '[') or_return
|
||||||
for i in 0..<info.count {
|
for i in 0..<info.count {
|
||||||
opt_write_iteration(w, opt, i) or_return
|
opt_write_iteration(w, opt, i == 0) or_return
|
||||||
data := uintptr(v.data) + uintptr(i*info.elem_size)
|
data := uintptr(v.data) + uintptr(i*info.elem_size)
|
||||||
marshal_to_writer(w, any{rawptr(data), info.elem.id}, opt) or_return
|
marshal_to_writer(w, any{rawptr(data), info.elem.id}, opt) or_return
|
||||||
}
|
}
|
||||||
@@ -258,7 +258,7 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
|
|||||||
opt_write_start(w, opt, '[') or_return
|
opt_write_start(w, opt, '[') or_return
|
||||||
array := cast(^mem.Raw_Dynamic_Array)v.data
|
array := cast(^mem.Raw_Dynamic_Array)v.data
|
||||||
for i in 0..<array.len {
|
for i in 0..<array.len {
|
||||||
opt_write_iteration(w, opt, i) or_return
|
opt_write_iteration(w, opt, i == 0) or_return
|
||||||
data := uintptr(array.data) + uintptr(i*info.elem_size)
|
data := uintptr(array.data) + uintptr(i*info.elem_size)
|
||||||
marshal_to_writer(w, any{rawptr(data), info.elem.id}, opt) or_return
|
marshal_to_writer(w, any{rawptr(data), info.elem.id}, opt) or_return
|
||||||
}
|
}
|
||||||
@@ -268,7 +268,7 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
|
|||||||
opt_write_start(w, opt, '[') or_return
|
opt_write_start(w, opt, '[') or_return
|
||||||
slice := cast(^mem.Raw_Slice)v.data
|
slice := cast(^mem.Raw_Slice)v.data
|
||||||
for i in 0..<slice.len {
|
for i in 0..<slice.len {
|
||||||
opt_write_iteration(w, opt, i) or_return
|
opt_write_iteration(w, opt, i == 0) or_return
|
||||||
data := uintptr(slice.data) + uintptr(i*info.elem_size)
|
data := uintptr(slice.data) + uintptr(i*info.elem_size)
|
||||||
marshal_to_writer(w, any{rawptr(data), info.elem.id}, opt) or_return
|
marshal_to_writer(w, any{rawptr(data), info.elem.id}, opt) or_return
|
||||||
}
|
}
|
||||||
@@ -290,7 +290,7 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
|
|||||||
for bucket_index in 0..<map_cap {
|
for bucket_index in 0..<map_cap {
|
||||||
runtime.map_hash_is_valid(hs[bucket_index]) or_continue
|
runtime.map_hash_is_valid(hs[bucket_index]) or_continue
|
||||||
|
|
||||||
opt_write_iteration(w, opt, i) or_return
|
opt_write_iteration(w, opt, i == 0) or_return
|
||||||
i += 1
|
i += 1
|
||||||
|
|
||||||
key := rawptr(runtime.map_cell_index_dynamic(ks, info.map_info.ks, bucket_index))
|
key := rawptr(runtime.map_cell_index_dynamic(ks, info.map_info.ks, bucket_index))
|
||||||
@@ -356,7 +356,7 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
|
|||||||
slice.sort_by(sorted[:], proc(i, j: Entry) -> bool { return i.key < j.key })
|
slice.sort_by(sorted[:], proc(i, j: Entry) -> bool { return i.key < j.key })
|
||||||
|
|
||||||
for s, i in sorted {
|
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
|
opt_write_key(w, opt, s.key) or_return
|
||||||
marshal_to_writer(w, s.value, opt) or_return
|
marshal_to_writer(w, s.value, opt) or_return
|
||||||
}
|
}
|
||||||
@@ -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) {
|
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))
|
ti := runtime.type_info_base(type_info_of(v.id))
|
||||||
info := ti.variant.(runtime.Type_Info_Struct)
|
info := ti.variant.(runtime.Type_Info_Struct)
|
||||||
|
first_iteration := true
|
||||||
for name, i in info.names {
|
for name, i in info.names {
|
||||||
omitempty := false
|
omitempty := false
|
||||||
|
|
||||||
@@ -424,7 +425,8 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
opt_write_iteration(w, opt, i) or_return
|
opt_write_iteration(w, opt, first_iteration) or_return
|
||||||
|
first_iteration = false
|
||||||
if json_name != "" {
|
if json_name != "" {
|
||||||
opt_write_key(w, opt, json_name) or_return
|
opt_write_key(w, opt, json_name) or_return
|
||||||
} else {
|
} 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
|
// 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 {
|
switch opt.spec {
|
||||||
case .JSON, .JSON5:
|
case .JSON, .JSON5:
|
||||||
if iteration > 0 {
|
if !first_iteration {
|
||||||
io.write_byte(w, ',') or_return
|
io.write_byte(w, ',') or_return
|
||||||
|
|
||||||
if opt.pretty {
|
if opt.pretty {
|
||||||
@@ -602,7 +604,7 @@ opt_write_iteration :: proc(w: io.Writer, opt: ^Marshal_Options, iteration: int)
|
|||||||
opt_write_indentation(w, opt) or_return
|
opt_write_indentation(w, opt) or_return
|
||||||
|
|
||||||
case .MJSON:
|
case .MJSON:
|
||||||
if iteration > 0 {
|
if !first_iteration {
|
||||||
// on pretty no commas necessary
|
// on pretty no commas necessary
|
||||||
if opt.pretty {
|
if opt.pretty {
|
||||||
io.write_byte(w, '\n') or_return
|
io.write_byte(w, '\n') or_return
|
||||||
|
|||||||
@@ -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.
|
||||||
@@ -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,
|
||||||
|
}
|
||||||
@@ -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
|
||||||
@@ -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,
|
||||||
|
}
|
||||||
@@ -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,
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
@@ -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,
|
||||||
|
}
|
||||||
@@ -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,
|
||||||
|
}
|
||||||
+101
-108
@@ -45,45 +45,45 @@ parse_and_set_pointer_by_base_type :: proc(ptr: rawptr, str: string, type_info:
|
|||||||
if specific_type_info.signed {
|
if specific_type_info.signed {
|
||||||
value := strconv.parse_i128(str) or_return
|
value := strconv.parse_i128(str) or_return
|
||||||
switch type_info.id {
|
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 i8: (^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 i16: (^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 i32: (^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 i64: (^i64) (ptr)^ = cast(i64) bounded_int(value, cast(i128)min(i64), cast(i128)max(i64) ) or_return
|
||||||
case i128: (cast(^i128) ptr)^ = value
|
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 i16le: (^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 i32le: (^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 i64le: (^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 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 i16be: (^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 i32be: (^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 i64be: (^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 i128be: (^i128be)(ptr)^ = cast(i128be) bounded_int(value, cast(i128)min(i128be), cast(i128)max(i128be)) or_return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
value := strconv.parse_u128(str) or_return
|
value := strconv.parse_u128(str) or_return
|
||||||
switch type_info.id {
|
switch type_info.id {
|
||||||
case u8: (cast(^u8) ptr)^ = cast(u8) bounded_uint(value, cast(u128)max(u8) ) or_return
|
case u8: (^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 u16: (^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 u32: (^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 u64: (^u64) (ptr)^ = cast(u64) bounded_uint(value, cast(u128)max(u64) ) or_return
|
||||||
case u128: (cast(^u128) ptr)^ = value
|
case u128: (^u128) (ptr)^ = value
|
||||||
|
|
||||||
case uint: (cast(^uint) ptr)^ = cast(uint) bounded_uint(value, cast(u128)max(uint) ) or_return
|
case uint: (^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 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 u16le: (^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 u32le: (^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 u64le: (^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 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 u16be: (^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 u32be: (^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 u64be: (^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 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
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
(cast(^rune)ptr)^ = utf8.rune_at_pos(str, 0)
|
(^rune)(ptr)^ = utf8.rune_at_pos(str, 0)
|
||||||
|
|
||||||
case runtime.Type_Info_Float:
|
case runtime.Type_Info_Float:
|
||||||
value := strconv.parse_f64(str) or_return
|
value := strconv.parse_f64(str) or_return
|
||||||
switch type_info.id {
|
switch type_info.id {
|
||||||
case f16: (cast(^f16) ptr)^ = cast(f16) value
|
case f16: (^f16) (ptr)^ = cast(f16) value
|
||||||
case f32: (cast(^f32) ptr)^ = cast(f32) value
|
case f32: (^f32) (ptr)^ = cast(f32) value
|
||||||
case f64: (cast(^f64) ptr)^ = value
|
case f64: (^f64) (ptr)^ = value
|
||||||
|
|
||||||
case f16le: (cast(^f16le)ptr)^ = cast(f16le) value
|
case f16le: (^f16le)(ptr)^ = cast(f16le) value
|
||||||
case f32le: (cast(^f32le)ptr)^ = cast(f32le) value
|
case f32le: (^f32le)(ptr)^ = cast(f32le) value
|
||||||
case f64le: (cast(^f64le)ptr)^ = cast(f64le) value
|
case f64le: (^f64le)(ptr)^ = cast(f64le) value
|
||||||
|
|
||||||
case f16be: (cast(^f16be)ptr)^ = cast(f16be) value
|
case f16be: (^f16be)(ptr)^ = cast(f16be) value
|
||||||
case f32be: (cast(^f32be)ptr)^ = cast(f32be) value
|
case f32be: (^f32be)(ptr)^ = cast(f32be) value
|
||||||
case f64be: (cast(^f64be)ptr)^ = cast(f64be) value
|
case f64be: (^f64be)(ptr)^ = cast(f64be) value
|
||||||
}
|
}
|
||||||
|
|
||||||
case runtime.Type_Info_Complex:
|
case runtime.Type_Info_Complex:
|
||||||
value := strconv.parse_complex128(str) or_return
|
value := strconv.parse_complex128(str) or_return
|
||||||
switch type_info.id {
|
switch type_info.id {
|
||||||
case complex128: (cast(^complex128)ptr)^ = value
|
case complex32: (^complex32) (ptr)^ = (complex32)(value)
|
||||||
case complex64: (cast(^complex64) ptr)^ = cast(complex64)value
|
case complex64: (^complex64) (ptr)^ = (complex64)(value)
|
||||||
case complex32: (cast(^complex32) ptr)^ = cast(complex32)value
|
case complex128: (^complex128)(ptr)^ = value
|
||||||
}
|
}
|
||||||
|
|
||||||
case runtime.Type_Info_Quaternion:
|
case runtime.Type_Info_Quaternion:
|
||||||
value := strconv.parse_quaternion256(str) or_return
|
value := strconv.parse_quaternion256(str) or_return
|
||||||
switch type_info.id {
|
switch type_info.id {
|
||||||
case quaternion256: (cast(^quaternion256)ptr)^ = value
|
case quaternion64: (^quaternion64) (ptr)^ = (quaternion64)(value)
|
||||||
case quaternion128: (cast(^quaternion128)ptr)^ = cast(quaternion128)value
|
case quaternion128: (^quaternion128)(ptr)^ = (quaternion128)(value)
|
||||||
case quaternion64: (cast(^quaternion64) ptr)^ = cast(quaternion64)value
|
case quaternion256: (^quaternion256)(ptr)^ = value
|
||||||
}
|
}
|
||||||
|
|
||||||
case runtime.Type_Info_String:
|
case runtime.Type_Info_String:
|
||||||
if specific_type_info.is_cstring {
|
if specific_type_info.is_cstring {
|
||||||
cstr_ptr := cast(^cstring)ptr
|
cstr_ptr := (^cstring)(ptr)
|
||||||
if cstr_ptr != nil {
|
if cstr_ptr != nil {
|
||||||
// Prevent memory leaks from us setting this value multiple times.
|
// Prevent memory leaks from us setting this value multiple times.
|
||||||
delete(cstr_ptr^)
|
delete(cstr_ptr^)
|
||||||
}
|
}
|
||||||
cstr_ptr^ = strings.clone_to_cstring(str)
|
cstr_ptr^ = strings.clone_to_cstring(str)
|
||||||
} else {
|
} else {
|
||||||
(cast(^string)ptr)^ = str
|
(^string)(ptr)^ = str
|
||||||
}
|
}
|
||||||
|
|
||||||
case runtime.Type_Info_Boolean:
|
case runtime.Type_Info_Boolean:
|
||||||
value := strconv.parse_bool(str) or_return
|
value := strconv.parse_bool(str) or_return
|
||||||
switch type_info.id {
|
switch type_info.id {
|
||||||
case bool: (cast(^bool) ptr)^ = value
|
case bool: (^bool)(ptr)^ = value
|
||||||
case b8: (cast(^b8) ptr)^ = cast(b8) value
|
case b8: (^b8) (ptr)^ = b8(value)
|
||||||
case b16: (cast(^b16) ptr)^ = cast(b16) value
|
case b16: (^b16) (ptr)^ = b16(value)
|
||||||
case b32: (cast(^b32) ptr)^ = cast(b32) value
|
case b32: (^b32) (ptr)^ = b32(value)
|
||||||
case b64: (cast(^b64) ptr)^ = cast(b64) value
|
case b64: (^b64) (ptr)^ = b64(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
case runtime.Type_Info_Bit_Set:
|
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
|
value: u128
|
||||||
|
|
||||||
// NOTE: `upper` is inclusive, i.e: `0..=31`
|
// NOTE: `upper` is inclusive, i.e: `0..=31`
|
||||||
max_bit_index := cast(u128)(1 + specific_type_info.upper - specific_type_info.lower)
|
max_bit_index := u128(1 + specific_type_info.upper - specific_type_info.lower)
|
||||||
bit_index : u128 = 0
|
bit_index := u128(0)
|
||||||
#no_bounds_check for string_index : uint = 0; string_index < len(str); string_index += 1 {
|
#no_bounds_check for string_index in 0..<uint(len(str)) {
|
||||||
if bit_index == max_bit_index {
|
if bit_index == max_bit_index {
|
||||||
// The string's too long for this bit_set.
|
// The string's too long for this bit_set.
|
||||||
return false
|
return false
|
||||||
@@ -180,11 +180,11 @@ parse_and_set_pointer_by_base_type :: proc(ptr: rawptr, str: string, type_info:
|
|||||||
set_unbounded_integer_by_type(ptr, value, specific_type_info.underlying.id)
|
set_unbounded_integer_by_type(ptr, value, specific_type_info.underlying.id)
|
||||||
} else {
|
} else {
|
||||||
switch 8*type_info.size {
|
switch 8*type_info.size {
|
||||||
case 8: (cast(^u8) ptr)^ = cast(u8) value
|
case 8: (^u8) (ptr)^ = cast(u8) value
|
||||||
case 16: (cast(^u16) ptr)^ = cast(u16) value
|
case 16: (^u16) (ptr)^ = cast(u16) value
|
||||||
case 32: (cast(^u32) ptr)^ = cast(u32) value
|
case 32: (^u32) (ptr)^ = cast(u32) value
|
||||||
case 64: (cast(^u64) ptr)^ = cast(u64) value
|
case 64: (^u64) (ptr)^ = cast(u64) value
|
||||||
case 128: (cast(^u128) ptr)^ = cast(u128) value
|
case 128: (^u128)(ptr)^ = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,7 +222,7 @@ parse_and_set_pointer_by_named_type :: proc(ptr: rawptr, str: string, data_type:
|
|||||||
mode: int
|
mode: int
|
||||||
|
|
||||||
if file, ok := get_struct_subtag(arg_tag, SUBTAG_FILE); ok {
|
if file, ok := get_struct_subtag(arg_tag, SUBTAG_FILE); ok {
|
||||||
for i := 0; i < len(file); i += 1 {
|
for i in 0..<len(file) {
|
||||||
#no_bounds_check switch file[i] {
|
#no_bounds_check switch file[i] {
|
||||||
case 'r': wants_read = true
|
case 'r': wants_read = true
|
||||||
case 'w': wants_write = true
|
case 'w': wants_write = true
|
||||||
@@ -249,7 +249,7 @@ parse_and_set_pointer_by_named_type :: proc(ptr: rawptr, str: string, data_type:
|
|||||||
|
|
||||||
if permstr, ok := get_struct_subtag(arg_tag, SUBTAG_PERMS); ok {
|
if permstr, ok := get_struct_subtag(arg_tag, SUBTAG_PERMS); ok {
|
||||||
if value, parse_ok := strconv.parse_u64_of_base(permstr, 8); parse_ok {
|
if value, parse_ok := strconv.parse_u64_of_base(permstr, 8); parse_ok {
|
||||||
perms = cast(int)value
|
perms = int(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,7 +271,7 @@ parse_and_set_pointer_by_named_type :: proc(ptr: rawptr, str: string, data_type:
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
(cast(^os.Handle)ptr)^ = handle
|
(^os.Handle)(ptr)^ = handle
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -289,7 +289,7 @@ parse_and_set_pointer_by_named_type :: proc(ptr: rawptr, str: string, data_type:
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
(cast(^time.Time)ptr)^ = res
|
(^time.Time)(ptr)^ = res
|
||||||
return
|
return
|
||||||
} else if data_type == datetime.DateTime {
|
} else if data_type == datetime.DateTime {
|
||||||
// NOTE: The UTC offset and leap second data are discarded.
|
// NOTE: The UTC offset and leap second data are discarded.
|
||||||
@@ -302,7 +302,7 @@ parse_and_set_pointer_by_named_type :: proc(ptr: rawptr, str: string, data_type:
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
(cast(^datetime.DateTime)ptr)^ = res
|
(^datetime.DateTime)(ptr)^ = res
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -323,44 +323,44 @@ parse_and_set_pointer_by_named_type :: proc(ptr: rawptr, str: string, data_type:
|
|||||||
@(optimization_mode="size")
|
@(optimization_mode="size")
|
||||||
set_unbounded_integer_by_type :: proc(ptr: rawptr, value: $T, data_type: typeid) where intrinsics.type_is_integer(T) {
|
set_unbounded_integer_by_type :: proc(ptr: rawptr, value: $T, data_type: typeid) where intrinsics.type_is_integer(T) {
|
||||||
switch data_type {
|
switch data_type {
|
||||||
case i8: (cast(^i8) ptr)^ = cast(i8) value
|
case i8: (^i8) (ptr)^ = cast(i8) value
|
||||||
case i16: (cast(^i16) ptr)^ = cast(i16) value
|
case i16: (^i16) (ptr)^ = cast(i16) value
|
||||||
case i32: (cast(^i32) ptr)^ = cast(i32) value
|
case i32: (^i32) (ptr)^ = cast(i32) value
|
||||||
case i64: (cast(^i64) ptr)^ = cast(i64) value
|
case i64: (^i64) (ptr)^ = cast(i64) value
|
||||||
case i128: (cast(^i128) ptr)^ = cast(i128) value
|
case i128: (^i128) (ptr)^ = cast(i128) value
|
||||||
|
|
||||||
case int: (cast(^int) ptr)^ = cast(int) value
|
case int: (^int) (ptr)^ = cast(int) value
|
||||||
|
|
||||||
case i16le: (cast(^i16le) ptr)^ = cast(i16le) value
|
case i16le: (^i16le) (ptr)^ = cast(i16le) value
|
||||||
case i32le: (cast(^i32le) ptr)^ = cast(i32le) value
|
case i32le: (^i32le) (ptr)^ = cast(i32le) value
|
||||||
case i64le: (cast(^i64le) ptr)^ = cast(i64le) value
|
case i64le: (^i64le) (ptr)^ = cast(i64le) value
|
||||||
case i128le: (cast(^i128le) ptr)^ = cast(i128le) value
|
case i128le: (^i128le) (ptr)^ = cast(i128le) value
|
||||||
|
|
||||||
case i16be: (cast(^i16be) ptr)^ = cast(i16be) value
|
case i16be: (^i16be) (ptr)^ = cast(i16be) value
|
||||||
case i32be: (cast(^i32be) ptr)^ = cast(i32be) value
|
case i32be: (^i32be) (ptr)^ = cast(i32be) value
|
||||||
case i64be: (cast(^i64be) ptr)^ = cast(i64be) value
|
case i64be: (^i64be) (ptr)^ = cast(i64be) value
|
||||||
case i128be: (cast(^i128be) ptr)^ = cast(i128be) value
|
case i128be: (^i128be) (ptr)^ = cast(i128be) value
|
||||||
|
|
||||||
case u8: (cast(^u8) ptr)^ = cast(u8) value
|
case u8: (^u8) (ptr)^ = cast(u8) value
|
||||||
case u16: (cast(^u16) ptr)^ = cast(u16) value
|
case u16: (^u16) (ptr)^ = cast(u16) value
|
||||||
case u32: (cast(^u32) ptr)^ = cast(u32) value
|
case u32: (^u32) (ptr)^ = cast(u32) value
|
||||||
case u64: (cast(^u64) ptr)^ = cast(u64) value
|
case u64: (^u64) (ptr)^ = cast(u64) value
|
||||||
case u128: (cast(^u128) ptr)^ = cast(u128) value
|
case u128: (^u128) (ptr)^ = cast(u128) value
|
||||||
|
|
||||||
case uint: (cast(^uint) ptr)^ = cast(uint) value
|
case uint: (^uint) (ptr)^ = cast(uint) value
|
||||||
case uintptr: (cast(^uintptr)ptr)^ = cast(uintptr) value
|
case uintptr: (^uintptr)(ptr)^ = cast(uintptr) value
|
||||||
|
|
||||||
case u16le: (cast(^u16le) ptr)^ = cast(u16le) value
|
case u16le: (^u16le) (ptr)^ = cast(u16le) value
|
||||||
case u32le: (cast(^u32le) ptr)^ = cast(u32le) value
|
case u32le: (^u32le) (ptr)^ = cast(u32le) value
|
||||||
case u64le: (cast(^u64le) ptr)^ = cast(u64le) value
|
case u64le: (^u64le) (ptr)^ = cast(u64le) value
|
||||||
case u128le: (cast(^u128le) ptr)^ = cast(u128le) value
|
case u128le: (^u128le) (ptr)^ = cast(u128le) value
|
||||||
|
|
||||||
case u16be: (cast(^u16be) ptr)^ = cast(u16be) value
|
case u16be: (^u16be) (ptr)^ = cast(u16be) value
|
||||||
case u32be: (cast(^u32be) ptr)^ = cast(u32be) value
|
case u32be: (^u32be) (ptr)^ = cast(u32be) value
|
||||||
case u64be: (cast(^u64be) ptr)^ = cast(u64be) value
|
case u64be: (^u64be) (ptr)^ = cast(u64be) value
|
||||||
case u128be: (cast(^u128be) ptr)^ = cast(u128be) value
|
case u128be: (^u128be) (ptr)^ = cast(u128be) value
|
||||||
|
|
||||||
case rune: (cast(^rune) ptr)^ = cast(rune) value
|
case rune: (^rune) (ptr)^ = cast(rune) value
|
||||||
|
|
||||||
case:
|
case:
|
||||||
fmt.panicf("Unsupported integer backing type: %v", data_type)
|
fmt.panicf("Unsupported integer backing type: %v", data_type)
|
||||||
@@ -443,9 +443,9 @@ parse_and_set_pointer_by_type :: proc(ptr: rawptr, str: string, type_info: ^runt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
subptr := cast(rawptr)(
|
subptr := rawptr(
|
||||||
cast(uintptr)ptr.data +
|
uintptr(ptr.data) +
|
||||||
cast(uintptr)((ptr.len - 1) * specific_type_info.elem.size))
|
uintptr((ptr.len - 1) * specific_type_info.elem.size))
|
||||||
mem.copy(subptr, raw_data(elem_backing), len(elem_backing))
|
mem.copy(subptr, raw_data(elem_backing), len(elem_backing))
|
||||||
|
|
||||||
case runtime.Type_Info_Enum:
|
case runtime.Type_Info_Enum:
|
||||||
@@ -490,7 +490,7 @@ get_field_pos :: proc(field: reflect.Struct_Field) -> (int, bool) {
|
|||||||
if args_tag, ok := reflect.struct_tag_lookup(field.tag, TAG_ARGS); ok {
|
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 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 {
|
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 a struct field by its `pos` subtag.
|
||||||
get_field_by_pos :: proc(model: ^$T, pos: int) -> (result: reflect.Struct_Field, index: int, ok: bool) {
|
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) {
|
for field, i in reflect.struct_fields_zipped(T) {
|
||||||
args_tag, tag_ok := reflect.struct_tag_lookup(field.tag, TAG_ARGS)
|
args_tag := reflect.struct_tag_lookup(field.tag, TAG_ARGS) or_continue
|
||||||
if !tag_ok {
|
pos_subtag := get_struct_subtag(args_tag, SUBTAG_POS) or_continue
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
pos_subtag, pos_ok := get_struct_subtag(args_tag, SUBTAG_POS)
|
|
||||||
if !pos_ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
value, parse_ok := strconv.parse_u64_of_base(pos_subtag, 10)
|
value, parse_ok := strconv.parse_u64_of_base(pos_subtag, 10)
|
||||||
if parse_ok && cast(int)value == pos {
|
if parse_ok && cast(int)value == pos {
|
||||||
|
|||||||
+6
-9
@@ -1072,8 +1072,8 @@ _fmt_int :: proc(fi: ^Info, u: u64, base: int, is_signed: bool, bit_size: int, d
|
|||||||
}
|
}
|
||||||
|
|
||||||
flags: strconv.Int_Flags
|
flags: strconv.Int_Flags
|
||||||
if fi.hash && !fi.zero && start == 0 { flags |= {.Prefix} }
|
if fi.hash && !fi.zero && start == 0 { flags += {.Prefix} }
|
||||||
if fi.plus { flags |= {.Plus} }
|
if fi.plus { flags += {.Plus} }
|
||||||
s := strconv.append_bits(buf[start:], u, base, is_signed, bit_size, digits, flags)
|
s := strconv.append_bits(buf[start:], u, base, is_signed, bit_size, digits, flags)
|
||||||
prev_zero := fi.zero
|
prev_zero := fi.zero
|
||||||
defer fi.zero = prev_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
|
flags: strconv.Int_Flags
|
||||||
if fi.hash && !fi.zero && start == 0 { flags |= {.Prefix} }
|
if fi.hash && !fi.zero && start == 0 { flags += {.Prefix} }
|
||||||
if fi.plus { flags |= {.Plus} }
|
if fi.plus { flags += {.Plus} }
|
||||||
s := strconv.append_bits_128(buf[start:], u, base, is_signed, bit_size, digits, flags)
|
s := strconv.append_bits_128(buf[start:], u, base, is_signed, bit_size, digits, flags)
|
||||||
|
|
||||||
if fi.hash && fi.zero && fi.indent == 0 {
|
if fi.hash && fi.zero && fi.indent == 0 {
|
||||||
@@ -1460,13 +1460,10 @@ fmt_string :: proc(fi: ^Info, s: string, verb: rune) {
|
|||||||
if !fi.minus {
|
if !fi.minus {
|
||||||
io.write_string(fi.writer, s, &fi.n)
|
io.write_string(fi.writer, s, &fi.n)
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
io.write_string(fi.writer, s, &fi.n)
|
io.write_string(fi.writer, s, &fi.n)
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
io.write_string(fi.writer, s, &fi.n)
|
io.write_string(fi.writer, s, &fi.n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -897,20 +897,21 @@ 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.
|
why (uop cache maybe?), but the difference is large and easily measurable.
|
||||||
*/
|
*/
|
||||||
@(optimization_mode="speed")
|
@(optimization_mode="speed")
|
||||||
XXH3_hashLong_64b_withSeed_internal :: #force_no_inline proc(input: []u8,
|
XXH3_hashLong_64b_withSeed_internal :: #force_no_inline proc(
|
||||||
|
input: []u8,
|
||||||
seed: xxh_u64,
|
seed: xxh_u64,
|
||||||
f_acc512: XXH3_accumulate_512_f,
|
f_acc512: XXH3_accumulate_512_f,
|
||||||
f_scramble: XXH3_scramble_accumulator_f,
|
f_scramble: XXH3_scramble_accumulator_f,
|
||||||
f_init_sec: XXH3_init_custom_secret_f) -> (hash: xxh_u64) {
|
f_init_sec: XXH3_init_custom_secret_f,
|
||||||
|
) -> (hash: xxh_u64) {
|
||||||
if seed == 0 {
|
if seed == 0 {
|
||||||
return XXH3_hashLong_64b_internal(input, XXH3_kSecret[:], f_acc512, f_scramble)
|
return XXH3_hashLong_64b_internal(input, XXH3_kSecret[:], f_acc512, f_scramble)
|
||||||
}
|
}
|
||||||
{
|
|
||||||
secret: [XXH_SECRET_DEFAULT_SIZE]u8
|
secret: [XXH_SECRET_DEFAULT_SIZE]u8
|
||||||
f_init_sec(secret[:], seed)
|
f_init_sec(secret[:], seed)
|
||||||
return XXH3_hashLong_64b_internal(input, secret[:], f_acc512, f_scramble)
|
return XXH3_hashLong_64b_internal(input, secret[:], f_acc512, f_scramble)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
It's important for performance that XXH3_hashLong is not inlined.
|
It's important for performance that XXH3_hashLong is not inlined.
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
|
|||||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||||
|
|
||||||
if .info in options {
|
if .info in options {
|
||||||
options |= {.return_metadata, .do_not_decompress_image}
|
options += {.return_metadata, .do_not_decompress_image}
|
||||||
options -= {.info}
|
options -= {.info}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -341,7 +341,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
|
|||||||
options := options
|
options := options
|
||||||
|
|
||||||
if .info in options {
|
if .info in options {
|
||||||
options |= {.return_metadata, .do_not_decompress_image}
|
options += {.return_metadata, .do_not_decompress_image}
|
||||||
options -= {.info}
|
options -= {.info}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,7 +354,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
|
|||||||
}
|
}
|
||||||
|
|
||||||
if .do_not_expand_channels in options {
|
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 {
|
if img == nil {
|
||||||
|
|||||||
@@ -139,15 +139,13 @@ save_to_buffer :: proc(output: ^bytes.Buffer, img: ^Image, options := Options{}
|
|||||||
} else {
|
} else {
|
||||||
// Write RGB literal
|
// Write RGB literal
|
||||||
output.buf[written] = u8(QOI_Opcode_Tag.RGB)
|
output.buf[written] = u8(QOI_Opcode_Tag.RGB)
|
||||||
pix_bytes := transmute([4]u8)pix
|
copy(output.buf[written + 1:], pix[:3])
|
||||||
copy(output.buf[written + 1:], pix_bytes[:3])
|
|
||||||
written += 4
|
written += 4
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Write RGBA literal
|
// Write RGBA literal
|
||||||
output.buf[written] = u8(QOI_Opcode_Tag.RGBA)
|
output.buf[written] = u8(QOI_Opcode_Tag.RGBA)
|
||||||
pix_bytes := transmute([4]u8)pix
|
copy(output.buf[written + 1:], pix[:])
|
||||||
copy(output.buf[written + 1:], pix_bytes[:])
|
|
||||||
written += 5
|
written += 5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -178,7 +176,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
|
|||||||
options := options
|
options := options
|
||||||
|
|
||||||
if .info in options {
|
if .info in options {
|
||||||
options |= {.return_metadata, .do_not_decompress_image}
|
options += {.return_metadata, .do_not_decompress_image}
|
||||||
options -= {.info}
|
options -= {.info}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ load_from_context :: proc(ctx: ^$C, options := Options{}, allocator := context.a
|
|||||||
}
|
}
|
||||||
|
|
||||||
if .info in options {
|
if .info in options {
|
||||||
options |= {.return_metadata, .do_not_decompress_image}
|
options += {.return_metadata, .do_not_decompress_image}
|
||||||
options -= {.info}
|
options -= {.info}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -975,7 +975,7 @@ _private_int_div_3 :: proc(quotient, numerator: ^Int, allocator := context.alloc
|
|||||||
q.sign = numerator.sign
|
q.sign = numerator.sign
|
||||||
|
|
||||||
w, t: _WORD
|
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])
|
w = (w << _WORD(_DIGIT_BITS)) | _WORD(numerator.digit[ix])
|
||||||
if w >= 3 {
|
if w >= 3 {
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package linalg
|
|||||||
import "core:math"
|
import "core:math"
|
||||||
import "base:builtin"
|
import "base:builtin"
|
||||||
import "base:intrinsics"
|
import "base:intrinsics"
|
||||||
import "base:runtime"
|
@require import "base:runtime"
|
||||||
|
|
||||||
// Generic
|
// Generic
|
||||||
|
|
||||||
|
|||||||
@@ -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.
|
// 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
|
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
|
svp.x += PRIME_X
|
||||||
si.x -= 1
|
si.x -= 1
|
||||||
ssi -= UNSKEW_4D
|
ssi -= UNSKEW_4D
|
||||||
}
|
case si.y > si.x && si.y >= si.z && si.y >= si.w && si.y >= score:
|
||||||
else if si.y > si.x && si.y >= si.z && si.y >= si.w && si.y >= score {
|
|
||||||
svp.y += PRIME_Y
|
svp.y += PRIME_Y
|
||||||
si.y -= 1
|
si.y -= 1
|
||||||
ssi -= UNSKEW_4D
|
ssi -= UNSKEW_4D
|
||||||
}
|
case si.z > si.x && si.z > si.y && si.z >= si.w && si.z >= score:
|
||||||
else if si.z > si.x && si.z > si.y && si.z >= si.w && si.z >= score {
|
|
||||||
svp.z += PRIME_Z
|
svp.z += PRIME_Z
|
||||||
si.z -= 1
|
si.z -= 1
|
||||||
ssi -= UNSKEW_4D
|
ssi -= UNSKEW_4D
|
||||||
}
|
case si.w > si.x && si.w > si.y && si.w > si.z && si.w >= score:
|
||||||
else if si.w > si.x && si.w > si.y && si.w > si.z && si.w >= score {
|
|
||||||
svp.w += PRIME_W
|
svp.w += PRIME_W
|
||||||
si.w -= 1
|
si.w -= 1
|
||||||
ssi -= UNSKEW_4D
|
ssi -= UNSKEW_4D
|
||||||
|
|||||||
@@ -655,7 +655,7 @@ choice_enum :: proc($T: typeid) -> T
|
|||||||
where
|
where
|
||||||
intrinsics.type_is_enum(T),
|
intrinsics.type_is_enum(T),
|
||||||
size_of(T) <= 8,
|
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)) &&
|
when intrinsics.type_is_unsigned(intrinsics.type_core_type(T)) &&
|
||||||
u64(max(T)) > u64(max(i64)) {
|
u64(max(T)) > u64(max(i64)) {
|
||||||
|
|||||||
@@ -97,6 +97,10 @@ init :: proc{init_from_buffer, init_from_allocator}
|
|||||||
destroy :: proc(control: ^Allocator) {
|
destroy :: proc(control: ^Allocator) {
|
||||||
if control == nil { return }
|
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.
|
// 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.
|
// 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
|
// 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
|
return nil, nil
|
||||||
|
|
||||||
case .Free_All:
|
case .Free_All:
|
||||||
clear(control)
|
// NOTE: this doesn't work right at the moment, Jeroen has it on his to-do list :)
|
||||||
return nil, nil
|
// clear(control)
|
||||||
|
return nil, .Mode_Not_Implemented
|
||||||
|
|
||||||
case .Resize:
|
case .Resize:
|
||||||
return resize(control, old_memory, uint(old_size), uint(size), uint(alignment))
|
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:
|
case .Query_Features:
|
||||||
set := (^runtime.Allocator_Mode_Set)(old_memory)
|
set := (^runtime.Allocator_Mode_Set)(old_memory)
|
||||||
if set != nil {
|
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
|
return nil, nil
|
||||||
|
|
||||||
|
|||||||
@@ -630,7 +630,7 @@ alloc_bytes_non_zeroed :: proc(control: ^Allocator, size: uint, align: uint) ->
|
|||||||
@(require_results)
|
@(require_results)
|
||||||
alloc_bytes :: proc(control: ^Allocator, size: uint, align: uint) -> (res: []byte, err: runtime.Allocator_Error) {
|
alloc_bytes :: proc(control: ^Allocator, size: uint, align: uint) -> (res: []byte, err: runtime.Allocator_Error) {
|
||||||
res, err = alloc_bytes_non_zeroed(control, size, align)
|
res, err = alloc_bytes_non_zeroed(control, size, align)
|
||||||
if err != nil {
|
if err == nil {
|
||||||
intrinsics.mem_zero(raw_data(res), len(res))
|
intrinsics.mem_zero(raw_data(res), len(res))
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -36,9 +36,9 @@ _release :: proc "contextless" (data: rawptr, size: uint) {
|
|||||||
_protect :: proc "contextless" (data: rawptr, size: uint, flags: Protect_Flags) -> bool {
|
_protect :: proc "contextless" (data: rawptr, size: uint, flags: Protect_Flags) -> bool {
|
||||||
pflags: linux.Mem_Protection
|
pflags: linux.Mem_Protection
|
||||||
pflags = {}
|
pflags = {}
|
||||||
if .Read in flags { pflags |= {.READ} }
|
if .Read in flags { pflags += {.READ} }
|
||||||
if .Write in flags { pflags |= {.WRITE} }
|
if .Write in flags { pflags += {.WRITE} }
|
||||||
if .Execute in flags { pflags |= {.EXEC} }
|
if .Execute in flags { pflags += {.EXEC} }
|
||||||
errno := linux.mprotect(data, size, pflags)
|
errno := linux.mprotect(data, size, pflags)
|
||||||
return errno == .NONE
|
return errno == .NONE
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-4
@@ -370,7 +370,7 @@ parse_ip6_address :: proc(address_and_maybe_port: string) -> (addr: IP6_Address,
|
|||||||
val |= u16(ipv4[3])
|
val |= u16(ipv4[3])
|
||||||
piece_values[7] = u16be(val)
|
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}
|
run := Zero_Run{-1, -1}
|
||||||
best := Zero_Run{-1, -1}
|
best := Zero_Run{-1, -1}
|
||||||
|
|
||||||
addr := transmute([8]u16be)v
|
|
||||||
|
|
||||||
last := u16be(1)
|
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.
|
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
|
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
|
last = val
|
||||||
}
|
}
|
||||||
|
|
||||||
for val, i in addr {
|
for val, i in v {
|
||||||
if best.start == i || best.end == i {
|
if best.start == i || best.end == i {
|
||||||
// For the left and right side of the best zero run, print a `:`.
|
// For the left and right side of the best zero run, print a `:`.
|
||||||
fmt.sbprint(&b, ":")
|
fmt.sbprint(&b, ":")
|
||||||
|
|||||||
@@ -135,6 +135,7 @@ TCP_Send_Error :: enum c.int {
|
|||||||
No_Buffer_Space_Available = win.WSAENOBUFS,
|
No_Buffer_Space_Available = win.WSAENOBUFS,
|
||||||
Network_Subsystem_Failure = win.WSAENETDOWN,
|
Network_Subsystem_Failure = win.WSAENETDOWN,
|
||||||
Host_Unreachable = win.WSAEHOSTUNREACH,
|
Host_Unreachable = win.WSAEHOSTUNREACH,
|
||||||
|
Would_Block = win.WSAEWOULDBLOCK,
|
||||||
|
|
||||||
// TODO: verify possible, as not mentioned in docs
|
// TODO: verify possible, as not mentioned in docs
|
||||||
Offline = win.WSAENETUNREACH,
|
Offline = win.WSAENETUNREACH,
|
||||||
|
|||||||
@@ -59,7 +59,6 @@ _enumerate_interfaces :: proc(allocator := context.allocator) -> (interfaces: []
|
|||||||
switch int(ifaddr.address.family) {
|
switch int(ifaddr.address.family) {
|
||||||
case os.AF_INET, os.AF_INET6:
|
case os.AF_INET, os.AF_INET6:
|
||||||
address = _sockaddr_basic_to_endpoint(ifaddr.address).address
|
address = _sockaddr_basic_to_endpoint(ifaddr.address).address
|
||||||
case:
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +66,6 @@ _enumerate_interfaces :: proc(allocator := context.allocator) -> (interfaces: []
|
|||||||
switch int(ifaddr.netmask.family) {
|
switch int(ifaddr.netmask.family) {
|
||||||
case os.AF_INET, os.AF_INET6:
|
case os.AF_INET, os.AF_INET6:
|
||||||
netmask = Netmask(_sockaddr_basic_to_endpoint(ifaddr.netmask).address)
|
netmask = Netmask(_sockaddr_basic_to_endpoint(ifaddr.netmask).address)
|
||||||
case:
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +74,6 @@ _enumerate_interfaces :: proc(allocator := context.allocator) -> (interfaces: []
|
|||||||
case os.AF_INET, os.AF_INET6:
|
case os.AF_INET, os.AF_INET6:
|
||||||
broadcast := _sockaddr_basic_to_endpoint(ifaddr.broadcast_or_dest).address
|
broadcast := _sockaddr_basic_to_endpoint(ifaddr.broadcast_or_dest).address
|
||||||
append(&iface.multicast, broadcast)
|
append(&iface.multicast, broadcast)
|
||||||
case:
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,7 +91,7 @@ _enumerate_interfaces :: proc(allocator := context.allocator) -> (interfaces: []
|
|||||||
state := Link_State{}
|
state := Link_State{}
|
||||||
|
|
||||||
if .UP in ifaddr.flags {
|
if .UP in ifaddr.flags {
|
||||||
state |= {.Up}
|
state += {.Up}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*if .DORMANT in ifaddr.flags {
|
/*if .DORMANT in ifaddr.flags {
|
||||||
@@ -102,7 +99,7 @@ _enumerate_interfaces :: proc(allocator := context.allocator) -> (interfaces: []
|
|||||||
}*/
|
}*/
|
||||||
|
|
||||||
if .LOOPBACK in ifaddr.flags {
|
if .LOOPBACK in ifaddr.flags {
|
||||||
state |= {.Loopback}
|
state += {.Loopback}
|
||||||
}
|
}
|
||||||
iface.link.state = state
|
iface.link.state = state
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -274,8 +274,7 @@ _set_option :: proc(s: Any_Socket, option: Socket_Option, value: any, loc := #ca
|
|||||||
.Linger,
|
.Linger,
|
||||||
.Send_Timeout,
|
.Send_Timeout,
|
||||||
.Receive_Timeout:
|
.Receive_Timeout:
|
||||||
t, ok := value.(time.Duration)
|
t := value.(time.Duration) or_else panic("set_option() value must be a time.Duration here", loc)
|
||||||
if !ok do panic("set_option() value must be a time.Duration here", loc)
|
|
||||||
|
|
||||||
micros := i64(time.duration_microseconds(t))
|
micros := i64(time.duration_microseconds(t))
|
||||||
timeval_value.microseconds = int(micros % 1e6)
|
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 {
|
if should_block {
|
||||||
flags &= ~int(os.O_NONBLOCK)
|
flags &~= int(os.O_NONBLOCK)
|
||||||
} else {
|
} else {
|
||||||
flags |= int(os.O_NONBLOCK)
|
flags |= int(os.O_NONBLOCK)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ _unwrap_os_addr :: proc "contextless" (endpoint: Endpoint)->(linux.Sock_Addr_Any
|
|||||||
ipv4 = {
|
ipv4 = {
|
||||||
sin_family = .INET,
|
sin_family = .INET,
|
||||||
sin_port = u16be(endpoint.port),
|
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:
|
case IP6_Address:
|
||||||
@@ -377,9 +377,9 @@ _set_blocking :: proc(sock: Any_Socket, should_block: bool) -> (err: Network_Err
|
|||||||
return Set_Blocking_Error(errno)
|
return Set_Blocking_Error(errno)
|
||||||
}
|
}
|
||||||
if should_block {
|
if should_block {
|
||||||
flags &= ~{.NONBLOCK}
|
flags -= {.NONBLOCK}
|
||||||
} else {
|
} else {
|
||||||
flags |= {.NONBLOCK}
|
flags += {.NONBLOCK}
|
||||||
}
|
}
|
||||||
errno = linux.fcntl(os_sock, linux.F_SETFL, flags)
|
errno = linux.fcntl(os_sock, linux.F_SETFL, flags)
|
||||||
if errno != .NONE {
|
if errno != .NONE {
|
||||||
|
|||||||
@@ -263,12 +263,15 @@ _set_option :: proc(s: Any_Socket, option: Socket_Option, value: any, loc := #ca
|
|||||||
ptr = &bool_value
|
ptr = &bool_value
|
||||||
len = size_of(bool_value)
|
len = size_of(bool_value)
|
||||||
case .Linger:
|
case .Linger:
|
||||||
t, ok := value.(time.Duration)
|
t := value.(time.Duration) or_else panic("set_option() value must be a time.Duration here", loc)
|
||||||
if !ok do panic("set_option() value must be a time.Duration here", loc)
|
|
||||||
|
|
||||||
num_secs := i64(time.duration_seconds(t))
|
num_secs := i64(time.duration_seconds(t))
|
||||||
if time.Duration(num_secs * 1e9) != t do return .Linger_Only_Supports_Whole_Seconds
|
if time.Duration(num_secs * 1e9) != t {
|
||||||
if num_secs > i64(max(u16)) do return .Value_Out_Of_Range
|
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_onoff = 1
|
||||||
linger_value.l_linger = c.ushort(num_secs)
|
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
|
case
|
||||||
.Receive_Timeout,
|
.Receive_Timeout,
|
||||||
.Send_Timeout:
|
.Send_Timeout:
|
||||||
t, ok := value.(time.Duration)
|
t := value.(time.Duration) or_else panic("set_option() value must be a time.Duration here", loc)
|
||||||
if !ok do panic("set_option() value must be a time.Duration here", loc)
|
|
||||||
|
|
||||||
int_value = i32(time.duration_milliseconds(t))
|
int_value = i32(time.duration_milliseconds(t))
|
||||||
ptr = &int_value
|
ptr = &int_value
|
||||||
|
|||||||
@@ -513,6 +513,7 @@ Package_Decl :: struct {
|
|||||||
Import_Decl :: struct {
|
Import_Decl :: struct {
|
||||||
using node: Decl,
|
using node: Decl,
|
||||||
docs: ^Comment_Group,
|
docs: ^Comment_Group,
|
||||||
|
attributes: [dynamic]^Attribute, // dynamic as parsing will add to them lazily
|
||||||
is_using: bool,
|
is_using: bool,
|
||||||
import_tok: tokenizer.Token,
|
import_tok: tokenizer.Token,
|
||||||
name: tokenizer.Token,
|
name: tokenizer.Token,
|
||||||
|
|||||||
@@ -689,7 +689,12 @@ parse_when_stmt :: proc(p: ^Parser) -> ^ast.When_Stmt {
|
|||||||
|
|
||||||
prev_level := p.expr_level
|
prev_level := p.expr_level
|
||||||
p.expr_level = -1
|
p.expr_level = -1
|
||||||
|
prev_allow_in_expr := p.allow_in_expr
|
||||||
|
p.allow_in_expr = true
|
||||||
|
|
||||||
cond = parse_expr(p, false)
|
cond = parse_expr(p, false)
|
||||||
|
|
||||||
|
p.allow_in_expr = prev_allow_in_expr
|
||||||
p.expr_level = prev_level
|
p.expr_level = prev_level
|
||||||
|
|
||||||
if cond == nil {
|
if cond == nil {
|
||||||
@@ -1103,6 +1108,9 @@ parse_attribute :: proc(p: ^Parser, tok: tokenizer.Token, open_kind, close_kind:
|
|||||||
case ^ast.Foreign_Import_Decl:
|
case ^ast.Foreign_Import_Decl:
|
||||||
if d.docs == nil { d.docs = docs }
|
if d.docs == nil { d.docs = docs }
|
||||||
append(&d.attributes, attribute)
|
append(&d.attributes, attribute)
|
||||||
|
case ^ast.Import_Decl:
|
||||||
|
if d.docs == nil { d.docs = docs }
|
||||||
|
append(&d.attributes, attribute)
|
||||||
case:
|
case:
|
||||||
error(p, decl.pos, "expected a value or foreign declaration after an attribute")
|
error(p, decl.pos, "expected a value or foreign declaration after an attribute")
|
||||||
free(attribute)
|
free(attribute)
|
||||||
|
|||||||
+208
-7
@@ -2,29 +2,230 @@
|
|||||||
package os2
|
package os2
|
||||||
|
|
||||||
import "base:runtime"
|
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 <key>=<value> 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) {
|
_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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_set_env :: proc(key, value: string) -> bool {
|
_set_env :: proc(key, v_new: string) -> bool {
|
||||||
//TODO
|
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
|
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 {
|
_unset_env :: proc(key: string) -> bool {
|
||||||
//TODO
|
if _org_env_begin == 0 {
|
||||||
|
_build_env()
|
||||||
|
}
|
||||||
|
|
||||||
|
v: string
|
||||||
|
i: int
|
||||||
|
if v, i = _lookup(key); i == -1 {
|
||||||
return false
|
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() {
|
_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 {
|
_environ :: proc(allocator: runtime.Allocator) -> []string {
|
||||||
//TODO
|
if _org_env_begin == 0 {
|
||||||
return nil
|
_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
|
||||||
|
}
|
||||||
|
|||||||
@@ -99,3 +99,19 @@ error_string :: proc(ferr: Error) -> string {
|
|||||||
|
|
||||||
return "unknown error"
|
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)
|
||||||
|
}
|
||||||
|
|||||||
+154
-134
@@ -1,145 +1,165 @@
|
|||||||
//+private
|
//+private
|
||||||
package os2
|
package os2
|
||||||
|
|
||||||
import "core:sys/unix"
|
import "core:sys/linux"
|
||||||
|
|
||||||
EPERM :: 1
|
@(rodata)
|
||||||
ENOENT :: 2
|
_errno_strings : [linux.Errno]string = {
|
||||||
ESRCH :: 3
|
.NONE = "Success",
|
||||||
EINTR :: 4
|
.EPERM = "Operation not permitted",
|
||||||
EIO :: 5
|
.ENOENT = "No such file or directory",
|
||||||
ENXIO :: 6
|
.ESRCH = "No such process",
|
||||||
EBADF :: 9
|
.EINTR = "Interrupted system call",
|
||||||
EAGAIN :: 11
|
.EIO = "Input/output error",
|
||||||
ENOMEM :: 12
|
.ENXIO = "No such device or address",
|
||||||
EACCES :: 13
|
.E2BIG = "Argument list too long",
|
||||||
EFAULT :: 14
|
.ENOEXEC = "Exec format error",
|
||||||
EEXIST :: 17
|
.EBADF = "Bad file descriptor",
|
||||||
ENODEV :: 19
|
.ECHILD = "No child processes",
|
||||||
ENOTDIR :: 20
|
.EAGAIN = "Resource temporarily unavailable",
|
||||||
EISDIR :: 21
|
.ENOMEM = "Cannot allocate memory",
|
||||||
EINVAL :: 22
|
.EACCES = "Permission denied",
|
||||||
ENFILE :: 23
|
.EFAULT = "Bad address",
|
||||||
EMFILE :: 24
|
.ENOTBLK = "Block device required",
|
||||||
ETXTBSY :: 26
|
.EBUSY = "Device or resource busy",
|
||||||
EFBIG :: 27
|
.EEXIST = "File exists",
|
||||||
ENOSPC :: 28
|
.EXDEV = "Invalid cross-device link",
|
||||||
ESPIPE :: 29
|
.ENODEV = "No such device",
|
||||||
EROFS :: 30
|
.ENOTDIR = "Not a directory",
|
||||||
EPIPE :: 32
|
.EISDIR = "Is a directory",
|
||||||
ERANGE :: 34 /* Result too large */
|
.EINVAL = "Invalid argument",
|
||||||
EDEADLK :: 35 /* Resource deadlock would occur */
|
.ENFILE = "Too many open files in system",
|
||||||
ENAMETOOLONG :: 36 /* File name too long */
|
.EMFILE = "Too many open files",
|
||||||
ENOLCK :: 37 /* No record locks available */
|
.ENOTTY = "Inappropriate ioctl for device",
|
||||||
ENOSYS :: 38 /* Invalid system call number */
|
.ETXTBSY = "Text file busy",
|
||||||
ENOTEMPTY :: 39 /* Directory not empty */
|
.EFBIG = "File too large",
|
||||||
ELOOP :: 40 /* Too many symbolic links encountered */
|
.ENOSPC = "No space left on device",
|
||||||
EWOULDBLOCK :: EAGAIN /* Operation would block */
|
.ESPIPE = "Illegal seek",
|
||||||
ENOMSG :: 42 /* No message of desired type */
|
.EROFS = "Read-only file system",
|
||||||
EIDRM :: 43 /* Identifier removed */
|
.EMLINK = "Too many links",
|
||||||
ECHRNG :: 44 /* Channel number out of range */
|
.EPIPE = "Broken pipe",
|
||||||
EL2NSYNC :: 45 /* Level 2 not synchronized */
|
.EDOM = "Numerical argument out of domain",
|
||||||
EL3HLT :: 46 /* Level 3 halted */
|
.ERANGE = "Numerical result out of range",
|
||||||
EL3RST :: 47 /* Level 3 reset */
|
.EDEADLK = "Resource deadlock avoided",
|
||||||
ELNRNG :: 48 /* Link number out of range */
|
.ENAMETOOLONG = "File name too long",
|
||||||
EUNATCH :: 49 /* Protocol driver not attached */
|
.ENOLCK = "No locks available",
|
||||||
ENOCSI :: 50 /* No CSI structure available */
|
.ENOSYS = "Function not implemented",
|
||||||
EL2HLT :: 51 /* Level 2 halted */
|
.ENOTEMPTY = "Directory not empty",
|
||||||
EBADE :: 52 /* Invalid exchange */
|
.ELOOP = "Too many levels of symbolic links",
|
||||||
EBADR :: 53 /* Invalid request descriptor */
|
.EUNKNOWN_41 = "Unknown Error (41)",
|
||||||
EXFULL :: 54 /* Exchange full */
|
.ENOMSG = "No message of desired type",
|
||||||
ENOANO :: 55 /* No anode */
|
.EIDRM = "Identifier removed",
|
||||||
EBADRQC :: 56 /* Invalid request code */
|
.ECHRNG = "Channel number out of range",
|
||||||
EBADSLT :: 57 /* Invalid slot */
|
.EL2NSYNC = "Level 2 not synchronized",
|
||||||
EDEADLOCK :: EDEADLK
|
.EL3HLT = "Level 3 halted",
|
||||||
EBFONT :: 59 /* Bad font file format */
|
.EL3RST = "Level 3 reset",
|
||||||
ENOSTR :: 60 /* Device not a stream */
|
.ELNRNG = "Link number out of range",
|
||||||
ENODATA :: 61 /* No data available */
|
.EUNATCH = "Protocol driver not attached",
|
||||||
ETIME :: 62 /* Timer expired */
|
.ENOCSI = "No CSI structure available",
|
||||||
ENOSR :: 63 /* Out of streams resources */
|
.EL2HLT = "Level 2 halted",
|
||||||
ENONET :: 64 /* Machine is not on the network */
|
.EBADE = "Invalid exchange",
|
||||||
ENOPKG :: 65 /* Package not installed */
|
.EBADR = "Invalid request descriptor",
|
||||||
EREMOTE :: 66 /* Object is remote */
|
.EXFULL = "Exchange full",
|
||||||
ENOLINK :: 67 /* Link has been severed */
|
.ENOANO = "No anode",
|
||||||
EADV :: 68 /* Advertise error */
|
.EBADRQC = "Invalid request code",
|
||||||
ESRMNT :: 69 /* Srmount error */
|
.EBADSLT = "Invalid slot",
|
||||||
ECOMM :: 70 /* Communication error on send */
|
.EUNKNOWN_58 = "Unknown Error (58)",
|
||||||
EPROTO :: 71 /* Protocol error */
|
.EBFONT = "Bad font file format",
|
||||||
EMULTIHOP :: 72 /* Multihop attempted */
|
.ENOSTR = "Device not a stream",
|
||||||
EDOTDOT :: 73 /* RFS specific error */
|
.ENODATA = "No data available",
|
||||||
EBADMSG :: 74 /* Not a data message */
|
.ETIME = "Timer expired",
|
||||||
EOVERFLOW :: 75 /* Value too large for defined data type */
|
.ENOSR = "Out of streams resources",
|
||||||
ENOTUNIQ :: 76 /* Name not unique on network */
|
.ENONET = "Machine is not on the network",
|
||||||
EBADFD :: 77 /* File descriptor in bad state */
|
.ENOPKG = "Package not installed",
|
||||||
EREMCHG :: 78 /* Remote address changed */
|
.EREMOTE = "Object is remote",
|
||||||
ELIBACC :: 79 /* Can not access a needed shared library */
|
.ENOLINK = "Link has been severed",
|
||||||
ELIBBAD :: 80 /* Accessing a corrupted shared library */
|
.EADV = "Advertise error",
|
||||||
ELIBSCN :: 81 /* .lib section in a.out corrupted */
|
.ESRMNT = "Srmount error",
|
||||||
ELIBMAX :: 82 /* Attempting to link in too many shared libraries */
|
.ECOMM = "Communication error on send",
|
||||||
ELIBEXEC :: 83 /* Cannot exec a shared library directly */
|
.EPROTO = "Protocol error",
|
||||||
EILSEQ :: 84 /* Illegal byte sequence */
|
.EMULTIHOP = "Multihop attempted",
|
||||||
ERESTART :: 85 /* Interrupted system call should be restarted */
|
.EDOTDOT = "RFS specific error",
|
||||||
ESTRPIPE :: 86 /* Streams pipe error */
|
.EBADMSG = "Bad message",
|
||||||
EUSERS :: 87 /* Too many users */
|
.EOVERFLOW = "Value too large for defined data type",
|
||||||
ENOTSOCK :: 88 /* Socket operation on non-socket */
|
.ENOTUNIQ = "Name not unique on network",
|
||||||
EDESTADDRREQ :: 89 /* Destination address required */
|
.EBADFD = "File descriptor in bad state",
|
||||||
EMSGSIZE :: 90 /* Message too long */
|
.EREMCHG = "Remote address changed",
|
||||||
EPROTOTYPE :: 91 /* Protocol wrong type for socket */
|
.ELIBACC = "Can not access a needed shared library",
|
||||||
ENOPROTOOPT :: 92 /* Protocol not available */
|
.ELIBBAD = "Accessing a corrupted shared library",
|
||||||
EPROTONOSUPPORT:: 93 /* Protocol not supported */
|
.ELIBSCN = ".lib section in a.out corrupted",
|
||||||
ESOCKTNOSUPPORT:: 94 /* Socket type not supported */
|
.ELIBMAX = "Attempting to link in too many shared libraries",
|
||||||
EOPNOTSUPP :: 95 /* Operation not supported on transport endpoint */
|
.ELIBEXEC = "Cannot exec a shared library directly",
|
||||||
EPFNOSUPPORT :: 96 /* Protocol family not supported */
|
.EILSEQ = "Invalid or incomplete multibyte or wide character",
|
||||||
EAFNOSUPPORT :: 97 /* Address family not supported by protocol */
|
.ERESTART = "Interrupted system call should be restarted",
|
||||||
EADDRINUSE :: 98 /* Address already in use */
|
.ESTRPIPE = "Streams pipe error",
|
||||||
EADDRNOTAVAIL :: 99 /* Cannot assign requested address */
|
.EUSERS = "Too many users",
|
||||||
ENETDOWN :: 100 /* Network is down */
|
.ENOTSOCK = "Socket operation on non-socket",
|
||||||
ENETUNREACH :: 101 /* Network is unreachable */
|
.EDESTADDRREQ = "Destination address required",
|
||||||
ENETRESET :: 102 /* Network dropped connection because of reset */
|
.EMSGSIZE = "Message too long",
|
||||||
ECONNABORTED :: 103 /* Software caused connection abort */
|
.EPROTOTYPE = "Protocol wrong type for socket",
|
||||||
ECONNRESET :: 104 /* Connection reset by peer */
|
.ENOPROTOOPT = "Protocol not available",
|
||||||
ENOBUFS :: 105 /* No buffer space available */
|
.EPROTONOSUPPORT = "Protocol not supported",
|
||||||
EISCONN :: 106 /* Transport endpoint is already connected */
|
.ESOCKTNOSUPPORT = "Socket type not supported",
|
||||||
ENOTCONN :: 107 /* Transport endpoint is not connected */
|
.EOPNOTSUPP = "Operation not supported",
|
||||||
ESHUTDOWN :: 108 /* Cannot send after transport endpoint shutdown */
|
.EPFNOSUPPORT = "Protocol family not supported",
|
||||||
ETOOMANYREFS :: 109 /* Too many references: cannot splice */
|
.EAFNOSUPPORT = "Address family not supported by protocol",
|
||||||
ETIMEDOUT :: 110 /* Connection timed out */
|
.EADDRINUSE = "Address already in use",
|
||||||
ECONNREFUSED :: 111 /* Connection refused */
|
.EADDRNOTAVAIL = "Cannot assign requested address",
|
||||||
EHOSTDOWN :: 112 /* Host is down */
|
.ENETDOWN = "Network is down",
|
||||||
EHOSTUNREACH :: 113 /* No route to host */
|
.ENETUNREACH = "Network is unreachable",
|
||||||
EALREADY :: 114 /* Operation already in progress */
|
.ENETRESET = "Network dropped connection on reset",
|
||||||
EINPROGRESS :: 115 /* Operation now in progress */
|
.ECONNABORTED = "Software caused connection abort",
|
||||||
ESTALE :: 116 /* Stale file handle */
|
.ECONNRESET = "Connection reset by peer",
|
||||||
EUCLEAN :: 117 /* Structure needs cleaning */
|
.ENOBUFS = "No buffer space available",
|
||||||
ENOTNAM :: 118 /* Not a XENIX named type file */
|
.EISCONN = "Transport endpoint is already connected",
|
||||||
ENAVAIL :: 119 /* No XENIX semaphores available */
|
.ENOTCONN = "Transport endpoint is not connected",
|
||||||
EISNAM :: 120 /* Is a named type file */
|
.ESHUTDOWN = "Cannot send after transport endpoint shutdown",
|
||||||
EREMOTEIO :: 121 /* Remote I/O error */
|
.ETOOMANYREFS = "Too many references: cannot splice",
|
||||||
EDQUOT :: 122 /* Quota exceeded */
|
.ETIMEDOUT = "Connection timed out",
|
||||||
ENOMEDIUM :: 123 /* No medium found */
|
.ECONNREFUSED = "Connection refused",
|
||||||
EMEDIUMTYPE :: 124 /* Wrong medium type */
|
.EHOSTDOWN = "Host is down",
|
||||||
ECANCELED :: 125 /* Operation Canceled */
|
.EHOSTUNREACH = "No route to host",
|
||||||
ENOKEY :: 126 /* Required key not available */
|
.EALREADY = "Operation already in progress",
|
||||||
EKEYEXPIRED :: 127 /* Key has expired */
|
.EINPROGRESS = "Operation now in progress",
|
||||||
EKEYREVOKED :: 128 /* Key has been revoked */
|
.ESTALE = "Stale file handle",
|
||||||
EKEYREJECTED :: 129 /* Key was rejected by service */
|
.EUCLEAN = "Structure needs cleaning",
|
||||||
EOWNERDEAD :: 130 /* Owner died */
|
.ENOTNAM = "Not a XENIX named type file",
|
||||||
ENOTRECOVERABLE:: 131 /* State not recoverable */
|
.ENAVAIL = "No XENIX semaphores available",
|
||||||
ERFKILL :: 132 /* Operation not possible due to RF-kill */
|
.EISNAM = "Is a named type file",
|
||||||
EHWPOISON :: 133 /* Memory page has hardware error */
|
.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))
|
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 {
|
_error_string :: proc(errno: i32) -> string {
|
||||||
if errno == 0 {
|
if errno >= 0 && errno <= i32(max(linux.Errno)) {
|
||||||
return ""
|
return _errno_strings[linux.Errno(errno)]
|
||||||
}
|
}
|
||||||
return "Error"
|
return "Unknown Error"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,13 +45,10 @@ O_TRUNC :: File_Flags{.Trunc}
|
|||||||
O_SPARSE :: File_Flags{.Sparse}
|
O_SPARSE :: File_Flags{.Sparse}
|
||||||
O_CLOEXEC :: File_Flags{.Close_On_Exec}
|
O_CLOEXEC :: File_Flags{.Close_On_Exec}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
stdin: ^File = nil // OS-Specific
|
stdin: ^File = nil // OS-Specific
|
||||||
stdout: ^File = nil // OS-Specific
|
stdout: ^File = nil // OS-Specific
|
||||||
stderr: ^File = nil // OS-Specific
|
stderr: ^File = nil // OS-Specific
|
||||||
|
|
||||||
|
|
||||||
@(require_results)
|
@(require_results)
|
||||||
create :: proc(name: string) -> (^File, Error) {
|
create :: proc(name: string) -> (^File, Error) {
|
||||||
return open(name, {.Read, .Write, .Create}, File_Mode(0o777))
|
return open(name, {.Read, .Write, .Create}, File_Mode(0o777))
|
||||||
|
|||||||
+229
-159
@@ -1,39 +1,64 @@
|
|||||||
//+private
|
//+private
|
||||||
package os2
|
package os2
|
||||||
|
|
||||||
import "base:runtime"
|
|
||||||
import "core:io"
|
import "core:io"
|
||||||
import "core:time"
|
import "core:time"
|
||||||
import "core:sys/unix"
|
import "base:runtime"
|
||||||
|
import "core:sys/linux"
|
||||||
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
|
|
||||||
|
|
||||||
_File :: struct {
|
_File :: struct {
|
||||||
name: string,
|
name: string,
|
||||||
fd: int,
|
fd: linux.Fd,
|
||||||
allocator: runtime.Allocator,
|
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) {
|
_open :: proc(name: string, flags: File_Flags, perm: File_Mode) -> (f: ^File, err: Error) {
|
||||||
TEMP_ALLOCATOR_GUARD()
|
TEMP_ALLOCATOR_GUARD()
|
||||||
name_cstr := temp_cstring(name) or_return
|
name_cstr := temp_cstring(name) or_return
|
||||||
@@ -41,38 +66,46 @@ _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
|
// Just default to using O_NOCTTY because needing to open a controlling
|
||||||
// terminal would be incredibly rare. This has no effect on files while
|
// terminal would be incredibly rare. This has no effect on files while
|
||||||
// allowing us to open serial devices.
|
// 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 {
|
switch flags & O_RDONLY|O_WRONLY|O_RDWR {
|
||||||
case O_RDONLY: flags_i = _O_RDONLY
|
case O_RDONLY:
|
||||||
case O_WRONLY: flags_i = _O_WRONLY
|
case O_WRONLY: sys_flags += {.WRONLY}
|
||||||
case O_RDWR: flags_i = _O_RDWR
|
case O_RDWR: sys_flags += {.RDWR}
|
||||||
}
|
}
|
||||||
|
|
||||||
if .Append in flags { flags_i |= _O_APPEND }
|
if .Append in flags { sys_flags += {.APPEND} }
|
||||||
if .Create in flags { flags_i |= _O_CREAT }
|
if .Create in flags { sys_flags += {.CREAT} }
|
||||||
if .Excl in flags { flags_i |= _O_EXCL }
|
if .Excl in flags { sys_flags += {.EXCL} }
|
||||||
if .Sync in flags { flags_i |= _O_SYNC }
|
if .Sync in flags { sys_flags += {.DSYNC} }
|
||||||
if .Trunc in flags { flags_i |= _O_TRUNC }
|
if .Trunc in flags { sys_flags += {.TRUNC} }
|
||||||
if .Close_On_Exec in flags { flags_i |= _O_CLOEXEC }
|
if .Close_On_Exec in flags { sys_flags += {.CLOEXEC} }
|
||||||
|
|
||||||
fd := unix.sys_open(name_cstr, flags_i, uint(perm))
|
fd, errno := linux.open(name_cstr, sys_flags, transmute(linux.Mode)(u32(perm)))
|
||||||
if fd < 0 {
|
if errno != .NONE {
|
||||||
return nil, _get_platform_error(fd)
|
return nil, _get_platform_error(errno)
|
||||||
}
|
}
|
||||||
|
|
||||||
return _new_file(uintptr(fd), name), nil
|
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 := new(File, file_allocator())
|
||||||
file.impl.fd = int(fd)
|
_construct_file(file, fd, "")
|
||||||
file.impl.allocator = file_allocator()
|
return file
|
||||||
file.impl.name = _get_full_path(file.impl.fd, file.impl.allocator)
|
}
|
||||||
file.stream = {
|
|
||||||
|
_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,
|
data = file,
|
||||||
procedure = _file_stream_proc,
|
procedure = _file_stream_proc,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
return file
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_destroy :: proc(f: ^File) -> Error {
|
_destroy :: proc(f: ^File) -> Error {
|
||||||
@@ -86,13 +119,16 @@ _destroy :: proc(f: ^File) -> Error {
|
|||||||
|
|
||||||
|
|
||||||
_close :: proc(f: ^File) -> Error {
|
_close :: proc(f: ^File) -> Error {
|
||||||
if f != nil {
|
if f == nil {
|
||||||
res := unix.sys_close(f.impl.fd)
|
|
||||||
_destroy(f)
|
|
||||||
return _ok_or_error(res)
|
|
||||||
}
|
|
||||||
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 {
|
_fd :: proc(f: ^File) -> uintptr {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
@@ -106,20 +142,32 @@ _name :: proc(f: ^File) -> string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_seek :: proc(f: ^File, offset: i64, whence: io.Seek_From) -> (ret: i64, err: Error) {
|
_seek :: proc(f: ^File, offset: i64, whence: io.Seek_From) -> (ret: i64, err: Error) {
|
||||||
res := unix.sys_lseek(f.impl.fd, offset, int(whence))
|
n, errno := linux.lseek(f.impl.fd, offset, linux.Seek_Whence(whence))
|
||||||
if res < 0 {
|
if errno != .NONE {
|
||||||
return -1, _get_platform_error(int(res))
|
return -1, _get_platform_error(errno)
|
||||||
}
|
}
|
||||||
return res, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
_read :: proc(f: ^File, p: []byte) -> (i64, Error) {
|
_read :: proc(f: ^File, p: []byte) -> (i64, Error) {
|
||||||
if len(p) == 0 {
|
if len(p) == 0 {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
n := unix.sys_read(f.impl.fd, &p[0], len(p))
|
n, errno := linux.read(f.impl.fd, p[:])
|
||||||
if n < 0 {
|
if errno != .NONE {
|
||||||
return -1, _get_platform_error(n)
|
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 {
|
if n == 0 {
|
||||||
return 0, .EOF
|
return 0, .EOF
|
||||||
@@ -127,91 +175,67 @@ _read :: proc(f: ^File, p: []byte) -> (i64, Error) {
|
|||||||
return i64(n), nil
|
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) {
|
_write :: proc(f: ^File, p: []byte) -> (i64, Error) {
|
||||||
if len(p) == 0 {
|
if len(p) == 0 {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
}
|
}
|
||||||
n := unix.sys_write(f.impl.fd, &p[0], uint(len(p)))
|
n, errno := linux.write(f.impl.fd, p[:])
|
||||||
if n < 0 {
|
if errno != .NONE {
|
||||||
return -1, _get_platform_error(n)
|
return -1, _get_platform_error(errno)
|
||||||
}
|
}
|
||||||
return i64(n), nil
|
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 {
|
if offset < 0 {
|
||||||
return 0, .Invalid_Offset
|
return 0, .Invalid_Offset
|
||||||
}
|
}
|
||||||
|
|
||||||
b, offset := p, offset
|
n, errno := linux.pwrite(f.impl.fd, p[:], offset)
|
||||||
for len(b) > 0 {
|
if errno != .NONE {
|
||||||
m := unix.sys_pwrite(f.impl.fd, &b[0], len(b), offset)
|
return -1, _get_platform_error(errno)
|
||||||
if m < 0 {
|
|
||||||
return -1, _get_platform_error(m)
|
|
||||||
}
|
}
|
||||||
n += i64(m)
|
return i64(n), nil
|
||||||
b = b[m:]
|
|
||||||
offset += i64(m)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_file_size :: proc(f: ^File) -> (n: i64, err: Error) {
|
_file_size :: proc(f: ^File) -> (n: i64, err: Error) {
|
||||||
s: _Stat = ---
|
s: linux.Stat = ---
|
||||||
res := unix.sys_fstat(f.impl.fd, &s)
|
errno := linux.fstat(f.impl.fd, &s)
|
||||||
if res < 0 {
|
if errno != .NONE {
|
||||||
return -1, _get_platform_error(res)
|
return -1, _get_platform_error(errno)
|
||||||
}
|
}
|
||||||
return s.size, nil
|
return i64(s.size), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
_sync :: proc(f: ^File) -> Error {
|
_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 {
|
_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 {
|
_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 {
|
_remove :: proc(name: string) -> Error {
|
||||||
TEMP_ALLOCATOR_GUARD()
|
TEMP_ALLOCATOR_GUARD()
|
||||||
name_cstr := temp_cstring(name) or_return
|
name_cstr := temp_cstring(name) or_return
|
||||||
|
|
||||||
fd := unix.sys_open(name_cstr, int(File_Flags.Read))
|
fd, errno := linux.open(name_cstr, {.NOFOLLOW})
|
||||||
if fd < 0 {
|
#partial switch (errno) {
|
||||||
return _get_platform_error(fd)
|
case .ELOOP: /* symlink */
|
||||||
}
|
case .NONE:
|
||||||
defer unix.sys_close(fd)
|
defer linux.close(fd)
|
||||||
|
|
||||||
if _is_dir_fd(fd) {
|
if _is_dir_fd(fd) {
|
||||||
return _ok_or_error(unix.sys_rmdir(name_cstr))
|
return _get_platform_error(linux.rmdir(name_cstr))
|
||||||
}
|
}
|
||||||
return _ok_or_error(unix.sys_unlink(name_cstr))
|
case:
|
||||||
|
return _get_platform_error(errno)
|
||||||
|
}
|
||||||
|
|
||||||
|
return _get_platform_error(linux.unlink(name_cstr))
|
||||||
}
|
}
|
||||||
|
|
||||||
_rename :: proc(old_name, new_name: string) -> Error {
|
_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
|
old_name_cstr := temp_cstring(old_name) or_return
|
||||||
new_name_cstr := temp_cstring(new_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 {
|
_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
|
old_name_cstr := temp_cstring(old_name) or_return
|
||||||
new_name_cstr := temp_cstring(new_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 {
|
_symlink :: proc(old_name, new_name: string) -> Error {
|
||||||
TEMP_ALLOCATOR_GUARD()
|
TEMP_ALLOCATOR_GUARD()
|
||||||
old_name_cstr := temp_cstring(old_name) or_return
|
old_name_cstr := temp_cstring(old_name) or_return
|
||||||
new_name_cstr := temp_cstring(new_name) or_return
|
new_name_cstr := temp_cstring(new_name) or_return
|
||||||
|
return _get_platform_error(linux.symlink(old_name_cstr, new_name_cstr))
|
||||||
return _ok_or_error(unix.sys_symlink(old_name_cstr, new_name_cstr))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_read_link_cstr :: proc(name_cstr: cstring, allocator: runtime.Allocator) -> (string, Error) {
|
_read_link_cstr :: proc(name_cstr: cstring, allocator: runtime.Allocator) -> (string, Error) {
|
||||||
bufsz : uint = 256
|
bufsz : uint = 256
|
||||||
buf := make([]byte, bufsz, allocator)
|
buf := make([]byte, bufsz, allocator)
|
||||||
for {
|
for {
|
||||||
rc := unix.sys_readlink(name_cstr, &buf[0], bufsz)
|
sz, errno := linux.readlink(name_cstr, buf[:])
|
||||||
if rc < 0 {
|
if errno != .NONE {
|
||||||
delete(buf)
|
delete(buf, allocator)
|
||||||
return "", _get_platform_error(rc)
|
return "", _get_platform_error(errno)
|
||||||
} else if rc == int(bufsz) {
|
} else if sz == int(bufsz) {
|
||||||
bufsz *= 2
|
bufsz *= 2
|
||||||
delete(buf)
|
delete(buf, allocator)
|
||||||
buf = make([]byte, bufsz, allocator)
|
buf = make([]byte, bufsz, allocator)
|
||||||
} else {
|
} 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()
|
TEMP_ALLOCATOR_GUARD()
|
||||||
name_cstr := temp_cstring(name) or_return
|
name_cstr := temp_cstring(name) or_return
|
||||||
return _read_link_cstr(name_cstr, allocator)
|
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 {
|
_chdir :: proc(name: string) -> Error {
|
||||||
TEMP_ALLOCATOR_GUARD()
|
TEMP_ALLOCATOR_GUARD()
|
||||||
name_cstr := temp_cstring(name) or_return
|
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 {
|
_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 {
|
_chmod :: proc(name: string, mode: File_Mode) -> Error {
|
||||||
TEMP_ALLOCATOR_GUARD()
|
TEMP_ALLOCATOR_GUARD()
|
||||||
name_cstr := temp_cstring(name) or_return
|
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 {
|
_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
|
// NOTE: will throw error without super user priviledges
|
||||||
_chown :: proc(name: string, uid, gid: int) -> Error {
|
_chown :: proc(name: string, uid, gid: int) -> Error {
|
||||||
TEMP_ALLOCATOR_GUARD()
|
TEMP_ALLOCATOR_GUARD()
|
||||||
name_cstr := temp_cstring(name) or_return
|
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
|
// NOTE: will throw error without super user priviledges
|
||||||
_lchown :: proc(name: string, uid, gid: int) -> Error {
|
_lchown :: proc(name: string, uid, gid: int) -> Error {
|
||||||
TEMP_ALLOCATOR_GUARD()
|
TEMP_ALLOCATOR_GUARD()
|
||||||
name_cstr := temp_cstring(name) or_return
|
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
|
// NOTE: will throw error without super user priviledges
|
||||||
_fchown :: proc(f: ^File, uid, gid: int) -> Error {
|
_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 {
|
_chtimes :: proc(name: string, atime, mtime: time.Time) -> Error {
|
||||||
TEMP_ALLOCATOR_GUARD()
|
TEMP_ALLOCATOR_GUARD()
|
||||||
name_cstr := temp_cstring(name) or_return
|
name_cstr := temp_cstring(name) or_return
|
||||||
times := [2]Unix_File_Time {
|
times := [2]linux.Time_Spec {
|
||||||
{ atime._nsec, 0 },
|
{
|
||||||
{ mtime._nsec, 0 },
|
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 {
|
_fchtimes :: proc(f: ^File, atime, mtime: time.Time) -> Error {
|
||||||
times := [2]Unix_File_Time {
|
times := [2]linux.Time_Spec {
|
||||||
{ atime._nsec, 0 },
|
{
|
||||||
{ mtime._nsec, 0 },
|
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 {
|
_exists :: proc(name: string) -> bool {
|
||||||
TEMP_ALLOCATOR_GUARD()
|
TEMP_ALLOCATOR_GUARD()
|
||||||
name_cstr, _ := temp_cstring(name)
|
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 {
|
_is_file :: proc(name: string) -> bool {
|
||||||
TEMP_ALLOCATOR_GUARD()
|
TEMP_ALLOCATOR_GUARD()
|
||||||
name_cstr, _ := temp_cstring(name)
|
name_cstr, _ := temp_cstring(name)
|
||||||
s: _Stat
|
s: linux.Stat
|
||||||
res := unix.sys_stat(name_cstr, &s)
|
if linux.stat(name_cstr, &s) != .NONE {
|
||||||
if res < 0 {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return S_ISREG(s.mode)
|
return linux.S_ISREG(s.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
_is_file_fd :: proc(fd: int) -> bool {
|
_is_file_fd :: proc(fd: linux.Fd) -> bool {
|
||||||
s: _Stat
|
s: linux.Stat
|
||||||
res := unix.sys_fstat(fd, &s)
|
if linux.fstat(fd, &s) != .NONE {
|
||||||
if res < 0 { // error
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return S_ISREG(s.mode)
|
return linux.S_ISREG(s.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
_is_dir :: proc(name: string) -> bool {
|
_is_dir :: proc(name: string) -> bool {
|
||||||
TEMP_ALLOCATOR_GUARD()
|
TEMP_ALLOCATOR_GUARD()
|
||||||
name_cstr, _ := temp_cstring(name)
|
name_cstr, _ := temp_cstring(name)
|
||||||
s: _Stat
|
s: linux.Stat
|
||||||
res := unix.sys_stat(name_cstr, &s)
|
if linux.stat(name_cstr, &s) != .NONE {
|
||||||
if res < 0 {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return S_ISDIR(s.mode)
|
return linux.S_ISDIR(s.mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
_is_dir_fd :: proc(fd: int) -> bool {
|
_is_dir_fd :: proc(fd: linux.Fd) -> bool {
|
||||||
s: _Stat
|
s: linux.Stat
|
||||||
res := unix.sys_fstat(fd, &s)
|
if linux.fstat(fd, &s) != .NONE {
|
||||||
if res < 0 { // error
|
|
||||||
return false
|
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")
|
@(private="package")
|
||||||
|
|||||||
+11
-17
@@ -1,7 +1,7 @@
|
|||||||
//+private
|
//+private
|
||||||
package os2
|
package os2
|
||||||
|
|
||||||
import "core:sys/unix"
|
import "core:sys/linux"
|
||||||
import "core:sync"
|
import "core:sync"
|
||||||
import "core:mem"
|
import "core:mem"
|
||||||
|
|
||||||
@@ -97,9 +97,8 @@ CURRENTLY_ACTIVE :: (^^Region)(~uintptr(0))
|
|||||||
|
|
||||||
FREE_LIST_ENTRIES_PER_BLOCK :: BLOCK_SIZE / size_of(u16)
|
FREE_LIST_ENTRIES_PER_BLOCK :: BLOCK_SIZE / size_of(u16)
|
||||||
|
|
||||||
MMAP_FLAGS :: unix.MAP_ANONYMOUS | unix.MAP_PRIVATE
|
MMAP_FLAGS : linux.Map_Flags : {.ANONYMOUS, .PRIVATE}
|
||||||
MMAP_PROT :: unix.PROT_READ | unix.PROT_WRITE
|
MMAP_PROT : linux.Mem_Protection : {.READ, .WRITE}
|
||||||
|
|
||||||
|
|
||||||
@thread_local _local_region: ^Region
|
@thread_local _local_region: ^Region
|
||||||
global_regions: ^Region
|
global_regions: ^Region
|
||||||
@@ -324,11 +323,11 @@ heap_free :: proc(memory: rawptr) {
|
|||||||
// Regions
|
// Regions
|
||||||
//
|
//
|
||||||
_new_region :: proc() -> ^Region #no_bounds_check {
|
_new_region :: proc() -> ^Region #no_bounds_check {
|
||||||
res := unix.sys_mmap(nil, uint(SIZE_OF_REGION), MMAP_PROT, MMAP_FLAGS, -1, 0)
|
ptr, errno := linux.mmap(0, uint(SIZE_OF_REGION), MMAP_PROT, MMAP_FLAGS, -1, 0)
|
||||||
if res < 0 {
|
if errno != .NONE {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
new_region := (^Region)(uintptr(res))
|
new_region := (^Region)(ptr)
|
||||||
|
|
||||||
new_region.hdr.local_addr = CURRENTLY_ACTIVE
|
new_region.hdr.local_addr = CURRENTLY_ACTIVE
|
||||||
new_region.hdr.reset_addr = &_local_region
|
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 {
|
_direct_mmap_alloc :: proc(size: int) -> rawptr {
|
||||||
mmap_size := _round_up_to_nearest(size + BLOCK_SIZE, PAGE_SIZE)
|
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)
|
new_allocation, errno := linux.mmap(0, uint(mmap_size), MMAP_PROT, MMAP_FLAGS, -1, 0)
|
||||||
if new_allocation < 0 && new_allocation > -4096 {
|
if errno != .NONE {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -655,13 +654,8 @@ _direct_mmap_resize :: proc(alloc: ^Allocation_Header, new_size: int) -> rawptr
|
|||||||
return mem.ptr_offset(alloc, 1)
|
return mem.ptr_offset(alloc, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
new_allocation := unix.sys_mremap(
|
new_allocation, errno := linux.mremap(alloc, uint(old_mmap_size), uint(new_mmap_size), {.MAYMOVE})
|
||||||
alloc,
|
if errno != .NONE {
|
||||||
uint(old_mmap_size),
|
|
||||||
uint(new_mmap_size),
|
|
||||||
unix.MREMAP_MAYMOVE,
|
|
||||||
)
|
|
||||||
if new_allocation < 0 && new_allocation > -4096 {
|
|
||||||
return nil
|
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) {
|
_direct_mmap_free :: proc(alloc: ^Allocation_Header) {
|
||||||
requested := int(alloc.requested & REQUESTED_MASK)
|
requested := int(alloc.requested & REQUESTED_MASK)
|
||||||
mmap_size := _round_up_to_nearest(requested + BLOCK_SIZE, PAGE_SIZE)
|
mmap_size := _round_up_to_nearest(requested + BLOCK_SIZE, PAGE_SIZE)
|
||||||
unix.sys_munmap(alloc, uint(mmap_size))
|
linux.munmap(alloc, uint(mmap_size))
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|||||||
+70
-86
@@ -3,104 +3,89 @@ package os2
|
|||||||
|
|
||||||
import "core:strconv"
|
import "core:strconv"
|
||||||
import "base:runtime"
|
import "base:runtime"
|
||||||
import "core:sys/unix"
|
import "core:sys/linux"
|
||||||
|
|
||||||
_Path_Separator :: '/'
|
_Path_Separator :: '/'
|
||||||
_Path_Separator_String :: "/"
|
_Path_Separator_String :: "/"
|
||||||
_Path_List_Separator :: ':'
|
_Path_List_Separator :: ':'
|
||||||
|
|
||||||
_S_IFMT :: 0o170000 // Type of file mask
|
_OPENDIR_FLAGS : linux.Open_Flags : {.NONBLOCK, .DIRECTORY, .LARGEFILE, .CLOEXEC}
|
||||||
_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
|
|
||||||
|
|
||||||
_is_path_separator :: proc(c: byte) -> bool {
|
_is_path_separator :: proc(c: byte) -> bool {
|
||||||
return c == '/'
|
return c == '/'
|
||||||
}
|
}
|
||||||
|
|
||||||
_mkdir :: proc(path: string, perm: File_Mode) -> Error {
|
_mkdir :: proc(path: string, perm: File_Mode) -> Error {
|
||||||
// NOTE: These modes would require sys_mknod, however, that would require
|
// TODO: These modes would require mknod, however, that would also
|
||||||
// additional arguments to this function.
|
// require additional arguments to this function..
|
||||||
if perm & (File_Mode_Named_Pipe | File_Mode_Device | File_Mode_Char_Device | File_Mode_Sym_Link) != 0 {
|
if perm & (File_Mode_Named_Pipe | File_Mode_Device | File_Mode_Char_Device | File_Mode_Sym_Link) != 0 {
|
||||||
return .Invalid_Argument
|
return .Invalid_Argument
|
||||||
}
|
}
|
||||||
|
|
||||||
TEMP_ALLOCATOR_GUARD()
|
TEMP_ALLOCATOR_GUARD()
|
||||||
path_cstr := temp_cstring(path) or_return
|
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 {
|
_mkdir_all :: proc(path: string, perm: File_Mode) -> Error {
|
||||||
_mkdirat :: proc(dfd: int, path: []u8, perm: int, has_created: ^bool) -> Error {
|
mkdirat :: proc(dfd: linux.Fd, path: []u8, perm: int, has_created: ^bool) -> Error {
|
||||||
if len(path) == 0 {
|
|
||||||
return _ok_or_error(unix.sys_close(dfd))
|
|
||||||
}
|
|
||||||
i: int
|
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
|
path[i] = 0
|
||||||
new_dfd := unix.sys_openat(dfd, cstring(&path[0]), _OPENDIR_FLAGS)
|
new_dfd, errno := linux.openat(dfd, cstring(&path[0]), _OPENDIR_FLAGS)
|
||||||
switch new_dfd {
|
#partial switch errno {
|
||||||
case -ENOENT:
|
case .ENOENT:
|
||||||
if res := unix.sys_mkdirat(dfd, cstring(&path[0]), uint(perm)); res < 0 {
|
if errno = linux.mkdirat(dfd, cstring(&path[0]), transmute(linux.Mode)(u32(perm))); errno != .NONE {
|
||||||
return _get_platform_error(res)
|
return _get_platform_error(errno)
|
||||||
}
|
}
|
||||||
has_created^ = true
|
has_created^ = true
|
||||||
if new_dfd = unix.sys_openat(dfd, cstring(&path[0]), _OPENDIR_FLAGS); new_dfd < 0 {
|
if new_dfd, errno = linux.openat(dfd, cstring(&path[0]), _OPENDIR_FLAGS); errno != .NONE {
|
||||||
return _get_platform_error(new_dfd)
|
return _get_platform_error(errno)
|
||||||
}
|
}
|
||||||
fallthrough
|
fallthrough
|
||||||
case 0:
|
case .NONE:
|
||||||
if res := unix.sys_close(dfd); res < 0 {
|
if errno = linux.close(dfd); errno != .NONE {
|
||||||
return _get_platform_error(res)
|
return _get_platform_error(errno)
|
||||||
}
|
}
|
||||||
// skip consecutive '/'
|
// skip consecutive '/'
|
||||||
for i += 1; i < len(path) && path[i] == '/'; i += 1 {}
|
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:
|
case:
|
||||||
return _get_platform_error(new_dfd)
|
return _get_platform_error(errno)
|
||||||
}
|
}
|
||||||
unreachable()
|
unreachable()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
if perm & (File_Mode_Named_Pipe | File_Mode_Device | File_Mode_Char_Device | File_Mode_Sym_Link) != 0 {
|
if perm & (File_Mode_Named_Pipe | File_Mode_Device | File_Mode_Char_Device | File_Mode_Sym_Link) != 0 {
|
||||||
return .Invalid_Argument
|
return .Invalid_Argument
|
||||||
}
|
}
|
||||||
|
|
||||||
TEMP_ALLOCATOR_GUARD()
|
TEMP_ALLOCATOR_GUARD()
|
||||||
|
|
||||||
// need something we can edit, and use to generate cstrings
|
// need something we can edit, and use to generate cstrings
|
||||||
allocated: bool
|
path_bytes := make([]u8, len(path) + 1, temp_allocator())
|
||||||
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())
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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)
|
copy(path_bytes, path)
|
||||||
path_bytes[len(path)] = 0
|
path_bytes[len(path)] = 0
|
||||||
|
|
||||||
dfd: int
|
dfd: linux.Fd
|
||||||
|
errno: linux.Errno
|
||||||
if path_bytes[0] == '/' {
|
if path_bytes[0] == '/' {
|
||||||
dfd = unix.sys_open("/", _OPENDIR_FLAGS)
|
dfd, errno = linux.open("/", _OPENDIR_FLAGS)
|
||||||
path_bytes = path_bytes[1:]
|
path_bytes = path_bytes[1:]
|
||||||
} else {
|
} else {
|
||||||
dfd = unix.sys_open(".", _OPENDIR_FLAGS)
|
dfd, errno = linux.open(".", _OPENDIR_FLAGS)
|
||||||
}
|
}
|
||||||
if dfd < 0 {
|
if errno != .NONE {
|
||||||
return _get_platform_error(dfd)
|
return _get_platform_error(errno)
|
||||||
}
|
}
|
||||||
|
|
||||||
has_created: bool
|
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 {
|
if has_created {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -119,28 +104,28 @@ dirent64 :: struct {
|
|||||||
_remove_all :: proc(path: string) -> Error {
|
_remove_all :: proc(path: string) -> Error {
|
||||||
DT_DIR :: 4
|
DT_DIR :: 4
|
||||||
|
|
||||||
_remove_all_dir :: proc(dfd: int) -> Error {
|
remove_all_dir :: proc(dfd: linux.Fd) -> Error {
|
||||||
n := 64
|
n := 64
|
||||||
buf := make([]u8, n)
|
buf := make([]u8, n)
|
||||||
defer delete(buf)
|
defer delete(buf)
|
||||||
|
|
||||||
loop: for {
|
loop: for {
|
||||||
getdents_res := unix.sys_getdents64(dfd, &buf[0], n)
|
buflen, errno := linux.getdents(dfd, buf[:])
|
||||||
switch getdents_res {
|
#partial switch errno {
|
||||||
case -EINVAL:
|
case .EINVAL:
|
||||||
delete(buf)
|
delete(buf)
|
||||||
n *= 2
|
n *= 2
|
||||||
buf = make([]u8, n)
|
buf = make([]u8, n)
|
||||||
continue loop
|
continue loop
|
||||||
case -4096..<0:
|
case .NONE:
|
||||||
return _get_platform_error(getdents_res)
|
if buflen == 0 { break loop }
|
||||||
case 0:
|
case:
|
||||||
break loop
|
return _get_platform_error(errno)
|
||||||
}
|
}
|
||||||
|
|
||||||
d: ^dirent64
|
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 = (^dirent64)(rawptr(&buf[i]))
|
||||||
d_name_cstr := cstring(&d.d_name[0])
|
d_name_cstr := cstring(&d.d_name[0])
|
||||||
|
|
||||||
@@ -156,23 +141,22 @@ _remove_all :: proc(path: string) -> Error {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
unlink_res: int
|
|
||||||
|
|
||||||
switch d.d_type {
|
switch d.d_type {
|
||||||
case DT_DIR:
|
case DT_DIR:
|
||||||
new_dfd := unix.sys_openat(dfd, d_name_cstr, _OPENDIR_FLAGS)
|
new_dfd: linux.Fd
|
||||||
if new_dfd < 0 {
|
new_dfd, errno = linux.openat(dfd, d_name_cstr, _OPENDIR_FLAGS)
|
||||||
return _get_platform_error(new_dfd)
|
if errno != .NONE {
|
||||||
|
return _get_platform_error(errno)
|
||||||
}
|
}
|
||||||
defer unix.sys_close(new_dfd)
|
defer linux.close(new_dfd)
|
||||||
_remove_all_dir(new_dfd) or_return
|
remove_all_dir(new_dfd) or_return
|
||||||
unlink_res = unix.sys_unlinkat(dfd, d_name_cstr, int(unix.AT_REMOVEDIR))
|
errno = linux.unlinkat(dfd, d_name_cstr, {.REMOVEDIR})
|
||||||
case:
|
case:
|
||||||
unlink_res = unix.sys_unlinkat(dfd, d_name_cstr)
|
errno = linux.unlinkat(dfd, d_name_cstr, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
if unlink_res < 0 {
|
if errno != .NONE {
|
||||||
return _get_platform_error(unlink_res)
|
return _get_platform_error(errno)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -182,17 +166,19 @@ _remove_all :: proc(path: string) -> Error {
|
|||||||
TEMP_ALLOCATOR_GUARD()
|
TEMP_ALLOCATOR_GUARD()
|
||||||
path_cstr := temp_cstring(path) or_return
|
path_cstr := temp_cstring(path) or_return
|
||||||
|
|
||||||
fd := unix.sys_open(path_cstr, _OPENDIR_FLAGS)
|
fd, errno := linux.open(path_cstr, _OPENDIR_FLAGS)
|
||||||
switch fd {
|
#partial switch errno {
|
||||||
case -ENOTDIR:
|
case .NONE:
|
||||||
return _ok_or_error(unix.sys_unlink(path_cstr))
|
break
|
||||||
case -4096..<0:
|
case .ENOTDIR:
|
||||||
return _get_platform_error(fd)
|
return _get_platform_error(linux.unlink(path_cstr))
|
||||||
|
case:
|
||||||
|
return _get_platform_error(errno)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer unix.sys_close(fd)
|
defer linux.close(fd)
|
||||||
_remove_all_dir(fd) or_return
|
remove_all_dir(fd) or_return
|
||||||
return _ok_or_error(unix.sys_rmdir(path_cstr))
|
return _get_platform_error(linux.rmdir(path_cstr))
|
||||||
}
|
}
|
||||||
|
|
||||||
_getwd :: proc(allocator: runtime.Allocator) -> (string, Error) {
|
_getwd :: proc(allocator: runtime.Allocator) -> (string, Error) {
|
||||||
@@ -203,13 +189,12 @@ _getwd :: proc(allocator: runtime.Allocator) -> (string, Error) {
|
|||||||
PATH_MAX :: 4096
|
PATH_MAX :: 4096
|
||||||
buf := make([dynamic]u8, PATH_MAX, allocator)
|
buf := make([dynamic]u8, PATH_MAX, allocator)
|
||||||
for {
|
for {
|
||||||
#no_bounds_check res := unix.sys_getcwd(&buf[0], uint(len(buf)))
|
#no_bounds_check n, errno := linux.getcwd(buf[:])
|
||||||
|
if errno == .NONE {
|
||||||
if res >= 0 {
|
return string(buf[:n-1]), nil
|
||||||
return string_from_null_terminated_bytes(buf[:]), nil
|
|
||||||
}
|
}
|
||||||
if res != -ERANGE {
|
if errno != .ERANGE {
|
||||||
return "", _get_platform_error(res)
|
return "", _get_platform_error(errno)
|
||||||
}
|
}
|
||||||
resize(&buf, len(buf)+PATH_MAX)
|
resize(&buf, len(buf)+PATH_MAX)
|
||||||
}
|
}
|
||||||
@@ -218,16 +203,16 @@ _getwd :: proc(allocator: runtime.Allocator) -> (string, Error) {
|
|||||||
|
|
||||||
_setwd :: proc(dir: string) -> Error {
|
_setwd :: proc(dir: string) -> Error {
|
||||||
dir_cstr := temp_cstring(dir) or_return
|
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/"
|
PROC_FD_PATH :: "/proc/self/fd/"
|
||||||
|
|
||||||
buf: [32]u8
|
buf: [32]u8
|
||||||
copy(buf[:], PROC_FD_PATH)
|
copy(buf[:], PROC_FD_PATH)
|
||||||
|
|
||||||
strconv.itoa(buf[len(PROC_FD_PATH):], fd)
|
strconv.itoa(buf[len(PROC_FD_PATH):], int(fd))
|
||||||
|
|
||||||
fullpath: string
|
fullpath: string
|
||||||
err: Error
|
err: Error
|
||||||
@@ -236,4 +221,3 @@ _get_full_path :: proc(fd: int, allocator: runtime.Allocator) -> string {
|
|||||||
}
|
}
|
||||||
return fullpath
|
return fullpath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,17 @@
|
|||||||
//+private
|
//+private
|
||||||
package os2
|
package os2
|
||||||
|
|
||||||
|
import "core:sys/linux"
|
||||||
|
|
||||||
_pipe :: proc() -> (r, w: ^File, err: Error) {
|
_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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+20
-96
@@ -3,108 +3,32 @@ package os2
|
|||||||
|
|
||||||
import "core:time"
|
import "core:time"
|
||||||
import "base:runtime"
|
import "base:runtime"
|
||||||
import "core:sys/unix"
|
import "core:sys/linux"
|
||||||
import "core:path/filepath"
|
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) {
|
_fstat :: proc(f: ^File, allocator: runtime.Allocator) -> (File_Info, Error) {
|
||||||
return _fstat_internal(f.impl.fd, allocator)
|
return _fstat_internal(f.impl.fd, allocator)
|
||||||
}
|
}
|
||||||
|
|
||||||
_fstat_internal :: proc(fd: int, allocator: runtime.Allocator) -> (File_Info, Error) {
|
_fstat_internal :: proc(fd: linux.Fd, allocator: runtime.Allocator) -> (File_Info, Error) {
|
||||||
s: _Stat
|
s: linux.Stat
|
||||||
result := unix.sys_fstat(fd, &s)
|
errno := linux.fstat(fd, &s)
|
||||||
if result < 0 {
|
if errno != .NONE {
|
||||||
return {}, _get_platform_error(result)
|
return {}, _get_platform_error(errno)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: As of Linux 4.11, the new statx syscall can retrieve creation_time
|
// TODO: As of Linux 4.11, the new statx syscall can retrieve creation_time
|
||||||
fi := File_Info {
|
fi := File_Info {
|
||||||
fullpath = _get_full_path(fd, allocator),
|
fullpath = _get_full_path(fd, allocator),
|
||||||
name = "",
|
name = "",
|
||||||
size = s.size,
|
size = i64(s.size),
|
||||||
mode = 0,
|
mode = 0,
|
||||||
is_directory = S_ISDIR(s.mode),
|
is_directory = linux.S_ISDIR(s.mode),
|
||||||
modification_time = time.Time {s.modified.seconds},
|
modification_time = time.Time {i64(s.mtime.time_sec) * i64(time.Second) + i64(s.mtime.time_nsec)},
|
||||||
access_time = time.Time {s.last_access.seconds},
|
access_time = time.Time {i64(s.atime.time_sec) * i64(time.Second) + i64(s.atime.time_nsec)},
|
||||||
creation_time = time.Time{0}, // regular stat does not provide this
|
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)
|
fi.name = filepath.base(fi.fullpath)
|
||||||
return fi, nil
|
return fi, nil
|
||||||
@@ -115,11 +39,11 @@ _stat :: proc(name: string, allocator: runtime.Allocator) -> (fi: File_Info, err
|
|||||||
TEMP_ALLOCATOR_GUARD()
|
TEMP_ALLOCATOR_GUARD()
|
||||||
name_cstr := temp_cstring(name) or_return
|
name_cstr := temp_cstring(name) or_return
|
||||||
|
|
||||||
fd := unix.sys_open(name_cstr, _O_RDONLY)
|
fd, errno := linux.open(name_cstr, {})
|
||||||
if fd < 0 {
|
if errno != .NONE {
|
||||||
return {}, _get_platform_error(fd)
|
return {}, _get_platform_error(errno)
|
||||||
}
|
}
|
||||||
defer unix.sys_close(fd)
|
defer linux.close(fd)
|
||||||
return _fstat_internal(fd, allocator)
|
return _fstat_internal(fd, allocator)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,11 +51,11 @@ _lstat :: proc(name: string, allocator: runtime.Allocator) -> (fi: File_Info, er
|
|||||||
TEMP_ALLOCATOR_GUARD()
|
TEMP_ALLOCATOR_GUARD()
|
||||||
name_cstr := temp_cstring(name) or_return
|
name_cstr := temp_cstring(name) or_return
|
||||||
|
|
||||||
fd := unix.sys_open(name_cstr, _O_RDONLY | _O_PATH | _O_NOFOLLOW)
|
fd, errno := linux.open(name_cstr, {.PATH, .NOFOLLOW})
|
||||||
if fd < 0 {
|
if errno != .NONE {
|
||||||
return {}, _get_platform_error(fd)
|
return {}, _get_platform_error(errno)
|
||||||
}
|
}
|
||||||
defer unix.sys_close(fd)
|
defer linux.close(fd)
|
||||||
return _fstat_internal(fd, allocator)
|
return _fstat_internal(fd, allocator)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -555,7 +555,7 @@ open :: proc(path: string, flags: int = O_RDWR, mode: int = 0) -> (Handle, Errno
|
|||||||
err := fchmod(handle, cast(u16)mode)
|
err := fchmod(handle, cast(u16)mode)
|
||||||
if err != 0 {
|
if err != 0 {
|
||||||
_unix_close(handle)
|
_unix_close(handle)
|
||||||
return INVALID_HANDLE, cast(Errno)err
|
return INVALID_HANDLE, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -883,7 +883,7 @@ absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Errno) {
|
|||||||
}
|
}
|
||||||
defer _unix_free(path_ptr)
|
defer _unix_free(path_ptr)
|
||||||
|
|
||||||
path_cstr := transmute(cstring)path_ptr
|
path_cstr := cast(cstring)path_ptr
|
||||||
path = strings.clone(string(path_cstr))
|
path = strings.clone(string(path_cstr))
|
||||||
|
|
||||||
return path, ERROR_NONE
|
return path, ERROR_NONE
|
||||||
|
|||||||
@@ -648,8 +648,8 @@ absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Errno) {
|
|||||||
}
|
}
|
||||||
defer _unix_free(path_ptr)
|
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
|
return path, ERROR_NONE
|
||||||
}
|
}
|
||||||
@@ -705,7 +705,9 @@ set_current_directory :: proc(path: string) -> (err: Errno) {
|
|||||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||||
cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
||||||
res := _unix_chdir(cstr)
|
res := _unix_chdir(cstr)
|
||||||
if res == -1 do return Errno(get_last_error())
|
if res == -1 {
|
||||||
|
return Errno(get_last_error())
|
||||||
|
}
|
||||||
return ERROR_NONE
|
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
|
// NOTE(tetra): The page size never changes, so why do anything complicated
|
||||||
// if we don't have to.
|
// if we don't have to.
|
||||||
@static page_size := -1
|
@static page_size := -1
|
||||||
if page_size != -1 do return page_size
|
if page_size != -1 {
|
||||||
|
return page_size
|
||||||
|
}
|
||||||
|
|
||||||
page_size = int(_unix_getpagesize())
|
page_size = int(_unix_getpagesize())
|
||||||
return page_size
|
return page_size
|
||||||
|
|||||||
@@ -890,8 +890,7 @@ absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Errno) {
|
|||||||
}
|
}
|
||||||
defer _unix_free(path_ptr)
|
defer _unix_free(path_ptr)
|
||||||
|
|
||||||
path_cstr := transmute(cstring)path_ptr
|
path = strings.clone(string(cstring(path_ptr)))
|
||||||
path = strings.clone( string(path_cstr) )
|
|
||||||
|
|
||||||
return path, ERROR_NONE
|
return path, ERROR_NONE
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -658,8 +658,7 @@ absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Errno) {
|
|||||||
}
|
}
|
||||||
defer _unix_free(path_ptr)
|
defer _unix_free(path_ptr)
|
||||||
|
|
||||||
path_cstr := transmute(cstring)path_ptr
|
path = strings.clone(string(cstring(path_ptr)))
|
||||||
path = strings.clone( string(path_cstr) )
|
|
||||||
|
|
||||||
return path, ERROR_NONE
|
return path, ERROR_NONE
|
||||||
}
|
}
|
||||||
@@ -715,7 +714,9 @@ set_current_directory :: proc(path: string) -> (err: Errno) {
|
|||||||
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
|
||||||
cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
cstr := strings.clone_to_cstring(path, context.temp_allocator)
|
||||||
res := _unix_chdir(cstr)
|
res := _unix_chdir(cstr)
|
||||||
if res == -1 do return Errno(get_last_error())
|
if res == -1 {
|
||||||
|
return Errno(get_last_error())
|
||||||
|
}
|
||||||
return ERROR_NONE
|
return ERROR_NONE
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -756,7 +757,9 @@ get_page_size :: proc() -> int {
|
|||||||
// NOTE(tetra): The page size never changes, so why do anything complicated
|
// NOTE(tetra): The page size never changes, so why do anything complicated
|
||||||
// if we don't have to.
|
// if we don't have to.
|
||||||
@static page_size := -1
|
@static page_size := -1
|
||||||
if page_size != -1 do return page_size
|
if page_size != -1 {
|
||||||
|
return page_size
|
||||||
|
}
|
||||||
|
|
||||||
page_size = int(_unix_getpagesize())
|
page_size = int(_unix_getpagesize())
|
||||||
return page_size
|
return page_size
|
||||||
|
|||||||
@@ -610,8 +610,7 @@ absolute_path_from_relative :: proc(rel: string) -> (path: string, err: Errno) {
|
|||||||
}
|
}
|
||||||
defer _unix_free(path_ptr)
|
defer _unix_free(path_ptr)
|
||||||
|
|
||||||
path_cstr := transmute(cstring)path_ptr
|
path = strings.clone(string(cstring(path_ptr)))
|
||||||
path = strings.clone( string(path_cstr) )
|
|
||||||
|
|
||||||
return path, ERROR_NONE
|
return path, ERROR_NONE
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import "base:runtime"
|
|||||||
Handle :: distinct i32
|
Handle :: distinct i32
|
||||||
Errno :: distinct i32
|
Errno :: distinct i32
|
||||||
|
|
||||||
|
INVALID_HANDLE :: -1
|
||||||
|
|
||||||
ERROR_NONE :: Errno(wasi.errno_t.SUCCESS)
|
ERROR_NONE :: Errno(wasi.errno_t.SUCCESS)
|
||||||
|
|
||||||
O_RDONLY :: 0x00000
|
O_RDONLY :: 0x00000
|
||||||
@@ -26,6 +28,16 @@ stdout: Handle = 1
|
|||||||
stderr: Handle = 2
|
stderr: Handle = 2
|
||||||
current_dir: Handle = 3
|
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) {
|
write :: proc(fd: Handle, data: []byte) -> (int, Errno) {
|
||||||
iovs := wasi.ciovec_t(data)
|
iovs := wasi.ciovec_t(data)
|
||||||
n, err := wasi.fd_write(wasi.fd_t(fd), {iovs})
|
n, err := wasi.fd_write(wasi.fd_t(fd), {iovs})
|
||||||
|
|||||||
@@ -156,8 +156,7 @@ linear_search_proc :: proc(array: $A/[]$T, f: proc(T) -> bool) -> (index: int, f
|
|||||||
*/
|
*/
|
||||||
@(require_results)
|
@(require_results)
|
||||||
binary_search :: proc(array: $A/[]$T, key: T) -> (index: int, found: bool)
|
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))
|
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)
|
@(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 {
|
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 {
|
for v in enums {
|
||||||
bits |= {v}
|
bits += {v}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ Builder :: struct {
|
|||||||
buf: [dynamic]byte,
|
buf: [dynamic]byte,
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Produces a Builder with a default length of 0 and cap of 16
|
Produces an empty Builder
|
||||||
|
|
||||||
*Allocates Using Provided Allocator*
|
*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
|
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*
|
*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
|
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*
|
*Allocates Using Provided Allocator*
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ builder_make :: proc{
|
|||||||
builder_make_len_cap,
|
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`
|
It replaces the existing `buf`
|
||||||
|
|
||||||
*Allocates Using Provided Allocator*
|
*Allocates Using Provided Allocator*
|
||||||
@@ -121,7 +121,7 @@ builder_init_none :: proc(b: ^Builder, allocator := context.allocator, loc := #c
|
|||||||
return b, nil
|
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`
|
It replaces the existing `buf`
|
||||||
|
|
||||||
*Allocates Using Provided Allocator*
|
*Allocates Using Provided Allocator*
|
||||||
@@ -140,7 +140,7 @@ builder_init_len :: proc(b: ^Builder, len: int, allocator := context.allocator,
|
|||||||
return b, nil
|
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`
|
It replaces the existing `buf`
|
||||||
|
|
||||||
Inputs:
|
Inputs:
|
||||||
@@ -723,11 +723,11 @@ write_f32 :: proc(b: ^Builder, f: f32, fmt: byte, always_signed := false) -> (n:
|
|||||||
return write_string(b, s)
|
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:
|
Inputs:
|
||||||
- b: A pointer to the Builder
|
- b: A pointer to the Builder
|
||||||
- f: The f32 value to be appended
|
- f: The f64 value to be appended
|
||||||
- fmt: The format byte
|
- fmt: The format byte
|
||||||
- always_signed: Optional boolean flag to always include the sign
|
- always_signed: Optional boolean flag to always include the sign
|
||||||
|
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ StringCopyToOdinString :: proc(
|
|||||||
max := StringGetMaximumSizeForEncoding(length, StringEncoding(StringBuiltInEncodings.UTF8))
|
max := StringGetMaximumSizeForEncoding(length, StringEncoding(StringBuiltInEncodings.UTF8))
|
||||||
|
|
||||||
buf, err := make([]byte, max, allocator)
|
buf, err := make([]byte, max, allocator)
|
||||||
if err != nil do return
|
if err != nil { return }
|
||||||
|
|
||||||
raw_str := runtime.Raw_String {
|
raw_str := runtime.Raw_String {
|
||||||
data = raw_data(buf),
|
data = raw_data(buf),
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ init_cpu_name :: proc "c" () {
|
|||||||
return
|
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[ 0], _buf[ 1], _buf[ 2], _buf[ 3] = cpuid(0x8000_0002, 0)
|
||||||
_buf[ 4], _buf[ 5], _buf[ 6], _buf[ 7] = cpuid(0x8000_0003, 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)
|
_buf[ 8], _buf[ 9], _buf[10], _buf[11] = cpuid(0x8000_0004, 0)
|
||||||
|
|||||||
+48
-11
@@ -48,6 +48,7 @@ Errno :: enum i32 {
|
|||||||
ENOSYS = 38,
|
ENOSYS = 38,
|
||||||
ENOTEMPTY = 39,
|
ENOTEMPTY = 39,
|
||||||
ELOOP = 40,
|
ELOOP = 40,
|
||||||
|
EUNKNOWN_41 = 41,
|
||||||
ENOMSG = 42,
|
ENOMSG = 42,
|
||||||
EIDRM = 43,
|
EIDRM = 43,
|
||||||
ECHRNG = 44,
|
ECHRNG = 44,
|
||||||
@@ -64,6 +65,7 @@ Errno :: enum i32 {
|
|||||||
ENOANO = 55,
|
ENOANO = 55,
|
||||||
EBADRQC = 56,
|
EBADRQC = 56,
|
||||||
EBADSLT = 57,
|
EBADSLT = 57,
|
||||||
|
EUNKNOWN_58 = 58,
|
||||||
EBFONT = 59,
|
EBFONT = 59,
|
||||||
ENOSTR = 60,
|
ENOSTR = 60,
|
||||||
ENODATA = 61,
|
ENODATA = 61,
|
||||||
@@ -150,6 +152,7 @@ Errno :: enum i32 {
|
|||||||
RDONLY flag is not present, because it has the value of 0, i.e. it is the
|
RDONLY flag is not present, because it has the value of 0, i.e. it is the
|
||||||
default, unless WRONLY or RDWR is specified.
|
default, unless WRONLY or RDWR is specified.
|
||||||
*/
|
*/
|
||||||
|
when ODIN_ARCH != .arm64 && ODIN_ARCH != .arm32 {
|
||||||
Open_Flags_Bits :: enum {
|
Open_Flags_Bits :: enum {
|
||||||
WRONLY = 0,
|
WRONLY = 0,
|
||||||
RDWR = 1,
|
RDWR = 1,
|
||||||
@@ -169,7 +172,6 @@ Open_Flags_Bits :: enum {
|
|||||||
CLOEXEC = 19,
|
CLOEXEC = 19,
|
||||||
PATH = 21,
|
PATH = 21,
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://github.com/torvalds/linux/blob/7367539ad4b0f8f9b396baf02110962333719a48/include/uapi/asm-generic/fcntl.h#L19
|
// 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.WRONLY) == 0o0000000_1)
|
||||||
#assert(1 << uint(Open_Flags_Bits.RDWR) == 0o0000000_2)
|
#assert(1 << uint(Open_Flags_Bits.RDWR) == 0o0000000_2)
|
||||||
@@ -189,6 +191,28 @@ Open_Flags_Bits :: enum {
|
|||||||
#assert(1 << uint(Open_Flags_Bits.CLOEXEC) == 0o0_2000000)
|
#assert(1 << uint(Open_Flags_Bits.CLOEXEC) == 0o0_2000000)
|
||||||
#assert(1 << uint(Open_Flags_Bits.PATH) == 0o_10000000)
|
#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
|
Bits for FD_Flags bitset
|
||||||
*/
|
*/
|
||||||
@@ -946,6 +970,19 @@ Sig_Stack_Flag :: enum i32 {
|
|||||||
AUTODISARM = 31,
|
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
|
Type of socket to create
|
||||||
- For TCP you want to use SOCK_STREAM
|
- For TCP you want to use SOCK_STREAM
|
||||||
@@ -1427,16 +1464,16 @@ Futex_Flags_Bits :: enum {
|
|||||||
Kind of operation on futex, see FUTEX_WAKE_OP
|
Kind of operation on futex, see FUTEX_WAKE_OP
|
||||||
*/
|
*/
|
||||||
Futex_Arg_Op :: enum {
|
Futex_Arg_Op :: enum {
|
||||||
SET = 0, /* uaddr2 = oparg; */
|
SET = 0, /* uaddr2 = oparg */
|
||||||
ADD = 1, /* uaddr2 += oparg; */
|
ADD = 1, /* uaddr2 += oparg */
|
||||||
OR = 2, /* uaddr2 |= oparg; */
|
OR = 2, /* uaddr2 |= oparg */
|
||||||
ANDN = 3, /* uaddr2 &= ~oparg; */
|
ANDN = 3, /* uaddr2 &= ~oparg */
|
||||||
XOR = 4, /* uaddr2 ^= oparg; */
|
XOR = 4, /* uaddr2 ^= oparg */
|
||||||
PO2_SET = 0, /* uaddr2 = 1<<oparg; */
|
PO2_SET = 0, /* uaddr2 = 1<<oparg */
|
||||||
PO2_ADD = 1, /* uaddr2 += 1<<oparg; */
|
PO2_ADD = 1, /* uaddr2 += 1<<oparg */
|
||||||
PO2_OR = 2, /* uaddr2 |= 1<<oparg; */
|
PO2_OR = 2, /* uaddr2 |= 1<<oparg */
|
||||||
PO2_ANDN = 3, /* uaddr2 &= ~(1<<oparg); */
|
PO2_ANDN = 3, /* uaddr2 &~= 1<<oparg */
|
||||||
PO2_XOR = 4, /* uaddr2 ^= 1<<oparg; */
|
PO2_XOR = 4, /* uaddr2 ^= 1<<oparg */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
+36
-26
@@ -69,7 +69,7 @@ close :: proc "contextless" (fd: Fd) -> (Errno) {
|
|||||||
stat :: proc "contextless" (filename: cstring, stat: ^Stat) -> (Errno) {
|
stat :: proc "contextless" (filename: cstring, stat: ^Stat) -> (Errno) {
|
||||||
when size_of(int) == 8 {
|
when size_of(int) == 8 {
|
||||||
when ODIN_ARCH == .arm64 {
|
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)
|
return Errno(-ret)
|
||||||
} else {
|
} else {
|
||||||
ret := syscall(SYS_stat, cast(rawptr) filename, stat)
|
ret := syscall(SYS_stat, cast(rawptr) filename, stat)
|
||||||
@@ -200,10 +200,25 @@ brk :: proc "contextless" (addr: uintptr) -> (Errno) {
|
|||||||
return Errno(-ret)
|
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.
|
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))
|
ret := syscall(SYS_rt_sigaction, sig, sigaction, old_sigaction, size_of(Sig_Set))
|
||||||
return Errno(-ret)
|
return Errno(-ret)
|
||||||
}
|
}
|
||||||
@@ -1123,7 +1138,7 @@ ftruncate :: proc "contextless" (fd: Fd, length: i64) -> (Errno) {
|
|||||||
ret := syscall(SYS_ftruncate64, fd, compat64_arg_pair(length))
|
ret := syscall(SYS_ftruncate64, fd, compat64_arg_pair(length))
|
||||||
return Errno(-ret)
|
return Errno(-ret)
|
||||||
} else {
|
} else {
|
||||||
ret := syscall(SYS_truncate, fd, compat64_arg_pair(length))
|
ret := syscall(SYS_ftruncate, fd, compat64_arg_pair(length))
|
||||||
return Errno(-ret)
|
return Errno(-ret)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1231,7 +1246,7 @@ creat :: proc "contextless" (name: cstring, mode: Mode) -> (Fd, Errno) {
|
|||||||
*/
|
*/
|
||||||
link :: proc "contextless" (target: cstring, linkpath: cstring) -> (Errno) {
|
link :: proc "contextless" (target: cstring, linkpath: cstring) -> (Errno) {
|
||||||
when ODIN_ARCH == .arm64 {
|
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)
|
return Errno(-ret)
|
||||||
} else {
|
} else {
|
||||||
ret := syscall(SYS_link, cast(rawptr) target, cast(rawptr) linkpath)
|
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) {
|
symlink :: proc "contextless" (target: cstring, linkpath: cstring) -> (Errno) {
|
||||||
when ODIN_ARCH == .arm64 {
|
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)
|
return Errno(-ret)
|
||||||
} else {
|
} else {
|
||||||
ret := syscall(SYS_symlink, cast(rawptr) target, cast(rawptr) linkpath)
|
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) {
|
chmod :: proc "contextless" (name: cstring, mode: Mode) -> (Errno) {
|
||||||
when ODIN_ARCH == .arm64 {
|
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)
|
return Errno(-ret)
|
||||||
} else {
|
} else {
|
||||||
ret := syscall(SYS_chmod, cast(rawptr) name, transmute(u32) mode)
|
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.
|
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,
|
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
|
futex_flags := cast(u32) op + transmute(u32) flags
|
||||||
ret := syscall(SYS_futex, futex, futex_flags, requeue_threshold, requeue_max, requeue_futex, val)
|
ret := syscall(SYS_futex, futex, futex_flags, requeue_threshold, requeue_max, requeue_futex, val)
|
||||||
return errno_unwrap(ret, int)
|
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.
|
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,
|
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
|
futex_flags := cast(u32) op + transmute(u32) flags
|
||||||
ret := syscall(SYS_futex, futex, futex_flags, requeue_threshold, requeue_max, requeue_futex)
|
ret := syscall(SYS_futex, futex, futex_flags, requeue_threshold, requeue_max, requeue_futex)
|
||||||
return errno_unwrap(ret, int)
|
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.
|
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,
|
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
|
futex_flags := cast(u32) op + transmute(u32) flags
|
||||||
ret := syscall(SYS_futex, futex, futex_flags, wakeup, dst_wakeup, dst, futex_op)
|
ret := syscall(SYS_futex, futex, futex_flags, wakeup, dst_wakeup, dst, futex_op)
|
||||||
return errno_unwrap(ret, int)
|
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.
|
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,
|
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
|
futex_flags := cast(u32) op + transmute(u32) flags
|
||||||
ret := syscall(SYS_futex, futex, futex_flags, val, timeout, 0, mask)
|
ret := syscall(SYS_futex, futex, futex_flags, val, timeout, 0, mask)
|
||||||
return errno_unwrap(ret, int)
|
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.
|
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
|
futex_flags := cast(u32) op + transmute(u32) flags
|
||||||
ret := syscall(SYS_futex, futex, futex_flags, n_wakeup, 0, 0, mask)
|
ret := syscall(SYS_futex, futex, futex_flags, n_wakeup, 0, 0, mask)
|
||||||
return errno_unwrap(ret, int)
|
return errno_unwrap(ret, int)
|
||||||
@@ -2476,8 +2486,8 @@ tgkill :: proc "contextless" (tgid, tid: Pid, sig: Signal) -> (Errno) {
|
|||||||
Wait on process, process group or pid file descriptor.
|
Wait on process, process group or pid file descriptor.
|
||||||
Available since Linux 2.6.10.
|
Available since Linux 2.6.10.
|
||||||
*/
|
*/
|
||||||
waitid :: proc "contextless" (id_type: Id_Type, id: Id, sig_info: ^Sig_Info, options: Wait_Options) -> (Errno) {
|
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)
|
ret := syscall(SYS_waitid, id_type, id, sig_info, transmute(i32) options, rusage)
|
||||||
return Errno(-ret)
|
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.
|
Available since Linux 2.6.16.
|
||||||
*/
|
*/
|
||||||
openat :: proc "contextless" (fd: Fd, name: cstring, flags: Open_Flags, mode: Mode = {}) -> (Fd, Errno) {
|
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)
|
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.
|
Create a symbolic link at specified dirfd.
|
||||||
Available since Linux 2.6.16.
|
Available since Linux 2.6.16.
|
||||||
*/
|
*/
|
||||||
symlinkat :: proc "contextless" (dirfd: Fd, target: cstring, linkpath: cstring) -> (Errno) {
|
symlinkat :: proc "contextless" (target: cstring, dirfd: Fd, linkpath: cstring) -> (Errno) {
|
||||||
ret := syscall(SYS_symlinkat, dirfd, cast(rawptr) target, cast(rawptr) linkpath)
|
ret := syscall(SYS_symlinkat, cast(rawptr) target, dirfd, cast(rawptr) linkpath)
|
||||||
return Errno(-ret)
|
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.
|
Wait for events on a file descriptor.
|
||||||
Available since Linux 2.6.16.
|
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 {
|
when size_of(int) == 8 {
|
||||||
ret := syscall(SYS_ppoll, raw_data(fds), len(fds), timeout, sigmask, size_of(Sig_Set))
|
ret := syscall(SYS_ppoll, raw_data(fds), len(fds), timeout, sigmask, size_of(Sig_Set))
|
||||||
return Errno(-ret)
|
return errno_unwrap(ret, i32)
|
||||||
} else {
|
} else {
|
||||||
ret := syscall(SYS_ppoll_time64, raw_data(fds), len(fds), timeout, sigmask, size_of(Sig_Set))
|
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.
|
Execute program relative to a directory file descriptor.
|
||||||
Available since Linux 3.19.
|
Available since Linux 3.19.
|
||||||
*/
|
*/
|
||||||
execveat :: proc "contextless" (dirfd: Fd, name: cstring, argv: [^]cstring, envp: [^]cstring) -> (Errno) {
|
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)
|
ret := syscall(SYS_execveat, dirfd, cast(rawptr) name, cast(rawptr) argv, cast(rawptr) envp, transmute(i32) flags)
|
||||||
return Errno(-ret)
|
return Errno(-ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+66
-10
@@ -18,7 +18,7 @@ Gid :: distinct u32
|
|||||||
/*
|
/*
|
||||||
Type for Process IDs, Thread IDs, Thread group ID.
|
Type for Process IDs, Thread IDs, Thread group ID.
|
||||||
*/
|
*/
|
||||||
Pid :: distinct int
|
Pid :: distinct i32
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Type for any of: pid, pidfd, pgid.
|
Type for any of: pid, pidfd, pgid.
|
||||||
@@ -151,9 +151,9 @@ when ODIN_ARCH == .amd64 {
|
|||||||
size: i64,
|
size: i64,
|
||||||
blksize: uint,
|
blksize: uint,
|
||||||
blocks: u64,
|
blocks: u64,
|
||||||
atim: Time_Spec,
|
atime: Time_Spec,
|
||||||
mtim: Time_Spec,
|
mtime: Time_Spec,
|
||||||
ctim: Time_Spec,
|
ctime: Time_Spec,
|
||||||
ino: Inode,
|
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
|
// 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?).
|
// 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.
|
// 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
|
Sig_Set :: [_SIGSET_NWORDS]uint
|
||||||
|
|
||||||
@private SI_MAX_SIZE :: 128
|
@private SI_MAX_SIZE :: 128
|
||||||
@private SI_ARCH_PREAMBLE :: 3 * size_of(i32)
|
@private SI_ARCH_PREAMBLE :: 4 * size_of(i32)
|
||||||
@private SI_PAD_SIZE :: (SI_MAX_SIZE - SI_ARCH_PREAMBLE) / size_of(i32)
|
@private SI_PAD_SIZE :: SI_MAX_SIZE - SI_ARCH_PREAMBLE
|
||||||
@private SI_TIMER_PAD_SIZE :: size_of(Uid) - size_of(i32)
|
|
||||||
|
|
||||||
Sig_Handler_Fn :: #type proc "c" (sig: Signal)
|
Sig_Handler_Fn :: #type proc "c" (sig: Signal)
|
||||||
Sig_Restore_Fn :: #type proc "c" ()
|
Sig_Restore_Fn :: #type proc "c" () -> !
|
||||||
|
|
||||||
Sig_Info :: struct #packed {
|
Sig_Info :: struct #packed {
|
||||||
signo: Signal,
|
signo: Signal,
|
||||||
@@ -520,6 +519,7 @@ Sig_Info :: struct #packed {
|
|||||||
using _timer: struct {
|
using _timer: struct {
|
||||||
timerid: i32, /* timer id */
|
timerid: i32, /* timer id */
|
||||||
overrun: i32, /* overrun count */
|
overrun: i32, /* overrun count */
|
||||||
|
value: Sig_Val, /* timer value */
|
||||||
},
|
},
|
||||||
/* POSIX.1b signals */
|
/* POSIX.1b signals */
|
||||||
using _rt: struct {
|
using _rt: struct {
|
||||||
@@ -537,7 +537,24 @@ Sig_Info :: struct #packed {
|
|||||||
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
|
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
|
||||||
using _sigfault: struct {
|
using _sigfault: struct {
|
||||||
addr: rawptr, /* faulting insn/memory ref. */
|
addr: rawptr, /* faulting insn/memory ref. */
|
||||||
|
using _: struct #raw_union {
|
||||||
|
trapno: i32, /* Trap number that caused signal */
|
||||||
addr_lsb: i16, /* LSB of the reported address */
|
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 */
|
/* SIGPOLL */
|
||||||
using _sigpoll: struct {
|
using _sigpoll: struct {
|
||||||
@@ -553,6 +570,37 @@ Sig_Info :: struct #packed {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#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_MAX_SIZE :: 64
|
||||||
SIGEV_PAD_SIZE :: ((SIGEV_MAX_SIZE-size_of(i32)*2+size_of(Sig_Val))/size_of(i32))
|
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,
|
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) {
|
Sig_Action :: struct($T: typeid) {
|
||||||
using _u: struct #raw_union {
|
using _u: struct #raw_union {
|
||||||
handler: Sig_Handler_Fn,
|
handler: Sig_Handler_Fn,
|
||||||
sigaction: #type proc "c" (sig: Signal, si: ^Sig_Info, ctx: ^T),
|
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,
|
restorer: Sig_Restore_Fn,
|
||||||
mask: Sig_Set,
|
mask: Sig_Set,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,13 +85,13 @@ dirent_iterate_buf :: proc "contextless" (buf: []u8, offs: ^int) -> (d: ^Dirent,
|
|||||||
/// Obtain the name of dirent as a string
|
/// Obtain the name of dirent as a string
|
||||||
/// The lifetime of the string is bound to the lifetime of the provided dirent structure
|
/// 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 {
|
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
|
// 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
|
// 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
|
// 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
|
// 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.
|
// 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,
|
// This skips *only* over the garbage, since if we're not garbage we're at nul terminator,
|
||||||
// which skips this loop
|
// which skips this loop
|
||||||
for str[str_size] != 0 {
|
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
|
/// Helper function for constructing the config for caches
|
||||||
perf_cache_config :: #force_inline proc "contextless" (id: Perf_Hardware_Cache_Id,
|
perf_cache_config :: #force_inline proc "contextless" (id: Perf_Hardware_Cache_Id,
|
||||||
op: Perf_Hardware_Cache_Op_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)
|
return u64(id) | (u64(op) << 8) | (u64(res) << 16)
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
@@ -51,12 +51,11 @@ get_log_level :: #force_inline proc() -> runtime.Logger_Level {
|
|||||||
// Always use .Debug in `-debug` mode.
|
// Always use .Debug in `-debug` mode.
|
||||||
return .Debug
|
return .Debug
|
||||||
} else {
|
} else {
|
||||||
when LOG_LEVEL == "debug" { return .Debug }
|
when LOG_LEVEL == "debug" { return .Debug } else
|
||||||
else when LOG_LEVEL == "info" { return .Info }
|
when LOG_LEVEL == "info" { return .Info } else
|
||||||
else when LOG_LEVEL == "warning" { return .Warning }
|
when LOG_LEVEL == "warning" { return .Warning } else
|
||||||
else when LOG_LEVEL == "error" { return .Error }
|
when LOG_LEVEL == "error" { return .Error } else
|
||||||
else when LOG_LEVEL == "fatal" { return .Fatal }
|
when LOG_LEVEL == "fatal" { return .Fatal } else {
|
||||||
else {
|
|
||||||
#panic("Unknown `ODIN_TEST_LOG_LEVEL`: \"" + LOG_LEVEL + "\", possible levels are: \"debug\", \"info\", \"warning\", \"error\", or \"fatal\".")
|
#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.
|
// Intentional shadow with user-specified tests.
|
||||||
internal_tests := select_internal_tests[:]
|
internal_tests = select_internal_tests[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
total_failure_count := 0
|
total_failure_count := 0
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ Stop_Reason :: enum {
|
|||||||
Illegal_Instruction,
|
Illegal_Instruction,
|
||||||
Arithmetic_Error,
|
Arithmetic_Error,
|
||||||
Segmentation_Fault,
|
Segmentation_Fault,
|
||||||
|
Unhandled_Trap,
|
||||||
}
|
}
|
||||||
|
|
||||||
test_assertion_failure_proc :: proc(prefix, message: string, loc: runtime.Source_Code_Location) -> ! {
|
test_assertion_failure_proc :: proc(prefix, message: string, loc: runtime.Source_Code_Location) -> ! {
|
||||||
|
|||||||
@@ -19,6 +19,11 @@ import "core:os"
|
|||||||
@(private="file", thread_local)
|
@(private="file", thread_local)
|
||||||
local_test_index: libc.sig_atomic_t
|
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")
|
@(private="file")
|
||||||
stop_runner_callback :: proc "c" (sig: libc.int) {
|
stop_runner_callback :: proc "c" (sig: libc.int) {
|
||||||
prev := intrinsics.atomic_add(&stop_runner_flag, 1)
|
prev := intrinsics.atomic_add(&stop_runner_flag, 1)
|
||||||
@@ -110,6 +115,10 @@ _setup_signal_handler :: proc() {
|
|||||||
// For tests:
|
// For tests:
|
||||||
// Catch asserts and panics.
|
// Catch asserts and panics.
|
||||||
libc.signal(libc.SIGILL, stop_test_callback)
|
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.
|
// Catch arithmetic errors.
|
||||||
libc.signal(libc.SIGFPE, stop_test_callback)
|
libc.signal(libc.SIGFPE, stop_test_callback)
|
||||||
// Catch segmentation faults (illegal memory access).
|
// 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.SIGFPE: reason = .Arithmetic_Error
|
||||||
case libc.SIGILL: reason = .Illegal_Instruction
|
case libc.SIGILL: reason = .Illegal_Instruction
|
||||||
case libc.SIGSEGV: reason = .Segmentation_Fault
|
case libc.SIGSEGV: reason = .Segmentation_Fault
|
||||||
|
case SIGTRAP: reason = .Unhandled_Trap
|
||||||
}
|
}
|
||||||
ok = true
|
ok = true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import "base:intrinsics"
|
|||||||
|
|
||||||
_ :: intrinsics
|
_ :: intrinsics
|
||||||
|
|
||||||
|
IS_SUPPORTED :: _IS_SUPPORTED
|
||||||
|
|
||||||
Thread_Proc :: #type proc(^Thread)
|
Thread_Proc :: #type proc(^Thread)
|
||||||
|
|
||||||
MAX_USER_ARGUMENTS :: 8
|
MAX_USER_ARGUMENTS :: 8
|
||||||
@@ -58,7 +60,9 @@ Thread :: struct {
|
|||||||
creation_allocator: mem.Allocator,
|
creation_allocator: mem.Allocator,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
when IS_SUPPORTED {
|
||||||
#assert(size_of(Thread{}.user_index) == size_of(uintptr))
|
#assert(size_of(Thread{}.user_index) == size_of(uintptr))
|
||||||
|
}
|
||||||
|
|
||||||
Thread_Priority :: enum {
|
Thread_Priority :: enum {
|
||||||
Normal,
|
Normal,
|
||||||
|
|||||||
@@ -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")
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -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")
|
||||||
|
}
|
||||||
|
|
||||||
@@ -6,6 +6,8 @@ import "core:sync"
|
|||||||
import "core:sys/unix"
|
import "core:sys/unix"
|
||||||
import "core:time"
|
import "core:time"
|
||||||
|
|
||||||
|
_IS_SUPPORTED :: true
|
||||||
|
|
||||||
CAS :: sync.atomic_compare_exchange_strong
|
CAS :: sync.atomic_compare_exchange_strong
|
||||||
|
|
||||||
// NOTE(tetra): Aligned here because of core/unix/pthread_linux.odin/pthread_t.
|
// 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 {
|
__unix_thread_entry_proc :: proc "c" (t: rawptr) -> rawptr {
|
||||||
t := (^Thread)(t)
|
t := (^Thread)(t)
|
||||||
|
|
||||||
when ODIN_OS != .Darwin {
|
|
||||||
// We need to give the thread a moment to start up before we enable cancellation.
|
// 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
|
can_set_thread_cancel_state := unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_ENABLE, nil) == 0
|
||||||
}
|
|
||||||
|
|
||||||
sync.lock(&t.mutex)
|
sync.lock(&t.mutex)
|
||||||
|
|
||||||
@@ -42,13 +42,11 @@ _create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
when ODIN_OS != .Darwin {
|
|
||||||
// Enable thread's cancelability.
|
// Enable thread's cancelability.
|
||||||
if can_set_thread_cancel_state {
|
if can_set_thread_cancel_state {
|
||||||
unix.pthread_setcanceltype (unix.PTHREAD_CANCEL_ASYNCHRONOUS, nil)
|
unix.pthread_setcanceltype (unix.PTHREAD_CANCEL_ASYNCHRONOUS, nil)
|
||||||
unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_ENABLE, nil)
|
unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_ENABLE, nil)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
init_context := t.init_context
|
init_context := t.init_context
|
||||||
@@ -169,11 +167,18 @@ _destroy :: proc(t: ^Thread) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_terminate :: proc(t: ^Thread, exit_code: int) {
|
_terminate :: proc(t: ^Thread, exit_code: int) {
|
||||||
// `pthread_cancel` is unreliable on Darwin for unknown reasons.
|
// NOTE(Feoramund): For thread cancellation to succeed on BSDs and
|
||||||
when ODIN_OS != .Darwin {
|
// 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)
|
unix.pthread_cancel(t.unix_thread)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
_yield :: proc() {
|
_yield :: proc() {
|
||||||
unix.sched_yield()
|
unix.sched_yield()
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import "base:intrinsics"
|
|||||||
import "core:sync"
|
import "core:sync"
|
||||||
import win32 "core:sys/windows"
|
import win32 "core:sys/windows"
|
||||||
|
|
||||||
|
_IS_SUPPORTED :: true
|
||||||
|
|
||||||
Thread_Os_Specific :: struct {
|
Thread_Os_Specific :: struct {
|
||||||
win32_thread: win32.HANDLE,
|
win32_thread: win32.HANDLE,
|
||||||
win32_thread_id: win32.DWORD,
|
win32_thread_id: win32.DWORD,
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ generate_encoding_entity_table :: proc() {
|
|||||||
/*
|
/*
|
||||||
Generate table.
|
Generate table.
|
||||||
*/
|
*/
|
||||||
fmt.wprintln(w, "package unicode_entity")
|
fmt.wprintln(w, "package encoding_unicode_entity")
|
||||||
fmt.wprintln(w, "")
|
fmt.wprintln(w, "")
|
||||||
fmt.wprintln(w, GENERATED)
|
fmt.wprintln(w, GENERATED)
|
||||||
fmt.wprintln(w, "")
|
fmt.wprintln(w, "")
|
||||||
@@ -195,12 +195,12 @@ named_xml_entity_to_rune :: proc(name: string) -> (decoded: rune, ok: bool) {
|
|||||||
|
|
||||||
e := entity_map[v]
|
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 {
|
for i := len(e.name); i < max_name_length; i += 1 {
|
||||||
fmt.wprintf(w, " ")
|
fmt.wprintf(w, " ")
|
||||||
}
|
}
|
||||||
fmt.wprintf(w, " // %v\n", e.description)
|
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
|
should_close = true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -240,8 +240,7 @@ decode_grapheme_clusters :: proc(
|
|||||||
// GB8: (LVT | T) × T
|
// GB8: (LVT | T) × T
|
||||||
if is_hangul_syllable_leading(this_rune) ||
|
if is_hangul_syllable_leading(this_rune) ||
|
||||||
is_hangul_syllable_lv(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) {
|
if !is_hangul_syllable_leading(last_rune) {
|
||||||
grapheme_count += 1
|
grapheme_count += 1
|
||||||
}
|
}
|
||||||
@@ -251,8 +250,7 @@ decode_grapheme_clusters :: proc(
|
|||||||
if is_hangul_syllable_vowel(this_rune) {
|
if is_hangul_syllable_vowel(this_rune) {
|
||||||
if is_hangul_syllable_leading(last_rune) ||
|
if is_hangul_syllable_leading(last_rune) ||
|
||||||
is_hangul_syllable_vowel(last_rune) ||
|
is_hangul_syllable_vowel(last_rune) ||
|
||||||
is_hangul_syllable_lv(last_rune)
|
is_hangul_syllable_lv(last_rune) {
|
||||||
{
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
grapheme_count += 1
|
grapheme_count += 1
|
||||||
@@ -263,8 +261,7 @@ decode_grapheme_clusters :: proc(
|
|||||||
if is_hangul_syllable_trailing(last_rune) ||
|
if is_hangul_syllable_trailing(last_rune) ||
|
||||||
is_hangul_syllable_lvt(last_rune) ||
|
is_hangul_syllable_lvt(last_rune) ||
|
||||||
is_hangul_syllable_lv(last_rune) ||
|
is_hangul_syllable_lv(last_rune) ||
|
||||||
is_hangul_syllable_vowel(last_rune)
|
is_hangul_syllable_vowel(last_rune) {
|
||||||
{
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
grapheme_count += 1
|
grapheme_count += 1
|
||||||
@@ -285,8 +282,7 @@ decode_grapheme_clusters :: proc(
|
|||||||
if current_sequence == .Indic {
|
if current_sequence == .Indic {
|
||||||
if is_indic_conjunct_break_extend(this_rune) && (
|
if is_indic_conjunct_break_extend(this_rune) && (
|
||||||
is_indic_conjunct_break_linker(last_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_sequence = true
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -294,8 +290,7 @@ decode_grapheme_clusters :: proc(
|
|||||||
if is_indic_conjunct_break_linker(this_rune) && (
|
if is_indic_conjunct_break_linker(this_rune) && (
|
||||||
is_indic_conjunct_break_linker(last_rune) ||
|
is_indic_conjunct_break_linker(last_rune) ||
|
||||||
is_indic_conjunct_break_extend(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_sequence = true
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -306,8 +301,7 @@ decode_grapheme_clusters :: proc(
|
|||||||
// (Support for GB11.)
|
// (Support for GB11.)
|
||||||
if current_sequence == .Emoji && (
|
if current_sequence == .Emoji && (
|
||||||
is_gcb_extend_class(last_rune) ||
|
is_gcb_extend_class(last_rune) ||
|
||||||
is_emoji_extended_pictographic(last_rune) )
|
is_emoji_extended_pictographic(last_rune) ) {
|
||||||
{
|
|
||||||
continue_sequence = true
|
continue_sequence = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,8 +330,7 @@ decode_grapheme_clusters :: proc(
|
|||||||
if is_indic_conjunct_break_consonant(this_rune) {
|
if is_indic_conjunct_break_consonant(this_rune) {
|
||||||
if current_sequence == .Indic {
|
if current_sequence == .Indic {
|
||||||
if last_rune == ZERO_WIDTH_JOINER ||
|
if last_rune == ZERO_WIDTH_JOINER ||
|
||||||
is_indic_conjunct_break_linker(last_rune)
|
is_indic_conjunct_break_linker(last_rune) {
|
||||||
{
|
|
||||||
continue_sequence = true
|
continue_sequence = true
|
||||||
} else {
|
} else {
|
||||||
grapheme_count += 1
|
grapheme_count += 1
|
||||||
@@ -353,8 +346,7 @@ decode_grapheme_clusters :: proc(
|
|||||||
if is_indic_conjunct_break_extend(this_rune) {
|
if is_indic_conjunct_break_extend(this_rune) {
|
||||||
if current_sequence == .Indic {
|
if current_sequence == .Indic {
|
||||||
if is_indic_conjunct_break_consonant(last_rune) ||
|
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
|
continue_sequence = true
|
||||||
} else {
|
} else {
|
||||||
grapheme_count += 1
|
grapheme_count += 1
|
||||||
@@ -366,8 +358,7 @@ decode_grapheme_clusters :: proc(
|
|||||||
if is_indic_conjunct_break_linker(this_rune) {
|
if is_indic_conjunct_break_linker(this_rune) {
|
||||||
if current_sequence == .Indic {
|
if current_sequence == .Indic {
|
||||||
if is_indic_conjunct_break_extend(last_rune) ||
|
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
|
continue_sequence = true
|
||||||
} else {
|
} else {
|
||||||
grapheme_count += 1
|
grapheme_count += 1
|
||||||
|
|||||||
@@ -49,25 +49,30 @@ import tuplehash "core:crypto/tuplehash"
|
|||||||
import x25519 "core:crypto/x25519"
|
import x25519 "core:crypto/x25519"
|
||||||
|
|
||||||
import pe "core:debug/pe"
|
import pe "core:debug/pe"
|
||||||
|
import trace "core:debug/trace"
|
||||||
|
|
||||||
import dynlib "core:dynlib"
|
import dynlib "core:dynlib"
|
||||||
import net "core:net"
|
import net "core:net"
|
||||||
|
|
||||||
|
import ansi "core:encoding/ansi"
|
||||||
import base32 "core:encoding/base32"
|
import base32 "core:encoding/base32"
|
||||||
import base64 "core:encoding/base64"
|
import base64 "core:encoding/base64"
|
||||||
|
import cbor "core:encoding/cbor"
|
||||||
import csv "core:encoding/csv"
|
import csv "core:encoding/csv"
|
||||||
|
import endian "core:encoding/endian"
|
||||||
import hxa "core:encoding/hxa"
|
import hxa "core:encoding/hxa"
|
||||||
import json "core:encoding/json"
|
import json "core:encoding/json"
|
||||||
import varint "core:encoding/varint"
|
import varint "core:encoding/varint"
|
||||||
import xml "core:encoding/xml"
|
import xml "core:encoding/xml"
|
||||||
import endian "core:encoding/endian"
|
import uuid "core:encoding/uuid"
|
||||||
import cbor "core:encoding/cbor"
|
import uuid_legacy "core:encoding/uuid/legacy"
|
||||||
|
|
||||||
import fmt "core:fmt"
|
import fmt "core:fmt"
|
||||||
import hash "core:hash"
|
import hash "core:hash"
|
||||||
import xxhash "core:hash/xxhash"
|
import xxhash "core:hash/xxhash"
|
||||||
|
|
||||||
import image "core:image"
|
import image "core:image"
|
||||||
|
import bmp "core:image/bmp"
|
||||||
import netpbm "core:image/netpbm"
|
import netpbm "core:image/netpbm"
|
||||||
import png "core:image/png"
|
import png "core:image/png"
|
||||||
import qoi "core:image/qoi"
|
import qoi "core:image/qoi"
|
||||||
@@ -89,6 +94,7 @@ import ease "core:math/ease"
|
|||||||
import cmplx "core:math/cmplx"
|
import cmplx "core:math/cmplx"
|
||||||
|
|
||||||
import mem "core:mem"
|
import mem "core:mem"
|
||||||
|
import tlsf "core:mem/tlsf"
|
||||||
import virtual "core:mem/virtual"
|
import virtual "core:mem/virtual"
|
||||||
|
|
||||||
import ast "core:odin/ast"
|
import ast "core:odin/ast"
|
||||||
@@ -103,6 +109,8 @@ import os "core:os"
|
|||||||
import slashpath "core:path/slashpath"
|
import slashpath "core:path/slashpath"
|
||||||
import filepath "core:path/filepath"
|
import filepath "core:path/filepath"
|
||||||
|
|
||||||
|
import relative "core:relative"
|
||||||
|
|
||||||
import reflect "core:reflect"
|
import reflect "core:reflect"
|
||||||
import runtime "base:runtime"
|
import runtime "base:runtime"
|
||||||
import simd "core:simd"
|
import simd "core:simd"
|
||||||
@@ -113,11 +121,13 @@ import strconv "core:strconv"
|
|||||||
import strings "core:strings"
|
import strings "core:strings"
|
||||||
import sync "core:sync"
|
import sync "core:sync"
|
||||||
import testing "core:testing"
|
import testing "core:testing"
|
||||||
import scanner "core:text/scanner"
|
|
||||||
|
import edit "core:text/edit"
|
||||||
import i18n "core:text/i18n"
|
import i18n "core:text/i18n"
|
||||||
import match "core:text/match"
|
import match "core:text/match"
|
||||||
|
import scanner "core:text/scanner"
|
||||||
import table "core:text/table"
|
import table "core:text/table"
|
||||||
import edit "core:text/edit"
|
|
||||||
import thread "core:thread"
|
import thread "core:thread"
|
||||||
import time "core:time"
|
import time "core:time"
|
||||||
import datetime "core:time/datetime"
|
import datetime "core:time/datetime"
|
||||||
@@ -174,8 +184,10 @@ _ :: sm3
|
|||||||
_ :: tuplehash
|
_ :: tuplehash
|
||||||
_ :: x25519
|
_ :: x25519
|
||||||
_ :: pe
|
_ :: pe
|
||||||
|
_ :: trace
|
||||||
_ :: dynlib
|
_ :: dynlib
|
||||||
_ :: net
|
_ :: net
|
||||||
|
_ :: ansi
|
||||||
_ :: base32
|
_ :: base32
|
||||||
_ :: base64
|
_ :: base64
|
||||||
_ :: csv
|
_ :: csv
|
||||||
@@ -189,6 +201,7 @@ _ :: fmt
|
|||||||
_ :: hash
|
_ :: hash
|
||||||
_ :: xxhash
|
_ :: xxhash
|
||||||
_ :: image
|
_ :: image
|
||||||
|
_ :: bmp
|
||||||
_ :: netpbm
|
_ :: netpbm
|
||||||
_ :: png
|
_ :: png
|
||||||
_ :: qoi
|
_ :: qoi
|
||||||
@@ -207,6 +220,7 @@ _ :: rand
|
|||||||
_ :: ease
|
_ :: ease
|
||||||
_ :: cmplx
|
_ :: cmplx
|
||||||
_ :: mem
|
_ :: mem
|
||||||
|
_ :: tlsf
|
||||||
_ :: virtual
|
_ :: virtual
|
||||||
_ :: ast
|
_ :: ast
|
||||||
_ :: doc_format
|
_ :: doc_format
|
||||||
@@ -216,6 +230,7 @@ _ :: os
|
|||||||
_ :: spall
|
_ :: spall
|
||||||
_ :: slashpath
|
_ :: slashpath
|
||||||
_ :: filepath
|
_ :: filepath
|
||||||
|
_ :: relative
|
||||||
_ :: reflect
|
_ :: reflect
|
||||||
_ :: runtime
|
_ :: runtime
|
||||||
_ :: simd
|
_ :: simd
|
||||||
@@ -237,6 +252,8 @@ _ :: datetime
|
|||||||
_ :: flags
|
_ :: flags
|
||||||
_ :: sysinfo
|
_ :: sysinfo
|
||||||
_ :: unicode
|
_ :: unicode
|
||||||
|
_ :: uuid
|
||||||
|
_ :: uuid_legacy
|
||||||
_ :: utf8
|
_ :: utf8
|
||||||
_ :: utf8string
|
_ :: utf8string
|
||||||
_ :: utf16
|
_ :: utf16
|
||||||
|
|||||||
@@ -1140,6 +1140,7 @@ prefix_table := [?]string{
|
|||||||
|
|
||||||
print_mutex := b64(false)
|
print_mutex := b64(false)
|
||||||
|
|
||||||
|
@(disabled=!thread.IS_SUPPORTED)
|
||||||
threading_example :: proc() {
|
threading_example :: proc() {
|
||||||
fmt.println("\n# threading_example")
|
fmt.println("\n# threading_example")
|
||||||
|
|
||||||
@@ -2550,6 +2551,50 @@ matrix_type :: proc() {
|
|||||||
// matrix_minor(m)
|
// 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() {
|
main :: proc() {
|
||||||
/*
|
/*
|
||||||
For More Odin Examples - https://github.com/odin-lang/examples
|
For More Odin Examples - https://github.com/odin-lang/examples
|
||||||
@@ -2595,5 +2640,6 @@ main :: proc() {
|
|||||||
or_break_and_or_continue_operators()
|
or_break_and_or_continue_operators()
|
||||||
arbitrary_precision_mathematics()
|
arbitrary_precision_mathematics()
|
||||||
matrix_type()
|
matrix_type()
|
||||||
|
bit_field_type()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-464
@@ -106,468 +106,7 @@ gb_global String target_arch_names[TargetArch_COUNT] = {
|
|||||||
str_lit("wasm64p32"),
|
str_lit("wasm64p32"),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generated with the featuregen script in `misc/featuregen`
|
#include "build_settings_microarch.cpp"
|
||||||
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("") },
|
|
||||||
};
|
|
||||||
|
|
||||||
gb_global String target_endian_names[TargetEndian_COUNT] = {
|
gb_global String target_endian_names[TargetEndian_COUNT] = {
|
||||||
str_lit("little"),
|
str_lit("little"),
|
||||||
@@ -742,10 +281,12 @@ enum VetFlags : u64 {
|
|||||||
VetFlag_UnusedVariables = 1u<<5,
|
VetFlag_UnusedVariables = 1u<<5,
|
||||||
VetFlag_UnusedImports = 1u<<6,
|
VetFlag_UnusedImports = 1u<<6,
|
||||||
VetFlag_Deprecated = 1u<<7,
|
VetFlag_Deprecated = 1u<<7,
|
||||||
|
VetFlag_Cast = 1u<<8,
|
||||||
|
VetFlag_Tabs = 1u<<9,
|
||||||
|
|
||||||
VetFlag_Unused = VetFlag_UnusedVariables|VetFlag_UnusedImports,
|
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,
|
VetFlag_Using = VetFlag_UsingStmt|VetFlag_UsingParam,
|
||||||
};
|
};
|
||||||
@@ -769,6 +310,10 @@ u64 get_vet_flag_from_name(String const &name) {
|
|||||||
return VetFlag_Semicolon;
|
return VetFlag_Semicolon;
|
||||||
} else if (name == "deprecated") {
|
} else if (name == "deprecated") {
|
||||||
return VetFlag_Deprecated;
|
return VetFlag_Deprecated;
|
||||||
|
} else if (name == "cast") {
|
||||||
|
return VetFlag_Cast;
|
||||||
|
} else if (name == "tabs") {
|
||||||
|
return VetFlag_Tabs;
|
||||||
}
|
}
|
||||||
return VetFlag_NONE;
|
return VetFlag_NONE;
|
||||||
}
|
}
|
||||||
@@ -862,6 +407,8 @@ struct BuildContext {
|
|||||||
bool keep_object_files;
|
bool keep_object_files;
|
||||||
bool disallow_do;
|
bool disallow_do;
|
||||||
|
|
||||||
|
StringSet custom_attributes;
|
||||||
|
|
||||||
bool strict_style;
|
bool strict_style;
|
||||||
|
|
||||||
bool ignore_warnings;
|
bool ignore_warnings;
|
||||||
@@ -873,6 +420,7 @@ struct BuildContext {
|
|||||||
|
|
||||||
bool ignore_lazy;
|
bool ignore_lazy;
|
||||||
bool ignore_llvm_build;
|
bool ignore_llvm_build;
|
||||||
|
bool ignore_panic;
|
||||||
|
|
||||||
bool ignore_microsoft_magic;
|
bool ignore_microsoft_magic;
|
||||||
bool linker_map_file;
|
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);
|
bc->thread_count = gb_max(bc->affinity.thread_count, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string_set_init(&bc->custom_attributes);
|
||||||
|
|
||||||
bc->ODIN_VENDOR = str_lit("odin");
|
bc->ODIN_VENDOR = str_lit("odin");
|
||||||
bc->ODIN_VERSION = ODIN_VERSION;
|
bc->ODIN_VERSION = ODIN_VERSION;
|
||||||
bc->ODIN_ROOT = odin_root_dir();
|
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(), " ");
|
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-all ");
|
||||||
// link_flags = gb_string_appendc(link_flags, "--export-table ");
|
// link_flags = gb_string_appendc(link_flags, "--export-table ");
|
||||||
link_flags = gb_string_appendc(link_flags, "--allow-undefined ");
|
|
||||||
// if (bc->metrics.arch == TargetArch_wasm64) {
|
// if (bc->metrics.arch == TargetArch_wasm64) {
|
||||||
// link_flags = gb_string_appendc(link_flags, "-mwasm64 ");
|
// 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) {
|
if (bc->no_entry_point || bc->metrics.os == TargetOs_orca) {
|
||||||
link_flags = gb_string_appendc(link_flags, "--no-entry ");
|
link_flags = gb_string_appendc(link_flags, "--no-entry ");
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user