CI / release (arm64, , ubuntu-latest-arm64) (push) Successful in 2m21s
CI / pre-commit (push) Successful in 2m1s
CI / test (-DCMAKE_BUILD_TYPE=Debug -DMSAN_TOOLCHAIN_PATH=/opt/msan, debug) (push) Successful in 3m48s
CI / test (-DCMAKE_CXX_FLAGS=-DUSE_64_BIT=1, 64-bit-versions) (push) Successful in 3m18s
CI / test (-DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++, gcc) (push) Successful in 3m15s
CI / test (-DUSE_SIMD_FALLBACK=ON, simd-fallback) (push) Successful in 3m17s
CI / release (amd64, -DMSAN_TOOLCHAIN_PATH=/opt/msan, ubuntu-latest-amd64) (push) Successful in 5m33s
CI / coverage (push) Successful in 3m47s
The assembly file was missing the GNU property note that records control-flow integrity (CET) support, causing hardening-check to report 'Control flow integrity: no, not found!'. Add the note matching what clang emits with -fcf-protection.
85 lines
3.2 KiB
ArmAsm
85 lines
3.2 KiB
ArmAsm
// SIMD operations on potentially-indeterminate Node16::index[16] bytes.
|
|
// Written in assembly so msan doesn't track the loads. The caller is
|
|
// responsible for masking the returned bitfield to [0, numChildren) before
|
|
// using it.
|
|
//
|
|
// All functions return a 16-bit bitmask in %eax (bit i set = condition true
|
|
// at index i). The upper 16 bits of %eax are zero.
|
|
//
|
|
// System V AMD64 ABI:
|
|
// %rdi = const uint8_t *idx (16 bytes)
|
|
// %esi = uint8_t key (find_eq_16, find_ge_16)
|
|
// %sil = uint8_t begin (mask_in_range_16)
|
|
// %dl = uint8_t end (mask_in_range_16)
|
|
|
|
.text
|
|
|
|
// uint32_t find_eq_16(const uint8_t idx[16], uint8_t key)
|
|
// Returns bit i set if idx[i] == key
|
|
.globl find_eq_16
|
|
.type find_eq_16, @function
|
|
find_eq_16:
|
|
vmovd %esi, %xmm1 // broadcast key
|
|
vpbroadcastb %xmm1, %xmm1
|
|
vmovdqu (%rdi), %xmm0 // load 16 bytes (may contain indeterminate data)
|
|
vpcmpeqb %xmm0, %xmm1, %xmm0 // 0xff for each match
|
|
vpmovmskb %xmm0, %eax // 16-bit bitmask
|
|
movzwl %ax, %eax // zero-extend to 32 bits
|
|
ret
|
|
.size find_eq_16, .-find_eq_16
|
|
|
|
// uint32_t find_ge_16(const uint8_t idx[16], uint8_t child)
|
|
// Returns bit i set if idx[i] >= child
|
|
// x86 doesn't have a "compare unsigned >=" for bytes directly, so we use:
|
|
// min(key, idx[i]) == key iff idx[i] >= key
|
|
.globl find_ge_16
|
|
.type find_ge_16, @function
|
|
find_ge_16:
|
|
vmovd %esi, %xmm1
|
|
vpbroadcastb %xmm1, %xmm1 // key broadcast
|
|
vmovdqu (%rdi), %xmm0 // load 16 bytes
|
|
vpminub %xmm0, %xmm1, %xmm2 // min(key, idx[i])
|
|
vpcmpeqb %xmm2, %xmm1, %xmm0 // 0xff where min == key, i.e. idx[i] >= key
|
|
vpmovmskb %xmm0, %eax
|
|
movzwl %ax, %eax
|
|
ret
|
|
.size find_ge_16, .-find_ge_16
|
|
|
|
// uint32_t mask_in_range_16(const uint8_t idx[16], uint8_t begin, uint8_t end)
|
|
// Returns bit i set if begin <= idx[i] < end
|
|
// Logic: (idx[i] - begin) < (end - begin) [unsigned wrapping arithmetic]
|
|
// Equivalently: idx[i] - begin != max(idx[i] - begin, end - begin)
|
|
// i.e. idx[i] - begin is NOT equal to the saturated value.
|
|
// We compute: sub = idx - begin; result = (sub < (end-begin)) for each byte.
|
|
// Using: sub == max(sub, end-begin) means NOT in range.
|
|
// So: in_range = ~(movemask(cmpeq(sub, max(sub, range_size))))
|
|
.globl mask_in_range_16
|
|
.type mask_in_range_16, @function
|
|
mask_in_range_16:
|
|
vmovd %esi, %xmm1 // begin
|
|
vpbroadcastb %xmm1, %xmm1
|
|
vmovd %edx, %xmm2 // end
|
|
vpbroadcastb %xmm2, %xmm2
|
|
vmovdqu (%rdi), %xmm0 // load 16 bytes
|
|
vpsubb %xmm1, %xmm0, %xmm0 // idx - begin (wrapping)
|
|
vpsubb %xmm1, %xmm2, %xmm2 // end - begin (range size)
|
|
vpmaxub %xmm0, %xmm2, %xmm3 // max(idx-begin, range_size)
|
|
vpcmpeqb %xmm3, %xmm0, %xmm0 // 0xff where NOT in range
|
|
vpmovmskb %xmm0, %eax
|
|
not %eax // invert: 1 = in range
|
|
movzwl %ax, %eax
|
|
ret
|
|
.size mask_in_range_16, .-mask_in_range_16
|
|
|
|
.section .note.gnu.property,"a",@note
|
|
.p2align 3, 0x0
|
|
.long 4
|
|
.long 16
|
|
.long 5
|
|
.asciz "GNU"
|
|
.long 0xc0000002
|
|
.long 4
|
|
.long 0x3
|
|
.p2align 3, 0x0
|
|
|
|
.section .note.GNU-stack,"",@progbits
|