Skip to content

Commit 7cbebed

Browse files
committed
Make align generic across all vector types
1 parent a1b459a commit 7cbebed

28 files changed

Lines changed: 200 additions & 155 deletions

File tree

crates/thermite-compensated/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1424,6 +1424,14 @@ impl<V: CompensatedFloatVector> GenericVector for Compensated<V> {
14241424
}
14251425
}
14261426

1427+
#[inline(always)]
1428+
fn align<const OFFSET: usize>(self, other: Self) -> Self {
1429+
Self {
1430+
value: self.value.align::<OFFSET>(other.value),
1431+
error: self.error.align::<OFFSET>(other.error),
1432+
}
1433+
}
1434+
14271435

14281436
fn map<F>(mut self, f: F) -> Self
14291437
where

crates/thermite-dual/src/vector.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,14 @@ impl<V: DualFloatVector, const N: usize> GenericVector for Dual<V, N> {
592592
}
593593
}
594594

595+
#[inline(always)]
596+
fn align<const OFFSET: usize>(self, other: Self) -> Self {
597+
Self {
598+
re: self.re.align::<OFFSET>(other.re),
599+
dual: array_each!([V::ZERO; N], |j| self.dual[j].align::<OFFSET>(other.dual[j])),
600+
}
601+
}
602+
595603
#[inline(always)] fn map<F>(mut self, f: F) -> Self
596604
where
597605
F: Fn(Self::Element) -> Self::Element,

crates/thermite/src/backend/macros.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,45 @@ macro_rules! impl_byte_align_alignr256 {
9999
};
100100
}
101101

102+
/// Whole-register byte-shift `align` override (`Register::align`) for a full,
103+
/// unpadded 128-bit integer register with native full-width byte shifts
104+
/// (`bshli`/`bshri` = `pslldq`/`psrldq`), e.g. SSE2 where there is no `palignr`.
105+
/// Drop into an `impl Register` block.
106+
///
107+
/// `align::<OFFSET>(a, b)` is `(a >> ob) | (b << (16 - ob))` in bytes, where
108+
/// `ob = OFFSET * size_of::<Element>()`. The match is keyed on `ob` so each
109+
/// arm's shift counts are literals (stable rejects a const expr of `OFFSET` in
110+
/// const-generic position); `ob` const-folds to one arm. `ob > 16` means
111+
/// `OFFSET > LANES` (out of range) and falls back to the generic default.
112+
///
113+
/// NOTE: 128-bit only - AVX2 `_mm256_bslli/bsrli_epi128` shift per 128-bit lane.
114+
macro_rules! impl_byteshift_align {
115+
() => {
116+
fn align<const OFFSET: usize>(a: Storage<Self>, b: Storage<Self>) -> Storage<Self> {
117+
match const { OFFSET * core::mem::size_of::<Self::Element>() } {
118+
0 => Self::bitor(Self::bshri::<0>(a), Self::bshli::<16>(b)),
119+
1 => Self::bitor(Self::bshri::<1>(a), Self::bshli::<15>(b)),
120+
2 => Self::bitor(Self::bshri::<2>(a), Self::bshli::<14>(b)),
121+
3 => Self::bitor(Self::bshri::<3>(a), Self::bshli::<13>(b)),
122+
4 => Self::bitor(Self::bshri::<4>(a), Self::bshli::<12>(b)),
123+
5 => Self::bitor(Self::bshri::<5>(a), Self::bshli::<11>(b)),
124+
6 => Self::bitor(Self::bshri::<6>(a), Self::bshli::<10>(b)),
125+
7 => Self::bitor(Self::bshri::<7>(a), Self::bshli::<9>(b)),
126+
8 => Self::bitor(Self::bshri::<8>(a), Self::bshli::<8>(b)),
127+
9 => Self::bitor(Self::bshri::<9>(a), Self::bshli::<7>(b)),
128+
10 => Self::bitor(Self::bshri::<10>(a), Self::bshli::<6>(b)),
129+
11 => Self::bitor(Self::bshri::<11>(a), Self::bshli::<5>(b)),
130+
12 => Self::bitor(Self::bshri::<12>(a), Self::bshli::<4>(b)),
131+
13 => Self::bitor(Self::bshri::<13>(a), Self::bshli::<3>(b)),
132+
14 => Self::bitor(Self::bshri::<14>(a), Self::bshli::<2>(b)),
133+
15 => Self::bitor(Self::bshri::<15>(a), Self::bshli::<1>(b)),
134+
16 => Self::bitor(Self::bshri::<16>(a), Self::bshli::<0>(b)),
135+
_ => Self::swizzle_const::<$crate::swizzle::AlignIndices<OFFSET, Self::Lanes>>(a, b),
136+
}
137+
}
138+
};
139+
}
140+
102141
macro_rules! impl_bit_casts {
103142
($($from:ty as $to:ty => $conv:ident),* $(,)?) => {
104143
const _: () = {$(

crates/thermite/src/backend/x86_v1/registers/i16x8.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,8 @@ impl Register for I16x8V1 {
233233

234234
// no `pshufb` on SSE2, so variable permutes fall back to the scalar defaults
235235
const HAS_PERMUTEV: bool = false;
236+
237+
impl_byteshift_align!();
236238
}
237239

238240
#[rustfmt::skip] #[thermite_macros::inline_always]

crates/thermite/src/backend/x86_v1/registers/i32x4.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,8 @@ impl Register for I32x4V1 {
223223

224224
// no `pshufb` on SSE2, so variable permutes fall back to the scalar defaults
225225
const HAS_PERMUTEV: bool = false;
226+
227+
impl_byteshift_align!();
226228
}
227229

228230
#[rustfmt::skip] #[thermite_macros::inline_always]

crates/thermite/src/backend/x86_v1/registers/i64x2.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,8 @@ impl Register for I64x2V1 {
239239
}
240240

241241
const HAS_PERMUTEV: bool = false;
242+
243+
impl_byteshift_align!();
242244
}
243245

244246
#[thermite_macros::inline_always]

crates/thermite/src/backend/x86_v1/registers/i8x16.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,8 @@ impl Register for I8x16V1 {
235235

236236
// no `pshufb` on SSE2, so variable permutes fall back to the scalar defaults
237237
const HAS_PERMUTEV: bool = false;
238+
239+
impl_byteshift_align!();
238240
}
239241

240242
#[rustfmt::skip] #[thermite_macros::inline_always]

crates/thermite/src/backend/x86_v1/registers/u16x8.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,8 @@ impl Register for U16x8V1 {
198198
}
199199

200200
const HAS_PERMUTEV: bool = false;
201+
202+
impl_byteshift_align!();
201203
}
202204

203205
#[rustfmt::skip] #[thermite_macros::inline_always]

crates/thermite/src/backend/x86_v1/registers/u32x4.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ impl Register for U32x4V1 {
209209
}
210210

211211
const HAS_PERMUTEV: bool = false;
212+
213+
impl_byteshift_align!();
212214
}
213215

214216
#[thermite_macros::inline_always]

crates/thermite/src/backend/x86_v1/registers/u64x2.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,8 @@ impl Register for U64x2V1 {
233233
}
234234

235235
const HAS_PERMUTEV: bool = false;
236+
237+
impl_byteshift_align!();
236238
}
237239

238240
#[rustfmt::skip] #[thermite_macros::inline_always]

0 commit comments

Comments
 (0)