Skip to main content

aes/backends/x86_aes/
utils.rs

1use crate::Block;
2use cipher::{Array, array::ArraySize};
3
4#[cfg(target_arch = "x86")]
5use core::arch::x86::*;
6#[cfg(target_arch = "x86_64")]
7use core::arch::x86_64::*;
8
9#[target_feature(enable = "sse2")]
10pub(super) fn load_block(block: &Block) -> __m128i {
11    let p: *const __m128i = block.as_ptr().cast();
12    // SAFETY: sizes of `Block` and `__m128i` are equal and we use unaligned load instruction
13    unsafe { _mm_loadu_si128(p) }
14}
15
16#[target_feature(enable = "sse2")]
17pub(super) fn store_block(dst: &mut Block, block: __m128i) {
18    let p: *mut __m128i = dst.as_mut_ptr().cast();
19    // SAFETY: sizes of `Block` and `__m128i` are equal and we use unaligned store instruction
20    unsafe { _mm_storeu_si128(p, block) }
21}
22
23#[target_feature(enable = "sse2")]
24pub(super) fn load_batch_blocks<N: ArraySize>(blocks: &Array<Block, N>) -> Array<__m128i, N> {
25    Array::from_fn(|i| load_block(&blocks[i]))
26}
27
28#[target_feature(enable = "sse2")]
29pub(super) fn store_batch_blocks<N: ArraySize>(
30    dst: &mut Array<Block, N>,
31    blocks: Array<__m128i, N>,
32) {
33    for i in 0..N::USIZE {
34        store_block(&mut dst[i], blocks[i]);
35    }
36}