5
5
using System . Numerics ;
6
6
using System . Runtime . CompilerServices ;
7
7
using System . Runtime . InteropServices ;
8
+ using static SixLabors . ImageSharp . SimdUtils ;
8
9
9
10
// The JIT can detect and optimize rotation idioms ROTL (Rotate Left)
10
11
// and ROTR (Rotate Right) emitting efficient CPU instructions:
@@ -18,9 +19,12 @@ namespace SixLabors.ImageSharp;
18
19
internal interface IComponentShuffle
19
20
{
20
21
/// <summary>
21
- /// Gets the shuffle control.
22
+ /// Shuffles then slices 8-bit integers within 128-bit lanes in <paramref name="source"/>
23
+ /// using the control and store the results in <paramref name="dest"/>.
22
24
/// </summary>
23
- byte Control { get ; }
25
+ /// <param name="source">The source span of bytes.</param>
26
+ /// <param name="dest">The destination span of bytes.</param>
27
+ void ShuffleReduce ( ref ReadOnlySpan < byte > source , ref Span < byte > dest ) ;
24
28
25
29
/// <summary>
26
30
/// Shuffle 8-bit integers within 128-bit lanes in <paramref name="source"/>
@@ -58,11 +62,15 @@ public DefaultShuffle4(byte p3, byte p2, byte p1, byte p0)
58
62
this . p2 = p2 ;
59
63
this . p1 = p1 ;
60
64
this . p0 = p0 ;
61
- this . Control = SimdUtils . Shuffle . MmShuffle ( p3 , p2 , p1 , p0 ) ;
65
+ this . Control = Shuffle . MmShuffle ( p3 , p2 , p1 , p0 ) ;
62
66
}
63
67
64
68
public byte Control { get ; }
65
69
70
+ [ MethodImpl ( InliningOptions . ShortMethod ) ]
71
+ public void ShuffleReduce ( ref ReadOnlySpan < byte > source , ref Span < byte > dest )
72
+ => HwIntrinsics . Shuffle4Reduce ( ref source , ref dest , this . Control ) ;
73
+
66
74
[ MethodImpl ( InliningOptions . ShortMethod ) ]
67
75
public void RunFallbackShuffle ( ReadOnlySpan < byte > source , Span < byte > dest )
68
76
{
@@ -86,11 +94,9 @@ public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)
86
94
87
95
internal readonly struct WXYZShuffle4 : IShuffle4
88
96
{
89
- public byte Control
90
- {
91
- [ MethodImpl ( InliningOptions . ShortMethod ) ]
92
- get => SimdUtils . Shuffle . MmShuffle ( 2 , 1 , 0 , 3 ) ;
93
- }
97
+ [ MethodImpl ( InliningOptions . ShortMethod ) ]
98
+ public void ShuffleReduce ( ref ReadOnlySpan < byte > source , ref Span < byte > dest )
99
+ => HwIntrinsics . Shuffle4Reduce ( ref source , ref dest , Shuffle . MMShuffle2103 ) ;
94
100
95
101
[ MethodImpl ( InliningOptions . ShortMethod ) ]
96
102
public void RunFallbackShuffle ( ReadOnlySpan < byte > source , Span < byte > dest )
@@ -112,11 +118,9 @@ public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)
112
118
113
119
internal readonly struct WZYXShuffle4 : IShuffle4
114
120
{
115
- public byte Control
116
- {
117
- [ MethodImpl ( InliningOptions . ShortMethod ) ]
118
- get => SimdUtils . Shuffle . MmShuffle ( 0 , 1 , 2 , 3 ) ;
119
- }
121
+ [ MethodImpl ( InliningOptions . ShortMethod ) ]
122
+ public void ShuffleReduce ( ref ReadOnlySpan < byte > source , ref Span < byte > dest )
123
+ => HwIntrinsics . Shuffle4Reduce ( ref source , ref dest , Shuffle . MMShuffle0123 ) ;
120
124
121
125
[ MethodImpl ( InliningOptions . ShortMethod ) ]
122
126
public void RunFallbackShuffle ( ReadOnlySpan < byte > source , Span < byte > dest )
@@ -138,11 +142,9 @@ public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)
138
142
139
143
internal readonly struct YZWXShuffle4 : IShuffle4
140
144
{
141
- public byte Control
142
- {
143
- [ MethodImpl ( InliningOptions . ShortMethod ) ]
144
- get => SimdUtils . Shuffle . MmShuffle ( 0 , 3 , 2 , 1 ) ;
145
- }
145
+ [ MethodImpl ( InliningOptions . ShortMethod ) ]
146
+ public void ShuffleReduce ( ref ReadOnlySpan < byte > source , ref Span < byte > dest )
147
+ => HwIntrinsics . Shuffle4Reduce ( ref source , ref dest , Shuffle . MMShuffle0321 ) ;
146
148
147
149
[ MethodImpl ( InliningOptions . ShortMethod ) ]
148
150
public void RunFallbackShuffle ( ReadOnlySpan < byte > source , Span < byte > dest )
@@ -164,11 +166,9 @@ public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)
164
166
165
167
internal readonly struct ZYXWShuffle4 : IShuffle4
166
168
{
167
- public byte Control
168
- {
169
- [ MethodImpl ( InliningOptions . ShortMethod ) ]
170
- get => SimdUtils . Shuffle . MmShuffle ( 3 , 0 , 1 , 2 ) ;
171
- }
169
+ [ MethodImpl ( InliningOptions . ShortMethod ) ]
170
+ public void ShuffleReduce ( ref ReadOnlySpan < byte > source , ref Span < byte > dest )
171
+ => HwIntrinsics . Shuffle4Reduce ( ref source , ref dest , Shuffle . MMShuffle3012 ) ;
172
172
173
173
[ MethodImpl ( InliningOptions . ShortMethod ) ]
174
174
public void RunFallbackShuffle ( ReadOnlySpan < byte > source , Span < byte > dest )
@@ -197,11 +197,9 @@ public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)
197
197
198
198
internal readonly struct XWZYShuffle4 : IShuffle4
199
199
{
200
- public byte Control
201
- {
202
- [ MethodImpl ( InliningOptions . ShortMethod ) ]
203
- get => SimdUtils . Shuffle . MmShuffle ( 1 , 2 , 3 , 0 ) ;
204
- }
200
+ [ MethodImpl ( InliningOptions . ShortMethod ) ]
201
+ public void ShuffleReduce ( ref ReadOnlySpan < byte > source , ref Span < byte > dest )
202
+ => HwIntrinsics . Shuffle4Reduce ( ref source , ref dest , Shuffle . MMShuffle1230 ) ;
205
203
206
204
[ MethodImpl ( InliningOptions . ShortMethod ) ]
207
205
public void RunFallbackShuffle ( ReadOnlySpan < byte > source , Span < byte > dest )
0 commit comments