#![allow(unsafe_op_in_unsafe_fn)]
use super::generic;
use crate::{get_chars_table, Output};
use core::arch::wasm32::*;
pub(crate) const USE_CHECK_FN: bool = true;
#[inline]
#[target_feature(enable = "simd128")]
pub(crate) unsafe fn encode<const UPPER: bool>(input: &[u8], output: impl Output) {
let hex_table = v128_load(get_chars_table::<UPPER>().as_ptr().cast());
generic::encode_unaligned_chunks::<UPPER, _, _>(input, output, |chunk: v128| {
let mut lo = v128_and(chunk, u8x16_splat(0x0F));
let mut hi = u8x16_shr(chunk, 4);
lo = u8x16_swizzle(hex_table, lo);
hi = u8x16_swizzle(hex_table, hi);
#[rustfmt::skip]
let hex_lo = u8x16_shuffle::<
0, 16,
1, 17,
2, 18,
3, 19,
4, 20,
5, 21,
6, 22,
7, 23,
>(hi, lo);
#[rustfmt::skip]
let hex_hi = u8x16_shuffle::<
8, 24,
9, 25,
10, 26,
11, 27,
12, 28,
13, 29,
14, 30,
15, 31,
>(hi, lo);
[hex_lo, hex_hi]
});
}
#[inline]
#[target_feature(enable = "simd128")]
pub(crate) fn check(input: &[u8]) -> bool {
generic::check_unaligned_chunks(input, |chunk: v128| {
let ge0 = u8x16_ge(chunk, u8x16_splat(b'0'));
let le9 = u8x16_le(chunk, u8x16_splat(b'9'));
let valid_digit = v128_and(ge0, le9);
let geua = u8x16_ge(chunk, u8x16_splat(b'A'));
let leuf = u8x16_le(chunk, u8x16_splat(b'F'));
let valid_upper = v128_and(geua, leuf);
let gela = u8x16_ge(chunk, u8x16_splat(b'a'));
let lelf = u8x16_le(chunk, u8x16_splat(b'f'));
let valid_lower = v128_and(gela, lelf);
let valid_letter = v128_or(valid_lower, valid_upper);
let valid = v128_or(valid_digit, valid_letter);
u8x16_all_true(valid)
})
}
pub(crate) use generic::decode_checked;
pub(crate) use generic::decode_unchecked;