#![cfg(target_arch = "x86_64")]
use crate::arch::{HasSse2, Simd, with_simd};
use crate::base::block::{
Array128, Block, gen_shared_block128, gen_shared_block256,
gen_shared_block512,
};
use std::arch::x86_64::*;
use std::ops::{BitAnd, BitXor};
use zerocopy::transmute;
#[derive(Clone, Copy)]
pub struct Sse1x128<S: Simd> {
val: __m128i,
simd: S,
}
impl<S: Simd> Block for Sse1x128<S>
where
S: HasSse2,
{
gen_shared_block128!(S);
#[inline(always)]
fn aes_encrypt_round(state: Self, round_key: Self) -> Self {
with_simd! {
fn helper(
token: impl HasSse2,
state: __m128i,
round_key: __m128i
) -> __m128i {
_mm_aesenc_si128(state, round_key)
}
}
Self {
val: helper(state.simd, state.val, round_key.val),
simd: state.simd,
}
}
}
impl<S: Simd> BitAnd for Sse1x128<S>
where
S: HasSse2,
{
type Output = Sse1x128<S>;
#[inline(always)]
fn bitand(self, rhs: Self) -> Self::Output {
with_simd! {
fn helper(
token: impl HasSse2,
first: __m128i,
second: __m128i
) -> __m128i {
_mm_and_si128(first, second)
}
}
Self {
val: helper(self.simd, self.val, rhs.val),
simd: self.simd,
}
}
}
impl<S: Simd> BitXor for Sse1x128<S>
where
S: HasSse2,
{
type Output = Sse1x128<S>;
#[inline(always)]
fn bitxor(self, rhs: Self) -> Self::Output {
with_simd! {
fn helper(
token: impl HasSse2,
first: __m128i,
second: __m128i
) -> __m128i {
_mm_xor_si128(first, second)
}
}
Self {
val: helper(self.simd, self.val, rhs.val),
simd: self.simd,
}
}
}
#[derive(Clone, Copy)]
pub struct Sse2x128<S: Simd> {
val: [__m128i; 2],
simd: S,
}
impl<S: Simd> Block for Sse2x128<S>
where
S: HasSse2,
{
gen_shared_block256!(S);
fn xor_down(self) -> Array128 {
with_simd! {
fn helper(
token: impl HasSse2,
input: [__m128i; 2]
) -> Array128 {
transmute!(_mm_xor_si128(input[0], input[1]))
}
}
helper(self.simd, self.val)
}
fn aes_encrypt_round(state: Self, round_key: Self) -> Self {
with_simd! {
fn helper(
token: impl HasSse2,
state: [__m128i; 2],
round_key: [__m128i; 2],
) -> [__m128i; 2] {
[
_mm_aesenc_si128(state[0], round_key[0]),
_mm_aesenc_si128(state[1], round_key[1]),
]
}
}
Self {
val: helper(state.simd, state.val, round_key.val),
simd: state.simd,
}
}
}
impl<S: Simd> BitAnd for Sse2x128<S>
where
S: HasSse2,
{
type Output = Sse2x128<S>;
#[inline(always)]
fn bitand(self, rhs: Self) -> Self::Output {
with_simd! {
fn helper(
token: impl HasSse2,
first: [__m128i; 2],
second: [__m128i; 2],
) -> [__m128i; 2]{
[
_mm_and_si128(first[0], second[0]),
_mm_and_si128(first[1], second[1]),
]
}
}
Self {
val: helper(self.simd, self.val, rhs.val),
simd: self.simd,
}
}
}
impl<S: Simd> BitXor for Sse2x128<S>
where
S: HasSse2,
{
type Output = Sse2x128<S>;
#[inline(always)]
fn bitxor(self, rhs: Self) -> Self::Output {
with_simd! {
fn helper(
token: impl HasSse2,
first: [__m128i; 2],
second: [__m128i; 2],
) -> [__m128i; 2]{
[
_mm_xor_si128(first[0], second[0]),
_mm_xor_si128(first[1], second[1]),
]
}
}
Self {
val: helper(self.simd, self.val, rhs.val),
simd: self.simd,
}
}
}
#[derive(Clone, Copy)]
pub struct Sse4x128<S: Simd> {
val: [__m128i; 4],
simd: S,
}
impl<S: Simd> Block for Sse4x128<S>
where
S: HasSse2,
{
gen_shared_block512!(S);
fn xor_down(self) -> Array128 {
with_simd! {
fn helper(
token: impl HasSse2,
input: [__m128i; 4]
) -> Array128 {
let temp1 = _mm_xor_si128(input[0], input[1]);
let temp2 = _mm_xor_si128(input[2], input[3]);
let out = _mm_xor_si128(temp1, temp2);
transmute!(out)
}
}
helper(self.simd, self.val)
}
fn aes_encrypt_round(state: Self, round_key: Self) -> Self {
with_simd! {
fn helper(
token: impl HasSse2,
state: [__m128i; 4],
round_key: [__m128i; 4],
) -> [__m128i; 4] {
[
_mm_aesenc_si128(state[0], round_key[0]),
_mm_aesenc_si128(state[1], round_key[1]),
_mm_aesenc_si128(state[2], round_key[2]),
_mm_aesenc_si128(state[3], round_key[3]),
]
}
}
Self {
val: helper(state.simd, state.val, round_key.val),
simd: state.simd,
}
}
}
impl<S: Simd> BitAnd for Sse4x128<S>
where
S: HasSse2,
{
type Output = Sse4x128<S>;
#[inline(always)]
fn bitand(self, rhs: Self) -> Self::Output {
with_simd! {
fn helper(
token: impl HasSse2,
first: [__m128i; 4],
second: [__m128i; 4],
) -> [__m128i; 4]{
[
_mm_and_si128(first[0], second[0]),
_mm_and_si128(first[1], second[1]),
_mm_and_si128(first[2], second[2]),
_mm_and_si128(first[3], second[3]),
]
}
}
Self {
val: helper(self.simd, self.val, rhs.val),
simd: self.simd,
}
}
}
impl<S: Simd> BitXor for Sse4x128<S>
where
S: HasSse2,
{
type Output = Sse4x128<S>;
#[inline(always)]
fn bitxor(self, rhs: Self) -> Self::Output {
with_simd! {
fn helper(
token: impl HasSse2,
first: [__m128i; 4],
second: [__m128i; 4],
) -> [__m128i; 4]{
[
_mm_xor_si128(first[0], second[0]),
_mm_xor_si128(first[1], second[1]),
_mm_xor_si128(first[2], second[2]),
_mm_xor_si128(first[3], second[3]),
]
}
}
Self {
val: helper(self.simd, self.val, rhs.val),
simd: self.simd,
}
}
}