aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure/Instructions/InstEmitSimdShift.cs
diff options
context:
space:
mode:
Diffstat (limited to 'ARMeilleure/Instructions/InstEmitSimdShift.cs')
-rw-r--r--ARMeilleure/Instructions/InstEmitSimdShift.cs134
1 files changed, 129 insertions, 5 deletions
diff --git a/ARMeilleure/Instructions/InstEmitSimdShift.cs b/ARMeilleure/Instructions/InstEmitSimdShift.cs
index 146aeafa..cf3b51bd 100644
--- a/ARMeilleure/Instructions/InstEmitSimdShift.cs
+++ b/ARMeilleure/Instructions/InstEmitSimdShift.cs
@@ -88,8 +88,35 @@ namespace ARMeilleure.Instructions
OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp;
int shift = GetImmShl(op);
+ int eSize = 8 << op.Size;
- if (Optimizations.UseSse2 && op.Size > 0)
+ if (shift >= eSize)
+ {
+ if ((op.RegisterSize == RegisterSize.Simd64))
+ {
+ Operand res = context.VectorZeroUpper64(GetVec(op.Rd));
+
+ context.Copy(GetVec(op.Rd), res);
+ }
+ }
+ else if (Optimizations.UseGfni && op.Size == 0)
+ {
+ Operand n = GetVec(op.Rn);
+
+ ulong bitMatrix = X86GetGf2p8LogicalShiftLeft(shift);
+
+ Operand vBitMatrix = X86GetElements(context, bitMatrix, bitMatrix);
+
+ Operand res = context.AddIntrinsic(Intrinsic.X86Gf2p8affineqb, n, vBitMatrix, Const(0));
+
+ if (op.RegisterSize == RegisterSize.Simd64)
+ {
+ res = context.VectorZeroUpper64(res);
+ }
+
+ context.Copy(GetVec(op.Rd), res);
+ }
+ else if (Optimizations.UseSse2 && op.Size > 0)
{
Operand n = GetVec(op.Rn);
@@ -396,10 +423,40 @@ namespace ARMeilleure.Instructions
{
OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp;
- if (Optimizations.UseSse2 && op.Size > 0 && op.Size < 3)
+ int shift = GetImmShr(op);
+
+ if (Optimizations.UseGfni && op.Size == 0)
{
- int shift = GetImmShr(op);
+ Operand n = GetVec(op.Rn);
+ ulong bitMatrix;
+
+ if (shift < 8)
+ {
+ bitMatrix = X86GetGf2p8LogicalShiftLeft(-shift);
+
+ // Extend sign-bit
+ bitMatrix |= 0x8080808080808080UL >> (64 - shift * 8);
+ }
+ else
+ {
+ // Replicate sign-bit into all bits
+ bitMatrix = 0x8080808080808080UL;
+ }
+
+ Operand vBitMatrix = X86GetElements(context, bitMatrix, bitMatrix);
+
+ Operand res = context.AddIntrinsic(Intrinsic.X86Gf2p8affineqb, n, vBitMatrix, Const(0));
+
+ if (op.RegisterSize == RegisterSize.Simd64)
+ {
+ res = context.VectorZeroUpper64(res);
+ }
+
+ context.Copy(GetVec(op.Rd), res);
+ }
+ else if (Optimizations.UseSse2 && op.Size > 0 && op.Size < 3)
+ {
Operand n = GetVec(op.Rn);
Intrinsic sraInst = X86PsraInstruction[op.Size];
@@ -929,10 +986,44 @@ namespace ARMeilleure.Instructions
OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp;
int shift = GetImmShl(op);
+ int eSize = 8 << op.Size;
ulong mask = shift != 0 ? ulong.MaxValue >> (64 - shift) : 0UL;
- if (Optimizations.UseSse2 && op.Size > 0)
+ if (shift >= eSize)
+ {
+ if ((op.RegisterSize == RegisterSize.Simd64) || scalar)
+ {
+ Operand res = context.VectorZeroUpper64(GetVec(op.Rd));
+
+ context.Copy(GetVec(op.Rd), res);
+ }
+ }
+ else if (Optimizations.UseGfni && op.Size == 0)
+ {
+ Operand d = GetVec(op.Rd);
+ Operand n = GetVec(op.Rn);
+
+ ulong bitMatrix = X86GetGf2p8LogicalShiftLeft(shift);
+
+ Operand vBitMatrix = X86GetElements(context, bitMatrix, bitMatrix);
+
+ Operand nShifted = context.AddIntrinsic(Intrinsic.X86Gf2p8affineqb, n, vBitMatrix, Const(0));
+
+ Operand dMask = X86GetAllElements(context, (long)mask * _masks_SliSri[op.Size]);
+
+ Operand dMasked = context.AddIntrinsic(Intrinsic.X86Pand, d, dMask);
+
+ Operand res = context.AddIntrinsic(Intrinsic.X86Por, nShifted, dMasked);
+
+ if ((op.RegisterSize == RegisterSize.Simd64) || scalar)
+ {
+ res = context.VectorZeroUpper64(res);
+ }
+
+ context.Copy(d, res);
+ }
+ else if (Optimizations.UseSse2 && op.Size > 0)
{
Operand d = GetVec(op.Rd);
Operand n = GetVec(op.Rn);
@@ -988,7 +1079,40 @@ namespace ARMeilleure.Instructions
ulong mask = (ulong.MaxValue << (eSize - shift)) & (ulong.MaxValue >> (64 - eSize));
- if (Optimizations.UseSse2 && op.Size > 0)
+ if (shift >= eSize)
+ {
+ if ((op.RegisterSize == RegisterSize.Simd64) || scalar)
+ {
+ Operand res = context.VectorZeroUpper64(GetVec(op.Rd));
+
+ context.Copy(GetVec(op.Rd), res);
+ }
+ }
+ else if (Optimizations.UseGfni && op.Size == 0)
+ {
+ Operand d = GetVec(op.Rd);
+ Operand n = GetVec(op.Rn);
+
+ ulong bitMatrix = X86GetGf2p8LogicalShiftLeft(-shift);
+
+ Operand vBitMatrix = X86GetElements(context, bitMatrix, bitMatrix);
+
+ Operand nShifted = context.AddIntrinsic(Intrinsic.X86Gf2p8affineqb, n, vBitMatrix, Const(0));
+
+ Operand dMask = X86GetAllElements(context, (long)mask * _masks_SliSri[op.Size]);
+
+ Operand dMasked = context.AddIntrinsic(Intrinsic.X86Pand, d, dMask);
+
+ Operand res = context.AddIntrinsic(Intrinsic.X86Por, nShifted, dMasked);
+
+ if ((op.RegisterSize == RegisterSize.Simd64) || scalar)
+ {
+ res = context.VectorZeroUpper64(res);
+ }
+
+ context.Copy(d, res);
+ }
+ else if (Optimizations.UseSse2 && op.Size > 0)
{
Operand d = GetVec(op.Rd);
Operand n = GetVec(op.Rn);