// Copyright 2025 International Digital Economy Academy
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
///|
#cfg(any(target="native", target="wasm"))
#inline
fn parse_be_u32_block_into(
bytes : FixedArray[Byte],
byte_offset : Int,
words : FixedArray[UInt],
) -> Unit {
for group in 0..<4 {
let value = @v128.v128_load(bytes, byte_offset + group * 16)
let value = @v128.i8x16_shuffle(
value, value, 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12,
)
let word_offset = group * 4
words.unsafe_set(word_offset, @v128.i32x4_extract_lane(value, 0))
words.unsafe_set(word_offset + 1, @v128.i32x4_extract_lane(value, 1))
words.unsafe_set(word_offset + 2, @v128.i32x4_extract_lane(value, 2))
words.unsafe_set(word_offset + 3, @v128.i32x4_extract_lane(value, 3))
}
}
///|
#cfg(not(any(target="native", target="wasm")))
#inline
fn parse_be_u32_block_into(
bytes : FixedArray[Byte],
byte_offset : Int,
words : FixedArray[UInt],
) -> Unit {
for word_offset in 0..<16 {
let offset = byte_offset + word_offset * 4
words.unsafe_set(
word_offset,
(bytes.unsafe_get(offset).to_uint() << 24) |
(bytes.unsafe_get(offset + 1).to_uint() << 16) |
(bytes.unsafe_get(offset + 2).to_uint() << 8) |
bytes.unsafe_get(offset + 3).to_uint(),
)
}
}
///|
#cfg(any(target="native", target="wasm"))
fn xor_bytes_with_splat_in_place(
bytes : FixedArray[Byte],
length : Int,
mask : Byte,
) -> Unit {
let simd_end = length / 16 * 16
let vector_mask = @v128.i8x16_splat(mask)
for offset = 0; offset < simd_end; offset = offset + 16 {
@v128.v128_load(bytes, offset)
|> @v128.v128_xor(vector_mask)
|> value => { @v128.v128_store(bytes, offset, value) }
}
for offset in simd_end.. Unit {
for offset in 0..