Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 8c78f07

Browse files
committed
Add Shuffle* Sse2 hardware intrinsics tests
1 parent 85685d6 commit 8c78f07

13 files changed

+2340
-10
lines changed

tests/src/JIT/HardwareIntrinsics/X86/Sse2/Shuffle.cs

+297
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
<#@ template debug="false" hostspecific="false" language="C#" #>
2+
<#@ assembly name="System.Core" #>
3+
<#@ import namespace="System.Linq" #>
4+
<#@ import namespace="System.Text" #>
5+
<#@ import namespace="System.Collections.Generic" #>
6+
<#@ output extension=".cs" encoding="utf-8" #>
7+
// Licensed to the .NET Foundation under one or more agreements.
8+
// The .NET Foundation licenses this file to you under the MIT license.
9+
// See the LICENSE file in the project root for more information.
10+
//
11+
12+
using System;
13+
using System.Runtime.Intrinsics;
14+
using System.Runtime.Intrinsics.X86;
15+
16+
namespace IntelHardwareIntrinsicTest
17+
{
18+
internal static partial class Program
19+
{
20+
const int Pass = 100;
21+
const int Fail = 0;
22+
23+
static unsafe int Main(string[] args)
24+
{
25+
int testResult = Pass;
26+
int testCount = 16;
27+
string methodUnderTestName = nameof(Sse2.Shuffle);
28+
29+
<#
30+
string[] permuteData = new string[]
31+
{
32+
"0b11100100", // identity
33+
"0b00011011", // invert
34+
"0b00000000", // broadcast element 0
35+
"0b11111111", // broadcast element 3
36+
"0b01010101", // broadcast element 1
37+
"0b10101010", // broadcast element 2
38+
"0b11011000", // swap middle elements
39+
"0b00100111", // swap external elements
40+
"0b10110001", // swap internal with external elements
41+
"0b11110000", // divide everything between external elements
42+
"0b10100101", // divide everything between internal elements
43+
"0b00010100", // pattern (0, 1, 1, 0)
44+
"0b10000010", // pattern (2, 0, 0, 2)
45+
"0b11001100", // pattern (3, 0, 3, 0)
46+
"0b01100110", // pattern (1, 2, 1, 2)
47+
"0b10011001" // pattern (2, 1, 2, 1)
48+
};
49+
50+
string[] permuteDouble = new string[]
51+
{
52+
"0b00",
53+
"0b01",
54+
"0b10",
55+
"0b11",
56+
};
57+
58+
#>
59+
60+
if (Sse2.IsSupported)
61+
{
62+
63+
string[] permuteData = new string[]
64+
{
65+
"0b11100100", // identity
66+
"0b00011011", // invert
67+
"0b00000000", // broadcast element 0
68+
"0b11111111", // broadcast element 3
69+
"0b01010101", // broadcast element 1
70+
"0b10101010", // broadcast element 2
71+
"0b11011000", // swap middle elements
72+
"0b00100111", // swap external elements
73+
"0b10110001", // swap internal with external elements
74+
"0b11110000", // divide everything between external elements
75+
"0b10100101", // divide everything between internal elements
76+
"0b00010100", // pattern (0, 1, 1, 0)
77+
"0b10000010", // pattern (2, 0, 0, 2)
78+
"0b11001100", // pattern (3, 0, 3, 0)
79+
"0b01100110", // pattern (1, 2, 1, 2)
80+
"0b10011001" // pattern (2, 1, 2, 1)
81+
};
82+
83+
string[] permuteDouble = new string[]
84+
{
85+
"0b00",
86+
"0b01",
87+
"0b10",
88+
"0b11",
89+
};
90+
91+
using (var doubleTable = TestTableTuvImmSse2<double, double, byte>.Create(permuteDouble.Length))
92+
using (var intTable = TestTableTuvImmSse2<int, int, byte>.Create(permuteData.Length))
93+
using (var uintTable = TestTableTuvImmSse2<uint, uint, byte>.Create(permuteData.Length))
94+
{
95+
96+
// Vector128<double> tests
97+
98+
TestUtilities.InitializeWithElementNumberingModuloVectorLength<double>(
99+
doubleTable.inArray1, 16, (int i, int elNo) =>
100+
{
101+
return (uint) i % 2;
102+
});
103+
104+
TestUtilities.InitializeWithElementNumberingModuloVectorLength<double>(
105+
doubleTable.inArray2, 16, (int i, int elNo) =>
106+
{
107+
return (uint) i % 2 + 10;
108+
});
109+
110+
<#
111+
for (int i = 0; i < permuteDouble.Length; i++)
112+
{
113+
#>
114+
(Vector128<double>, Vector128<double>) valueDouble_<#= i #> = doubleTable[<#= i #>];
115+
Vector128<double> resultDouble_<#= i #> = Sse2.Shuffle(valueDouble_<#= i #>.Item1, valueDouble_<#= i #>.Item2, (byte) <#= permuteDouble[i] #>);
116+
doubleTable.SetOutArray(resultDouble_<#= i #>, <#= i #>, (byte) <#= permuteDouble[i] #>);
117+
118+
<#
119+
120+
}
121+
#>
122+
123+
// Vector128<int> tests
124+
125+
TestUtilities.InitializeWithElementNumberingModuloVectorLength<uint>(
126+
uintTable.inArray1, 16, (int i, int elNo) =>
127+
{
128+
return (uint) i % 4;
129+
});
130+
131+
<#
132+
for (int i = 0; i < permuteData.Length; i++)
133+
{
134+
#>
135+
(Vector128<int>, Vector128<int>) valueInt32_<#= i #> = intTable[<#= i #>];
136+
Vector128<int> resultInt32_<#= i #> = Sse2.Shuffle(valueInt32_<#= i #>.Item1, (byte) <#= permuteData[i] #>);
137+
intTable.SetOutArray(resultInt32_<#= i #>, <#= i #>, (byte) <#= permuteData[i] #>);
138+
139+
<#
140+
141+
}
142+
#>
143+
144+
// Vector128<uint> tests
145+
146+
TestUtilities.InitializeWithElementNumberingModuloVectorLength<uint>(
147+
uintTable.inArray1, 16, (int i, int elNo) =>
148+
{
149+
return (uint) i % 4;
150+
});
151+
152+
<#
153+
for (int i = 0; i < permuteData.Length; i++)
154+
{
155+
#>
156+
(Vector128<uint>, Vector128<uint>) valueUInt32_<#= i #> = uintTable[<#= i #>];
157+
Vector128<uint> resultUInt32_<#= i #> = Sse2.Shuffle(valueUInt32_<#= i #>.Item1, (byte) <#= permuteData[i] #>);
158+
uintTable.SetOutArray(resultUInt32_<#= i #>, <#= i #>, (byte) <#= permuteData[i] #>);
159+
160+
<#
161+
162+
}
163+
#>
164+
165+
CheckMethodFiveDouble<double, double, byte> checkDouble =
166+
(Span<double> x, Span<double> y, byte imm, Span<double> z, Span<double> a) =>
167+
{
168+
a[0] = (0x01 & imm) > 0 ? x[1] : x[0];
169+
a[1] = (0x02 & imm) > 0 ? y[1] : y[0];
170+
return a[0] == z[0] && a[1] == z[1];
171+
};
172+
173+
if (!doubleTable.CheckResultShuffle(checkDouble))
174+
{
175+
PrintError8(doubleTable, methodUnderTestName, "(double x, byte y, double z, ref double a) => (a = x * y) == z", checkDouble);
176+
testResult = Fail;
177+
}
178+
179+
CheckMethodFive<int, int, byte> checkInt32 = (Span<int> x, byte imm, Span<int> z, Span<int> a) =>
180+
{
181+
bool result = true;
182+
for (int i = 0; i < x.Length; i++)
183+
{
184+
a[i] = x[imm & 0x03];
185+
if (z[i] != a[i])
186+
result = false;
187+
imm = (byte) (imm >> 2);
188+
}
189+
return result;
190+
};
191+
192+
if (!intTable.CheckResultShuffle(checkInt32))
193+
{
194+
PrintError(intTable, methodUnderTestName, "(int x, byte y, int z, ref int a) => (a = x << y) == z", checkInt32);
195+
testResult = Fail;
196+
}
197+
198+
CheckMethodFive<uint, uint, byte> checkUInt32 = (Span<uint> x, byte imm, Span<uint> z, Span<uint> a) =>
199+
{
200+
bool result = true;
201+
for (int i = 0; i < x.Length; i++)
202+
{
203+
a[i] = x[imm & 0x03];
204+
if (z[i] != a[i])
205+
result = false;
206+
imm = (byte) (imm >> 2);
207+
}
208+
return result;
209+
};
210+
211+
if (!uintTable.CheckResultShuffle(checkUInt32))
212+
{
213+
PrintError(uintTable, methodUnderTestName, "(uint x, byte y, uint z, ref uint a) => (a = x << y) == z", checkUInt32);
214+
testResult = Fail;
215+
}
216+
}
217+
}
218+
else
219+
{
220+
Console.WriteLine($"Sse2.IsSupported: {Sse2.IsSupported}, skipped tests of {typeof(Sse2)}.{methodUnderTestName}");
221+
}
222+
return testResult;
223+
}
224+
}
225+
}

0 commit comments

Comments
 (0)