1
0
Fork 0
mirror of https://github.com/VSadov/Satori.git synced 2025-06-10 18:11:04 +09:00

Add VectorTableList and TableVectorExtension intrinsics (#35600)

This commit is contained in:
Tamar Christina 2020-04-30 18:02:03 +01:00 committed by GitHub
parent 0764d8c117
commit aa81328f4e
Signed by: github
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 4776 additions and 20 deletions

View file

@ -1222,9 +1222,11 @@ protected:
#define PERFSCORE_THROUGHPUT_ILLEGAL -1024.0f
#define PERFSCORE_THROUGHPUT_4X 0.25f // Fastest - Quad issue
#define PERFSCORE_THROUGHPUT_3X (1.0f / 3.0f) // Faster - Three issue
#define PERFSCORE_THROUGHPUT_2X 0.5f // Faster - Dual issue
#define PERFSCORE_THROUGHPUT_6X (1.0f / 6.0f) // Hextuple issue
#define PERFSCORE_THROUGHPUT_5X 0.20f // Pentuple issue
#define PERFSCORE_THROUGHPUT_4X 0.25f // Quad issue
#define PERFSCORE_THROUGHPUT_3X (1.0f / 3.0f) // Three issue
#define PERFSCORE_THROUGHPUT_2X 0.5f // Dual issue
#define PERFSCORE_THROUGHPUT_1C 1.0f // Single Issue

View file

@ -817,6 +817,22 @@ void emitter::emitInsSanityCheck(instrDesc* id)
break;
case IF_DV_3C: // DV_3C .Q.........mmmmm ......nnnnnddddd Vd Vn Vm (vector)
switch (id->idIns())
{
case INS_tbl:
case INS_tbl_2regs:
case INS_tbl_3regs:
case INS_tbl_4regs:
case INS_tbx:
case INS_tbx_2regs:
case INS_tbx_3regs:
case INS_tbx_4regs:
elemsize = optGetElemsize(id->idInsOpt());
assert(elemsize == EA_1BYTE);
break;
default:
break;
}
assert(isValidVectorDatasize(id->idOpSize()));
assert(isValidArrangement(id->idOpSize(), id->idInsOpt()));
assert(isVectorRegister(id->idReg1()));
@ -3213,15 +3229,16 @@ emitter::code_t emitter::emitInsCode(instruction ins, insFormat fmt)
}
//------------------------------------------------------------------------
// insGetLoadStoreRegisterListSize: Returns a size of the register list a given instruction operates on.
// insGetRegisterListSize: Returns a size of the register list a given instruction operates on.
//
// Arguments:
// ins - A Load/Store Vector instruction (e.g. ld1 (2 registers), ld1r, st1).
// ins - An instruction which uses a register list
// (e.g. ld1 (2 registers), ld1r, st1, tbl, tbx).
//
// Return value:
// A number of consecutive SIMD and floating-point registers the instruction loads to/store from.
//
/*static*/ unsigned emitter::insGetLoadStoreRegisterListSize(instruction ins)
/*static*/ unsigned emitter::insGetRegisterListSize(instruction ins)
{
unsigned registerListSize = 0;
@ -3230,6 +3247,8 @@ emitter::code_t emitter::emitInsCode(instruction ins, insFormat fmt)
case INS_ld1:
case INS_ld1r:
case INS_st1:
case INS_tbl:
case INS_tbx:
registerListSize = 1;
break;
@ -3238,6 +3257,8 @@ emitter::code_t emitter::emitInsCode(instruction ins, insFormat fmt)
case INS_ld2r:
case INS_st1_2regs:
case INS_st2:
case INS_tbl_2regs:
case INS_tbx_2regs:
registerListSize = 2;
break;
@ -3246,6 +3267,8 @@ emitter::code_t emitter::emitInsCode(instruction ins, insFormat fmt)
case INS_ld3r:
case INS_st1_3regs:
case INS_st3:
case INS_tbl_3regs:
case INS_tbx_3regs:
registerListSize = 3;
break;
@ -3254,6 +3277,8 @@ emitter::code_t emitter::emitInsCode(instruction ins, insFormat fmt)
case INS_ld4r:
case INS_st1_4regs:
case INS_st4:
case INS_tbl_4regs:
case INS_tbx_4regs:
registerListSize = 4;
break;
@ -5192,7 +5217,7 @@ void emitter::emitIns_R_R_I(
if (insOptsAnyArrangement(opt))
{
registerListSize = insGetLoadStoreRegisterListSize(ins);
registerListSize = insGetRegisterListSize(ins);
assert(isValidVectorDatasize(size));
assert(isValidArrangement(size, opt));
assert((size * registerListSize) == imm);
@ -5226,7 +5251,7 @@ void emitter::emitIns_R_R_I(
assert(isValidArrangement(size, opt));
elemsize = optGetElemsize(opt);
registerListSize = insGetLoadStoreRegisterListSize(ins);
registerListSize = insGetRegisterListSize(ins);
assert((elemsize * registerListSize) == imm);
// Load single structure and replicate post-indexed by an immediate
@ -5676,6 +5701,14 @@ void emitter::emitIns_R_R_R(
case INS_eor:
case INS_orr:
case INS_orn:
case INS_tbl:
case INS_tbl_2regs:
case INS_tbl_3regs:
case INS_tbl_4regs:
case INS_tbx:
case INS_tbx_2regs:
case INS_tbx_3regs:
case INS_tbx_4regs:
if (isVectorRegister(reg1))
{
assert(isValidVectorDatasize(size));
@ -6612,7 +6645,7 @@ void emitter::emitIns_R_R_I_I(
assert(isValidVectorElemsize(elemsize));
assert(isValidVectorIndex(EA_16BYTE, elemsize, imm1));
registerListSize = insGetLoadStoreRegisterListSize(ins);
registerListSize = insGetRegisterListSize(ins);
assert((elemsize * registerListSize) == (unsigned)imm2);
assert(insOptsPostIndex(opt));
@ -11884,7 +11917,7 @@ void emitter::emitDispIns(
case IF_LS_2D: // LS_2D .Q.............. ....ssnnnnnttttt Vt Rn
case IF_LS_2E: // LS_2E .Q.............. ....ssnnnnnttttt Vt Rn
registerListSize = insGetLoadStoreRegisterListSize(id->idIns());
registerListSize = insGetRegisterListSize(id->idIns());
emitDispVectorRegList(id->idReg1(), registerListSize, id->idInsOpt(), true);
if (fmt == IF_LS_2D)
@ -11903,7 +11936,7 @@ void emitter::emitDispIns(
case IF_LS_2F: // LS_2F .Q.............. xx.Sssnnnnnttttt Vt[] Rn
case IF_LS_2G: // LS_2G .Q.............. xx.Sssnnnnnttttt Vt[] Rn
registerListSize = insGetLoadStoreRegisterListSize(id->idIns());
registerListSize = insGetRegisterListSize(id->idIns());
elemsize = id->idOpSize();
emitDispVectorElemList(id->idReg1(), registerListSize, elemsize, id->idSmallCns(), true);
@ -11967,7 +12000,7 @@ void emitter::emitDispIns(
case IF_LS_3F: // LS_3F .Q.........mmmmm ....ssnnnnnttttt Vt Rn Rm
case IF_LS_3G: // LS_3G .Q.........mmmmm ...Sssnnnnnttttt Vt[] Rn Rm
registerListSize = insGetLoadStoreRegisterListSize(id->idIns());
registerListSize = insGetRegisterListSize(id->idIns());
if (fmt == IF_LS_3F)
{
@ -12468,9 +12501,25 @@ void emitter::emitDispIns(
case IF_DV_3C: // DV_3C .Q.........mmmmm ......nnnnnddddd Vd Vn Vm (vector)
emitDispVectorReg(id->idReg1(), id->idInsOpt(), true);
if (ins != INS_mov)
switch (ins)
{
emitDispVectorReg(id->idReg2(), id->idInsOpt(), true);
case INS_tbl:
case INS_tbl_2regs:
case INS_tbl_3regs:
case INS_tbl_4regs:
case INS_tbx:
case INS_tbx_2regs:
case INS_tbx_3regs:
case INS_tbx_4regs:
registerListSize = insGetRegisterListSize(ins);
elemsize = id->idOpSize();
emitDispVectorRegList(id->idReg2(), registerListSize, id->idInsOpt(), true);
break;
case INS_mov:
break;
default:
emitDispVectorReg(id->idReg2(), id->idInsOpt(), true);
break;
}
emitDispVectorReg(id->idReg3(), id->idInsOpt(), false);
break;
@ -14145,9 +14194,48 @@ emitter::insExecutionCharacteristics emitter::getInsExecutionCharacteristics(ins
}
break;
case IF_DV_3C: // mov,and, bic, eor, mov,mvn, orn, bsl, bit, bif (vector)
result.insThroughput = PERFSCORE_THROUGHPUT_2X;
result.insLatency = PERFSCORE_LATENCY_1C;
case IF_DV_3C: // mov,and, bic, eor, mov,mvn, orn, bsl, bit, bif,
// tbl, tbx (vector)
switch (ins)
{
case INS_tbl:
result.insThroughput = PERFSCORE_THROUGHPUT_2X;
result.insLatency = PERFSCORE_LATENCY_1C;
break;
case INS_tbl_2regs:
result.insThroughput = PERFSCORE_THROUGHPUT_3X;
result.insLatency = PERFSCORE_LATENCY_2C;
break;
case INS_tbl_3regs:
result.insThroughput = PERFSCORE_THROUGHPUT_4X;
result.insLatency = PERFSCORE_LATENCY_3C;
break;
case INS_tbl_4regs:
result.insThroughput = PERFSCORE_THROUGHPUT_3X;
result.insLatency = PERFSCORE_LATENCY_4C;
break;
case INS_tbx:
result.insThroughput = PERFSCORE_THROUGHPUT_3X;
result.insLatency = PERFSCORE_LATENCY_2C;
break;
case INS_tbx_2regs:
result.insThroughput = PERFSCORE_THROUGHPUT_4X;
result.insLatency = PERFSCORE_LATENCY_3C;
break;
case INS_tbx_3regs:
result.insThroughput = PERFSCORE_THROUGHPUT_5X;
result.insLatency = PERFSCORE_LATENCY_4C;
break;
case INS_tbx_4regs:
result.insThroughput = PERFSCORE_THROUGHPUT_6X;
result.insLatency = PERFSCORE_LATENCY_5C;
break;
default:
// All other instructions
result.insThroughput = PERFSCORE_THROUGHPUT_2X;
result.insLatency = PERFSCORE_LATENCY_1C;
break;
}
break;
case IF_DV_2E: // mov, dup (scalar)

View file

@ -453,9 +453,9 @@ static emitAttr optGetSrcsize(insOpts conversion);
// for an element of size 'elemsize' in a vector register of size 'datasize'
static bool isValidVectorIndex(emitAttr datasize, emitAttr elemsize, ssize_t index);
// For a given Load/Store Vector instruction 'ins' returns a number of consecutive SIMD registers
// the instruction loads to/store from.
static unsigned insGetLoadStoreRegisterListSize(instruction ins);
// For a given instruction 'ins' which contains a register lists returns a
// number of consecutive SIMD registers the instruction loads to/store from.
static unsigned insGetRegisterListSize(instruction ins);
/************************************************************************/
/* Public inline informational methods */

View file

@ -118,6 +118,8 @@ HARDWARE_INTRINSIC(AdvSimd, SqrtScalar,
HARDWARE_INTRINSIC(AdvSimd, Store, -1, 2, {INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1, INS_st1}, HW_Category_MemoryStore, HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromSecondArg)
HARDWARE_INTRINSIC(AdvSimd, Subtract, -1, 2, {INS_sub, INS_sub, INS_sub, INS_sub, INS_sub, INS_sub, INS_sub, INS_sub, INS_fsub, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag)
HARDWARE_INTRINSIC(AdvSimd, SubtractScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sub, INS_sub, INS_fsub, INS_fsub}, HW_Category_SIMDScalar, HW_Flag_NoFlag)
HARDWARE_INTRINSIC(AdvSimd, VectorTableLookup, 8, 2, {INS_tbl, INS_tbl, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag)
HARDWARE_INTRINSIC(AdvSimd, VectorTableLookupExtension, 8, 3, {INS_tbx, INS_tbx, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics)
HARDWARE_INTRINSIC(AdvSimd, Xor, -1, 2, {INS_eor, INS_eor, INS_eor, INS_eor, INS_eor, INS_eor, INS_eor, INS_eor, INS_eor, INS_eor}, HW_Category_SimpleSIMD, HW_Flag_Commutative)
// ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
@ -195,6 +197,8 @@ HARDWARE_INTRINSIC(AdvSimd_Arm64, TransposeEven, -
HARDWARE_INTRINSIC(AdvSimd_Arm64, TransposeOdd, -1, 2, {INS_trn2, INS_trn2, INS_trn2, INS_trn2, INS_trn2, INS_trn2, INS_trn2, INS_trn2, INS_trn2, INS_trn2}, HW_Category_SimpleSIMD, HW_Flag_NoFlag)
HARDWARE_INTRINSIC(AdvSimd_Arm64, UnzipEven, -1, 2, {INS_uzp1, INS_uzp1, INS_uzp1, INS_uzp1, INS_uzp1, INS_uzp1, INS_uzp1, INS_uzp1, INS_uzp1, INS_uzp1}, HW_Category_SimpleSIMD, HW_Flag_NoFlag)
HARDWARE_INTRINSIC(AdvSimd_Arm64, UnzipOdd, -1, 2, {INS_uzp2, INS_uzp2, INS_uzp2, INS_uzp2, INS_uzp2, INS_uzp2, INS_uzp2, INS_uzp2, INS_uzp2, INS_uzp2}, HW_Category_SimpleSIMD, HW_Flag_NoFlag)
HARDWARE_INTRINSIC(AdvSimd_Arm64, VectorTableLookup, 16, 2, {INS_tbl, INS_tbl, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoFlag)
HARDWARE_INTRINSIC(AdvSimd_Arm64, VectorTableLookupExtension, 16, 3, {INS_tbx, INS_tbx, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_HasRMWSemantics)
HARDWARE_INTRINSIC(AdvSimd_Arm64, ZipHigh, -1, 2, {INS_zip2, INS_zip2, INS_zip2, INS_zip2, INS_zip2, INS_zip2, INS_zip2, INS_zip2, INS_zip2, INS_zip2}, HW_Category_SimpleSIMD, HW_Flag_NoFlag)
HARDWARE_INTRINSIC(AdvSimd_Arm64, ZipLow, -1, 2, {INS_zip1, INS_zip1, INS_zip1, INS_zip1, INS_zip1, INS_zip1, INS_zip1, INS_zip1, INS_zip1, INS_zip1}, HW_Category_SimpleSIMD, HW_Flag_NoFlag)

View file

@ -1832,6 +1832,31 @@ INST1(uxtl, "uxtl", 0, 0, IF_DV_2O, 0x2F00A400)
INST1(uxtl2, "uxtl2", 0, 0, IF_DV_2O, 0x6F00A400)
// uxtl2 Vd,Vn DV_2O 011011110iiiiiii 101001nnnnnddddd 6F00 A400 Vd,Vn (shift - vector)
INST1(tbl, "tbl", 0, 0, IF_DV_3C, 0x0E000000)
// tbl Vd,{Vn},Vm DV_3C 0Q001110000mmmmm 000000nnnnnddddd 0E00 0000 Vd,Vn,Vm (vector)
INST1(tbl_2regs, "tbl", 0, 0, IF_DV_3C, 0x0E002000)
// tbl Vd,{Vn,Vn+1},Vm DV_3C 0Q001110000mmmmm 001000nnnnnddddd 0E00 2000 Vd,Vn,Vm (vector)
INST1(tbl_3regs, "tbl", 0, 0, IF_DV_3C, 0x0E004000)
// tbl Vd,{Vn,Vn+1,Vn+2},Vm DV_3C 0Q001110000mmmmm 010000nnnnnddddd 0E00 4000 Vd,Vn,Vm (vector)
INST1(tbl_4regs, "tbl", 0, 0, IF_DV_3C, 0x0E006000)
// tbl Vd,{Vn,Vn+1,Vn+2,Vn+3},Vm DV_3C 0Q001110000mmmmm 011000nnnnnddddd 0E00 6000 Vd,Vn,Vm (vector)
INST1(tbx, "tbx", 0, 0, IF_DV_3C, 0x0E001000)
// tbx Vd,{Vn},Vm DV_3C 0Q001110000mmmmm 000100nnnnnddddd 0E00 1000 Vd,Vn,Vm (vector)
INST1(tbx_2regs, "tbx", 0, 0, IF_DV_3C, 0x0E003000)
// tbx Vd,{Vn,Vn+1},Vm DV_3C 0Q001110000mmmmm 001100nnnnnddddd 0E00 3000 Vd,Vn,Vm (vector)
INST1(tbx_3regs, "tbx", 0, 0, IF_DV_3C, 0x0E005000)
// tbx Vd,{Vn,Vn+1,Vn+2},Vm DV_3C 0Q001110000mmmmm 010100nnnnnddddd 0E00 5000 Vd,Vn,Vm (vector)
INST1(tbx_4regs, "tbx", 0, 0, IF_DV_3C, 0x0E007000)
// tbx Vd,{Vn,Vn+1,Vn+2,Vn+3},Vm DV_3C 0Q001110000mmmmm 011100nnnnnddddd 0E00 7000 Vd,Vn,Vm (vector)
// clang-format on
/*****************************************************************************/

View file

@ -224,6 +224,10 @@
<Compile Include="TransposeOdd.Vector128.UInt16.cs" />
<Compile Include="TransposeOdd.Vector128.UInt32.cs" />
<Compile Include="TransposeOdd.Vector128.UInt64.cs" />
<Compile Include="VectorTableLookup.Vector128.Byte.cs" />
<Compile Include="VectorTableLookup.Vector128.SByte.cs" />
<Compile Include="VectorTableLookupExtension.Vector128.Byte.cs" />
<Compile Include="VectorTableLookupExtension.Vector128.SByte.cs" />
<Compile Include="UnzipEven.Vector64.Byte.cs" />
<Compile Include="UnzipEven.Vector64.Int16.cs" />
<Compile Include="UnzipEven.Vector64.Int32.cs" />

View file

@ -224,6 +224,10 @@
<Compile Include="TransposeOdd.Vector128.UInt16.cs" />
<Compile Include="TransposeOdd.Vector128.UInt32.cs" />
<Compile Include="TransposeOdd.Vector128.UInt64.cs" />
<Compile Include="VectorTableLookup.Vector128.Byte.cs" />
<Compile Include="VectorTableLookup.Vector128.SByte.cs" />
<Compile Include="VectorTableLookupExtension.Vector128.Byte.cs" />
<Compile Include="VectorTableLookupExtension.Vector128.SByte.cs" />
<Compile Include="UnzipEven.Vector64.Byte.cs" />
<Compile Include="UnzipEven.Vector64.Int16.cs" />
<Compile Include="UnzipEven.Vector64.Int32.cs" />

View file

@ -228,6 +228,10 @@ namespace JIT.HardwareIntrinsics.Arm
["TransposeOdd.Vector128.UInt16"] = TransposeOdd_Vector128_UInt16,
["TransposeOdd.Vector128.UInt32"] = TransposeOdd_Vector128_UInt32,
["TransposeOdd.Vector128.UInt64"] = TransposeOdd_Vector128_UInt64,
["VectorTableLookup.Vector128.Byte"] = VectorTableLookup_Vector128_Byte,
["VectorTableLookup.Vector128.SByte"] = VectorTableLookup_Vector128_SByte,
["VectorTableLookupExtension.Vector128.Byte"] = VectorTableLookupExtension_Vector128_Byte,
["VectorTableLookupExtension.Vector128.SByte"] = VectorTableLookupExtension_Vector128_SByte,
["UnzipEven.Vector64.Byte"] = UnzipEven_Vector64_Byte,
["UnzipEven.Vector64.Int16"] = UnzipEven_Vector64_Int16,
["UnzipEven.Vector64.Int32"] = UnzipEven_Vector64_Int32,

View file

@ -0,0 +1,537 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
/******************************************************************************
* This file is auto-generated from a template file by the GenerateTests.csx *
* script in tests\src\JIT\HardwareIntrinsics.Arm\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.Arm;
namespace JIT.HardwareIntrinsics.Arm
{
public static partial class Program
{
private static void VectorTableLookup_Vector128_Byte()
{
var test = new SimpleBinaryOpTest__VectorTableLookup_Vector128_Byte();
if (test.IsSupported)
{
// Validates basic functionality works, using Unsafe.Read
test.RunBasicScenario_UnsafeRead();
if (AdvSimd.IsSupported)
{
// Validates basic functionality works, using Load
test.RunBasicScenario_Load();
}
// Validates calling via reflection works, using Unsafe.Read
test.RunReflectionScenario_UnsafeRead();
if (AdvSimd.IsSupported)
{
// Validates calling via reflection works, using Load
test.RunReflectionScenario_Load();
}
// Validates passing a static member works
test.RunClsVarScenario();
if (AdvSimd.IsSupported)
{
// Validates passing a static member works, using pinning and Load
test.RunClsVarScenario_Load();
}
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
if (AdvSimd.IsSupported)
{
// Validates passing a local works, using Load
test.RunLclVarScenario_Load();
}
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing the field of a local class works, using pinning and Load
test.RunClassLclFldScenario_Load();
}
// Validates passing an instance member of a class works
test.RunClassFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing an instance member of a class works, using pinning and Load
test.RunClassFldScenario_Load();
}
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing the field of a local struct works, using pinning and Load
test.RunStructLclFldScenario_Load();
}
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing an instance member of a struct works, using pinning and Load
test.RunStructFldScenario_Load();
}
}
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 SimpleBinaryOpTest__VectorTableLookup_Vector128_Byte
{
private struct DataTable
{
private byte[] inArray1;
private byte[] inArray2;
private byte[] outArray;
private GCHandle inHandle1;
private GCHandle inHandle2;
private GCHandle outHandle;
private ulong alignment;
public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment)
{
int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
{
throw new ArgumentException("Invalid value of alignment");
}
this.inArray1 = new byte[alignment * 2];
this.inArray2 = new byte[alignment * 2];
this.outArray = new byte[alignment * 2];
this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
this.alignment = (ulong)alignment;
Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
}
public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
public void Dispose()
{
inHandle1.Free();
inHandle2.Free();
outHandle.Free();
}
private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
{
return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
}
}
private struct TestStruct
{
public Vector128<Byte> _fld1;
public Vector128<Byte> _fld2;
public static TestStruct Create()
{
var testStruct = new TestStruct();
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref testStruct._fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (Byte)(TestLibrary.Generator.GetByte() % 20); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref testStruct._fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
return testStruct;
}
public void RunStructFldScenario(SimpleBinaryOpTest__VectorTableLookup_Vector128_Byte testClass)
{
var result = AdvSimd.Arm64.VectorTableLookup(_fld1, _fld2);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
}
public void RunStructFldScenario_Load(SimpleBinaryOpTest__VectorTableLookup_Vector128_Byte testClass)
{
fixed (Vector128<Byte>* pFld1 = &_fld1)
fixed (Vector128<Byte>* pFld2 = &_fld2)
{
var result = AdvSimd.Arm64.VectorTableLookup(
AdvSimd.LoadVector128((Byte*)(pFld1)),
AdvSimd.LoadVector128((Byte*)(pFld2))
);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
}
}
}
private static readonly int LargestVectorSize = 16;
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Byte>>() / sizeof(Byte);
private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Byte>>() / sizeof(Byte);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Byte>>() / sizeof(Byte);
private static Byte[] _data1 = new Byte[Op1ElementCount];
private static Byte[] _data2 = new Byte[Op2ElementCount];
private static Vector128<Byte> _clsVar1;
private static Vector128<Byte> _clsVar2;
private Vector128<Byte> _fld1;
private Vector128<Byte> _fld2;
private DataTable _dataTable;
static SimpleBinaryOpTest__VectorTableLookup_Vector128_Byte()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (Byte)(TestLibrary.Generator.GetByte() % 20); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
}
public SimpleBinaryOpTest__VectorTableLookup_Vector128_Byte()
{
Succeeded = true;
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (Byte)(TestLibrary.Generator.GetByte() % 20); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (Byte)(TestLibrary.Generator.GetByte() % 20); }
_dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => AdvSimd.Arm64.IsSupported;
public bool Succeeded { get; set; }
public void RunBasicScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = AdvSimd.Arm64.VectorTableLookup(
Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = AdvSimd.Arm64.VectorTableLookup(
AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
AdvSimd.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.VectorTableLookup), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
.Invoke(null, new object[] {
Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.VectorTableLookup), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
.Invoke(null, new object[] {
AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
AdvSimd.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = AdvSimd.Arm64.VectorTableLookup(
_clsVar1,
_clsVar2
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
}
public void RunClsVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
fixed (Vector128<Byte>* pClsVar1 = &_clsVar1)
fixed (Vector128<Byte>* pClsVar2 = &_clsVar2)
{
var result = AdvSimd.Arm64.VectorTableLookup(
AdvSimd.LoadVector128((Byte*)(pClsVar1)),
AdvSimd.LoadVector128((Byte*)(pClsVar2))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
}
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
var op1 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
var op2 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
var result = AdvSimd.Arm64.VectorTableLookup(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
var op1 = AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
var op2 = AdvSimd.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
var result = AdvSimd.Arm64.VectorTableLookup(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleBinaryOpTest__VectorTableLookup_Vector128_Byte();
var result = AdvSimd.Arm64.VectorTableLookup(test._fld1, test._fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
var test = new SimpleBinaryOpTest__VectorTableLookup_Vector128_Byte();
fixed (Vector128<Byte>* pFld1 = &test._fld1)
fixed (Vector128<Byte>* pFld2 = &test._fld2)
{
var result = AdvSimd.Arm64.VectorTableLookup(
AdvSimd.LoadVector128((Byte*)(pFld1)),
AdvSimd.LoadVector128((Byte*)(pFld2))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
var result = AdvSimd.Arm64.VectorTableLookup(_fld1, _fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
}
public void RunClassFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
fixed (Vector128<Byte>* pFld1 = &_fld1)
fixed (Vector128<Byte>* pFld2 = &_fld2)
{
var result = AdvSimd.Arm64.VectorTableLookup(
AdvSimd.LoadVector128((Byte*)(pFld1)),
AdvSimd.LoadVector128((Byte*)(pFld2))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
}
}
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
var result = AdvSimd.Arm64.VectorTableLookup(test._fld1, test._fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
public void RunStructLclFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
var test = TestStruct.Create();
var result = AdvSimd.Arm64.VectorTableLookup(
AdvSimd.LoadVector128((Byte*)(&test._fld1)),
AdvSimd.LoadVector128((Byte*)(&test._fld2))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
var test = TestStruct.Create();
test.RunStructFldScenario(this);
}
public void RunStructFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
var test = TestStruct.Create();
test.RunStructFldScenario_Load(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(Vector128<Byte> op1, Vector128<Byte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
private void ValidateResult(Byte[] left, Byte[] right, Byte[] result, [CallerMemberName] string method = "")
{
bool succeeded = true;
if (Helpers.TableVectorLookup(0, right, left) != result[0])
{
succeeded = false;
}
else
{
for (var i = 1; i < RetElementCount; i++)
{
if (Helpers.TableVectorLookup(i, right, left) != result[i])
{
succeeded = false;
break;
}
}
}
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.VectorTableLookup)}<Byte>(Vector128<Byte>, Vector128<Byte>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
}
}
}
}

View file

@ -0,0 +1,537 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
/******************************************************************************
* This file is auto-generated from a template file by the GenerateTests.csx *
* script in tests\src\JIT\HardwareIntrinsics.Arm\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.Arm;
namespace JIT.HardwareIntrinsics.Arm
{
public static partial class Program
{
private static void VectorTableLookup_Vector128_SByte()
{
var test = new SimpleBinaryOpTest__VectorTableLookup_Vector128_SByte();
if (test.IsSupported)
{
// Validates basic functionality works, using Unsafe.Read
test.RunBasicScenario_UnsafeRead();
if (AdvSimd.IsSupported)
{
// Validates basic functionality works, using Load
test.RunBasicScenario_Load();
}
// Validates calling via reflection works, using Unsafe.Read
test.RunReflectionScenario_UnsafeRead();
if (AdvSimd.IsSupported)
{
// Validates calling via reflection works, using Load
test.RunReflectionScenario_Load();
}
// Validates passing a static member works
test.RunClsVarScenario();
if (AdvSimd.IsSupported)
{
// Validates passing a static member works, using pinning and Load
test.RunClsVarScenario_Load();
}
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
if (AdvSimd.IsSupported)
{
// Validates passing a local works, using Load
test.RunLclVarScenario_Load();
}
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing the field of a local class works, using pinning and Load
test.RunClassLclFldScenario_Load();
}
// Validates passing an instance member of a class works
test.RunClassFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing an instance member of a class works, using pinning and Load
test.RunClassFldScenario_Load();
}
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing the field of a local struct works, using pinning and Load
test.RunStructLclFldScenario_Load();
}
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing an instance member of a struct works, using pinning and Load
test.RunStructFldScenario_Load();
}
}
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 SimpleBinaryOpTest__VectorTableLookup_Vector128_SByte
{
private struct DataTable
{
private byte[] inArray1;
private byte[] inArray2;
private byte[] outArray;
private GCHandle inHandle1;
private GCHandle inHandle2;
private GCHandle outHandle;
private ulong alignment;
public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
{
int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
{
throw new ArgumentException("Invalid value of alignment");
}
this.inArray1 = new byte[alignment * 2];
this.inArray2 = new byte[alignment * 2];
this.outArray = new byte[alignment * 2];
this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
this.alignment = (ulong)alignment;
Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
}
public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
public void Dispose()
{
inHandle1.Free();
inHandle2.Free();
outHandle.Free();
}
private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
{
return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
}
}
private struct TestStruct
{
public Vector128<SByte> _fld1;
public Vector128<SByte> _fld2;
public static TestStruct Create()
{
var testStruct = new TestStruct();
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref testStruct._fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (SByte)(TestLibrary.Generator.GetSByte() % 20); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref testStruct._fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
return testStruct;
}
public void RunStructFldScenario(SimpleBinaryOpTest__VectorTableLookup_Vector128_SByte testClass)
{
var result = AdvSimd.Arm64.VectorTableLookup(_fld1, _fld2);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
}
public void RunStructFldScenario_Load(SimpleBinaryOpTest__VectorTableLookup_Vector128_SByte testClass)
{
fixed (Vector128<SByte>* pFld1 = &_fld1)
fixed (Vector128<SByte>* pFld2 = &_fld2)
{
var result = AdvSimd.Arm64.VectorTableLookup(
AdvSimd.LoadVector128((SByte*)(pFld1)),
AdvSimd.LoadVector128((SByte*)(pFld2))
);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
}
}
}
private static readonly int LargestVectorSize = 16;
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<SByte>>() / sizeof(SByte);
private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<SByte>>() / sizeof(SByte);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<SByte>>() / sizeof(SByte);
private static SByte[] _data1 = new SByte[Op1ElementCount];
private static SByte[] _data2 = new SByte[Op2ElementCount];
private static Vector128<SByte> _clsVar1;
private static Vector128<SByte> _clsVar2;
private Vector128<SByte> _fld1;
private Vector128<SByte> _fld2;
private DataTable _dataTable;
static SimpleBinaryOpTest__VectorTableLookup_Vector128_SByte()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (SByte)(TestLibrary.Generator.GetSByte() % 20); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar2), ref Unsafe.As<SByte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
}
public SimpleBinaryOpTest__VectorTableLookup_Vector128_SByte()
{
Succeeded = true;
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (SByte)(TestLibrary.Generator.GetSByte() % 20); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (SByte)(TestLibrary.Generator.GetSByte() % 20); }
_dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => AdvSimd.Arm64.IsSupported;
public bool Succeeded { get; set; }
public void RunBasicScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = AdvSimd.Arm64.VectorTableLookup(
Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = AdvSimd.Arm64.VectorTableLookup(
AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.VectorTableLookup), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
.Invoke(null, new object[] {
Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.VectorTableLookup), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
.Invoke(null, new object[] {
AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = AdvSimd.Arm64.VectorTableLookup(
_clsVar1,
_clsVar2
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
}
public void RunClsVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
fixed (Vector128<SByte>* pClsVar1 = &_clsVar1)
fixed (Vector128<SByte>* pClsVar2 = &_clsVar2)
{
var result = AdvSimd.Arm64.VectorTableLookup(
AdvSimd.LoadVector128((SByte*)(pClsVar1)),
AdvSimd.LoadVector128((SByte*)(pClsVar2))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
}
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
var op1 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
var op2 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
var result = AdvSimd.Arm64.VectorTableLookup(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
var op1 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
var op2 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
var result = AdvSimd.Arm64.VectorTableLookup(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleBinaryOpTest__VectorTableLookup_Vector128_SByte();
var result = AdvSimd.Arm64.VectorTableLookup(test._fld1, test._fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
var test = new SimpleBinaryOpTest__VectorTableLookup_Vector128_SByte();
fixed (Vector128<SByte>* pFld1 = &test._fld1)
fixed (Vector128<SByte>* pFld2 = &test._fld2)
{
var result = AdvSimd.Arm64.VectorTableLookup(
AdvSimd.LoadVector128((SByte*)(pFld1)),
AdvSimd.LoadVector128((SByte*)(pFld2))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
var result = AdvSimd.Arm64.VectorTableLookup(_fld1, _fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
}
public void RunClassFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
fixed (Vector128<SByte>* pFld1 = &_fld1)
fixed (Vector128<SByte>* pFld2 = &_fld2)
{
var result = AdvSimd.Arm64.VectorTableLookup(
AdvSimd.LoadVector128((SByte*)(pFld1)),
AdvSimd.LoadVector128((SByte*)(pFld2))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
}
}
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
var result = AdvSimd.Arm64.VectorTableLookup(test._fld1, test._fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
public void RunStructLclFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
var test = TestStruct.Create();
var result = AdvSimd.Arm64.VectorTableLookup(
AdvSimd.LoadVector128((SByte*)(&test._fld1)),
AdvSimd.LoadVector128((SByte*)(&test._fld2))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
var test = TestStruct.Create();
test.RunStructFldScenario(this);
}
public void RunStructFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
var test = TestStruct.Create();
test.RunStructFldScenario_Load(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(Vector128<SByte> op1, Vector128<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "")
{
bool succeeded = true;
if (Helpers.TableVectorLookup(0, right, left) != result[0])
{
succeeded = false;
}
else
{
for (var i = 1; i < RetElementCount; i++)
{
if (Helpers.TableVectorLookup(i, right, left) != result[i])
{
succeeded = false;
break;
}
}
}
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.VectorTableLookup)}<SByte>(Vector128<SByte>, Vector128<SByte>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
}
}
}
}

View file

@ -0,0 +1,571 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
/******************************************************************************
* This file is auto-generated from a template file by the GenerateTests.csx *
* script in tests\src\JIT\HardwareIntrinsics.Arm\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.Arm;
namespace JIT.HardwareIntrinsics.Arm
{
public static partial class Program
{
private static void VectorTableLookupExtension_Vector128_Byte()
{
var test = new SimpleTernaryOpTest__VectorTableLookupExtension_Vector128_Byte();
if (test.IsSupported)
{
// Validates basic functionality works, using Unsafe.Read
test.RunBasicScenario_UnsafeRead();
if (AdvSimd.IsSupported)
{
// Validates basic functionality works, using Load
test.RunBasicScenario_Load();
}
// Validates calling via reflection works, using Unsafe.Read
test.RunReflectionScenario_UnsafeRead();
if (AdvSimd.IsSupported)
{
// Validates calling via reflection works, using Load
test.RunReflectionScenario_Load();
}
// Validates passing a static member works
test.RunClsVarScenario();
if (AdvSimd.IsSupported)
{
// Validates passing a static member works, using pinning and Load
test.RunClsVarScenario_Load();
}
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
if (AdvSimd.IsSupported)
{
// Validates passing a local works, using Load
test.RunLclVarScenario_Load();
}
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing the field of a local class works, using pinning and Load
test.RunClassLclFldScenario_Load();
}
// Validates passing an instance member of a class works
test.RunClassFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing an instance member of a class works, using pinning and Load
test.RunClassFldScenario_Load();
}
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing the field of a local struct works, using pinning and Load
test.RunStructLclFldScenario_Load();
}
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing an instance member of a struct works, using pinning and Load
test.RunStructFldScenario_Load();
}
}
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 SimpleTernaryOpTest__VectorTableLookupExtension_Vector128_Byte
{
private struct DataTable
{
private byte[] inArray1;
private byte[] inArray2;
private byte[] inArray3;
private byte[] outArray;
private GCHandle inHandle1;
private GCHandle inHandle2;
private GCHandle inHandle3;
private GCHandle outHandle;
private ulong alignment;
public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] inArray3, Byte[] outArray, int alignment)
{
int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Byte>();
int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
{
throw new ArgumentException("Invalid value of alignment");
}
this.inArray1 = new byte[alignment * 2];
this.inArray2 = new byte[alignment * 2];
this.inArray3 = new byte[alignment * 2];
this.outArray = new byte[alignment * 2];
this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
this.alignment = (ulong)alignment;
Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Byte, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
}
public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
public void Dispose()
{
inHandle1.Free();
inHandle2.Free();
inHandle3.Free();
outHandle.Free();
}
private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
{
return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
}
}
private struct TestStruct
{
public Vector128<Byte> _fld1;
public Vector128<Byte> _fld2;
public Vector128<Byte> _fld3;
public static TestStruct Create()
{
var testStruct = new TestStruct();
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref testStruct._fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref testStruct._fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (Byte)(TestLibrary.Generator.GetByte() % 20); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref testStruct._fld3), ref Unsafe.As<Byte, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
return testStruct;
}
public void RunStructFldScenario(SimpleTernaryOpTest__VectorTableLookupExtension_Vector128_Byte testClass)
{
var result = AdvSimd.Arm64.VectorTableLookupExtension(_fld1, _fld2, _fld3);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
public void RunStructFldScenario_Load(SimpleTernaryOpTest__VectorTableLookupExtension_Vector128_Byte testClass)
{
fixed (Vector128<Byte>* pFld1 = &_fld1)
fixed (Vector128<Byte>* pFld2 = &_fld2)
fixed (Vector128<Byte>* pFld3 = &_fld3)
{
var result = AdvSimd.Arm64.VectorTableLookupExtension(
AdvSimd.LoadVector128((Byte*)(pFld1)),
AdvSimd.LoadVector128((Byte*)(pFld2)),
AdvSimd.LoadVector128((Byte*)(pFld3))
);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
}
}
private static readonly int LargestVectorSize = 16;
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Byte>>() / sizeof(Byte);
private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Byte>>() / sizeof(Byte);
private static readonly int Op3ElementCount = Unsafe.SizeOf<Vector128<Byte>>() / sizeof(Byte);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Byte>>() / sizeof(Byte);
private static Byte[] _data1 = new Byte[Op1ElementCount];
private static Byte[] _data2 = new Byte[Op2ElementCount];
private static Byte[] _data3 = new Byte[Op3ElementCount];
private static Vector128<Byte> _clsVar1;
private static Vector128<Byte> _clsVar2;
private static Vector128<Byte> _clsVar3;
private Vector128<Byte> _fld1;
private Vector128<Byte> _fld2;
private Vector128<Byte> _fld3;
private DataTable _dataTable;
static SimpleTernaryOpTest__VectorTableLookupExtension_Vector128_Byte()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (Byte)(TestLibrary.Generator.GetByte() % 20); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar3), ref Unsafe.As<Byte, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
}
public SimpleTernaryOpTest__VectorTableLookupExtension_Vector128_Byte()
{
Succeeded = true;
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (Byte)(TestLibrary.Generator.GetByte() % 20); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld3), ref Unsafe.As<Byte, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (Byte)(TestLibrary.Generator.GetByte() % 20); }
_dataTable = new DataTable(_data1, _data2, _data3, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => AdvSimd.Arm64.IsSupported;
public bool Succeeded { get; set; }
public void RunBasicScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = AdvSimd.Arm64.VectorTableLookupExtension(
Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr),
Unsafe.Read<Vector128<Byte>>(_dataTable.inArray3Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = AdvSimd.Arm64.VectorTableLookupExtension(
AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
AdvSimd.LoadVector128((Byte*)(_dataTable.inArray2Ptr)),
AdvSimd.LoadVector128((Byte*)(_dataTable.inArray3Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.VectorTableLookupExtension), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
.Invoke(null, new object[] {
Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr),
Unsafe.Read<Vector128<Byte>>(_dataTable.inArray3Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.VectorTableLookupExtension), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
.Invoke(null, new object[] {
AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
AdvSimd.LoadVector128((Byte*)(_dataTable.inArray2Ptr)),
AdvSimd.LoadVector128((Byte*)(_dataTable.inArray3Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = AdvSimd.Arm64.VectorTableLookupExtension(
_clsVar1,
_clsVar2,
_clsVar3
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
public void RunClsVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
fixed (Vector128<Byte>* pClsVar1 = &_clsVar1)
fixed (Vector128<Byte>* pClsVar2 = &_clsVar2)
fixed (Vector128<Byte>* pClsVar3 = &_clsVar3)
{
var result = AdvSimd.Arm64.VectorTableLookupExtension(
AdvSimd.LoadVector128((Byte*)(pClsVar1)),
AdvSimd.LoadVector128((Byte*)(pClsVar2)),
AdvSimd.LoadVector128((Byte*)(pClsVar3))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
var op1 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
var op2 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
var op3 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray3Ptr);
var result = AdvSimd.Arm64.VectorTableLookupExtension(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
var op1 = AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
var op2 = AdvSimd.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
var op3 = AdvSimd.LoadVector128((Byte*)(_dataTable.inArray3Ptr));
var result = AdvSimd.Arm64.VectorTableLookupExtension(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleTernaryOpTest__VectorTableLookupExtension_Vector128_Byte();
var result = AdvSimd.Arm64.VectorTableLookupExtension(test._fld1, test._fld2, test._fld3);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
var test = new SimpleTernaryOpTest__VectorTableLookupExtension_Vector128_Byte();
fixed (Vector128<Byte>* pFld1 = &test._fld1)
fixed (Vector128<Byte>* pFld2 = &test._fld2)
fixed (Vector128<Byte>* pFld3 = &test._fld3)
{
var result = AdvSimd.Arm64.VectorTableLookupExtension(
AdvSimd.LoadVector128((Byte*)(pFld1)),
AdvSimd.LoadVector128((Byte*)(pFld2)),
AdvSimd.LoadVector128((Byte*)(pFld3))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
var result = AdvSimd.Arm64.VectorTableLookupExtension(_fld1, _fld2, _fld3);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
public void RunClassFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
fixed (Vector128<Byte>* pFld1 = &_fld1)
fixed (Vector128<Byte>* pFld2 = &_fld2)
fixed (Vector128<Byte>* pFld3 = &_fld3)
{
var result = AdvSimd.Arm64.VectorTableLookupExtension(
AdvSimd.LoadVector128((Byte*)(pFld1)),
AdvSimd.LoadVector128((Byte*)(pFld2)),
AdvSimd.LoadVector128((Byte*)(pFld3))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
}
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
var result = AdvSimd.Arm64.VectorTableLookupExtension(test._fld1, test._fld2, test._fld3);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
public void RunStructLclFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
var test = TestStruct.Create();
var result = AdvSimd.Arm64.VectorTableLookupExtension(
AdvSimd.LoadVector128((Byte*)(&test._fld1)),
AdvSimd.LoadVector128((Byte*)(&test._fld2)),
AdvSimd.LoadVector128((Byte*)(&test._fld3))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
var test = TestStruct.Create();
test.RunStructFldScenario(this);
}
public void RunStructFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
var test = TestStruct.Create();
test.RunStructFldScenario_Load(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(Vector128<Byte> op1, Vector128<Byte> op2, Vector128<Byte> op3, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] inArray3 = new Byte[Op3ElementCount];
Byte[] outArray = new Byte[RetElementCount];
Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] inArray3 = new Byte[Op3ElementCount];
Byte[] outArray = new Byte[RetElementCount];
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
private void ValidateResult(Byte[] firstOp, Byte[] secondOp, Byte[] thirdOp, Byte[] result, [CallerMemberName] string method = "")
{
bool succeeded = true;
for (var i = 0; i < RetElementCount; i++)
{
if (Helpers.TableVectorExtension(i, firstOp, thirdOp, secondOp) != result[i])
{
succeeded = false;
break;
}
}
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.VectorTableLookupExtension)}<Byte>(Vector128<Byte>, Vector128<Byte>, Vector128<Byte>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
}
}
}
}

View file

@ -0,0 +1,571 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
/******************************************************************************
* This file is auto-generated from a template file by the GenerateTests.csx *
* script in tests\src\JIT\HardwareIntrinsics.Arm\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.Arm;
namespace JIT.HardwareIntrinsics.Arm
{
public static partial class Program
{
private static void VectorTableLookupExtension_Vector128_SByte()
{
var test = new SimpleTernaryOpTest__VectorTableLookupExtension_Vector128_SByte();
if (test.IsSupported)
{
// Validates basic functionality works, using Unsafe.Read
test.RunBasicScenario_UnsafeRead();
if (AdvSimd.IsSupported)
{
// Validates basic functionality works, using Load
test.RunBasicScenario_Load();
}
// Validates calling via reflection works, using Unsafe.Read
test.RunReflectionScenario_UnsafeRead();
if (AdvSimd.IsSupported)
{
// Validates calling via reflection works, using Load
test.RunReflectionScenario_Load();
}
// Validates passing a static member works
test.RunClsVarScenario();
if (AdvSimd.IsSupported)
{
// Validates passing a static member works, using pinning and Load
test.RunClsVarScenario_Load();
}
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
if (AdvSimd.IsSupported)
{
// Validates passing a local works, using Load
test.RunLclVarScenario_Load();
}
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing the field of a local class works, using pinning and Load
test.RunClassLclFldScenario_Load();
}
// Validates passing an instance member of a class works
test.RunClassFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing an instance member of a class works, using pinning and Load
test.RunClassFldScenario_Load();
}
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing the field of a local struct works, using pinning and Load
test.RunStructLclFldScenario_Load();
}
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing an instance member of a struct works, using pinning and Load
test.RunStructFldScenario_Load();
}
}
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 SimpleTernaryOpTest__VectorTableLookupExtension_Vector128_SByte
{
private struct DataTable
{
private byte[] inArray1;
private byte[] inArray2;
private byte[] inArray3;
private byte[] outArray;
private GCHandle inHandle1;
private GCHandle inHandle2;
private GCHandle inHandle3;
private GCHandle outHandle;
private ulong alignment;
public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] inArray3, SByte[] outArray, int alignment)
{
int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<SByte>();
int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
{
throw new ArgumentException("Invalid value of alignment");
}
this.inArray1 = new byte[alignment * 2];
this.inArray2 = new byte[alignment * 2];
this.inArray3 = new byte[alignment * 2];
this.outArray = new byte[alignment * 2];
this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
this.alignment = (ulong)alignment;
Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<SByte, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
}
public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
public void Dispose()
{
inHandle1.Free();
inHandle2.Free();
inHandle3.Free();
outHandle.Free();
}
private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
{
return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
}
}
private struct TestStruct
{
public Vector128<SByte> _fld1;
public Vector128<SByte> _fld2;
public Vector128<SByte> _fld3;
public static TestStruct Create()
{
var testStruct = new TestStruct();
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref testStruct._fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref testStruct._fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (SByte)(TestLibrary.Generator.GetSByte() % 20); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref testStruct._fld3), ref Unsafe.As<SByte, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
return testStruct;
}
public void RunStructFldScenario(SimpleTernaryOpTest__VectorTableLookupExtension_Vector128_SByte testClass)
{
var result = AdvSimd.Arm64.VectorTableLookupExtension(_fld1, _fld2, _fld3);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
public void RunStructFldScenario_Load(SimpleTernaryOpTest__VectorTableLookupExtension_Vector128_SByte testClass)
{
fixed (Vector128<SByte>* pFld1 = &_fld1)
fixed (Vector128<SByte>* pFld2 = &_fld2)
fixed (Vector128<SByte>* pFld3 = &_fld3)
{
var result = AdvSimd.Arm64.VectorTableLookupExtension(
AdvSimd.LoadVector128((SByte*)(pFld1)),
AdvSimd.LoadVector128((SByte*)(pFld2)),
AdvSimd.LoadVector128((SByte*)(pFld3))
);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
}
}
private static readonly int LargestVectorSize = 16;
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<SByte>>() / sizeof(SByte);
private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<SByte>>() / sizeof(SByte);
private static readonly int Op3ElementCount = Unsafe.SizeOf<Vector128<SByte>>() / sizeof(SByte);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<SByte>>() / sizeof(SByte);
private static SByte[] _data1 = new SByte[Op1ElementCount];
private static SByte[] _data2 = new SByte[Op2ElementCount];
private static SByte[] _data3 = new SByte[Op3ElementCount];
private static Vector128<SByte> _clsVar1;
private static Vector128<SByte> _clsVar2;
private static Vector128<SByte> _clsVar3;
private Vector128<SByte> _fld1;
private Vector128<SByte> _fld2;
private Vector128<SByte> _fld3;
private DataTable _dataTable;
static SimpleTernaryOpTest__VectorTableLookupExtension_Vector128_SByte()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar2), ref Unsafe.As<SByte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (SByte)(TestLibrary.Generator.GetSByte() % 20); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar3), ref Unsafe.As<SByte, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
}
public SimpleTernaryOpTest__VectorTableLookupExtension_Vector128_SByte()
{
Succeeded = true;
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (SByte)(TestLibrary.Generator.GetSByte() % 20); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld3), ref Unsafe.As<SByte, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (SByte)(TestLibrary.Generator.GetSByte() % 20); }
_dataTable = new DataTable(_data1, _data2, _data3, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => AdvSimd.Arm64.IsSupported;
public bool Succeeded { get; set; }
public void RunBasicScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = AdvSimd.Arm64.VectorTableLookupExtension(
Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr),
Unsafe.Read<Vector128<SByte>>(_dataTable.inArray3Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = AdvSimd.Arm64.VectorTableLookupExtension(
AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)),
AdvSimd.LoadVector128((SByte*)(_dataTable.inArray3Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.VectorTableLookupExtension), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
.Invoke(null, new object[] {
Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr),
Unsafe.Read<Vector128<SByte>>(_dataTable.inArray3Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
var result = typeof(AdvSimd.Arm64).GetMethod(nameof(AdvSimd.Arm64.VectorTableLookupExtension), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
.Invoke(null, new object[] {
AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)),
AdvSimd.LoadVector128((SByte*)(_dataTable.inArray3Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = AdvSimd.Arm64.VectorTableLookupExtension(
_clsVar1,
_clsVar2,
_clsVar3
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
public void RunClsVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
fixed (Vector128<SByte>* pClsVar1 = &_clsVar1)
fixed (Vector128<SByte>* pClsVar2 = &_clsVar2)
fixed (Vector128<SByte>* pClsVar3 = &_clsVar3)
{
var result = AdvSimd.Arm64.VectorTableLookupExtension(
AdvSimd.LoadVector128((SByte*)(pClsVar1)),
AdvSimd.LoadVector128((SByte*)(pClsVar2)),
AdvSimd.LoadVector128((SByte*)(pClsVar3))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
var op1 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
var op2 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
var op3 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray3Ptr);
var result = AdvSimd.Arm64.VectorTableLookupExtension(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
var op1 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
var op2 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
var op3 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray3Ptr));
var result = AdvSimd.Arm64.VectorTableLookupExtension(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleTernaryOpTest__VectorTableLookupExtension_Vector128_SByte();
var result = AdvSimd.Arm64.VectorTableLookupExtension(test._fld1, test._fld2, test._fld3);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
var test = new SimpleTernaryOpTest__VectorTableLookupExtension_Vector128_SByte();
fixed (Vector128<SByte>* pFld1 = &test._fld1)
fixed (Vector128<SByte>* pFld2 = &test._fld2)
fixed (Vector128<SByte>* pFld3 = &test._fld3)
{
var result = AdvSimd.Arm64.VectorTableLookupExtension(
AdvSimd.LoadVector128((SByte*)(pFld1)),
AdvSimd.LoadVector128((SByte*)(pFld2)),
AdvSimd.LoadVector128((SByte*)(pFld3))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
var result = AdvSimd.Arm64.VectorTableLookupExtension(_fld1, _fld2, _fld3);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
public void RunClassFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
fixed (Vector128<SByte>* pFld1 = &_fld1)
fixed (Vector128<SByte>* pFld2 = &_fld2)
fixed (Vector128<SByte>* pFld3 = &_fld3)
{
var result = AdvSimd.Arm64.VectorTableLookupExtension(
AdvSimd.LoadVector128((SByte*)(pFld1)),
AdvSimd.LoadVector128((SByte*)(pFld2)),
AdvSimd.LoadVector128((SByte*)(pFld3))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
}
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
var result = AdvSimd.Arm64.VectorTableLookupExtension(test._fld1, test._fld2, test._fld3);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
public void RunStructLclFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
var test = TestStruct.Create();
var result = AdvSimd.Arm64.VectorTableLookupExtension(
AdvSimd.LoadVector128((SByte*)(&test._fld1)),
AdvSimd.LoadVector128((SByte*)(&test._fld2)),
AdvSimd.LoadVector128((SByte*)(&test._fld3))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
var test = TestStruct.Create();
test.RunStructFldScenario(this);
}
public void RunStructFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
var test = TestStruct.Create();
test.RunStructFldScenario_Load(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(Vector128<SByte> op1, Vector128<SByte> op2, Vector128<SByte> op3, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] inArray3 = new SByte[Op3ElementCount];
SByte[] outArray = new SByte[RetElementCount];
Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] inArray3 = new SByte[Op3ElementCount];
SByte[] outArray = new SByte[RetElementCount];
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
private void ValidateResult(SByte[] firstOp, SByte[] secondOp, SByte[] thirdOp, SByte[] result, [CallerMemberName] string method = "")
{
bool succeeded = true;
for (var i = 0; i < RetElementCount; i++)
{
if (Helpers.TableVectorExtension(i, firstOp, thirdOp, secondOp) != result[i])
{
succeeded = false;
break;
}
}
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd.Arm64)}.{nameof(AdvSimd.Arm64.VectorTableLookupExtension)}<SByte>(Vector128<SByte>, Vector128<SByte>, Vector128<SByte>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
}
}
}
}

View file

@ -560,6 +560,10 @@
<Compile Include="SubtractScalar.Vector64.Int64.cs" />
<Compile Include="SubtractScalar.Vector64.Single.cs" />
<Compile Include="SubtractScalar.Vector64.UInt64.cs" />
<Compile Include="VectorTableLookup.Vector64.Byte.cs" />
<Compile Include="VectorTableLookup.Vector64.SByte.cs" />
<Compile Include="VectorTableLookupExtension.Vector64.Byte.cs" />
<Compile Include="VectorTableLookupExtension.Vector64.SByte.cs" />
<Compile Include="Xor.Vector64.Byte.cs" />
<Compile Include="Xor.Vector64.Double.cs" />
<Compile Include="Xor.Vector64.Int16.cs" />

View file

@ -560,6 +560,10 @@
<Compile Include="SubtractScalar.Vector64.Int64.cs" />
<Compile Include="SubtractScalar.Vector64.Single.cs" />
<Compile Include="SubtractScalar.Vector64.UInt64.cs" />
<Compile Include="VectorTableLookup.Vector64.Byte.cs" />
<Compile Include="VectorTableLookup.Vector64.SByte.cs" />
<Compile Include="VectorTableLookupExtension.Vector64.Byte.cs" />
<Compile Include="VectorTableLookupExtension.Vector64.SByte.cs" />
<Compile Include="Xor.Vector64.Byte.cs" />
<Compile Include="Xor.Vector64.Double.cs" />
<Compile Include="Xor.Vector64.Int16.cs" />

View file

@ -564,6 +564,10 @@ namespace JIT.HardwareIntrinsics.Arm
["SubtractScalar.Vector64.Int64"] = SubtractScalar_Vector64_Int64,
["SubtractScalar.Vector64.Single"] = SubtractScalar_Vector64_Single,
["SubtractScalar.Vector64.UInt64"] = SubtractScalar_Vector64_UInt64,
["VectorTableLookup.Vector64.Byte"] = VectorTableLookup_Vector64_Byte,
["VectorTableLookup.Vector64.SByte"] = VectorTableLookup_Vector64_SByte,
["VectorTableLookupExtension.Vector64.Byte"] = VectorTableLookupExtension_Vector64_Byte,
["VectorTableLookupExtension.Vector64.SByte"] = VectorTableLookupExtension_Vector64_SByte,
["Xor.Vector64.Byte"] = Xor_Vector64_Byte,
["Xor.Vector64.Double"] = Xor_Vector64_Double,
["Xor.Vector64.Int16"] = Xor_Vector64_Int16,

View file

@ -0,0 +1,537 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
/******************************************************************************
* This file is auto-generated from a template file by the GenerateTests.csx *
* script in tests\src\JIT\HardwareIntrinsics.Arm\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.Arm;
namespace JIT.HardwareIntrinsics.Arm
{
public static partial class Program
{
private static void VectorTableLookup_Vector64_Byte()
{
var test = new SimpleBinaryOpTest__VectorTableLookup_Vector64_Byte();
if (test.IsSupported)
{
// Validates basic functionality works, using Unsafe.Read
test.RunBasicScenario_UnsafeRead();
if (AdvSimd.IsSupported)
{
// Validates basic functionality works, using Load
test.RunBasicScenario_Load();
}
// Validates calling via reflection works, using Unsafe.Read
test.RunReflectionScenario_UnsafeRead();
if (AdvSimd.IsSupported)
{
// Validates calling via reflection works, using Load
test.RunReflectionScenario_Load();
}
// Validates passing a static member works
test.RunClsVarScenario();
if (AdvSimd.IsSupported)
{
// Validates passing a static member works, using pinning and Load
test.RunClsVarScenario_Load();
}
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
if (AdvSimd.IsSupported)
{
// Validates passing a local works, using Load
test.RunLclVarScenario_Load();
}
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing the field of a local class works, using pinning and Load
test.RunClassLclFldScenario_Load();
}
// Validates passing an instance member of a class works
test.RunClassFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing an instance member of a class works, using pinning and Load
test.RunClassFldScenario_Load();
}
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing the field of a local struct works, using pinning and Load
test.RunStructLclFldScenario_Load();
}
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing an instance member of a struct works, using pinning and Load
test.RunStructFldScenario_Load();
}
}
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 SimpleBinaryOpTest__VectorTableLookup_Vector64_Byte
{
private struct DataTable
{
private byte[] inArray1;
private byte[] inArray2;
private byte[] outArray;
private GCHandle inHandle1;
private GCHandle inHandle2;
private GCHandle outHandle;
private ulong alignment;
public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment)
{
int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
{
throw new ArgumentException("Invalid value of alignment");
}
this.inArray1 = new byte[alignment * 2];
this.inArray2 = new byte[alignment * 2];
this.outArray = new byte[alignment * 2];
this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
this.alignment = (ulong)alignment;
Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
}
public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
public void Dispose()
{
inHandle1.Free();
inHandle2.Free();
outHandle.Free();
}
private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
{
return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
}
}
private struct TestStruct
{
public Vector128<Byte> _fld1;
public Vector64<Byte> _fld2;
public static TestStruct Create()
{
var testStruct = new TestStruct();
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref testStruct._fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (Byte)(TestLibrary.Generator.GetByte() % 20); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector64<Byte>, byte>(ref testStruct._fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector64<Byte>>());
return testStruct;
}
public void RunStructFldScenario(SimpleBinaryOpTest__VectorTableLookup_Vector64_Byte testClass)
{
var result = AdvSimd.VectorTableLookup(_fld1, _fld2);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
}
public void RunStructFldScenario_Load(SimpleBinaryOpTest__VectorTableLookup_Vector64_Byte testClass)
{
fixed (Vector128<Byte>* pFld1 = &_fld1)
fixed (Vector64<Byte>* pFld2 = &_fld2)
{
var result = AdvSimd.VectorTableLookup(
AdvSimd.LoadVector128((Byte*)(pFld1)),
AdvSimd.LoadVector64((Byte*)(pFld2))
);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
}
}
}
private static readonly int LargestVectorSize = 16;
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Byte>>() / sizeof(Byte);
private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector64<Byte>>() / sizeof(Byte);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector64<Byte>>() / sizeof(Byte);
private static Byte[] _data1 = new Byte[Op1ElementCount];
private static Byte[] _data2 = new Byte[Op2ElementCount];
private static Vector128<Byte> _clsVar1;
private static Vector64<Byte> _clsVar2;
private Vector128<Byte> _fld1;
private Vector64<Byte> _fld2;
private DataTable _dataTable;
static SimpleBinaryOpTest__VectorTableLookup_Vector64_Byte()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (Byte)(TestLibrary.Generator.GetByte() % 20); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector64<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector64<Byte>>());
}
public SimpleBinaryOpTest__VectorTableLookup_Vector64_Byte()
{
Succeeded = true;
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (Byte)(TestLibrary.Generator.GetByte() % 20); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector64<Byte>, byte>(ref _fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector64<Byte>>());
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (Byte)(TestLibrary.Generator.GetByte() % 20); }
_dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => AdvSimd.IsSupported;
public bool Succeeded { get; set; }
public void RunBasicScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = AdvSimd.VectorTableLookup(
Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector64<Byte>>(_dataTable.inArray2Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = AdvSimd.VectorTableLookup(
AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
AdvSimd.LoadVector64((Byte*)(_dataTable.inArray2Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.VectorTableLookup), new Type[] { typeof(Vector128<Byte>), typeof(Vector64<Byte>) })
.Invoke(null, new object[] {
Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector64<Byte>>(_dataTable.inArray2Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector64<Byte>)(result));
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.VectorTableLookup), new Type[] { typeof(Vector128<Byte>), typeof(Vector64<Byte>) })
.Invoke(null, new object[] {
AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
AdvSimd.LoadVector64((Byte*)(_dataTable.inArray2Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector64<Byte>)(result));
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = AdvSimd.VectorTableLookup(
_clsVar1,
_clsVar2
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
}
public void RunClsVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
fixed (Vector128<Byte>* pClsVar1 = &_clsVar1)
fixed (Vector64<Byte>* pClsVar2 = &_clsVar2)
{
var result = AdvSimd.VectorTableLookup(
AdvSimd.LoadVector128((Byte*)(pClsVar1)),
AdvSimd.LoadVector64((Byte*)(pClsVar2))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
}
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
var op1 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
var op2 = Unsafe.Read<Vector64<Byte>>(_dataTable.inArray2Ptr);
var result = AdvSimd.VectorTableLookup(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
var op1 = AdvSimd.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
var op2 = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray2Ptr));
var result = AdvSimd.VectorTableLookup(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleBinaryOpTest__VectorTableLookup_Vector64_Byte();
var result = AdvSimd.VectorTableLookup(test._fld1, test._fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
var test = new SimpleBinaryOpTest__VectorTableLookup_Vector64_Byte();
fixed (Vector128<Byte>* pFld1 = &test._fld1)
fixed (Vector64<Byte>* pFld2 = &test._fld2)
{
var result = AdvSimd.VectorTableLookup(
AdvSimd.LoadVector128((Byte*)(pFld1)),
AdvSimd.LoadVector64((Byte*)(pFld2))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
var result = AdvSimd.VectorTableLookup(_fld1, _fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
}
public void RunClassFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
fixed (Vector128<Byte>* pFld1 = &_fld1)
fixed (Vector64<Byte>* pFld2 = &_fld2)
{
var result = AdvSimd.VectorTableLookup(
AdvSimd.LoadVector128((Byte*)(pFld1)),
AdvSimd.LoadVector64((Byte*)(pFld2))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
}
}
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
var result = AdvSimd.VectorTableLookup(test._fld1, test._fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
public void RunStructLclFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
var test = TestStruct.Create();
var result = AdvSimd.VectorTableLookup(
AdvSimd.LoadVector128((Byte*)(&test._fld1)),
AdvSimd.LoadVector64((Byte*)(&test._fld2))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
var test = TestStruct.Create();
test.RunStructFldScenario(this);
}
public void RunStructFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
var test = TestStruct.Create();
test.RunStructFldScenario_Load(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(Vector128<Byte> op1, Vector64<Byte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector64<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector64<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector64<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
private void ValidateResult(Byte[] left, Byte[] right, Byte[] result, [CallerMemberName] string method = "")
{
bool succeeded = true;
if (Helpers.TableVectorLookup(0, right, left) != result[0])
{
succeeded = false;
}
else
{
for (var i = 1; i < RetElementCount; i++)
{
if (Helpers.TableVectorLookup(i, right, left) != result[i])
{
succeeded = false;
break;
}
}
}
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.VectorTableLookup)}<Byte>(Vector128<Byte>, Vector64<Byte>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
}
}
}
}

View file

@ -0,0 +1,537 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
/******************************************************************************
* This file is auto-generated from a template file by the GenerateTests.csx *
* script in tests\src\JIT\HardwareIntrinsics.Arm\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.Arm;
namespace JIT.HardwareIntrinsics.Arm
{
public static partial class Program
{
private static void VectorTableLookup_Vector64_SByte()
{
var test = new SimpleBinaryOpTest__VectorTableLookup_Vector64_SByte();
if (test.IsSupported)
{
// Validates basic functionality works, using Unsafe.Read
test.RunBasicScenario_UnsafeRead();
if (AdvSimd.IsSupported)
{
// Validates basic functionality works, using Load
test.RunBasicScenario_Load();
}
// Validates calling via reflection works, using Unsafe.Read
test.RunReflectionScenario_UnsafeRead();
if (AdvSimd.IsSupported)
{
// Validates calling via reflection works, using Load
test.RunReflectionScenario_Load();
}
// Validates passing a static member works
test.RunClsVarScenario();
if (AdvSimd.IsSupported)
{
// Validates passing a static member works, using pinning and Load
test.RunClsVarScenario_Load();
}
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
if (AdvSimd.IsSupported)
{
// Validates passing a local works, using Load
test.RunLclVarScenario_Load();
}
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing the field of a local class works, using pinning and Load
test.RunClassLclFldScenario_Load();
}
// Validates passing an instance member of a class works
test.RunClassFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing an instance member of a class works, using pinning and Load
test.RunClassFldScenario_Load();
}
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing the field of a local struct works, using pinning and Load
test.RunStructLclFldScenario_Load();
}
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing an instance member of a struct works, using pinning and Load
test.RunStructFldScenario_Load();
}
}
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 SimpleBinaryOpTest__VectorTableLookup_Vector64_SByte
{
private struct DataTable
{
private byte[] inArray1;
private byte[] inArray2;
private byte[] outArray;
private GCHandle inHandle1;
private GCHandle inHandle2;
private GCHandle outHandle;
private ulong alignment;
public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
{
int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
{
throw new ArgumentException("Invalid value of alignment");
}
this.inArray1 = new byte[alignment * 2];
this.inArray2 = new byte[alignment * 2];
this.outArray = new byte[alignment * 2];
this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
this.alignment = (ulong)alignment;
Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
}
public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
public void Dispose()
{
inHandle1.Free();
inHandle2.Free();
outHandle.Free();
}
private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
{
return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
}
}
private struct TestStruct
{
public Vector128<SByte> _fld1;
public Vector64<SByte> _fld2;
public static TestStruct Create()
{
var testStruct = new TestStruct();
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref testStruct._fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (SByte)(TestLibrary.Generator.GetSByte() % 20); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector64<SByte>, byte>(ref testStruct._fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector64<SByte>>());
return testStruct;
}
public void RunStructFldScenario(SimpleBinaryOpTest__VectorTableLookup_Vector64_SByte testClass)
{
var result = AdvSimd.VectorTableLookup(_fld1, _fld2);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
}
public void RunStructFldScenario_Load(SimpleBinaryOpTest__VectorTableLookup_Vector64_SByte testClass)
{
fixed (Vector128<SByte>* pFld1 = &_fld1)
fixed (Vector64<SByte>* pFld2 = &_fld2)
{
var result = AdvSimd.VectorTableLookup(
AdvSimd.LoadVector128((SByte*)(pFld1)),
AdvSimd.LoadVector64((SByte*)(pFld2))
);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
}
}
}
private static readonly int LargestVectorSize = 16;
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<SByte>>() / sizeof(SByte);
private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector64<SByte>>() / sizeof(SByte);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector64<SByte>>() / sizeof(SByte);
private static SByte[] _data1 = new SByte[Op1ElementCount];
private static SByte[] _data2 = new SByte[Op2ElementCount];
private static Vector128<SByte> _clsVar1;
private static Vector64<SByte> _clsVar2;
private Vector128<SByte> _fld1;
private Vector64<SByte> _fld2;
private DataTable _dataTable;
static SimpleBinaryOpTest__VectorTableLookup_Vector64_SByte()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (SByte)(TestLibrary.Generator.GetSByte() % 20); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector64<SByte>, byte>(ref _clsVar2), ref Unsafe.As<SByte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector64<SByte>>());
}
public SimpleBinaryOpTest__VectorTableLookup_Vector64_SByte()
{
Succeeded = true;
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (SByte)(TestLibrary.Generator.GetSByte() % 20); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector64<SByte>, byte>(ref _fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector64<SByte>>());
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (SByte)(TestLibrary.Generator.GetSByte() % 20); }
_dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => AdvSimd.IsSupported;
public bool Succeeded { get; set; }
public void RunBasicScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = AdvSimd.VectorTableLookup(
Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector64<SByte>>(_dataTable.inArray2Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = AdvSimd.VectorTableLookup(
AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.VectorTableLookup), new Type[] { typeof(Vector128<SByte>), typeof(Vector64<SByte>) })
.Invoke(null, new object[] {
Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector64<SByte>>(_dataTable.inArray2Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector64<SByte>)(result));
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.VectorTableLookup), new Type[] { typeof(Vector128<SByte>), typeof(Vector64<SByte>) })
.Invoke(null, new object[] {
AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector64<SByte>)(result));
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = AdvSimd.VectorTableLookup(
_clsVar1,
_clsVar2
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
}
public void RunClsVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
fixed (Vector128<SByte>* pClsVar1 = &_clsVar1)
fixed (Vector64<SByte>* pClsVar2 = &_clsVar2)
{
var result = AdvSimd.VectorTableLookup(
AdvSimd.LoadVector128((SByte*)(pClsVar1)),
AdvSimd.LoadVector64((SByte*)(pClsVar2))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
}
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
var op1 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
var op2 = Unsafe.Read<Vector64<SByte>>(_dataTable.inArray2Ptr);
var result = AdvSimd.VectorTableLookup(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
var op1 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
var op2 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray2Ptr));
var result = AdvSimd.VectorTableLookup(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleBinaryOpTest__VectorTableLookup_Vector64_SByte();
var result = AdvSimd.VectorTableLookup(test._fld1, test._fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
var test = new SimpleBinaryOpTest__VectorTableLookup_Vector64_SByte();
fixed (Vector128<SByte>* pFld1 = &test._fld1)
fixed (Vector64<SByte>* pFld2 = &test._fld2)
{
var result = AdvSimd.VectorTableLookup(
AdvSimd.LoadVector128((SByte*)(pFld1)),
AdvSimd.LoadVector64((SByte*)(pFld2))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
var result = AdvSimd.VectorTableLookup(_fld1, _fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
}
public void RunClassFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
fixed (Vector128<SByte>* pFld1 = &_fld1)
fixed (Vector64<SByte>* pFld2 = &_fld2)
{
var result = AdvSimd.VectorTableLookup(
AdvSimd.LoadVector128((SByte*)(pFld1)),
AdvSimd.LoadVector64((SByte*)(pFld2))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
}
}
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
var result = AdvSimd.VectorTableLookup(test._fld1, test._fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
public void RunStructLclFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
var test = TestStruct.Create();
var result = AdvSimd.VectorTableLookup(
AdvSimd.LoadVector128((SByte*)(&test._fld1)),
AdvSimd.LoadVector64((SByte*)(&test._fld2))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
var test = TestStruct.Create();
test.RunStructFldScenario(this);
}
public void RunStructFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
var test = TestStruct.Create();
test.RunStructFldScenario_Load(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(Vector128<SByte> op1, Vector64<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector64<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector64<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector64<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
private void ValidateResult(SByte[] left, SByte[] right, SByte[] result, [CallerMemberName] string method = "")
{
bool succeeded = true;
if (Helpers.TableVectorLookup(0, right, left) != result[0])
{
succeeded = false;
}
else
{
for (var i = 1; i < RetElementCount; i++)
{
if (Helpers.TableVectorLookup(i, right, left) != result[i])
{
succeeded = false;
break;
}
}
}
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.VectorTableLookup)}<SByte>(Vector128<SByte>, Vector64<SByte>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
}
}
}
}

View file

@ -0,0 +1,571 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
/******************************************************************************
* This file is auto-generated from a template file by the GenerateTests.csx *
* script in tests\src\JIT\HardwareIntrinsics.Arm\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.Arm;
namespace JIT.HardwareIntrinsics.Arm
{
public static partial class Program
{
private static void VectorTableLookupExtension_Vector64_Byte()
{
var test = new SimpleTernaryOpTest__VectorTableLookupExtension_Vector64_Byte();
if (test.IsSupported)
{
// Validates basic functionality works, using Unsafe.Read
test.RunBasicScenario_UnsafeRead();
if (AdvSimd.IsSupported)
{
// Validates basic functionality works, using Load
test.RunBasicScenario_Load();
}
// Validates calling via reflection works, using Unsafe.Read
test.RunReflectionScenario_UnsafeRead();
if (AdvSimd.IsSupported)
{
// Validates calling via reflection works, using Load
test.RunReflectionScenario_Load();
}
// Validates passing a static member works
test.RunClsVarScenario();
if (AdvSimd.IsSupported)
{
// Validates passing a static member works, using pinning and Load
test.RunClsVarScenario_Load();
}
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
if (AdvSimd.IsSupported)
{
// Validates passing a local works, using Load
test.RunLclVarScenario_Load();
}
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing the field of a local class works, using pinning and Load
test.RunClassLclFldScenario_Load();
}
// Validates passing an instance member of a class works
test.RunClassFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing an instance member of a class works, using pinning and Load
test.RunClassFldScenario_Load();
}
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing the field of a local struct works, using pinning and Load
test.RunStructLclFldScenario_Load();
}
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing an instance member of a struct works, using pinning and Load
test.RunStructFldScenario_Load();
}
}
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 SimpleTernaryOpTest__VectorTableLookupExtension_Vector64_Byte
{
private struct DataTable
{
private byte[] inArray1;
private byte[] inArray2;
private byte[] inArray3;
private byte[] outArray;
private GCHandle inHandle1;
private GCHandle inHandle2;
private GCHandle inHandle3;
private GCHandle outHandle;
private ulong alignment;
public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] inArray3, Byte[] outArray, int alignment)
{
int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Byte>();
int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
{
throw new ArgumentException("Invalid value of alignment");
}
this.inArray1 = new byte[alignment * 2];
this.inArray2 = new byte[alignment * 2];
this.inArray3 = new byte[alignment * 2];
this.outArray = new byte[alignment * 2];
this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
this.alignment = (ulong)alignment;
Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Byte, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
}
public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
public void Dispose()
{
inHandle1.Free();
inHandle2.Free();
inHandle3.Free();
outHandle.Free();
}
private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
{
return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
}
}
private struct TestStruct
{
public Vector64<Byte> _fld1;
public Vector128<Byte> _fld2;
public Vector64<Byte> _fld3;
public static TestStruct Create()
{
var testStruct = new TestStruct();
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector64<Byte>, byte>(ref testStruct._fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector64<Byte>>());
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref testStruct._fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (Byte)(TestLibrary.Generator.GetByte() % 20); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector64<Byte>, byte>(ref testStruct._fld3), ref Unsafe.As<Byte, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector64<Byte>>());
return testStruct;
}
public void RunStructFldScenario(SimpleTernaryOpTest__VectorTableLookupExtension_Vector64_Byte testClass)
{
var result = AdvSimd.VectorTableLookupExtension(_fld1, _fld2, _fld3);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
public void RunStructFldScenario_Load(SimpleTernaryOpTest__VectorTableLookupExtension_Vector64_Byte testClass)
{
fixed (Vector64<Byte>* pFld1 = &_fld1)
fixed (Vector128<Byte>* pFld2 = &_fld2)
fixed (Vector64<Byte>* pFld3 = &_fld3)
{
var result = AdvSimd.VectorTableLookupExtension(
AdvSimd.LoadVector64((Byte*)(pFld1)),
AdvSimd.LoadVector128((Byte*)(pFld2)),
AdvSimd.LoadVector64((Byte*)(pFld3))
);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
}
}
private static readonly int LargestVectorSize = 16;
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector64<Byte>>() / sizeof(Byte);
private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<Byte>>() / sizeof(Byte);
private static readonly int Op3ElementCount = Unsafe.SizeOf<Vector64<Byte>>() / sizeof(Byte);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector64<Byte>>() / sizeof(Byte);
private static Byte[] _data1 = new Byte[Op1ElementCount];
private static Byte[] _data2 = new Byte[Op2ElementCount];
private static Byte[] _data3 = new Byte[Op3ElementCount];
private static Vector64<Byte> _clsVar1;
private static Vector128<Byte> _clsVar2;
private static Vector64<Byte> _clsVar3;
private Vector64<Byte> _fld1;
private Vector128<Byte> _fld2;
private Vector64<Byte> _fld3;
private DataTable _dataTable;
static SimpleTernaryOpTest__VectorTableLookupExtension_Vector64_Byte()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector64<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector64<Byte>>());
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (Byte)(TestLibrary.Generator.GetByte() % 20); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector64<Byte>, byte>(ref _clsVar3), ref Unsafe.As<Byte, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector64<Byte>>());
}
public SimpleTernaryOpTest__VectorTableLookupExtension_Vector64_Byte()
{
Succeeded = true;
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector64<Byte>, byte>(ref _fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector64<Byte>>());
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (Byte)(TestLibrary.Generator.GetByte() % 20); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector64<Byte>, byte>(ref _fld3), ref Unsafe.As<Byte, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector64<Byte>>());
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (Byte)(TestLibrary.Generator.GetByte() % 20); }
_dataTable = new DataTable(_data1, _data2, _data3, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => AdvSimd.IsSupported;
public bool Succeeded { get; set; }
public void RunBasicScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = AdvSimd.VectorTableLookupExtension(
Unsafe.Read<Vector64<Byte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr),
Unsafe.Read<Vector64<Byte>>(_dataTable.inArray3Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = AdvSimd.VectorTableLookupExtension(
AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)),
AdvSimd.LoadVector128((Byte*)(_dataTable.inArray2Ptr)),
AdvSimd.LoadVector64((Byte*)(_dataTable.inArray3Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.VectorTableLookupExtension), new Type[] { typeof(Vector64<Byte>), typeof(Vector128<Byte>), typeof(Vector64<Byte>) })
.Invoke(null, new object[] {
Unsafe.Read<Vector64<Byte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr),
Unsafe.Read<Vector64<Byte>>(_dataTable.inArray3Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector64<Byte>)(result));
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.VectorTableLookupExtension), new Type[] { typeof(Vector64<Byte>), typeof(Vector128<Byte>), typeof(Vector64<Byte>) })
.Invoke(null, new object[] {
AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr)),
AdvSimd.LoadVector128((Byte*)(_dataTable.inArray2Ptr)),
AdvSimd.LoadVector64((Byte*)(_dataTable.inArray3Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector64<Byte>)(result));
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = AdvSimd.VectorTableLookupExtension(
_clsVar1,
_clsVar2,
_clsVar3
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
public void RunClsVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
fixed (Vector64<Byte>* pClsVar1 = &_clsVar1)
fixed (Vector128<Byte>* pClsVar2 = &_clsVar2)
fixed (Vector64<Byte>* pClsVar3 = &_clsVar3)
{
var result = AdvSimd.VectorTableLookupExtension(
AdvSimd.LoadVector64((Byte*)(pClsVar1)),
AdvSimd.LoadVector128((Byte*)(pClsVar2)),
AdvSimd.LoadVector64((Byte*)(pClsVar3))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
var op1 = Unsafe.Read<Vector64<Byte>>(_dataTable.inArray1Ptr);
var op2 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
var op3 = Unsafe.Read<Vector64<Byte>>(_dataTable.inArray3Ptr);
var result = AdvSimd.VectorTableLookupExtension(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
var op1 = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray1Ptr));
var op2 = AdvSimd.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
var op3 = AdvSimd.LoadVector64((Byte*)(_dataTable.inArray3Ptr));
var result = AdvSimd.VectorTableLookupExtension(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleTernaryOpTest__VectorTableLookupExtension_Vector64_Byte();
var result = AdvSimd.VectorTableLookupExtension(test._fld1, test._fld2, test._fld3);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
var test = new SimpleTernaryOpTest__VectorTableLookupExtension_Vector64_Byte();
fixed (Vector64<Byte>* pFld1 = &test._fld1)
fixed (Vector128<Byte>* pFld2 = &test._fld2)
fixed (Vector64<Byte>* pFld3 = &test._fld3)
{
var result = AdvSimd.VectorTableLookupExtension(
AdvSimd.LoadVector64((Byte*)(pFld1)),
AdvSimd.LoadVector128((Byte*)(pFld2)),
AdvSimd.LoadVector64((Byte*)(pFld3))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
var result = AdvSimd.VectorTableLookupExtension(_fld1, _fld2, _fld3);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
public void RunClassFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
fixed (Vector64<Byte>* pFld1 = &_fld1)
fixed (Vector128<Byte>* pFld2 = &_fld2)
fixed (Vector64<Byte>* pFld3 = &_fld3)
{
var result = AdvSimd.VectorTableLookupExtension(
AdvSimd.LoadVector64((Byte*)(pFld1)),
AdvSimd.LoadVector128((Byte*)(pFld2)),
AdvSimd.LoadVector64((Byte*)(pFld3))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
}
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
var result = AdvSimd.VectorTableLookupExtension(test._fld1, test._fld2, test._fld3);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
public void RunStructLclFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
var test = TestStruct.Create();
var result = AdvSimd.VectorTableLookupExtension(
AdvSimd.LoadVector64((Byte*)(&test._fld1)),
AdvSimd.LoadVector128((Byte*)(&test._fld2)),
AdvSimd.LoadVector64((Byte*)(&test._fld3))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
var test = TestStruct.Create();
test.RunStructFldScenario(this);
}
public void RunStructFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
var test = TestStruct.Create();
test.RunStructFldScenario_Load(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(Vector64<Byte> op1, Vector128<Byte> op2, Vector64<Byte> op3, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] inArray3 = new Byte[Op3ElementCount];
Byte[] outArray = new Byte[RetElementCount];
Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector64<Byte>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] inArray3 = new Byte[Op3ElementCount];
Byte[] outArray = new Byte[RetElementCount];
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector64<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector64<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector64<Byte>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
private void ValidateResult(Byte[] firstOp, Byte[] secondOp, Byte[] thirdOp, Byte[] result, [CallerMemberName] string method = "")
{
bool succeeded = true;
for (var i = 0; i < RetElementCount; i++)
{
if (Helpers.TableVectorExtension(i, firstOp, thirdOp, secondOp) != result[i])
{
succeeded = false;
break;
}
}
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.VectorTableLookupExtension)}<Byte>(Vector64<Byte>, Vector128<Byte>, Vector64<Byte>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
}
}
}
}

View file

@ -0,0 +1,571 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
/******************************************************************************
* This file is auto-generated from a template file by the GenerateTests.csx *
* script in tests\src\JIT\HardwareIntrinsics.Arm\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.Arm;
namespace JIT.HardwareIntrinsics.Arm
{
public static partial class Program
{
private static void VectorTableLookupExtension_Vector64_SByte()
{
var test = new SimpleTernaryOpTest__VectorTableLookupExtension_Vector64_SByte();
if (test.IsSupported)
{
// Validates basic functionality works, using Unsafe.Read
test.RunBasicScenario_UnsafeRead();
if (AdvSimd.IsSupported)
{
// Validates basic functionality works, using Load
test.RunBasicScenario_Load();
}
// Validates calling via reflection works, using Unsafe.Read
test.RunReflectionScenario_UnsafeRead();
if (AdvSimd.IsSupported)
{
// Validates calling via reflection works, using Load
test.RunReflectionScenario_Load();
}
// Validates passing a static member works
test.RunClsVarScenario();
if (AdvSimd.IsSupported)
{
// Validates passing a static member works, using pinning and Load
test.RunClsVarScenario_Load();
}
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
if (AdvSimd.IsSupported)
{
// Validates passing a local works, using Load
test.RunLclVarScenario_Load();
}
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing the field of a local class works, using pinning and Load
test.RunClassLclFldScenario_Load();
}
// Validates passing an instance member of a class works
test.RunClassFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing an instance member of a class works, using pinning and Load
test.RunClassFldScenario_Load();
}
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing the field of a local struct works, using pinning and Load
test.RunStructLclFldScenario_Load();
}
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
if (AdvSimd.IsSupported)
{
// Validates passing an instance member of a struct works, using pinning and Load
test.RunStructFldScenario_Load();
}
}
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 SimpleTernaryOpTest__VectorTableLookupExtension_Vector64_SByte
{
private struct DataTable
{
private byte[] inArray1;
private byte[] inArray2;
private byte[] inArray3;
private byte[] outArray;
private GCHandle inHandle1;
private GCHandle inHandle2;
private GCHandle inHandle3;
private GCHandle outHandle;
private ulong alignment;
public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] inArray3, SByte[] outArray, int alignment)
{
int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<SByte>();
int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
if ((alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
{
throw new ArgumentException("Invalid value of alignment");
}
this.inArray1 = new byte[alignment * 2];
this.inArray2 = new byte[alignment * 2];
this.inArray3 = new byte[alignment * 2];
this.outArray = new byte[alignment * 2];
this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
this.alignment = (ulong)alignment;
Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<SByte, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
}
public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
public void Dispose()
{
inHandle1.Free();
inHandle2.Free();
inHandle3.Free();
outHandle.Free();
}
private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
{
return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
}
}
private struct TestStruct
{
public Vector64<SByte> _fld1;
public Vector128<SByte> _fld2;
public Vector64<SByte> _fld3;
public static TestStruct Create()
{
var testStruct = new TestStruct();
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector64<SByte>, byte>(ref testStruct._fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector64<SByte>>());
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref testStruct._fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (SByte)(TestLibrary.Generator.GetSByte() % 20); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector64<SByte>, byte>(ref testStruct._fld3), ref Unsafe.As<SByte, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector64<SByte>>());
return testStruct;
}
public void RunStructFldScenario(SimpleTernaryOpTest__VectorTableLookupExtension_Vector64_SByte testClass)
{
var result = AdvSimd.VectorTableLookupExtension(_fld1, _fld2, _fld3);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
public void RunStructFldScenario_Load(SimpleTernaryOpTest__VectorTableLookupExtension_Vector64_SByte testClass)
{
fixed (Vector64<SByte>* pFld1 = &_fld1)
fixed (Vector128<SByte>* pFld2 = &_fld2)
fixed (Vector64<SByte>* pFld3 = &_fld3)
{
var result = AdvSimd.VectorTableLookupExtension(
AdvSimd.LoadVector64((SByte*)(pFld1)),
AdvSimd.LoadVector128((SByte*)(pFld2)),
AdvSimd.LoadVector64((SByte*)(pFld3))
);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
}
}
private static readonly int LargestVectorSize = 16;
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector64<SByte>>() / sizeof(SByte);
private static readonly int Op2ElementCount = Unsafe.SizeOf<Vector128<SByte>>() / sizeof(SByte);
private static readonly int Op3ElementCount = Unsafe.SizeOf<Vector64<SByte>>() / sizeof(SByte);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector64<SByte>>() / sizeof(SByte);
private static SByte[] _data1 = new SByte[Op1ElementCount];
private static SByte[] _data2 = new SByte[Op2ElementCount];
private static SByte[] _data3 = new SByte[Op3ElementCount];
private static Vector64<SByte> _clsVar1;
private static Vector128<SByte> _clsVar2;
private static Vector64<SByte> _clsVar3;
private Vector64<SByte> _fld1;
private Vector128<SByte> _fld2;
private Vector64<SByte> _fld3;
private DataTable _dataTable;
static SimpleTernaryOpTest__VectorTableLookupExtension_Vector64_SByte()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector64<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector64<SByte>>());
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar2), ref Unsafe.As<SByte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (SByte)(TestLibrary.Generator.GetSByte() % 20); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector64<SByte>, byte>(ref _clsVar3), ref Unsafe.As<SByte, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector64<SByte>>());
}
public SimpleTernaryOpTest__VectorTableLookupExtension_Vector64_SByte()
{
Succeeded = true;
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector64<SByte>, byte>(ref _fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector64<SByte>>());
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (SByte)(TestLibrary.Generator.GetSByte() % 20); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector64<SByte>, byte>(ref _fld3), ref Unsafe.As<SByte, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector64<SByte>>());
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (SByte)(TestLibrary.Generator.GetSByte() % 20); }
_dataTable = new DataTable(_data1, _data2, _data3, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => AdvSimd.IsSupported;
public bool Succeeded { get; set; }
public void RunBasicScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = AdvSimd.VectorTableLookupExtension(
Unsafe.Read<Vector64<SByte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr),
Unsafe.Read<Vector64<SByte>>(_dataTable.inArray3Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = AdvSimd.VectorTableLookupExtension(
AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)),
AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)),
AdvSimd.LoadVector64((SByte*)(_dataTable.inArray3Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.VectorTableLookupExtension), new Type[] { typeof(Vector64<SByte>), typeof(Vector128<SByte>), typeof(Vector64<SByte>) })
.Invoke(null, new object[] {
Unsafe.Read<Vector64<SByte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr),
Unsafe.Read<Vector64<SByte>>(_dataTable.inArray3Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector64<SByte>)(result));
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
var result = typeof(AdvSimd).GetMethod(nameof(AdvSimd.VectorTableLookupExtension), new Type[] { typeof(Vector64<SByte>), typeof(Vector128<SByte>), typeof(Vector64<SByte>) })
.Invoke(null, new object[] {
AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr)),
AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr)),
AdvSimd.LoadVector64((SByte*)(_dataTable.inArray3Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector64<SByte>)(result));
ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = AdvSimd.VectorTableLookupExtension(
_clsVar1,
_clsVar2,
_clsVar3
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
public void RunClsVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
fixed (Vector64<SByte>* pClsVar1 = &_clsVar1)
fixed (Vector128<SByte>* pClsVar2 = &_clsVar2)
fixed (Vector64<SByte>* pClsVar3 = &_clsVar3)
{
var result = AdvSimd.VectorTableLookupExtension(
AdvSimd.LoadVector64((SByte*)(pClsVar1)),
AdvSimd.LoadVector128((SByte*)(pClsVar2)),
AdvSimd.LoadVector64((SByte*)(pClsVar3))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
var op1 = Unsafe.Read<Vector64<SByte>>(_dataTable.inArray1Ptr);
var op2 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
var op3 = Unsafe.Read<Vector64<SByte>>(_dataTable.inArray3Ptr);
var result = AdvSimd.VectorTableLookupExtension(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
var op1 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray1Ptr));
var op2 = AdvSimd.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
var op3 = AdvSimd.LoadVector64((SByte*)(_dataTable.inArray3Ptr));
var result = AdvSimd.VectorTableLookupExtension(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleTernaryOpTest__VectorTableLookupExtension_Vector64_SByte();
var result = AdvSimd.VectorTableLookupExtension(test._fld1, test._fld2, test._fld3);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
var test = new SimpleTernaryOpTest__VectorTableLookupExtension_Vector64_SByte();
fixed (Vector64<SByte>* pFld1 = &test._fld1)
fixed (Vector128<SByte>* pFld2 = &test._fld2)
fixed (Vector64<SByte>* pFld3 = &test._fld3)
{
var result = AdvSimd.VectorTableLookupExtension(
AdvSimd.LoadVector64((SByte*)(pFld1)),
AdvSimd.LoadVector128((SByte*)(pFld2)),
AdvSimd.LoadVector64((SByte*)(pFld3))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
var result = AdvSimd.VectorTableLookupExtension(_fld1, _fld2, _fld3);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
public void RunClassFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
fixed (Vector64<SByte>* pFld1 = &_fld1)
fixed (Vector128<SByte>* pFld2 = &_fld2)
fixed (Vector64<SByte>* pFld3 = &_fld3)
{
var result = AdvSimd.VectorTableLookupExtension(
AdvSimd.LoadVector64((SByte*)(pFld1)),
AdvSimd.LoadVector128((SByte*)(pFld2)),
AdvSimd.LoadVector64((SByte*)(pFld3))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
}
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
var result = AdvSimd.VectorTableLookupExtension(test._fld1, test._fld2, test._fld3);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
public void RunStructLclFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
var test = TestStruct.Create();
var result = AdvSimd.VectorTableLookupExtension(
AdvSimd.LoadVector64((SByte*)(&test._fld1)),
AdvSimd.LoadVector128((SByte*)(&test._fld2)),
AdvSimd.LoadVector64((SByte*)(&test._fld3))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
var test = TestStruct.Create();
test.RunStructFldScenario(this);
}
public void RunStructFldScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
var test = TestStruct.Create();
test.RunStructFldScenario_Load(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(Vector64<SByte> op1, Vector128<SByte> op2, Vector64<SByte> op3, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] inArray3 = new SByte[Op3ElementCount];
SByte[] outArray = new SByte[RetElementCount];
Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector64<SByte>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] inArray3 = new SByte[Op3ElementCount];
SByte[] outArray = new SByte[RetElementCount];
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector64<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector64<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector64<SByte>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
private void ValidateResult(SByte[] firstOp, SByte[] secondOp, SByte[] thirdOp, SByte[] result, [CallerMemberName] string method = "")
{
bool succeeded = true;
for (var i = 0; i < RetElementCount; i++)
{
if (Helpers.TableVectorExtension(i, firstOp, thirdOp, secondOp) != result[i])
{
succeeded = false;
break;
}
}
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(AdvSimd)}.{nameof(AdvSimd.VectorTableLookupExtension)}<SByte>(Vector64<SByte>, Vector128<SByte>, Vector64<SByte>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
}
}
}
}

View file

@ -654,6 +654,10 @@ private static readonly (string templateFileName, Dictionary<string, string> tem
("SimpleBinOpTest.template", new Dictionary<string, string> { ["TestName"] = "SubtractScalar_Vector64_Int64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateFirstResult"] = "Helpers.Subtract(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}),
("SimpleBinOpTest.template", new Dictionary<string, string> { ["TestName"] = "SubtractScalar_Vector64_Single", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(Helpers.Subtract(left[0], right[0])) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(result[i]) != 0"}),
("SimpleBinOpTest.template", new Dictionary<string, string> { ["TestName"] = "SubtractScalar_Vector64_UInt64", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "SubtractScalar", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateFirstResult"] = "Helpers.Subtract(left[0], right[0]) != result[0]", ["ValidateRemainingResults"] = "result[i] != 0"}),
("SimpleBinOpTest.template", new Dictionary<string, string> { ["TestName"] = "VectorTableLookup_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 20)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, right, left) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, right, left) != result[i]"}),
("SimpleBinOpTest.template", new Dictionary<string, string> { ["TestName"] = "VectorTableLookup_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 20)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, right, left) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, right, left) != result[i]"}),
("VecTernOpTest.template", new Dictionary<string, string> { ["TestName"] = "VectorTableLookupExtension_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "(Byte)(TestLibrary.Generator.GetByte() % 20)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, firstOp, thirdOp, secondOp) != result[i]"}),
("VecTernOpTest.template", new Dictionary<string, string> { ["TestName"] = "VectorTableLookupExtension_Vector64_SByte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector64", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "(SByte)(TestLibrary.Generator.GetSByte() % 20)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, firstOp, thirdOp, secondOp) != result[i]"}),
("VecBinOpTest.template", new Dictionary<string, string> { ["TestName"] = "Xor_Vector64_Byte", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}),
("VecBinOpTest.template", new Dictionary<string, string> { ["TestName"] = "Xor_Vector64_Double", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Double", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Double", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Double", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetDouble()", ["NextValueOp2"] = "TestLibrary.Generator.GetDouble()", ["ValidateIterResult"] = "BitConverter.DoubleToInt64Bits(Helpers.Xor(left[i], right[i])) != BitConverter.DoubleToInt64Bits(result[i])"}),
("VecBinOpTest.template", new Dictionary<string, string> { ["TestName"] = "Xor_Vector64_Int16", ["Isa"] = "AdvSimd", ["LoadIsa"] = "AdvSimd", ["Method"] = "Xor", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.Xor(left[i], right[i]) != result[i]"}),
@ -894,6 +898,10 @@ private static readonly (string templateFileName, Dictionary<string, string> tem
("VecPairBinOpTest.template", new Dictionary<string, string> { ["TestName"] = "TransposeOdd_Vector128_UInt16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}),
("VecPairBinOpTest.template", new Dictionary<string, string> { ["TestName"] = "TransposeOdd_Vector128_UInt32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}),
("VecPairBinOpTest.template", new Dictionary<string, string> { ["TestName"] = "TransposeOdd_Vector128_UInt64", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "TransposeOdd", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ValidateEntry"] = "result[index] != left[i+1] || result[++index] != right[i+1]"}),
("SimpleBinOpTest.template", new Dictionary<string, string> { ["TestName"] = "VectorTableLookup_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "(Byte)(TestLibrary.Generator.GetByte() % 20)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, right, left) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, right, left) != result[i]"}),
("SimpleBinOpTest.template", new Dictionary<string, string> { ["TestName"] = "VectorTableLookup_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "(SByte)(TestLibrary.Generator.GetSByte() % 20)", ["ValidateFirstResult"] = "Helpers.TableVectorLookup(0, right, left) != result[0]", ["ValidateRemainingResults"] = "Helpers.TableVectorLookup(i, right, left) != result[i]"}),
("VecTernOpTest.template", new Dictionary<string, string> { ["TestName"] = "VectorTableLookupExtension_Vector128_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "(Byte)(TestLibrary.Generator.GetByte() % 20)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, firstOp, thirdOp, secondOp) != result[i]"}),
("VecTernOpTest.template", new Dictionary<string, string> { ["TestName"] = "VectorTableLookupExtension_Vector128_SByte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "VectorTableLookupExtension", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector128", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "(SByte)(TestLibrary.Generator.GetSByte() % 20)", ["ValidateIterResult"] = "Helpers.TableVectorExtension(i, firstOp, thirdOp, secondOp) != result[i]"}),
("VecPairBinOpTest.template", new Dictionary<string, string> { ["TestName"] = "UnzipEven_Vector64_Byte", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}),
("VecPairBinOpTest.template", new Dictionary<string, string> { ["TestName"] = "UnzipEven_Vector64_Int16", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}),
("VecPairBinOpTest.template", new Dictionary<string, string> { ["TestName"] = "UnzipEven_Vector64_Int32", ["Isa"] = "AdvSimd.Arm64", ["LoadIsa"] = "AdvSimd", ["Method"] = "UnzipEven", ["RetVectorType"] = "Vector64", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector64", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector64", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "8", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateEntry"] = "result[index] != left[i] || result[index + half] != right[i]"}),

View file

@ -8,6 +8,7 @@
// "%DevEnvDir%\TextTransform.exe" .\Helpers.tt
using System;
using System.Linq;
namespace JIT.HardwareIntrinsics.Arm
{
@ -2391,5 +2392,41 @@ namespace JIT.HardwareIntrinsics.Arm
public static double Insert(double[] op1, int op2, double op3, int i) => (op2 != i) ? op1[i] : op3;
public static sbyte TableVectorExtension(int i, sbyte[] defaultValues, sbyte[] indices, params sbyte[][] table)
{
sbyte[] fullTable = table.SelectMany(x => x).ToArray();
int index = indices[i];
if (index < 0 || index >= fullTable.Length)
return defaultValues[i];
return fullTable[index];
}
public static sbyte TableVectorLookup(int i, sbyte[] indices, params sbyte[][] table)
{
sbyte[] zeros = new sbyte[indices.Length];
Array.Fill<sbyte>(zeros, 0, 0, indices.Length);
return TableVectorExtension(i, zeros, indices, table);
}
public static byte TableVectorExtension(int i, byte[] defaultValues, byte[] indices, params byte[][] table)
{
byte[] fullTable = table.SelectMany(x => x).ToArray();
int index = indices[i];
if (index < 0 || index >= fullTable.Length)
return defaultValues[i];
return fullTable[index];
}
public static byte TableVectorLookup(int i, byte[] indices, params byte[][] table)
{
byte[] zeros = new byte[indices.Length];
Array.Fill<byte>(zeros, 0, 0, indices.Length);
return TableVectorExtension(i, zeros, indices, table);
}
}
}

View file

@ -10,6 +10,7 @@
// "%DevEnvDir%\TextTransform.exe" .\Helpers.tt
using System;
using System.Linq;
namespace JIT.HardwareIntrinsics.Arm
{
@ -605,6 +606,30 @@ namespace JIT.HardwareIntrinsics.Arm
public static <#= typeName #> Insert(<#= typeName #>[] op1, int op2, <#= typeName #> op3, int i) => (op2 != i) ? op1[i] : op3;
<#
}
foreach (string typeName in new string[] { "sbyte", "byte" })
{
#>
public static <#= typeName #> TableVectorExtension(int i, <#= typeName #>[] defaultValues, <#= typeName #>[] indices, params <#= typeName #>[][] table)
{
<#= typeName #>[] fullTable = table.SelectMany(x => x).ToArray();
int index = indices[i];
if (index < 0 || index >= fullTable.Length)
return defaultValues[i];
return fullTable[index];
}
public static <#= typeName #> TableVectorLookup(int i, <#= typeName #>[] indices, params <#= typeName #>[][] table)
{
<#= typeName #>[] zeros = new <#= typeName #>[indices.Length];
Array.Fill<<#= typeName #>>(zeros, 0, 0, indices.Length);
return TableVectorExtension(i, zeros, indices, table);
}
<#
}
#>

View file

@ -1584,6 +1584,29 @@ namespace System.Runtime.Intrinsics.Arm
/// </summary>
public static Vector128<ulong> UnzipOdd(Vector128<ulong> left, Vector128<ulong> right) { throw new PlatformNotSupportedException(); }
/// <summary>
/// uint8x16_t vqvtbl1q_u8(uint8x16_t t, uint8x16_t idx)
/// A64: TBL Vd.16B, {Vn.16B}, Vm.16B
/// </summary>
public static Vector128<byte> VectorTableLookup(Vector128<byte> table, Vector128<byte> byteIndexes) { throw new PlatformNotSupportedException(); }
/// <summary>
/// int8x16_t vqvtbl1q_s8(int8x16_t t, uint8x16_t idx)
/// A64: TBL Vd.16B, {Vn.16B}, Vm.16B
/// </summary>
public static Vector128<sbyte> VectorTableLookup(Vector128<sbyte> table, Vector128<sbyte> byteIndexes) { throw new PlatformNotSupportedException(); }
/// <summary>
/// uint8x16_t vqvtbx1q_u8(uint8x16_t r, int8x16_t t, uint8x16_t idx)
/// A64: TBX Vd.16B, {Vn.16B}, Vm.16B
/// </summary>
public static Vector128<byte> VectorTableLookupExtension(Vector128<byte> defaultValues, Vector128<byte> table, Vector128<byte> byteIndexes) { throw new PlatformNotSupportedException(); }
/// <summary>
/// int8x16_t vqvtbx1q_s8(int8x16_t r, int8x16_t t, uint8x16_t idx)
/// A64: TBX Vd.16B, {Vn.16B}, Vm.16B
/// </summary>
public static Vector128<sbyte> VectorTableLookupExtension(Vector128<sbyte> defaultValues, Vector128<sbyte> table, Vector128<sbyte> byteIndexes) { throw new PlatformNotSupportedException(); }
/// <summary>
/// uint8x8_t vzip2_u8(uint8x8_t a, uint8x8_t b)
/// A64: ZIP2 Vd.8B, Vn.8B, Vm.8B
@ -5681,6 +5704,34 @@ namespace System.Runtime.Intrinsics.Arm
/// </summary>
public static Vector64<float> SubtractScalar(Vector64<float> left, Vector64<float> right) { throw new PlatformNotSupportedException(); }
/// <summary>
/// uint8x8_t vqvtbl1_u8(uint8x16_t t, uint8x8_t idx)
/// A32: VTBL Dd, {Dn, Dn+1}, Dm
/// A64: TBL Vd.8B, {Vn.16B}, Vm.8B
/// </summary>
public static Vector64<byte> VectorTableLookup(Vector128<byte> table, Vector64<byte> byteIndexes) { throw new PlatformNotSupportedException(); }
/// <summary>
/// int8x8_t vqvtbl1_s8(int8x16_t t, uint8x8_t idx)
/// A32: VTBL Dd, {Dn, Dn+1}, Dm
/// A64: TBL Vd.8B, {Vn.16B}, Vm.8B
/// </summary>
public static Vector64<sbyte> VectorTableLookup(Vector128<sbyte> table, Vector64<sbyte> byteIndexes) { throw new PlatformNotSupportedException(); }
/// <summary>
/// uint8x8_t vqvtbx1_u8(uint8x8_t r, uint8x16_t t, uint8x8_t idx)
/// A32: VTBX Dd, {Dn, Dn+1}, Dm
/// A64: TBX Vd.8B, {Vn.16B}, Vm.8B
/// </summary>
public static Vector64<byte> VectorTableLookupExtension(Vector64<byte> defaultValues, Vector128<byte> table, Vector64<byte> byteIndexes) { throw new PlatformNotSupportedException(); }
/// <summary>
/// int8x8_t vqvtbx1_s8(int8x8_t r, int8x16_t t, uint8x8_t idx)
/// A32: VTBX Dd, {Dn, Dn+1}, Dm
/// A64: TBX Vd.8B, {Vn.16B}, Vm.8B
/// </summary>
public static Vector64<sbyte> VectorTableLookupExtension(Vector64<sbyte> defaultValues, Vector128<sbyte> table, Vector64<sbyte> byteIndexes) { throw new PlatformNotSupportedException(); }
/// <summary>
/// uint64x1_t vsub_u64 (uint64x1_t a, uint64x1_t b)
/// A32: VSUB.I64 Dd, Dn, Dm

View file

@ -1586,6 +1586,30 @@ namespace System.Runtime.Intrinsics.Arm
/// </summary>
public static Vector128<ulong> UnzipOdd(Vector128<ulong> left, Vector128<ulong> right) => UnzipOdd(left, right);
/// <summary>
/// uint8x16_t vqvtbl1q_u8(uint8x16_t t, uint8x16_t idx)
/// A64: TBL Vd.16B, {Vn.16B}, Vm.16B
/// </summary>
public static Vector128<byte> VectorTableLookup(Vector128<byte> table, Vector128<byte> byteIndexes) => VectorTableLookup(table, byteIndexes);
/// <summary>
/// int8x16_t vqvtbl1q_s8(int8x16_t t, uint8x16_t idx)
/// A64: TBL Vd.16B, {Vn.16B}, Vm.16B
/// </summary>
public static Vector128<sbyte> VectorTableLookup(Vector128<sbyte> table, Vector128<sbyte> byteIndexes) => VectorTableLookup(table, byteIndexes);
/// <summary>
/// uint8x16_t vqvtbx1q_u8(uint8x16_t r, int8x16_t t, uint8x16_t idx)
/// A64: TBX Vd.16B, {Vn.16B}, Vm.16B
/// </summary>
public static Vector128<byte> VectorTableLookupExtension(Vector128<byte> defaultValues, Vector128<byte> table, Vector128<byte> byteIndexes) => VectorTableLookupExtension(defaultValues, table, byteIndexes);
/// <summary>
/// int8x16_t vqvtbx1q_s8(int8x16_t r, int8x16_t t, uint8x16_t idx)
/// A64: TBX Vd.16B, {Vn.16B}, Vm.16B
/// </summary>
public static Vector128<sbyte> VectorTableLookupExtension(Vector128<sbyte> defaultValues, Vector128<sbyte> table, Vector128<sbyte> byteIndexes) => VectorTableLookupExtension(defaultValues, table, byteIndexes);
/// <summary>
/// uint8x8_t vzip2_u8(uint8x8_t a, uint8x8_t b)
/// A64: ZIP2 Vd.8B, Vn.8B, Vm.8B
@ -5690,6 +5714,34 @@ namespace System.Runtime.Intrinsics.Arm
/// </summary>
public static Vector64<ulong> SubtractScalar(Vector64<ulong> left, Vector64<ulong> right) => SubtractScalar(left, right);
/// <summary>
/// uint8x8_t vqvtbl1_u8(uint8x16_t t, uint8x8_t idx)
/// A32: VTBL Dd, {Dn, Dn+1}, Dm
/// A64: TBL Vd.8B, {Vn.16B}, Vm.8B
/// </summary>
public static Vector64<byte> VectorTableLookup(Vector128<byte> table, Vector64<byte> byteIndexes) => VectorTableLookup(table, byteIndexes);
/// <summary>
/// int8x8_t vqvtbl1_s8(int8x16_t t, uint8x8_t idx)
/// A32: VTBL Dd, {Dn, Dn+1}, Dm
/// A64: TBL Vd.8B, {Vn.16B}, Vm.8B
/// </summary>
public static Vector64<sbyte> VectorTableLookup(Vector128<sbyte> table, Vector64<sbyte> byteIndexes) => VectorTableLookup(table, byteIndexes);
/// <summary>
/// uint8x8_t vqvtbx1_u8(uint8x8_t r, uint8x16_t t, uint8x8_t idx)
/// A32: VTBX Dd, {Dn, Dn+1}, Dm
/// A64: TBX Vd.8B, {Vn.16B}, Vm.8B
/// </summary>
public static Vector64<byte> VectorTableLookupExtension(Vector64<byte> defaultValues, Vector128<byte> table, Vector64<byte> byteIndexes) => VectorTableLookupExtension(defaultValues, table, byteIndexes);
/// <summary>
/// int8x8_t vqvtbx1_s8(int8x8_t r, int8x16_t t, uint8x8_t idx)
/// A32: VTBX Dd, {Dn, Dn+1}, Dm
/// A64: TBX Vd.8B, {Vn.16B}, Vm.8B
/// </summary>
public static Vector64<sbyte> VectorTableLookupExtension(Vector64<sbyte> defaultValues, Vector128<sbyte> table, Vector64<sbyte> byteIndexes) => VectorTableLookupExtension(defaultValues, table, byteIndexes);
/// <summary>
/// uint8x8_t veor_u8 (uint8x8_t a, uint8x8_t b)
/// A32: VEOR Dd, Dn, Dm

View file

@ -564,6 +564,10 @@ namespace System.Runtime.Intrinsics.Arm
public static System.Runtime.Intrinsics.Vector64<long> SubtractScalar(System.Runtime.Intrinsics.Vector64<long> left, System.Runtime.Intrinsics.Vector64<long> right) { throw null; }
public static System.Runtime.Intrinsics.Vector64<float> SubtractScalar(System.Runtime.Intrinsics.Vector64<float> left, System.Runtime.Intrinsics.Vector64<float> right) { throw null; }
public static System.Runtime.Intrinsics.Vector64<ulong> SubtractScalar(System.Runtime.Intrinsics.Vector64<ulong> left, System.Runtime.Intrinsics.Vector64<ulong> right) { throw null; }
public static System.Runtime.Intrinsics.Vector64<byte> VectorTableLookup(System.Runtime.Intrinsics.Vector128<byte> table, System.Runtime.Intrinsics.Vector64<byte> byteIndexes) { throw null; }
public static System.Runtime.Intrinsics.Vector64<sbyte> VectorTableLookup(System.Runtime.Intrinsics.Vector128<sbyte> table, System.Runtime.Intrinsics.Vector64<sbyte> byteIndexes) { throw null; }
public static System.Runtime.Intrinsics.Vector64<byte> VectorTableLookupExtension(System.Runtime.Intrinsics.Vector64<byte> defaultValues, System.Runtime.Intrinsics.Vector128<byte> table, System.Runtime.Intrinsics.Vector64<byte> byteIndexes) { throw null; }
public static System.Runtime.Intrinsics.Vector64<sbyte> VectorTableLookupExtension(System.Runtime.Intrinsics.Vector64<sbyte> defaultValues, System.Runtime.Intrinsics.Vector128<sbyte> table, System.Runtime.Intrinsics.Vector64<sbyte> byteIndexes) { throw null; }
public static System.Runtime.Intrinsics.Vector128<byte> Xor(System.Runtime.Intrinsics.Vector128<byte> left, System.Runtime.Intrinsics.Vector128<byte> right) { throw null; }
public static System.Runtime.Intrinsics.Vector128<double> Xor(System.Runtime.Intrinsics.Vector128<double> left, System.Runtime.Intrinsics.Vector128<double> right) { throw null; }
public static System.Runtime.Intrinsics.Vector128<short> Xor(System.Runtime.Intrinsics.Vector128<short> left, System.Runtime.Intrinsics.Vector128<short> right) { throw null; }
@ -838,6 +842,10 @@ namespace System.Runtime.Intrinsics.Arm
public static System.Runtime.Intrinsics.Vector64<float> UnzipOdd(System.Runtime.Intrinsics.Vector64<float> left, System.Runtime.Intrinsics.Vector64<float> right) { throw null; }
public static System.Runtime.Intrinsics.Vector64<ushort> UnzipOdd(System.Runtime.Intrinsics.Vector64<ushort> left, System.Runtime.Intrinsics.Vector64<ushort> right) { throw null; }
public static System.Runtime.Intrinsics.Vector64<uint> UnzipOdd(System.Runtime.Intrinsics.Vector64<uint> left, System.Runtime.Intrinsics.Vector64<uint> right) { throw null; }
public static System.Runtime.Intrinsics.Vector128<byte> VectorTableLookup(System.Runtime.Intrinsics.Vector128<byte> table, System.Runtime.Intrinsics.Vector128<byte> byteIndexes) { throw null; }
public static System.Runtime.Intrinsics.Vector128<sbyte> VectorTableLookup(System.Runtime.Intrinsics.Vector128<sbyte> table, System.Runtime.Intrinsics.Vector128<sbyte> byteIndexes) { throw null; }
public static System.Runtime.Intrinsics.Vector128<byte> VectorTableLookupExtension(System.Runtime.Intrinsics.Vector128<byte> defaultValues, System.Runtime.Intrinsics.Vector128<byte> table, System.Runtime.Intrinsics.Vector128<byte> byteIndexes) { throw null; }
public static System.Runtime.Intrinsics.Vector128<sbyte> VectorTableLookupExtension(System.Runtime.Intrinsics.Vector128<sbyte> defaultValues, System.Runtime.Intrinsics.Vector128<sbyte> table, System.Runtime.Intrinsics.Vector128<sbyte> byteIndexes) { throw null; }
public static System.Runtime.Intrinsics.Vector128<byte> ZipHigh(System.Runtime.Intrinsics.Vector128<byte> left, System.Runtime.Intrinsics.Vector128<byte> right) { throw null; }
public static System.Runtime.Intrinsics.Vector128<double> ZipHigh(System.Runtime.Intrinsics.Vector128<double> left, System.Runtime.Intrinsics.Vector128<double> right) { throw null; }
public static System.Runtime.Intrinsics.Vector128<short> ZipHigh(System.Runtime.Intrinsics.Vector128<short> left, System.Runtime.Intrinsics.Vector128<short> right) { throw null; }