2023-03-28 13:24:16 -04:00
using System ;
using System.Collections.Generic ;
using System.Diagnostics ;
namespace Unity.Burst.Intrinsics
{
public unsafe static partial class X86
{
/// <summary>
/// SSE 4.2 intrinsics
/// </summary>
public static class Sse4_2
{
/// <summary>
/// Evaluates to true at compile time if SSE 4.2 intrinsics are supported.
/// </summary>
public static bool IsSse42Supported { get { return false ; } }
/// <summary>
/// Constants for string comparison intrinsics
/// </summary>
[Flags]
public enum SIDD
{
/// <summary>
/// Compare 8-bit unsigned characters
/// </summary>
UBYTE_OPS = 0x00 ,
/// <summary>
/// Compare 16-bit unsigned characters
/// </summary>
UWORD_OPS = 0x01 ,
/// <summary>
/// Compare 8-bit signed characters
/// </summary>
SBYTE_OPS = 0x02 ,
/// <summary>
/// Compare 16-bit signed characters
/// </summary>
SWORD_OPS = 0x03 ,
/// <summary>
/// Compare any equal
/// </summary>
CMP_EQUAL_ANY = 0x00 ,
/// <summary>
/// Compare ranges
/// </summary>
CMP_RANGES = 0x04 ,
/// <summary>
/// Compare equal each
/// </summary>
CMP_EQUAL_EACH = 0x08 ,
/// <summary>
/// Compare equal ordered
/// </summary>
CMP_EQUAL_ORDERED = 0x0C ,
/// <summary>
/// Normal result polarity
/// </summary>
POSITIVE_POLARITY = 0x00 ,
/// <summary>
/// Negate results
/// </summary>
NEGATIVE_POLARITY = 0x10 ,
/// <summary>
/// Normal results only before end of string
/// </summary>
MASKED_POSITIVE_POLARITY = 0x20 ,
/// <summary>
/// Negate results only before end of string
/// </summary>
MASKED_NEGATIVE_POLARITY = 0x30 ,
/// <summary>
/// Index only: return least significant bit
/// </summary>
LEAST_SIGNIFICANT = 0x00 ,
/// <summary>
/// Index only: return most significan bit
/// </summary>
MOST_SIGNIFICANT = 0x40 ,
/// <summary>
/// mask only: return bit mask
/// </summary>
BIT_MASK = 0x00 ,
/// <summary>
/// mask only: return byte/word mask
/// </summary>
UNIT_MASK = 0x40 ,
}
/ *
* Intrinsics for text / string processing .
* /
private unsafe struct StrBoolArray
{
public fixed ushort Bits [ 16 ] ;
public void SetBit ( int aindex , int bindex , bool val )
{
fixed ( ushort * b = Bits )
{
if ( val )
b [ aindex ] | = ( ushort ) ( 1 < < bindex ) ;
else
b [ aindex ] & = ( ushort ) ( ~ ( 1 < < bindex ) ) ;
}
}
public bool GetBit ( int aindex , int bindex )
{
fixed ( ushort * b = Bits )
{
return ( b [ aindex ] & ( 1 < < bindex ) ) ! = 0 ;
}
}
}
private static v128 cmpistrm_emulation < T > ( T * a , T * b , int len , int imm8 , int allOnes , T allOnesT ) where T : unmanaged , IComparable < T > , IEquatable < T >
{
int intRes2 = ComputeStrCmpIntRes2 < T > ( a , ComputeStringLength < T > ( a , len ) , b , ComputeStringLength < T > ( b , len ) , len , imm8 , allOnes ) ;
return ComputeStrmOutput ( len , imm8 , allOnesT , intRes2 ) ;
}
private static v128 cmpestrm_emulation < T > ( T * a , int alen , T * b , int blen , int len , int imm8 , int allOnes , T allOnesT ) where T : unmanaged , IComparable < T > , IEquatable < T >
{
int intRes2 = ComputeStrCmpIntRes2 < T > ( a , alen , b , blen , len , imm8 , allOnes ) ;
return ComputeStrmOutput ( len , imm8 , allOnesT , intRes2 ) ;
}
private static v128 ComputeStrmOutput < T > ( int len , int imm8 , T allOnesT , int intRes2 ) where T : unmanaged , IComparable < T > , IEquatable < T >
{
// output
v128 result = default ;
if ( ( imm8 & ( 1 < < 6 ) ) ! = 0 )
{
// byte / word mask
T * maskDst = ( T * ) & result . Byte0 ;
for ( int i = 0 ; i < len ; + + i )
{
if ( ( intRes2 & ( 1 < < i ) ) ! = 0 )
{
maskDst [ i ] = allOnesT ;
}
else
{
maskDst [ i ] = default ( T ) ;
}
}
}
else
{
// bit mask
result . SInt0 = intRes2 ;
}
return result ;
}
private static int cmpistri_emulation < T > ( T * a , T * b , int len , int imm8 , int allOnes , T allOnesT ) where T : unmanaged , IComparable < T > , IEquatable < T >
{
int intRes2 = ComputeStrCmpIntRes2 < T > ( a , ComputeStringLength < T > ( a , len ) , b , ComputeStringLength < T > ( b , len ) , len , imm8 , allOnes ) ;
return ComputeStriOutput ( len , imm8 , intRes2 ) ;
}
private static int cmpestri_emulation < T > ( T * a , int alen , T * b , int blen , int len , int imm8 , int allOnes , T allOnesT ) where T : unmanaged , IComparable < T > , IEquatable < T >
{
int intRes2 = ComputeStrCmpIntRes2 < T > ( a , alen , b , blen , len , imm8 , allOnes ) ;
return ComputeStriOutput ( len , imm8 , intRes2 ) ;
}
private static int ComputeStriOutput ( int len , int imm8 , int intRes2 )
{
// output
if ( ( imm8 & ( 1 < < 6 ) ) = = 0 )
{
int bit = 0 ;
while ( bit < len )
{
if ( ( intRes2 & ( 1 < < bit ) ) ! = 0 )
return bit ;
+ + bit ;
}
}
else
{
int bit = len - 1 ;
while ( bit > = 0 )
{
if ( ( intRes2 & ( 1 < < bit ) ) ! = 0 )
return bit ;
- - bit ;
}
}
return len ;
}
private static int ComputeStringLength < T > ( T * ptr , int max ) where T : unmanaged , IEquatable < T >
{
for ( int i = 0 ; i < max ; + + i )
{
if ( EqualityComparer < T > . Default . Equals ( ptr [ i ] , default ( T ) ) )
{
return i ;
}
}
return max ;
}
private static int ComputeStrCmpIntRes2 < T > ( T * a , int alen , T * b , int blen , int len , int imm8 , int allOnes ) where T : unmanaged , IComparable < T > , IEquatable < T >
{
#if ! NET_DOTS
bool aInvalid = false ;
bool bInvalid = false ;
StrBoolArray boolRes = default ;
int i , j , intRes2 ;
for ( i = 0 ; i < len ; + + i )
{
T aCh = a [ i ] ;
if ( i = = alen )
aInvalid = true ;
bInvalid = false ;
for ( j = 0 ; j < len ; + + j )
{
T bCh = b [ j ] ;
if ( j = = blen )
bInvalid = true ;
bool match ;
// override comparisons for invalid characters
switch ( ( imm8 > > 2 ) & 3 )
{
case 0 : // equal any
match = EqualityComparer < T > . Default . Equals ( aCh , bCh ) ;
if ( ! aInvalid & & bInvalid )
match = false ;
else if ( aInvalid & & ! bInvalid )
match = false ;
else if ( aInvalid & & bInvalid )
match = false ;
break ;
case 1 : // ranges
if ( 0 = = ( i & 1 ) )
match = Comparer < T > . Default . Compare ( bCh , aCh ) > = 0 ;
else
match = Comparer < T > . Default . Compare ( bCh , aCh ) < = 0 ;
if ( ! aInvalid & & bInvalid )
match = false ;
else if ( aInvalid & & ! bInvalid )
match = false ;
else if ( aInvalid & & bInvalid )
match = false ;
break ;
case 2 : // equal each
match = EqualityComparer < T > . Default . Equals ( aCh , bCh ) ;
if ( ! aInvalid & & bInvalid )
match = false ;
else if ( aInvalid & & ! bInvalid )
match = false ;
else if ( aInvalid & & bInvalid )
match = true ;
break ;
default : // equal ordered
match = EqualityComparer < T > . Default . Equals ( aCh , bCh ) ;
if ( ! aInvalid & & bInvalid )
match = false ;
else if ( aInvalid & & ! bInvalid )
match = true ;
else if ( aInvalid & & bInvalid )
match = true ;
break ;
}
boolRes . SetBit ( i , j , match ) ;
}
}
int intRes1 = 0 ;
// aggregate results
switch ( ( imm8 > > 2 ) & 3 )
{
case 0 : // equal any
for ( i = 0 ; i < len ; + + i )
{
for ( j = 0 ; j < len ; + + j )
{
intRes1 | = ( boolRes . GetBit ( j , i ) ? 1 : 0 ) < < i ;
}
}
/ *
for ( i = 0 ; i < len ; + + i )
{
intRes1 | = boolRes . Bits [ i ] ;
} * /
break ;
case 1 : // ranges
for ( i = 0 ; i < len ; + + i )
{
for ( j = 0 ; j < len ; j + = 2 )
{
intRes1 | = ( ( boolRes . GetBit ( j , i ) & & boolRes . GetBit ( j + 1 , i ) ) ? 1 : 0 ) < < i ;
}
}
break ;
case 2 : // equal each
for ( i = 0 ; i < len ; + + i )
{
intRes1 | = ( boolRes . GetBit ( i , i ) ? 1 : 0 ) < < i ;
}
break ;
case 3 : // equal ordered
intRes1 = allOnes ;
for ( i = 0 ; i < len ; + + i )
{
int k = i ;
for ( j = 0 ; j < len - i ; + + j )
{
if ( ! boolRes . GetBit ( j , k ) )
intRes1 & = ~ ( 1 < < i ) ;
k + = 1 ;
}
}
break ;
}
intRes2 = 0 ;
// optionally negate results
bInvalid = false ;
for ( i = 0 ; i < len ; + + i )
{
if ( ( imm8 & ( 1 < < 4 ) ) ! = 0 )
{
if ( ( imm8 & ( 1 < < 5 ) ) ! = 0 ) // only negate valid
{
if ( EqualityComparer < T > . Default . Equals ( b [ i ] , default ( T ) ) )
{
bInvalid = true ;
}
if ( bInvalid ) // invalid, don't negate
intRes2 | = intRes1 & ( 1 < < i ) ;
else // valid, negate
intRes2 | = ( ~ intRes1 ) & ( 1 < < i ) ;
}
else // negate all
intRes2 | = ( ~ intRes1 ) & ( 1 < < i ) ;
}
else // don't negate
intRes2 | = intRes1 & ( 1 < < i ) ;
}
return intRes2 ;
#else
throw new NotImplementedException ( "dots runtime C# lacks comparer" ) ;
#endif
}
/// <summary>
/// Compare packed strings with implicit lengths in a and b using the control in imm8, and store the generated mask in dst.
/// </summary>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="imm8">Control</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 cmpistrm ( v128 a , v128 b , int imm8 )
{
v128 c ;
if ( 0 = = ( imm8 & 1 ) )
if ( 0 = = ( imm8 & 2 ) )
c = cmpistrm_emulation ( & a . Byte0 , & b . Byte0 , 16 , imm8 , 0xffff , ( byte ) 0xff ) ;
else
c = cmpistrm_emulation ( & a . SByte0 , & b . SByte0 , 16 , imm8 , 0xffff , ( sbyte ) - 1 ) ;
else
if ( 0 = = ( imm8 & 2 ) )
c = cmpistrm_emulation ( & a . UShort0 , & b . UShort0 , 8 , imm8 , 0xff , ( ushort ) 0xffff ) ;
else
c = cmpistrm_emulation ( & a . SShort0 , & b . SShort0 , 8 , imm8 , 0xff , ( short ) - 1 ) ;
return c ;
}
/// <summary>
/// Compare packed strings with implicit lengths in a and b using the control in imm8, and store the generated index in dst.
/// </summary>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="imm8">Control</param>
/// <returns>Index</returns>
[DebuggerStepThrough]
public static int cmpistri ( v128 a , v128 b , int imm8 )
{
if ( 0 = = ( imm8 & 1 ) )
if ( 0 = = ( imm8 & 2 ) )
return cmpistri_emulation ( & a . Byte0 , & b . Byte0 , 16 , imm8 , 0xffff , ( byte ) 0xff ) ;
else
return cmpistri_emulation ( & a . SByte0 , & b . SByte0 , 16 , imm8 , 0xffff , ( sbyte ) - 1 ) ;
else
if ( 0 = = ( imm8 & 2 ) )
return cmpistri_emulation ( & a . UShort0 , & b . UShort0 , 8 , imm8 , 0xff , ( ushort ) 0xffff ) ;
else
return cmpistri_emulation ( & a . SShort0 , & b . SShort0 , 8 , imm8 , 0xff , ( short ) - 1 ) ;
}
/// <summary>
/// Compare packed strings in a and b with lengths la and lb using the control in imm8, and store the generated mask in dst.
/// </summary>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="la">Length a</param>
/// <param name="lb">Length b</param>
/// <param name="imm8">Control</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 cmpestrm ( v128 a , int la , v128 b , int lb , int imm8 )
{
v128 c ;
if ( 0 = = ( imm8 & 1 ) )
if ( 0 = = ( imm8 & 2 ) )
c = cmpestrm_emulation ( & a . Byte0 , la , & b . Byte0 , lb , 16 , imm8 , 0xffff , ( byte ) 0xff ) ;
else
c = cmpestrm_emulation ( & a . SByte0 , la , & b . SByte0 , lb , 16 , imm8 , 0xffff , ( sbyte ) - 1 ) ;
else
if ( 0 = = ( imm8 & 2 ) )
c = cmpestrm_emulation ( & a . UShort0 , la , & b . UShort0 , lb , 8 , imm8 , 0xff , ( ushort ) 0xffff ) ;
else
c = cmpestrm_emulation ( & a . SShort0 , la , & b . SShort0 , lb , 8 , imm8 , 0xff , ( short ) - 1 ) ;
return c ;
}
/// <summary>
/// Compare packed strings in a and b with lengths la and lb using the control in imm8, and store the generated index in dst.
/// </summary>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="la">Length a</param>
/// <param name="lb">Length b</param>
/// <param name="imm8">Control</param>
/// <returns>Index</returns>
[DebuggerStepThrough]
public static int cmpestri ( v128 a , int la , v128 b , int lb , int imm8 )
{
if ( 0 = = ( imm8 & 1 ) )
if ( 0 = = ( imm8 & 2 ) )
return cmpestri_emulation ( & a . Byte0 , la , & b . Byte0 , lb , 16 , imm8 , 0xffff , ( byte ) 0xff ) ;
else
return cmpestri_emulation ( & a . SByte0 , la , & b . SByte0 , lb , 16 , imm8 , 0xffff , ( sbyte ) - 1 ) ;
else
if ( 0 = = ( imm8 & 2 ) )
return cmpestri_emulation ( & a . UShort0 , la , & b . UShort0 , lb , 8 , imm8 , 0xff , ( ushort ) 0xffff ) ;
else
return cmpestri_emulation ( & a . SShort0 , la , & b . SShort0 , lb , 8 , imm8 , 0xff , ( short ) - 1 ) ;
}
/ *
* Intrinsics for text / string processing and reading values of EFlags .
* /
/// <summary>
/// Compare packed strings with implicit lengths in a and b using the control in imm8, and returns 1 if any character in b was null, and 0 otherwise.
/// </summary>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="imm8">Control</param>
/// <returns>Boolean value</returns>
[DebuggerStepThrough]
public static int cmpistrz ( v128 a , v128 b , int imm8 )
{
if ( 0 = = ( imm8 & 1 ) )
return ComputeStringLength < byte > ( & b . Byte0 , 16 ) < 16 ? 1 : 0 ;
else
return ComputeStringLength < ushort > ( & b . UShort0 , 8 ) < 8 ? 1 : 0 ;
}
/// <summary>
/// Compare packed strings with implicit lengths in a and b using the control in imm8, and returns 1 if the resulting mask was non-zero, and 0 otherwise.
/// </summary>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="imm8">Control</param>
/// <returns>Boolean value</returns>
[DebuggerStepThrough]
public static int cmpistrc ( v128 a , v128 b , int imm8 )
{
v128 q = cmpistrm ( a , b , imm8 ) ;
return q . SInt0 = = 0 & & q . SInt1 = = 0 & & q . SInt2 = = 0 & & q . SInt3 = = 0 ? 0 : 1 ;
}
/// <summary>
/// Compare packed strings with implicit lengths in a and b using the control in imm8, and returns 1 if any character in a was null, and 0 otherwise.
/// </summary>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="imm8">Control</param>
/// <returns>Boolean value</returns>
[DebuggerStepThrough]
public static int cmpistrs ( v128 a , v128 b , int imm8 )
{
if ( 0 = = ( imm8 & 1 ) )
return ComputeStringLength < byte > ( & a . Byte0 , 16 ) < 16 ? 1 : 0 ;
else
return ComputeStringLength < ushort > ( & a . UShort0 , 8 ) < 8 ? 1 : 0 ;
}
/// <summary>
/// Compare packed strings with implicit lengths in a and b using the control in imm8, and returns bit 0 of the resulting bit mask.
/// </summary>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="imm8">Control</param>
/// <returns>Bit 0</returns>
[DebuggerStepThrough]
public static int cmpistro ( v128 a , v128 b , int imm8 )
{
int intRes2 ;
if ( 0 = = ( imm8 & 1 ) )
{
int al = ComputeStringLength < byte > ( & a . Byte0 , 16 ) ;
int bl = ComputeStringLength < byte > ( & b . Byte0 , 16 ) ;
if ( 0 = = ( imm8 & 2 ) )
intRes2 = ComputeStrCmpIntRes2 < byte > ( & a . Byte0 , al , & b . Byte0 , bl , 16 , imm8 , 0xffff ) ;
else
intRes2 = ComputeStrCmpIntRes2 < sbyte > ( & a . SByte0 , al , & b . SByte0 , bl , 16 , imm8 , 0xffff ) ;
}
else
{
int al = ComputeStringLength < ushort > ( & a . UShort0 , 8 ) ;
int bl = ComputeStringLength < ushort > ( & b . UShort0 , 8 ) ;
if ( 0 = = ( imm8 & 2 ) )
intRes2 = ComputeStrCmpIntRes2 < ushort > ( & a . UShort0 , al , & b . UShort0 , bl , 8 , imm8 , 0xff ) ;
else
intRes2 = ComputeStrCmpIntRes2 < short > ( & a . SShort0 , al , & b . SShort0 , bl , 8 , imm8 , 0xff ) ;
}
return intRes2 & 1 ;
}
/// <summary>
/// Compare packed strings with implicit lengths in a and b using the control in imm8, and returns 1 if b did not contain a null character and the resulting mask was zero, and 0 otherwise.
/// </summary>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="imm8">Control</param>
/// <returns>Boolean value</returns>
[DebuggerStepThrough]
public static int cmpistra ( v128 a , v128 b , int imm8 )
{
return ( ( ~ cmpistrc ( a , b , imm8 ) ) & ( ~ cmpistrz ( a , b , imm8 ) ) ) & 1 ;
}
/// <summary>
/// Compare packed strings in a and b with lengths la and lb using the control in imm8, and returns 1 if any character in b was null, and 0 otherwise.
/// </summary>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="la">Length a</param>
/// <param name="lb">Length b</param>
/// <param name="imm8">Control</param>
/// <returns>Boolean value</returns>
[DebuggerStepThrough]
public static int cmpestrz ( v128 a , int la , v128 b , int lb , int imm8 )
{
int size = ( imm8 & 1 ) = = 1 ? 16 : 8 ;
int upperBound = ( 128 / size ) - 1 ;
return lb < = upperBound ? 1 : 0 ;
}
/// <summary>
/// Compare packed strings in a and b with lengths la and lb using the control in imm8, and returns 1 if the resulting mask was non-zero, and 0 otherwise.
/// </summary>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="la">Length a</param>
/// <param name="lb">Length b</param>
/// <param name="imm8">Control</param>
/// <returns>Boolean value</returns>
[DebuggerStepThrough]
public static int cmpestrc ( v128 a , int la , v128 b , int lb , int imm8 )
{
int intRes2 ;
if ( 0 = = ( imm8 & 1 ) )
{
if ( 0 = = ( imm8 & 2 ) )
intRes2 = ComputeStrCmpIntRes2 < byte > ( & a . Byte0 , la , & b . Byte0 , lb , 16 , imm8 , 0xffff ) ;
else
intRes2 = ComputeStrCmpIntRes2 < sbyte > ( & a . SByte0 , la , & b . SByte0 , lb , 16 , imm8 , 0xffff ) ;
}
else
{
if ( 0 = = ( imm8 & 2 ) )
intRes2 = ComputeStrCmpIntRes2 < ushort > ( & a . UShort0 , la , & b . UShort0 , lb , 8 , imm8 , 0xff ) ;
else
intRes2 = ComputeStrCmpIntRes2 < short > ( & a . SShort0 , la , & b . SShort0 , lb , 8 , imm8 , 0xff ) ;
}
return intRes2 ! = 0 ? 1 : 0 ;
}
/// <summary>
/// Compare packed strings in a and b with lengths la and lb using the control in imm8, and returns 1 if any character in a was null, and 0 otherwise.
/// </summary>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="la">Length a</param>
/// <param name="lb">Length b</param>
/// <param name="imm8">Control</param>
/// <returns>Boolean value</returns>
[DebuggerStepThrough]
public static int cmpestrs ( v128 a , int la , v128 b , int lb , int imm8 )
{
2023-05-07 18:43:11 -04:00
int size = ( imm8 & 1 ) = = 1 ? 16 : 8 ;
int upperBound = ( 128 / size ) - 1 ;
return la < = upperBound ? 1 : 0 ;
2023-03-28 13:24:16 -04:00
}
/// <summary>
/// Compare packed strings in a and b with lengths la and lb using the control in imm8, and returns bit 0 of the resulting bit mask.
/// </summary>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="la">Length a</param>
/// <param name="lb">Length b</param>
/// <param name="imm8">Control</param>
/// <returns>Bit 0</returns>
[DebuggerStepThrough]
public static int cmpestro ( v128 a , int la , v128 b , int lb , int imm8 )
{
int intRes2 ;
if ( 0 = = ( imm8 & 1 ) )
{
if ( 0 = = ( imm8 & 2 ) )
intRes2 = ComputeStrCmpIntRes2 < byte > ( & a . Byte0 , la , & b . Byte0 , lb , 16 , imm8 , 0xffff ) ;
else
intRes2 = ComputeStrCmpIntRes2 < sbyte > ( & a . SByte0 , la , & b . SByte0 , lb , 16 , imm8 , 0xffff ) ;
}
else
{
if ( 0 = = ( imm8 & 2 ) )
intRes2 = ComputeStrCmpIntRes2 < ushort > ( & a . UShort0 , la , & b . UShort0 , lb , 8 , imm8 , 0xff ) ;
else
intRes2 = ComputeStrCmpIntRes2 < short > ( & a . SShort0 , la , & b . SShort0 , lb , 8 , imm8 , 0xff ) ;
}
return intRes2 & 1 ;
}
/// <summary>
/// Compare packed strings in a and b with lengths la and lb using the control in imm8, and returns 1 if b did not contain a null character and the resulting mask was zero, and 0 otherwise.
/// </summary>
/// <param name="a">Vector a</param>
/// <param name="b">Vector b</param>
/// <param name="la">Length a</param>
/// <param name="lb">Length b</param>
/// <param name="imm8">Control</param>
/// <returns>Boolean value</returns>
[DebuggerStepThrough]
public static int cmpestra ( v128 a , int la , v128 b , int lb , int imm8 )
{
return ( ( ~ cmpestrc ( a , la , b , lb , imm8 ) ) & ( ~ cmpestrz ( a , la , b , lb , imm8 ) ) ) & 1 ;
}
/// <summary>
/// Compare packed 64-bit integers in a and b for greater-than, and store the results in dst.
/// </summary>
/// <param name="val1">Vector a</param>
/// <param name="val2">Vector b</param>
/// <returns>Vector</returns>
[DebuggerStepThrough]
public static v128 cmpgt_epi64 ( v128 val1 , v128 val2 )
{
v128 result = default ;
result . SLong0 = val1 . SLong0 > val2 . SLong0 ? - 1 : 0 ;
result . SLong1 = val1 . SLong1 > val2 . SLong1 ? - 1 : 0 ;
return result ;
}
/ *
* Accumulate CRC32 ( polynomial 0x11EDC6F41 ) value
* /
private static readonly uint [ ] crctab = new uint [ ]
{
0x00000000 U , 0xF26B8303 U , 0xE13B70F7 U , 0x1350F3F4 U , 0xC79A971F U , 0x35F1141C U , 0x26A1E7E8 U , 0xD4CA64EB U ,
0x8AD958CF U , 0x78B2DBCC U , 0x6BE22838 U , 0x9989AB3B U , 0x4D43CFD0 U , 0xBF284CD3 U , 0xAC78BF27 U , 0x5E133C24 U ,
0x105EC76F U , 0xE235446C U , 0xF165B798 U , 0x030E349B U , 0xD7C45070 U , 0x25AFD373 U , 0x36FF2087 U , 0xC494A384 U ,
0x9A879FA0 U , 0x68EC1CA3 U , 0x7BBCEF57 U , 0x89D76C54 U , 0x5D1D08BF U , 0xAF768BBC U , 0xBC267848 U , 0x4E4DFB4B U ,
0x20BD8EDE U , 0xD2D60DDD U , 0xC186FE29 U , 0x33ED7D2A U , 0xE72719C1 U , 0x154C9AC2 U , 0x061C6936 U , 0xF477EA35 U ,
0xAA64D611 U , 0x580F5512 U , 0x4B5FA6E6 U , 0xB93425E5 U , 0x6DFE410E U , 0x9F95C20D U , 0x8CC531F9 U , 0x7EAEB2FA U ,
0x30E349B1 U , 0xC288CAB2 U , 0xD1D83946 U , 0x23B3BA45 U , 0xF779DEAE U , 0x05125DAD U , 0x1642AE59 U , 0xE4292D5A U ,
0xBA3A117E U , 0x4851927D U , 0x5B016189 U , 0xA96AE28A U , 0x7DA08661 U , 0x8FCB0562 U , 0x9C9BF696 U , 0x6EF07595 U ,
0x417B1DBC U , 0xB3109EBF U , 0xA0406D4B U , 0x522BEE48 U , 0x86E18AA3 U , 0x748A09A0 U , 0x67DAFA54 U , 0x95B17957 U ,
0xCBA24573 U , 0x39C9C670 U , 0x2A993584 U , 0xD8F2B687 U , 0x0C38D26C U , 0xFE53516F U , 0xED03A29B U , 0x1F682198 U ,
0x5125DAD3 U , 0xA34E59D0 U , 0xB01EAA24 U , 0x42752927 U , 0x96BF4DCC U , 0x64D4CECF U , 0x77843D3B U , 0x85EFBE38 U ,
0xDBFC821C U , 0x2997011F U , 0x3AC7F2EB U , 0xC8AC71E8 U , 0x1C661503 U , 0xEE0D9600 U , 0xFD5D65F4 U , 0x0F36E6F7 U ,
0x61C69362 U , 0x93AD1061 U , 0x80FDE395 U , 0x72966096 U , 0xA65C047D U , 0x5437877E U , 0x4767748A U , 0xB50CF789 U ,
0xEB1FCBAD U , 0x197448AE U , 0x0A24BB5A U , 0xF84F3859 U , 0x2C855CB2 U , 0xDEEEDFB1 U , 0xCDBE2C45 U , 0x3FD5AF46 U ,
0x7198540D U , 0x83F3D70E U , 0x90A324FA U , 0x62C8A7F9 U , 0xB602C312 U , 0x44694011 U , 0x5739B3E5 U , 0xA55230E6 U ,
0xFB410CC2 U , 0x092A8FC1 U , 0x1A7A7C35 U , 0xE811FF36 U , 0x3CDB9BDD U , 0xCEB018DE U , 0xDDE0EB2A U , 0x2F8B6829 U ,
0x82F63B78 U , 0x709DB87B U , 0x63CD4B8F U , 0x91A6C88C U , 0x456CAC67 U , 0xB7072F64 U , 0xA457DC90 U , 0x563C5F93 U ,
0x082F63B7 U , 0xFA44E0B4 U , 0xE9141340 U , 0x1B7F9043 U , 0xCFB5F4A8 U , 0x3DDE77AB U , 0x2E8E845F U , 0xDCE5075C U ,
0x92A8FC17 U , 0x60C37F14 U , 0x73938CE0 U , 0x81F80FE3 U , 0x55326B08 U , 0xA759E80B U , 0xB4091BFF U , 0x466298FC U ,
0x1871A4D8 U , 0xEA1A27DB U , 0xF94AD42F U , 0x0B21572C U , 0xDFEB33C7 U , 0x2D80B0C4 U , 0x3ED04330 U , 0xCCBBC033 U ,
0xA24BB5A6 U , 0x502036A5 U , 0x4370C551 U , 0xB11B4652 U , 0x65D122B9 U , 0x97BAA1BA U , 0x84EA524E U , 0x7681D14D U ,
0x2892ED69 U , 0xDAF96E6A U , 0xC9A99D9E U , 0x3BC21E9D U , 0xEF087A76 U , 0x1D63F975 U , 0x0E330A81 U , 0xFC588982 U ,
0xB21572C9 U , 0x407EF1CA U , 0x532E023E U , 0xA145813D U , 0x758FE5D6 U , 0x87E466D5 U , 0x94B49521 U , 0x66DF1622 U ,
0x38CC2A06 U , 0xCAA7A905 U , 0xD9F75AF1 U , 0x2B9CD9F2 U , 0xFF56BD19 U , 0x0D3D3E1A U , 0x1E6DCDEE U , 0xEC064EED U ,
0xC38D26C4 U , 0x31E6A5C7 U , 0x22B65633 U , 0xD0DDD530 U , 0x0417B1DB U , 0xF67C32D8 U , 0xE52CC12C U , 0x1747422F U ,
0x49547E0B U , 0xBB3FFD08 U , 0xA86F0EFC U , 0x5A048DFF U , 0x8ECEE914 U , 0x7CA56A17 U , 0x6FF599E3 U , 0x9D9E1AE0 U ,
0xD3D3E1AB U , 0x21B862A8 U , 0x32E8915C U , 0xC083125F U , 0x144976B4 U , 0xE622F5B7 U , 0xF5720643 U , 0x07198540 U ,
0x590AB964 U , 0xAB613A67 U , 0xB831C993 U , 0x4A5A4A90 U , 0x9E902E7B U , 0x6CFBAD78 U , 0x7FAB5E8C U , 0x8DC0DD8F U ,
0xE330A81A U , 0x115B2B19 U , 0x020BD8ED U , 0xF0605BEE U , 0x24AA3F05 U , 0xD6C1BC06 U , 0xC5914FF2 U , 0x37FACCF1 U ,
0x69E9F0D5 U , 0x9B8273D6 U , 0x88D28022 U , 0x7AB90321 U , 0xAE7367CA U , 0x5C18E4C9 U , 0x4F48173D U , 0xBD23943E U ,
0xF36E6F75 U , 0x0105EC76 U , 0x12551F82 U , 0xE03E9C81 U , 0x34F4F86A U , 0xC69F7B69 U , 0xD5CF889D U , 0x27A40B9E U ,
0x79B737BA U , 0x8BDCB4B9 U , 0x988C474D U , 0x6AE7C44E U , 0xBE2DA0A5 U , 0x4C4623A6 U , 0x5F16D052 U , 0xAD7D5351 U ,
} ;
/// <summary>
/// Starting with the initial value in crc, accumulates a CRC32 value for unsigned 32-bit integer v, and stores the result in dst.
/// </summary>
/// <param name="crc">Initial value</param>
/// <param name="v">Unsigned 32-bit integer</param>
/// <returns>Result</returns>
[DebuggerStepThrough]
public static uint crc32_u32 ( uint crc , uint v )
{
crc = crc32_u8 ( crc , ( byte ) v ) ; v > > = 8 ;
crc = crc32_u8 ( crc , ( byte ) v ) ; v > > = 8 ;
crc = crc32_u8 ( crc , ( byte ) v ) ; v > > = 8 ;
crc = crc32_u8 ( crc , ( byte ) v ) ;
return crc ;
}
/// <summary>
/// Starting with the initial value in crc, accumulates a CRC32 value for unsigned 8-bit integer v, and stores the result in dst.
/// </summary>
/// <param name="crc">Initial value</param>
/// <param name="v">Unsigned 8-bit integer</param>
/// <returns>Result</returns>
[DebuggerStepThrough]
public static uint crc32_u8 ( uint crc , byte v )
{
crc = ( crc > > 8 ) ^ crctab [ ( crc ^ v ) & 0xff ] ;
return crc ;
}
/// <summary>
/// Starting with the initial value in crc, accumulates a CRC32 value for unsigned 16-bit integer v, and stores the result in dst.
/// </summary>
/// <param name="crc">Initial value</param>
/// <param name="v">Unsigned 16-bit integer</param>
/// <returns>Result</returns>
[DebuggerStepThrough]
public static uint crc32_u16 ( uint crc , ushort v )
{
crc = crc32_u8 ( crc , ( byte ) v ) ; v > > = 8 ;
crc = crc32_u8 ( crc , ( byte ) v ) ;
return crc ;
}
/// <summary>
/// Starting with the initial value in crc, accumulates a CRC32 value for unsigned 64-bit integer v, and stores the result in dst.
/// </summary>
/// <param name="crc_ul">Initial value</param>
2023-05-07 18:43:11 -04:00
/// <param name="v">Signed 64-bit integer</param>
2023-03-28 13:24:16 -04:00
/// <returns>Result</returns>
[DebuggerStepThrough]
2023-05-07 18:43:11 -04:00
[Obsolete("Use the ulong version of this intrinsic instead.")]
2023-03-28 13:24:16 -04:00
public static ulong crc32_u64 ( ulong crc_ul , long v )
2023-05-07 18:43:11 -04:00
{
return crc32_u64 ( crc_ul , ( ulong ) v ) ;
}
/// <summary>
/// Starting with the initial value in crc, accumulates a CRC32 value for unsigned 64-bit integer v, and stores the result in dst.
/// </summary>
/// <param name="crc_ul">Initial value</param>
/// <param name="v">Unsigned 64-bit integer</param>
/// <returns>Result</returns>
[DebuggerStepThrough]
public static ulong crc32_u64 ( ulong crc_ul , ulong v )
2023-03-28 13:24:16 -04:00
{
uint crc = ( uint ) crc_ul ;
crc = crc32_u8 ( crc , ( byte ) v ) ; v > > = 8 ;
crc = crc32_u8 ( crc , ( byte ) v ) ; v > > = 8 ;
crc = crc32_u8 ( crc , ( byte ) v ) ; v > > = 8 ;
crc = crc32_u8 ( crc , ( byte ) v ) ; v > > = 8 ;
crc = crc32_u8 ( crc , ( byte ) v ) ; v > > = 8 ;
crc = crc32_u8 ( crc , ( byte ) v ) ; v > > = 8 ;
crc = crc32_u8 ( crc , ( byte ) v ) ; v > > = 8 ;
crc = crc32_u8 ( crc , ( byte ) v ) ;
return crc ;
}
}
}
}