@@ -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+
102141macro_rules! impl_bit_casts {
103142 ( $( $from: ty as $to: ty => $conv: ident) ,* $( , ) ?) => {
104143 const _: ( ) = { $(
0 commit comments