1
0
Fork 0
mirror of https://github.com/VSadov/Satori.git synced 2025-06-08 03:27:04 +09:00
Satori/src/tests/JIT/HardwareIntrinsics/X86/Bmi2/ParallelBitExtract.UInt32.cs
2022-11-23 11:59:22 -08:00

265 lines
8.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
/******************************************************************************
* This file is auto-generated from a template file by the GenerateTests.csx *
* script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
* changes, please update the corresponding template and run according to the *
* directions listed in the file. *
******************************************************************************/
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
using Xunit;
namespace JIT.HardwareIntrinsics.X86._Bmi2
{
public static partial class Program
{
[Fact]
public static void ParallelBitExtractUInt32()
{
var test = new ScalarBinaryOpTest__ParallelBitExtractUInt32();
if (test.IsSupported)
{
// Validates basic functionality works, using Unsafe.ReadUnaligned
test.RunBasicScenario_UnsafeRead();
// Validates calling via reflection works, using Unsafe.ReadUnaligned
test.RunReflectionScenario_UnsafeRead();
// Validates passing a static member works
test.RunClsVarScenario();
// Validates passing a local works, using Unsafe.ReadUnaligned
test.RunLclVarScenario_UnsafeRead();
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
// Validates passing an instance member of a class works
test.RunClassFldScenario();
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
}
else
{
// Validates we throw on unsupported hardware
test.RunUnsupportedScenario();
}
if (!test.Succeeded)
{
throw new Exception("One or more scenarios did not complete as expected.");
}
}
}
public sealed unsafe class ScalarBinaryOpTest__ParallelBitExtractUInt32
{
private struct TestStruct
{
public UInt32 _fld1;
public UInt32 _fld2;
public static TestStruct Create()
{
var testStruct = new TestStruct();
testStruct._fld1 = TestLibrary.Generator.GetUInt32();
testStruct._fld2 = TestLibrary.Generator.GetUInt32();
return testStruct;
}
public void RunStructFldScenario(ScalarBinaryOpTest__ParallelBitExtractUInt32 testClass)
{
var result = Bmi2.ParallelBitExtract(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
}
private static UInt32 _data1;
private static UInt32 _data2;
private static UInt32 _clsVar1;
private static UInt32 _clsVar2;
private UInt32 _fld1;
private UInt32 _fld2;
static ScalarBinaryOpTest__ParallelBitExtractUInt32()
{
_clsVar1 = TestLibrary.Generator.GetUInt32();
_clsVar2 = TestLibrary.Generator.GetUInt32();
}
public ScalarBinaryOpTest__ParallelBitExtractUInt32()
{
Succeeded = true;
_fld1 = TestLibrary.Generator.GetUInt32();
_fld2 = TestLibrary.Generator.GetUInt32();
_data1 = TestLibrary.Generator.GetUInt32();
_data2 = TestLibrary.Generator.GetUInt32();
}
public bool IsSupported => Bmi2.IsSupported;
public bool Succeeded { get; set; }
public void RunBasicScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Bmi2.ParallelBitExtract(
Unsafe.ReadUnaligned<UInt32>(ref Unsafe.As<UInt32, byte>(ref _data1)),
Unsafe.ReadUnaligned<UInt32>(ref Unsafe.As<UInt32, byte>(ref _data2))
);
ValidateResult(_data1, _data2, result);
}
public void RunReflectionScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
var result = typeof(Bmi2).GetMethod(nameof(Bmi2.ParallelBitExtract), new Type[] { typeof(UInt32), typeof(UInt32) })
.Invoke(null, new object[] {
Unsafe.ReadUnaligned<UInt32>(ref Unsafe.As<UInt32, byte>(ref _data1)),
Unsafe.ReadUnaligned<UInt32>(ref Unsafe.As<UInt32, byte>(ref _data2))
});
ValidateResult(_data1, _data2, (UInt32)result);
}
public void RunClsVarScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Bmi2.ParallelBitExtract(
_clsVar1,
_clsVar2
);
ValidateResult(_clsVar1, _clsVar2, result);
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
var data1 = Unsafe.ReadUnaligned<UInt32>(ref Unsafe.As<UInt32, byte>(ref _data1));
var data2 = Unsafe.ReadUnaligned<UInt32>(ref Unsafe.As<UInt32, byte>(ref _data2));
var result = Bmi2.ParallelBitExtract(data1, data2);
ValidateResult(data1, data2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new ScalarBinaryOpTest__ParallelBitExtractUInt32();
var result = Bmi2.ParallelBitExtract(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
var result = Bmi2.ParallelBitExtract(_fld1, _fld2);
ValidateResult(_fld1, _fld2, result);
}
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
var result = Bmi2.ParallelBitExtract(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
var test = TestStruct.Create();
test.RunStructFldScenario(this);
}
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
bool succeeded = false;
try
{
RunBasicScenario_UnsafeRead();
}
catch (PlatformNotSupportedException)
{
succeeded = true;
}
if (!succeeded)
{
Succeeded = false;
}
}
private void ValidateResult(UInt32 left, UInt32 right, UInt32 result, [CallerMemberName] string method = "")
{
var isUnexpectedResult = false;
// The validation logic defined here for Bmi2.ParallelBitDeposit and Bmi2.ParallelBitExtract is
// based on the 'Operation' pseudo-code defined for the pdep and pext instruction in the 'Intel\u00AE
// 64 and IA-32 Architectures Software Developers Manual; Volume 2 (2A, 2B, 2C & 2D): Instruction
// Set Reference, A-Z'
uint temp = left;
uint mask = right;
uint dest = 0;
byte m = 0, k = 0;
while (m < 32)
{
if (((mask >> m) & 1) == 1) // Extract bit at index m of mask
{
dest |= (((temp >> m) & 1) << k); // Extract bit at index m of temp and insert to index k of dest
k++;
}
m++;
}
isUnexpectedResult = (dest != result);
if (isUnexpectedResult)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Bmi2)}.{nameof(Bmi2.ParallelBitExtract)}<UInt32>(UInt32, UInt32): ParallelBitExtract failed:");
TestLibrary.TestFramework.LogInformation($" left: {left}");
TestLibrary.TestFramework.LogInformation($" right: {right}");
TestLibrary.TestFramework.LogInformation($" result: {result}");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
}
}
}
}