Remove all the calls to StaticCast methods (#605)

This commit is contained in:
gdkchan 2019-02-25 20:46:34 -03:00 committed by jduncanator
parent 5001f78b1d
commit 504f4f4abf
9 changed files with 245 additions and 589 deletions

View file

@ -208,8 +208,6 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.LoadScalarVector128), types)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.LoadScalarVector128), types));
VectorHelper.EmitCall(context, nameof(VectorHelper.VectorDoubleToSingle));
break; break;
} }
@ -284,16 +282,7 @@ namespace ChocolArm64.Instructions
switch (size) switch (size)
{ {
case 2: context.EmitCall(typeof(Sse), nameof(Sse.StoreScalar)); break; case 2: context.EmitCall(typeof(Sse), nameof(Sse.StoreScalar)); break;
case 3: context.EmitCall(typeof(Sse2), nameof(Sse2.StoreScalar)); break;
case 3:
{
VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleToDouble));
context.EmitCall(typeof(Sse2), nameof(Sse2.StoreScalar));
break;
}
case 4: context.EmitCall(typeof(Sse), nameof(Sse.StoreAligned)); break; case 4: context.EmitCall(typeof(Sse), nameof(Sse.StoreAligned)); break;
default: throw new InvalidOperationException($"Invalid vector store size of {1 << size} bytes."); default: throw new InvalidOperationException($"Invalid vector store size of {1 << size} bytes.");

View file

@ -194,7 +194,6 @@ namespace ChocolArm64.Instructions
context.EmitLdvec(op.Rm); context.EmitLdvec(op.Rm);
context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.SubtractScalar), typesSubAndNot)); context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.SubtractScalar), typesSubAndNot));
context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.AndNot), typesSubAndNot)); context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.AndNot), typesSubAndNot));
context.EmitStvec(op.Rd); context.EmitStvec(op.Rd);
@ -209,14 +208,13 @@ namespace ChocolArm64.Instructions
context.EmitLdc_R8(-0d); context.EmitLdc_R8(-0d);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetScalarVector128), typesSsv)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetScalarVector128), typesSsv));
EmitLdvecWithCastToDouble(context, op.Rn); context.EmitLdvec(op.Rn);
EmitLdvecWithCastToDouble(context, op.Rm); context.EmitLdvec(op.Rm);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SubtractScalar), typesSubAndNot)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SubtractScalar), typesSubAndNot));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), typesSubAndNot)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), typesSubAndNot));
EmitStvecWithCastFromDouble(context, op.Rd); context.EmitStvec(op.Rd);
EmitVectorZeroUpper(context, op.Rd); EmitVectorZeroUpper(context, op.Rd);
} }
@ -252,7 +250,6 @@ namespace ChocolArm64.Instructions
context.EmitLdvec(op.Rm); context.EmitLdvec(op.Rm);
context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Subtract), typesSubAndNot)); context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Subtract), typesSubAndNot));
context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.AndNot), typesSubAndNot)); context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.AndNot), typesSubAndNot));
context.EmitStvec(op.Rd); context.EmitStvec(op.Rd);
@ -270,14 +267,13 @@ namespace ChocolArm64.Instructions
context.EmitLdc_R8(-0d); context.EmitLdc_R8(-0d);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
EmitLdvecWithCastToDouble(context, op.Rn); context.EmitLdvec(op.Rn);
EmitLdvecWithCastToDouble(context, op.Rm); context.EmitLdvec(op.Rm);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesSubAndNot)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesSubAndNot));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), typesSubAndNot)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), typesSubAndNot));
EmitStvecWithCastFromDouble(context, op.Rd); context.EmitStvec(op.Rd);
} }
} }
else else
@ -321,11 +317,11 @@ namespace ChocolArm64.Instructions
context.EmitLdc_R8(-0d); context.EmitLdc_R8(-0d);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetScalarVector128), typesSsv)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetScalarVector128), typesSsv));
EmitLdvecWithCastToDouble(context, op.Rn); context.EmitLdvec(op.Rn);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), typesAndNot)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), typesAndNot));
EmitStvecWithCastFromDouble(context, op.Rd); context.EmitStvec(op.Rd);
EmitVectorZeroUpper(context, op.Rd); EmitVectorZeroUpper(context, op.Rd);
} }
@ -374,11 +370,11 @@ namespace ChocolArm64.Instructions
context.EmitLdc_R8(-0d); context.EmitLdc_R8(-0d);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
EmitLdvecWithCastToDouble(context, op.Rn); context.EmitLdvec(op.Rn);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), typesAndNot)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), typesAndNot));
EmitStvecWithCastFromDouble(context, op.Rd); context.EmitStvec(op.Rd);
} }
} }
else else
@ -445,12 +441,12 @@ namespace ChocolArm64.Instructions
{ {
Type[] typesAddH = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) }; Type[] typesAddH = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) };
EmitLdvecWithCastToDouble(context, op.Rn); context.EmitLdvec(op.Rn);
context.Emit(OpCodes.Dup); context.Emit(OpCodes.Dup);
context.EmitCall(typeof(Sse3).GetMethod(nameof(Sse3.HorizontalAdd), typesAddH)); context.EmitCall(typeof(Sse3).GetMethod(nameof(Sse3.HorizontalAdd), typesAddH));
EmitStvecWithCastFromDouble(context, op.Rd); context.EmitStvec(op.Rd);
EmitVectorZeroUpper(context, op.Rd); EmitVectorZeroUpper(context, op.Rd);
} }
@ -536,14 +532,14 @@ namespace ChocolArm64.Instructions
{ {
Type[] typesMulAdd = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) }; Type[] typesMulAdd = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) };
EmitLdvecWithCastToDouble(context, op.Ra); context.EmitLdvec(op.Ra);
EmitLdvecWithCastToDouble(context, op.Rn); context.EmitLdvec(op.Rn);
EmitLdvecWithCastToDouble(context, op.Rm); context.EmitLdvec(op.Rm);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.MultiplyScalar), typesMulAdd)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.MultiplyScalar), typesMulAdd));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AddScalar), typesMulAdd)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AddScalar), typesMulAdd));
EmitStvecWithCastFromDouble(context, op.Rd); context.EmitStvec(op.Rd);
EmitVectorZeroUpper(context, op.Rd); EmitVectorZeroUpper(context, op.Rd);
} }
@ -718,14 +714,14 @@ namespace ChocolArm64.Instructions
{ {
Type[] typesMulAdd = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) }; Type[] typesMulAdd = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) };
EmitLdvecWithCastToDouble(context, op.Rd); context.EmitLdvec(op.Rd);
EmitLdvecWithCastToDouble(context, op.Rn); context.EmitLdvec(op.Rn);
EmitLdvecWithCastToDouble(context, op.Rm); context.EmitLdvec(op.Rm);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), typesMulAdd)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), typesMulAdd));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesMulAdd)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesMulAdd));
EmitStvecWithCastFromDouble(context, op.Rd); context.EmitStvec(op.Rd);
} }
} }
else else
@ -751,17 +747,13 @@ namespace ChocolArm64.Instructions
Type[] typesMulAdd = new Type[] { typeof(Vector128<float>), typeof(Vector128<float>) }; Type[] typesMulAdd = new Type[] { typeof(Vector128<float>), typeof(Vector128<float>) };
context.EmitLdvec(op.Rd); context.EmitLdvec(op.Rd);
context.EmitLdvec(op.Rn); context.EmitLdvec(op.Rn);
context.EmitLdvec(op.Rm); context.EmitLdvec(op.Rm);
context.Emit(OpCodes.Dup); context.Emit(OpCodes.Dup);
context.EmitLdc_I4(op.Index | op.Index << 2 | op.Index << 4 | op.Index << 6); context.EmitLdc_I4(op.Index | op.Index << 2 | op.Index << 4 | op.Index << 6);
context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Shuffle), typesSfl)); context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Shuffle), typesSfl));
context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Multiply), typesMulAdd)); context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Multiply), typesMulAdd));
context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Add), typesMulAdd)); context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Add), typesMulAdd));
context.EmitStvec(op.Rd); context.EmitStvec(op.Rd);
@ -776,21 +768,17 @@ namespace ChocolArm64.Instructions
Type[] typesSfl = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>), typeof(byte) }; Type[] typesSfl = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>), typeof(byte) };
Type[] typesMulAdd = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) }; Type[] typesMulAdd = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) };
EmitLdvecWithCastToDouble(context, op.Rd); context.EmitLdvec(op.Rd);
context.EmitLdvec(op.Rn);
EmitLdvecWithCastToDouble(context, op.Rn); context.EmitLdvec(op.Rm);
EmitLdvecWithCastToDouble(context, op.Rm);
context.Emit(OpCodes.Dup); context.Emit(OpCodes.Dup);
context.EmitLdc_I4(op.Index | op.Index << 1); context.EmitLdc_I4(op.Index | op.Index << 1);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Shuffle), typesSfl)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Shuffle), typesSfl));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), typesMulAdd)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), typesMulAdd));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesMulAdd)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesMulAdd));
EmitStvecWithCastFromDouble(context, op.Rd); context.EmitStvec(op.Rd);
} }
} }
else else
@ -841,14 +829,14 @@ namespace ChocolArm64.Instructions
{ {
Type[] typesMulSub = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) }; Type[] typesMulSub = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) };
EmitLdvecWithCastToDouble(context, op.Rd); context.EmitLdvec(op.Rd);
EmitLdvecWithCastToDouble(context, op.Rn); context.EmitLdvec(op.Rn);
EmitLdvecWithCastToDouble(context, op.Rm); context.EmitLdvec(op.Rm);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), typesMulSub)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), typesMulSub));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesMulSub)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesMulSub));
EmitStvecWithCastFromDouble(context, op.Rd); context.EmitStvec(op.Rd);
} }
} }
else else
@ -874,17 +862,13 @@ namespace ChocolArm64.Instructions
Type[] typesMulSub = new Type[] { typeof(Vector128<float>), typeof(Vector128<float>) }; Type[] typesMulSub = new Type[] { typeof(Vector128<float>), typeof(Vector128<float>) };
context.EmitLdvec(op.Rd); context.EmitLdvec(op.Rd);
context.EmitLdvec(op.Rn); context.EmitLdvec(op.Rn);
context.EmitLdvec(op.Rm); context.EmitLdvec(op.Rm);
context.Emit(OpCodes.Dup); context.Emit(OpCodes.Dup);
context.EmitLdc_I4(op.Index | op.Index << 2 | op.Index << 4 | op.Index << 6); context.EmitLdc_I4(op.Index | op.Index << 2 | op.Index << 4 | op.Index << 6);
context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Shuffle), typesSfl)); context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Shuffle), typesSfl));
context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Multiply), typesMulSub)); context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Multiply), typesMulSub));
context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Subtract), typesMulSub)); context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Subtract), typesMulSub));
context.EmitStvec(op.Rd); context.EmitStvec(op.Rd);
@ -899,21 +883,17 @@ namespace ChocolArm64.Instructions
Type[] typesSfl = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>), typeof(byte) }; Type[] typesSfl = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>), typeof(byte) };
Type[] typesMulSub = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) }; Type[] typesMulSub = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) };
EmitLdvecWithCastToDouble(context, op.Rd); context.EmitLdvec(op.Rd);
context.EmitLdvec(op.Rn);
EmitLdvecWithCastToDouble(context, op.Rn); context.EmitLdvec(op.Rm);
EmitLdvecWithCastToDouble(context, op.Rm);
context.Emit(OpCodes.Dup); context.Emit(OpCodes.Dup);
context.EmitLdc_I4(op.Index | op.Index << 1); context.EmitLdc_I4(op.Index | op.Index << 1);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Shuffle), typesSfl)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Shuffle), typesSfl));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), typesMulSub)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), typesMulSub));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesMulSub)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesMulSub));
EmitStvecWithCastFromDouble(context, op.Rd); context.EmitStvec(op.Rd);
} }
} }
else else
@ -950,14 +930,14 @@ namespace ChocolArm64.Instructions
{ {
Type[] typesMulSub = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) }; Type[] typesMulSub = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) };
EmitLdvecWithCastToDouble(context, op.Ra); context.EmitLdvec(op.Ra);
EmitLdvecWithCastToDouble(context, op.Rn); context.EmitLdvec(op.Rn);
EmitLdvecWithCastToDouble(context, op.Rm); context.EmitLdvec(op.Rm);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.MultiplyScalar), typesMulSub)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.MultiplyScalar), typesMulSub));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SubtractScalar), typesMulSub)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SubtractScalar), typesMulSub));
EmitStvecWithCastFromDouble(context, op.Rd); context.EmitStvec(op.Rd);
EmitVectorZeroUpper(context, op.Rd); EmitVectorZeroUpper(context, op.Rd);
} }
@ -1020,13 +1000,11 @@ namespace ChocolArm64.Instructions
Type[] typesMul = new Type[] { typeof(Vector128<float>), typeof(Vector128<float>) }; Type[] typesMul = new Type[] { typeof(Vector128<float>), typeof(Vector128<float>) };
context.EmitLdvec(op.Rn); context.EmitLdvec(op.Rn);
context.EmitLdvec(op.Rm); context.EmitLdvec(op.Rm);
context.Emit(OpCodes.Dup); context.Emit(OpCodes.Dup);
context.EmitLdc_I4(op.Index | op.Index << 2 | op.Index << 4 | op.Index << 6); context.EmitLdc_I4(op.Index | op.Index << 2 | op.Index << 4 | op.Index << 6);
context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Shuffle), typesSfl)); context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Shuffle), typesSfl));
context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Multiply), typesMul)); context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.Multiply), typesMul));
context.EmitStvec(op.Rd); context.EmitStvec(op.Rd);
@ -1041,17 +1019,15 @@ namespace ChocolArm64.Instructions
Type[] typesSfl = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>), typeof(byte) }; Type[] typesSfl = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>), typeof(byte) };
Type[] typesMul = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) }; Type[] typesMul = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) };
EmitLdvecWithCastToDouble(context, op.Rn); context.EmitLdvec(op.Rn);
context.EmitLdvec(op.Rm);
EmitLdvecWithCastToDouble(context, op.Rm);
context.Emit(OpCodes.Dup); context.Emit(OpCodes.Dup);
context.EmitLdc_I4(op.Index | op.Index << 1); context.EmitLdc_I4(op.Index | op.Index << 1);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Shuffle), typesSfl)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Shuffle), typesSfl));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), typesMul)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), typesMul));
EmitStvecWithCastFromDouble(context, op.Rd); context.EmitStvec(op.Rd);
} }
} }
else else
@ -1125,11 +1101,11 @@ namespace ChocolArm64.Instructions
context.EmitLdc_R8(-0d); context.EmitLdc_R8(-0d);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetScalarVector128), typesSsv)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetScalarVector128), typesSsv));
EmitLdvecWithCastToDouble(context, op.Rn); context.EmitLdvec(op.Rn);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Xor), typesXor)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Xor), typesXor));
EmitStvecWithCastFromDouble(context, op.Rd); context.EmitStvec(op.Rd);
EmitVectorZeroUpper(context, op.Rd); EmitVectorZeroUpper(context, op.Rd);
} }
@ -1175,11 +1151,11 @@ namespace ChocolArm64.Instructions
context.EmitLdc_R8(-0d); context.EmitLdc_R8(-0d);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
EmitLdvecWithCastToDouble(context, op.Rn); context.EmitLdvec(op.Rn);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Xor), typesXor)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Xor), typesXor));
EmitStvecWithCastFromDouble(context, op.Rd); context.EmitStvec(op.Rd);
} }
} }
else else
@ -1242,8 +1218,7 @@ namespace ChocolArm64.Instructions
int sizeF = op.Size & 1; int sizeF = op.Size & 1;
if (Optimizations.FastFP && Optimizations.UseSse if (Optimizations.FastFP && Optimizations.UseSse && sizeF == 0)
&& sizeF == 0)
{ {
EmitScalarSseOrSse2OpF(context, nameof(Sse.ReciprocalScalar)); EmitScalarSseOrSse2OpF(context, nameof(Sse.ReciprocalScalar));
} }
@ -1262,8 +1237,7 @@ namespace ChocolArm64.Instructions
int sizeF = op.Size & 1; int sizeF = op.Size & 1;
if (Optimizations.FastFP && Optimizations.UseSse if (Optimizations.FastFP && Optimizations.UseSse && sizeF == 0)
&& sizeF == 0)
{ {
EmitVectorSseOrSse2OpF(context, nameof(Sse.Reciprocal)); EmitVectorSseOrSse2OpF(context, nameof(Sse.Reciprocal));
} }
@ -1310,13 +1284,13 @@ namespace ChocolArm64.Instructions
context.EmitLdc_R8(2d); context.EmitLdc_R8(2d);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetScalarVector128), typesSsv)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetScalarVector128), typesSsv));
EmitLdvecWithCastToDouble(context, op.Rn); context.EmitLdvec(op.Rn);
EmitLdvecWithCastToDouble(context, op.Rm); context.EmitLdvec(op.Rm);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.MultiplyScalar), typesMulSub)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.MultiplyScalar), typesMulSub));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SubtractScalar), typesMulSub)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SubtractScalar), typesMulSub));
EmitStvecWithCastFromDouble(context, op.Rd); context.EmitStvec(op.Rd);
EmitVectorZeroUpper(context, op.Rd); EmitVectorZeroUpper(context, op.Rd);
} }
@ -1367,13 +1341,13 @@ namespace ChocolArm64.Instructions
context.EmitLdc_R8(2d); context.EmitLdc_R8(2d);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
EmitLdvecWithCastToDouble(context, op.Rn); context.EmitLdvec(op.Rn);
EmitLdvecWithCastToDouble(context, op.Rm); context.EmitLdvec(op.Rm);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), typesMulSub)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), typesMulSub));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesMulSub)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesMulSub));
EmitStvecWithCastFromDouble(context, op.Rd); context.EmitStvec(op.Rd);
} }
} }
else else
@ -1579,8 +1553,7 @@ namespace ChocolArm64.Instructions
int sizeF = op.Size & 1; int sizeF = op.Size & 1;
if (Optimizations.FastFP && Optimizations.UseSse if (Optimizations.FastFP && Optimizations.UseSse && sizeF == 0)
&& sizeF == 0)
{ {
EmitScalarSseOrSse2OpF(context, nameof(Sse.ReciprocalSqrtScalar)); EmitScalarSseOrSse2OpF(context, nameof(Sse.ReciprocalSqrtScalar));
} }
@ -1599,8 +1572,7 @@ namespace ChocolArm64.Instructions
int sizeF = op.Size & 1; int sizeF = op.Size & 1;
if (Optimizations.FastFP && Optimizations.UseSse if (Optimizations.FastFP && Optimizations.UseSse && sizeF == 0)
&& sizeF == 0)
{ {
EmitVectorSseOrSse2OpF(context, nameof(Sse.ReciprocalSqrt)); EmitVectorSseOrSse2OpF(context, nameof(Sse.ReciprocalSqrt));
} }
@ -1654,14 +1626,14 @@ namespace ChocolArm64.Instructions
context.EmitLdc_R8(3d); context.EmitLdc_R8(3d);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetScalarVector128), typesSsv)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetScalarVector128), typesSsv));
EmitLdvecWithCastToDouble(context, op.Rn); context.EmitLdvec(op.Rn);
EmitLdvecWithCastToDouble(context, op.Rm); context.EmitLdvec(op.Rm);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.MultiplyScalar), typesMulSub)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.MultiplyScalar), typesMulSub));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SubtractScalar), typesMulSub)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SubtractScalar), typesMulSub));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.MultiplyScalar), typesMulSub)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.MultiplyScalar), typesMulSub));
EmitStvecWithCastFromDouble(context, op.Rd); context.EmitStvec(op.Rd);
EmitVectorZeroUpper(context, op.Rd); EmitVectorZeroUpper(context, op.Rd);
} }
@ -1719,14 +1691,14 @@ namespace ChocolArm64.Instructions
context.EmitLdc_R8(3d); context.EmitLdc_R8(3d);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
EmitLdvecWithCastToDouble(context, op.Rn); context.EmitLdvec(op.Rn);
EmitLdvecWithCastToDouble(context, op.Rm); context.EmitLdvec(op.Rm);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), typesMulSub)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), typesMulSub));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesMulSub)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesMulSub));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), typesMulSub)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Multiply), typesMulSub));
EmitStvecWithCastFromDouble(context, op.Rd); context.EmitStvec(op.Rd);
} }
} }
else else
@ -1864,11 +1836,11 @@ namespace ChocolArm64.Instructions
VectorHelper.EmitCall(context, namesSzv[op.Size]); VectorHelper.EmitCall(context, namesSzv[op.Size]);
EmitLdvecWithSignedCast(context, op.Rn, op.Size); context.EmitLdvec(op.Rn);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesSub)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesSub));
EmitStvecWithSignedCast(context, op.Rd, op.Size); context.EmitStvec(op.Rd);
if (op.RegisterSize == RegisterSize.Simd64) if (op.RegisterSize == RegisterSize.Simd64)
{ {
@ -1953,14 +1925,14 @@ namespace ChocolArm64.Instructions
int numBytes = op.RegisterSize == RegisterSize.Simd128 ? 8 : 0; int numBytes = op.RegisterSize == RegisterSize.Simd128 ? 8 : 0;
EmitLdvecWithSignedCast(context, op.Rn, op.Size); context.EmitLdvec(op.Rn);
context.EmitLdc_I4(numBytes); context.EmitLdc_I4(numBytes);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
context.EmitCall(typeof(Sse41).GetMethod(namesCvt[op.Size], typesCvt)); context.EmitCall(typeof(Sse41).GetMethod(namesCvt[op.Size], typesCvt));
EmitLdvecWithSignedCast(context, op.Rm, op.Size); context.EmitLdvec(op.Rm);
context.EmitLdc_I4(numBytes); context.EmitLdc_I4(numBytes);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
@ -1969,7 +1941,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd));
EmitStvecWithSignedCast(context, op.Rd, op.Size + 1); context.EmitStvec(op.Rd);
} }
else else
{ {
@ -1999,9 +1971,8 @@ namespace ChocolArm64.Instructions
int numBytes = op.RegisterSize == RegisterSize.Simd128 ? 8 : 0; int numBytes = op.RegisterSize == RegisterSize.Simd128 ? 8 : 0;
EmitLdvecWithSignedCast(context, op.Rn, op.Size + 1); context.EmitLdvec(op.Rn);
context.EmitLdvec(op.Rm);
EmitLdvecWithSignedCast(context, op.Rm, op.Size);
context.EmitLdc_I4(numBytes); context.EmitLdc_I4(numBytes);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
@ -2010,7 +1981,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd));
EmitStvecWithSignedCast(context, op.Rd, op.Size + 1); context.EmitStvec(op.Rd);
} }
else else
{ {
@ -2027,12 +1998,12 @@ namespace ChocolArm64.Instructions
Type[] typesSra = new Type[] { VectorIntTypesPerSizeLog2[op.Size], typeof(byte) }; Type[] typesSra = new Type[] { VectorIntTypesPerSizeLog2[op.Size], typeof(byte) };
Type[] typesAndXorAdd = new Type[] { VectorIntTypesPerSizeLog2[op.Size], VectorIntTypesPerSizeLog2[op.Size] }; Type[] typesAndXorAdd = new Type[] { VectorIntTypesPerSizeLog2[op.Size], VectorIntTypesPerSizeLog2[op.Size] };
EmitLdvecWithSignedCast(context, op.Rn, op.Size); context.EmitLdvec(op.Rn);
context.Emit(OpCodes.Dup); context.Emit(OpCodes.Dup);
context.EmitStvectmp(); context.EmitStvectmp();
EmitLdvecWithSignedCast(context, op.Rm, op.Size); context.EmitLdvec(op.Rm);
context.Emit(OpCodes.Dup); context.Emit(OpCodes.Dup);
context.EmitStvectmp2(); context.EmitStvectmp2();
@ -2046,10 +2017,9 @@ namespace ChocolArm64.Instructions
context.EmitLdc_I4(1); context.EmitLdc_I4(1);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightArithmetic), typesSra)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightArithmetic), typesSra));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAndXorAdd)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAndXorAdd));
EmitStvecWithSignedCast(context, op.Rd, op.Size); context.EmitStvec(op.Rd);
if (op.RegisterSize == RegisterSize.Simd64) if (op.RegisterSize == RegisterSize.Simd64)
{ {
@ -2083,23 +2053,21 @@ namespace ChocolArm64.Instructions
context.EmitStvectmp(); context.EmitStvectmp();
EmitLdvecWithSignedCast(context, op.Rn, op.Size); context.EmitLdvec(op.Rn);
context.EmitLdvectmp(); context.EmitLdvectmp();
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAddSub)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAddSub));
context.Emit(OpCodes.Dup); context.Emit(OpCodes.Dup);
EmitLdvecWithSignedCast(context, op.Rm, op.Size); context.EmitLdvec(op.Rm);
context.EmitLdvectmp(); context.EmitLdvectmp();
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAddSub)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAddSub));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Average), typesAvg)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Average), typesAvg));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesAddSub)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesAddSub));
EmitStvecWithSignedCast(context, op.Rd, op.Size); context.EmitStvec(op.Rd);
if (op.RegisterSize == RegisterSize.Simd64) if (op.RegisterSize == RegisterSize.Simd64)
{ {
@ -2128,12 +2096,12 @@ namespace ChocolArm64.Instructions
Type typeSse = op.Size == 1 ? typeof(Sse2) : typeof(Sse41); Type typeSse = op.Size == 1 ? typeof(Sse2) : typeof(Sse41);
EmitLdvecWithSignedCast(context, op.Rn, op.Size); context.EmitLdvec(op.Rn);
EmitLdvecWithSignedCast(context, op.Rm, op.Size); context.EmitLdvec(op.Rm);
context.EmitCall(typeSse.GetMethod(nameof(Sse2.Max), typesMax)); context.EmitCall(typeSse.GetMethod(nameof(Sse2.Max), typesMax));
EmitStvecWithSignedCast(context, op.Rd, op.Size); context.EmitStvec(op.Rd);
if (op.RegisterSize == RegisterSize.Simd64) if (op.RegisterSize == RegisterSize.Simd64)
{ {
@ -2169,12 +2137,12 @@ namespace ChocolArm64.Instructions
Type typeSse = op.Size == 1 ? typeof(Sse2) : typeof(Sse41); Type typeSse = op.Size == 1 ? typeof(Sse2) : typeof(Sse41);
EmitLdvecWithSignedCast(context, op.Rn, op.Size); context.EmitLdvec(op.Rn);
EmitLdvecWithSignedCast(context, op.Rm, op.Size); context.EmitLdvec(op.Rm);
context.EmitCall(typeSse.GetMethod(nameof(Sse2.Min), typesMin)); context.EmitCall(typeSse.GetMethod(nameof(Sse2.Min), typesMin));
EmitStvecWithSignedCast(context, op.Rd, op.Size); context.EmitStvec(op.Rd);
if (op.RegisterSize == RegisterSize.Simd64) if (op.RegisterSize == RegisterSize.Simd64)
{ {
@ -2219,16 +2187,15 @@ namespace ChocolArm64.Instructions
int numBytes = op.RegisterSize == RegisterSize.Simd128 ? 8 : 0; int numBytes = op.RegisterSize == RegisterSize.Simd128 ? 8 : 0;
EmitLdvecWithSignedCast(context, op.Rd, op.Size + 1); context.EmitLdvec(op.Rd);
context.EmitLdvec(op.Rn);
EmitLdvecWithSignedCast(context, op.Rn, op.Size);
context.EmitLdc_I4(numBytes); context.EmitLdc_I4(numBytes);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
context.EmitCall(typeof(Sse41).GetMethod(nameCvt, typesCvt)); context.EmitCall(typeof(Sse41).GetMethod(nameCvt, typesCvt));
EmitLdvecWithSignedCast(context, op.Rm, op.Size); context.EmitLdvec(op.Rm);
context.EmitLdc_I4(numBytes); context.EmitLdc_I4(numBytes);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
@ -2239,7 +2206,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesMulAdd)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesMulAdd));
EmitStvecWithSignedCast(context, op.Rd, op.Size + 1); context.EmitStvec(op.Rd);
} }
else else
{ {
@ -2279,16 +2246,15 @@ namespace ChocolArm64.Instructions
int numBytes = op.RegisterSize == RegisterSize.Simd128 ? 8 : 0; int numBytes = op.RegisterSize == RegisterSize.Simd128 ? 8 : 0;
EmitLdvecWithSignedCast(context, op.Rd, op.Size + 1); context.EmitLdvec(op.Rd);
context.EmitLdvec(op.Rn);
EmitLdvecWithSignedCast(context, op.Rn, op.Size);
context.EmitLdc_I4(numBytes); context.EmitLdc_I4(numBytes);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
context.EmitCall(typeof(Sse41).GetMethod(nameCvt, typesCvt)); context.EmitCall(typeof(Sse41).GetMethod(nameCvt, typesCvt));
EmitLdvecWithSignedCast(context, op.Rm, op.Size); context.EmitLdvec(op.Rm);
context.EmitLdc_I4(numBytes); context.EmitLdc_I4(numBytes);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
@ -2299,7 +2265,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesMulSub)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesMulSub));
EmitStvecWithSignedCast(context, op.Rd, op.Size + 1); context.EmitStvec(op.Rd);
} }
else else
{ {
@ -2426,20 +2392,19 @@ namespace ChocolArm64.Instructions
context.Emit(OpCodes.Dup); context.Emit(OpCodes.Dup);
context.EmitStvectmp(); context.EmitStvectmp();
EmitLdvecWithSignedCast(context, op.Rn, op.Size); context.EmitLdvec(op.Rn);
context.EmitLdvectmp(); context.EmitLdvectmp();
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesSubAdd)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesSubAdd));
EmitLdvecWithSignedCast(context, op.Rm, op.Size); context.EmitLdvec(op.Rm);
context.EmitLdvectmp(); context.EmitLdvectmp();
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesSubAdd)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesSubAdd));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Average), typesAvg)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Average), typesAvg));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesSubAdd)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesSubAdd));
EmitStvecWithSignedCast(context, op.Rd, op.Size); context.EmitStvec(op.Rd);
if (op.RegisterSize == RegisterSize.Simd64) if (op.RegisterSize == RegisterSize.Simd64)
{ {
@ -2478,14 +2443,14 @@ namespace ChocolArm64.Instructions
int numBytes = op.RegisterSize == RegisterSize.Simd128 ? 8 : 0; int numBytes = op.RegisterSize == RegisterSize.Simd128 ? 8 : 0;
EmitLdvecWithSignedCast(context, op.Rn, op.Size); context.EmitLdvec(op.Rn);
context.EmitLdc_I4(numBytes); context.EmitLdc_I4(numBytes);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
context.EmitCall(typeof(Sse41).GetMethod(namesCvt[op.Size], typesCvt)); context.EmitCall(typeof(Sse41).GetMethod(namesCvt[op.Size], typesCvt));
EmitLdvecWithSignedCast(context, op.Rm, op.Size); context.EmitLdvec(op.Rm);
context.EmitLdc_I4(numBytes); context.EmitLdc_I4(numBytes);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
@ -2494,7 +2459,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesSub)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesSub));
EmitStvecWithSignedCast(context, op.Rd, op.Size + 1); context.EmitStvec(op.Rd);
} }
else else
{ {
@ -2519,9 +2484,8 @@ namespace ChocolArm64.Instructions
int numBytes = op.RegisterSize == RegisterSize.Simd128 ? 8 : 0; int numBytes = op.RegisterSize == RegisterSize.Simd128 ? 8 : 0;
EmitLdvecWithSignedCast(context, op.Rn, op.Size + 1); context.EmitLdvec(op.Rn);
context.EmitLdvec(op.Rm);
EmitLdvecWithSignedCast(context, op.Rm, op.Size);
context.EmitLdc_I4(numBytes); context.EmitLdc_I4(numBytes);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
@ -2530,7 +2494,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesSub)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesSub));
EmitStvecWithSignedCast(context, op.Rd, op.Size + 1); context.EmitStvec(op.Rd);
} }
else else
{ {
@ -2632,14 +2596,14 @@ namespace ChocolArm64.Instructions
int numBytes = op.RegisterSize == RegisterSize.Simd128 ? 8 : 0; int numBytes = op.RegisterSize == RegisterSize.Simd128 ? 8 : 0;
EmitLdvecWithUnsignedCast(context, op.Rn, op.Size); context.EmitLdvec(op.Rn);
context.EmitLdc_I4(numBytes); context.EmitLdc_I4(numBytes);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
context.EmitCall(typeof(Sse41).GetMethod(namesCvt[op.Size], typesCvt)); context.EmitCall(typeof(Sse41).GetMethod(namesCvt[op.Size], typesCvt));
EmitLdvecWithUnsignedCast(context, op.Rm, op.Size); context.EmitLdvec(op.Rm);
context.EmitLdc_I4(numBytes); context.EmitLdc_I4(numBytes);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
@ -2648,7 +2612,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd));
EmitStvecWithUnsignedCast(context, op.Rd, op.Size + 1); context.EmitStvec(op.Rd);
} }
else else
{ {
@ -2697,9 +2661,8 @@ namespace ChocolArm64.Instructions
int numBytes = op.RegisterSize == RegisterSize.Simd128 ? 8 : 0; int numBytes = op.RegisterSize == RegisterSize.Simd128 ? 8 : 0;
EmitLdvecWithUnsignedCast(context, op.Rn, op.Size + 1); context.EmitLdvec(op.Rn);
context.EmitLdvec(op.Rm);
EmitLdvecWithUnsignedCast(context, op.Rm, op.Size);
context.EmitLdc_I4(numBytes); context.EmitLdc_I4(numBytes);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
@ -2708,7 +2671,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd));
EmitStvecWithUnsignedCast(context, op.Rd, op.Size + 1); context.EmitStvec(op.Rd);
} }
else else
{ {
@ -2725,12 +2688,12 @@ namespace ChocolArm64.Instructions
Type[] typesSrl = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], typeof(byte) }; Type[] typesSrl = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], typeof(byte) };
Type[] typesAndXorAdd = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], VectorUIntTypesPerSizeLog2[op.Size] }; Type[] typesAndXorAdd = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], VectorUIntTypesPerSizeLog2[op.Size] };
EmitLdvecWithUnsignedCast(context, op.Rn, op.Size); context.EmitLdvec(op.Rn);
context.Emit(OpCodes.Dup); context.Emit(OpCodes.Dup);
context.EmitStvectmp(); context.EmitStvectmp();
EmitLdvecWithUnsignedCast(context, op.Rm, op.Size); context.EmitLdvec(op.Rm);
context.Emit(OpCodes.Dup); context.Emit(OpCodes.Dup);
context.EmitStvectmp2(); context.EmitStvectmp2();
@ -2744,10 +2707,9 @@ namespace ChocolArm64.Instructions
context.EmitLdc_I4(1); context.EmitLdc_I4(1);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), typesSrl)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), typesSrl));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAndXorAdd)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAndXorAdd));
EmitStvecWithUnsignedCast(context, op.Rd, op.Size); context.EmitStvec(op.Rd);
if (op.RegisterSize == RegisterSize.Simd64) if (op.RegisterSize == RegisterSize.Simd64)
{ {
@ -2774,16 +2736,15 @@ namespace ChocolArm64.Instructions
{ {
Type[] typesAvgSub = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], VectorUIntTypesPerSizeLog2[op.Size] }; Type[] typesAvgSub = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], VectorUIntTypesPerSizeLog2[op.Size] };
EmitLdvecWithUnsignedCast(context, op.Rn, op.Size); context.EmitLdvec(op.Rn);
context.Emit(OpCodes.Dup); context.Emit(OpCodes.Dup);
EmitLdvecWithUnsignedCast(context, op.Rm, op.Size); context.EmitLdvec(op.Rm);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Average), typesAvgSub)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Average), typesAvgSub));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesAvgSub)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesAvgSub));
EmitStvecWithUnsignedCast(context, op.Rd, op.Size); context.EmitStvec(op.Rd);
if (op.RegisterSize == RegisterSize.Simd64) if (op.RegisterSize == RegisterSize.Simd64)
{ {
@ -2812,12 +2773,12 @@ namespace ChocolArm64.Instructions
Type typeSse = op.Size == 0 ? typeof(Sse2) : typeof(Sse41); Type typeSse = op.Size == 0 ? typeof(Sse2) : typeof(Sse41);
EmitLdvecWithUnsignedCast(context, op.Rn, op.Size); context.EmitLdvec(op.Rn);
EmitLdvecWithUnsignedCast(context, op.Rm, op.Size); context.EmitLdvec(op.Rm);
context.EmitCall(typeSse.GetMethod(nameof(Sse2.Max), typesMax)); context.EmitCall(typeSse.GetMethod(nameof(Sse2.Max), typesMax));
EmitStvecWithUnsignedCast(context, op.Rd, op.Size); context.EmitStvec(op.Rd);
if (op.RegisterSize == RegisterSize.Simd64) if (op.RegisterSize == RegisterSize.Simd64)
{ {
@ -2853,12 +2814,12 @@ namespace ChocolArm64.Instructions
Type typeSse = op.Size == 0 ? typeof(Sse2) : typeof(Sse41); Type typeSse = op.Size == 0 ? typeof(Sse2) : typeof(Sse41);
EmitLdvecWithUnsignedCast(context, op.Rn, op.Size); context.EmitLdvec(op.Rn);
EmitLdvecWithUnsignedCast(context, op.Rm, op.Size); context.EmitLdvec(op.Rm);
context.EmitCall(typeSse.GetMethod(nameof(Sse2.Min), typesMin)); context.EmitCall(typeSse.GetMethod(nameof(Sse2.Min), typesMin));
EmitStvecWithUnsignedCast(context, op.Rd, op.Size); context.EmitStvec(op.Rd);
if (op.RegisterSize == RegisterSize.Simd64) if (op.RegisterSize == RegisterSize.Simd64)
{ {
@ -2903,16 +2864,15 @@ namespace ChocolArm64.Instructions
int numBytes = op.RegisterSize == RegisterSize.Simd128 ? 8 : 0; int numBytes = op.RegisterSize == RegisterSize.Simd128 ? 8 : 0;
EmitLdvecWithUnsignedCast(context, op.Rd, op.Size + 1); context.EmitLdvec(op.Rd);
context.EmitLdvec(op.Rn);
EmitLdvecWithUnsignedCast(context, op.Rn, op.Size);
context.EmitLdc_I4(numBytes); context.EmitLdc_I4(numBytes);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
context.EmitCall(typeof(Sse41).GetMethod(nameCvt, typesCvt)); context.EmitCall(typeof(Sse41).GetMethod(nameCvt, typesCvt));
EmitLdvecWithUnsignedCast(context, op.Rm, op.Size); context.EmitLdvec(op.Rm);
context.EmitLdc_I4(numBytes); context.EmitLdc_I4(numBytes);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
@ -2923,7 +2883,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesMulAdd)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesMulAdd));
EmitStvecWithUnsignedCast(context, op.Rd, op.Size + 1); context.EmitStvec(op.Rd);
} }
else else
{ {
@ -2963,16 +2923,15 @@ namespace ChocolArm64.Instructions
int numBytes = op.RegisterSize == RegisterSize.Simd128 ? 8 : 0; int numBytes = op.RegisterSize == RegisterSize.Simd128 ? 8 : 0;
EmitLdvecWithUnsignedCast(context, op.Rd, op.Size + 1); context.EmitLdvec(op.Rd);
context.EmitLdvec(op.Rn);
EmitLdvecWithUnsignedCast(context, op.Rn, op.Size);
context.EmitLdc_I4(numBytes); context.EmitLdc_I4(numBytes);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
context.EmitCall(typeof(Sse41).GetMethod(nameCvt, typesCvt)); context.EmitCall(typeof(Sse41).GetMethod(nameCvt, typesCvt));
EmitLdvecWithUnsignedCast(context, op.Rm, op.Size); context.EmitLdvec(op.Rm);
context.EmitLdc_I4(numBytes); context.EmitLdc_I4(numBytes);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
@ -2983,7 +2942,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesMulSub)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesMulSub));
EmitStvecWithUnsignedCast(context, op.Rd, op.Size + 1); context.EmitStvec(op.Rd);
} }
else else
{ {
@ -3052,12 +3011,12 @@ namespace ChocolArm64.Instructions
{ {
Type[] typesAvg = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], VectorUIntTypesPerSizeLog2[op.Size] }; Type[] typesAvg = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], VectorUIntTypesPerSizeLog2[op.Size] };
EmitLdvecWithUnsignedCast(context, op.Rn, op.Size); context.EmitLdvec(op.Rn);
EmitLdvecWithUnsignedCast(context, op.Rm, op.Size); context.EmitLdvec(op.Rm);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Average), typesAvg)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Average), typesAvg));
EmitStvecWithUnsignedCast(context, op.Rd, op.Size); context.EmitStvec(op.Rd);
if (op.RegisterSize == RegisterSize.Simd64) if (op.RegisterSize == RegisterSize.Simd64)
{ {
@ -3106,14 +3065,14 @@ namespace ChocolArm64.Instructions
int numBytes = op.RegisterSize == RegisterSize.Simd128 ? 8 : 0; int numBytes = op.RegisterSize == RegisterSize.Simd128 ? 8 : 0;
EmitLdvecWithUnsignedCast(context, op.Rn, op.Size); context.EmitLdvec(op.Rn);
context.EmitLdc_I4(numBytes); context.EmitLdc_I4(numBytes);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
context.EmitCall(typeof(Sse41).GetMethod(namesCvt[op.Size], typesCvt)); context.EmitCall(typeof(Sse41).GetMethod(namesCvt[op.Size], typesCvt));
EmitLdvecWithUnsignedCast(context, op.Rm, op.Size); context.EmitLdvec(op.Rm);
context.EmitLdc_I4(numBytes); context.EmitLdc_I4(numBytes);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
@ -3122,7 +3081,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesSub)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesSub));
EmitStvecWithUnsignedCast(context, op.Rd, op.Size + 1); context.EmitStvec(op.Rd);
} }
else else
{ {
@ -3147,9 +3106,8 @@ namespace ChocolArm64.Instructions
int numBytes = op.RegisterSize == RegisterSize.Simd128 ? 8 : 0; int numBytes = op.RegisterSize == RegisterSize.Simd128 ? 8 : 0;
EmitLdvecWithUnsignedCast(context, op.Rn, op.Size + 1); context.EmitLdvec(op.Rn);
context.EmitLdvec(op.Rm);
EmitLdvecWithUnsignedCast(context, op.Rm, op.Size);
context.EmitLdc_I4(numBytes); context.EmitLdc_I4(numBytes);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSrl));
@ -3158,7 +3116,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesSub)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Subtract), typesSub));
EmitStvecWithUnsignedCast(context, op.Rd, op.Size + 1); context.EmitStvec(op.Rd);
} }
else else
{ {

View file

@ -382,7 +382,7 @@ namespace ChocolArm64.Instructions
ILLabel lblNaN = new ILLabel(); ILLabel lblNaN = new ILLabel();
ILLabel lblEnd = new ILLabel(); ILLabel lblEnd = new ILLabel();
EmitLdvecWithCastToDouble(context, op.Rn); context.EmitLdvec(op.Rn);
context.Emit(OpCodes.Dup); context.Emit(OpCodes.Dup);
context.EmitStvectmp(); context.EmitStvectmp();
@ -393,7 +393,7 @@ namespace ChocolArm64.Instructions
} }
else else
{ {
EmitLdvecWithCastToDouble(context, op.Rm); context.EmitLdvec(op.Rm);
} }
context.Emit(OpCodes.Dup); context.Emit(OpCodes.Dup);
@ -656,12 +656,12 @@ namespace ChocolArm64.Instructions
if (!isLeOrLt) if (!isLeOrLt)
{ {
EmitLdvecWithCastToDouble(context, op.Rn); context.EmitLdvec(op.Rn);
} }
if (op is OpCodeSimdReg64 binOp) if (op is OpCodeSimdReg64 binOp)
{ {
EmitLdvecWithCastToDouble(context, binOp.Rm); context.EmitLdvec(binOp.Rm);
} }
else else
{ {
@ -670,12 +670,12 @@ namespace ChocolArm64.Instructions
if (isLeOrLt) if (isLeOrLt)
{ {
EmitLdvecWithCastToDouble(context, op.Rn); context.EmitLdvec(op.Rn);
} }
context.EmitCall(typeof(Sse2).GetMethod(name, types)); context.EmitCall(typeof(Sse2).GetMethod(name, types));
EmitStvecWithCastFromDouble(context, op.Rd); context.EmitStvec(op.Rd);
if (scalar) if (scalar)
{ {

View file

@ -23,7 +23,7 @@ namespace ChocolArm64.Instructions
//Double -> Single. //Double -> Single.
VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero)); VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleZero));
EmitLdvecWithCastToDouble(context, op.Rn); context.EmitLdvec(op.Rn);
Type[] types = new Type[] { typeof(Vector128<float>), typeof(Vector128<double>) }; Type[] types = new Type[] { typeof(Vector128<float>), typeof(Vector128<double>) };
@ -42,7 +42,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertScalarToVector128Double), types)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertScalarToVector128Double), types));
EmitStvecWithCastFromDouble(context, op.Rd); context.EmitStvec(op.Rd);
} }
else else
{ {
@ -91,7 +91,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertToVector128Double), typesCvt)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertToVector128Double), typesCvt));
EmitStvecWithCastFromDouble(context, op.Rd); context.EmitStvec(op.Rd);
} }
else else
{ {
@ -154,7 +154,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.MoveLowToHigh))); context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.MoveLowToHigh)));
EmitLdvecWithCastToDouble(context, op.Rn); context.EmitLdvec(op.Rn);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertToVector128Single), typesCvt)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertToVector128Single), typesCvt));
context.Emit(OpCodes.Dup); context.Emit(OpCodes.Dup);
@ -332,7 +332,7 @@ namespace ChocolArm64.Instructions
{ {
Type[] typesCvt = new Type[] { typeof(Vector128<int>) }; Type[] typesCvt = new Type[] { typeof(Vector128<int>) };
EmitLdvecWithSignedCast(context, op.Rn, 2); context.EmitLdvec(op.Rn);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertToVector128Single), typesCvt)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ConvertToVector128Single), typesCvt));

View file

@ -86,13 +86,13 @@ namespace ChocolArm64.Instructions
{ {
OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp; OpCodeSimd64 op = (OpCodeSimd64)context.CurrOp;
EmitLdvecWithSignedCast(context, op.Rn, op.Size); context.EmitLdvec(op.Rn);
Type baseType = VectorIntTypesPerSizeLog2[op.Size]; Type baseType = VectorIntTypesPerSizeLog2[op.Size];
if (op is OpCodeSimdReg64 binOp) if (op is OpCodeSimdReg64 binOp)
{ {
EmitLdvecWithSignedCast(context, binOp.Rm, op.Size); context.EmitLdvec(binOp.Rm);
context.EmitCall(type.GetMethod(name, new Type[] { baseType, baseType })); context.EmitCall(type.GetMethod(name, new Type[] { baseType, baseType }));
} }
@ -101,7 +101,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(type.GetMethod(name, new Type[] { baseType })); context.EmitCall(type.GetMethod(name, new Type[] { baseType }));
} }
EmitStvecWithSignedCast(context, op.Rd, op.Size); context.EmitStvec(op.Rd);
if (op.RegisterSize == RegisterSize.Simd64) if (op.RegisterSize == RegisterSize.Simd64)
{ {
@ -109,80 +109,6 @@ namespace ChocolArm64.Instructions
} }
} }
public static void EmitLdvecWithSignedCast(ILEmitterCtx context, int reg, int size)
{
context.EmitLdvec(reg);
switch (size)
{
case 0: VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleToSByte)); break;
case 1: VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleToInt16)); break;
case 2: VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleToInt32)); break;
case 3: VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleToInt64)); break;
default: throw new ArgumentOutOfRangeException(nameof(size));
}
}
public static void EmitLdvecWithCastToDouble(ILEmitterCtx context, int reg)
{
context.EmitLdvec(reg);
VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleToDouble));
}
public static void EmitStvecWithCastFromDouble(ILEmitterCtx context, int reg)
{
VectorHelper.EmitCall(context, nameof(VectorHelper.VectorDoubleToSingle));
context.EmitStvec(reg);
}
public static void EmitLdvecWithUnsignedCast(ILEmitterCtx context, int reg, int size)
{
context.EmitLdvec(reg);
switch (size)
{
case 0: VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleToByte)); break;
case 1: VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleToUInt16)); break;
case 2: VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleToUInt32)); break;
case 3: VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleToUInt64)); break;
default: throw new ArgumentOutOfRangeException(nameof(size));
}
}
public static void EmitStvecWithSignedCast(ILEmitterCtx context, int reg, int size)
{
switch (size)
{
case 0: VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSByteToSingle)); break;
case 1: VectorHelper.EmitCall(context, nameof(VectorHelper.VectorInt16ToSingle)); break;
case 2: VectorHelper.EmitCall(context, nameof(VectorHelper.VectorInt32ToSingle)); break;
case 3: VectorHelper.EmitCall(context, nameof(VectorHelper.VectorInt64ToSingle)); break;
default: throw new ArgumentOutOfRangeException(nameof(size));
}
context.EmitStvec(reg);
}
public static void EmitStvecWithUnsignedCast(ILEmitterCtx context, int reg, int size)
{
switch (size)
{
case 0: VectorHelper.EmitCall(context, nameof(VectorHelper.VectorByteToSingle)); break;
case 1: VectorHelper.EmitCall(context, nameof(VectorHelper.VectorUInt16ToSingle)); break;
case 2: VectorHelper.EmitCall(context, nameof(VectorHelper.VectorUInt32ToSingle)); break;
case 3: VectorHelper.EmitCall(context, nameof(VectorHelper.VectorUInt64ToSingle)); break;
default: throw new ArgumentOutOfRangeException(nameof(size));
}
context.EmitStvec(reg);
}
public static void EmitScalarSseOrSse2OpF(ILEmitterCtx context, string name) public static void EmitScalarSseOrSse2OpF(ILEmitterCtx context, string name)
{ {
EmitSseOrSse2OpF(context, name, true); EmitSseOrSse2OpF(context, name, true);
@ -199,17 +125,7 @@ namespace ChocolArm64.Instructions
int sizeF = op.Size & 1; int sizeF = op.Size & 1;
void Ldvec(int reg) context.EmitLdvec(op.Rn);
{
context.EmitLdvec(reg);
if (sizeF == 1)
{
VectorHelper.EmitCall(context, nameof(VectorHelper.VectorSingleToDouble));
}
}
Ldvec(op.Rn);
Type type; Type type;
Type baseType; Type baseType;
@ -227,7 +143,7 @@ namespace ChocolArm64.Instructions
if (op is OpCodeSimdReg64 binOp) if (op is OpCodeSimdReg64 binOp)
{ {
Ldvec(binOp.Rm); context.EmitLdvec(binOp.Rm);
context.EmitCall(type.GetMethod(name, new Type[] { baseType, baseType })); context.EmitCall(type.GetMethod(name, new Type[] { baseType, baseType }));
} }
@ -236,11 +152,6 @@ namespace ChocolArm64.Instructions
context.EmitCall(type.GetMethod(name, new Type[] { baseType })); context.EmitCall(type.GetMethod(name, new Type[] { baseType }));
} }
if (sizeF == 1)
{
VectorHelper.EmitCall(context, nameof(VectorHelper.VectorDoubleToSingle));
}
context.EmitStvec(op.Rd); context.EmitStvec(op.Rd);
if (scalar) if (scalar)
@ -1014,12 +925,12 @@ namespace ChocolArm64.Instructions
{ {
Type[] types = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) }; Type[] types = new Type[] { typeof(Vector128<double>), typeof(Vector128<double>) };
EmitLdvecWithCastToDouble(context, op.Rn); context.EmitLdvec(op.Rn);
context.Emit(OpCodes.Dup); context.Emit(OpCodes.Dup);
context.EmitStvectmp(); context.EmitStvectmp();
EmitLdvecWithCastToDouble(context, op.Rm); context.EmitLdvec(op.Rm);
context.Emit(OpCodes.Dup); context.Emit(OpCodes.Dup);
context.EmitStvectmp2(); context.EmitStvectmp2();
@ -1033,7 +944,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Sse2).GetMethod(name, types)); context.EmitCall(typeof(Sse2).GetMethod(name, types));
EmitStvecWithCastFromDouble(context, op.Rd); context.EmitStvec(op.Rd);
} }
} }
@ -1277,13 +1188,9 @@ namespace ChocolArm64.Instructions
} }
// TSrc (16bit, 32bit, 64bit; signed, unsigned) > TDst (8bit, 16bit, 32bit; signed, unsigned). // TSrc (16bit, 32bit, 64bit; signed, unsigned) > TDst (8bit, 16bit, 32bit; signed, unsigned).
public static void EmitSatQ( public static void EmitSatQ(ILEmitterCtx context, int sizeDst, bool signedSrc, bool signedDst)
ILEmitterCtx context,
int sizeDst,
bool signedSrc,
bool signedDst)
{ {
if (sizeDst > 2) if ((uint)sizeDst > 2)
{ {
throw new ArgumentOutOfRangeException(nameof(sizeDst)); throw new ArgumentOutOfRangeException(nameof(sizeDst));
} }

View file

@ -32,12 +32,12 @@ namespace ChocolArm64.Instructions
Type[] typesAndNot = new Type[] { typeof(Vector128<byte>), typeof(Vector128<byte>) }; Type[] typesAndNot = new Type[] { typeof(Vector128<byte>), typeof(Vector128<byte>) };
EmitLdvecWithUnsignedCast(context, op.Rm, 0); context.EmitLdvec(op.Rm);
EmitLdvecWithUnsignedCast(context, op.Rn, 0); context.EmitLdvec(op.Rn);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), typesAndNot)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), typesAndNot));
EmitStvecWithUnsignedCast(context, op.Rd, 0); context.EmitStvec(op.Rd);
if (op.RegisterSize == RegisterSize.Simd64) if (op.RegisterSize == RegisterSize.Simd64)
{ {
@ -83,16 +83,16 @@ namespace ChocolArm64.Instructions
string nameAndNot = notRm ? nameof(Sse2.AndNot) : nameof(Sse2.And); string nameAndNot = notRm ? nameof(Sse2.AndNot) : nameof(Sse2.And);
EmitLdvecWithUnsignedCast(context, op.Rd, 0); context.EmitLdvec(op.Rd);
EmitLdvecWithUnsignedCast(context, op.Rm, 0); context.EmitLdvec(op.Rm);
EmitLdvecWithUnsignedCast(context, op.Rn, 0); context.EmitLdvec(op.Rn);
EmitLdvecWithUnsignedCast(context, op.Rd, 0); context.EmitLdvec(op.Rd);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Xor), typesXorAndNot)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Xor), typesXorAndNot));
context.EmitCall(typeof(Sse2).GetMethod(nameAndNot, typesXorAndNot)); context.EmitCall(typeof(Sse2).GetMethod(nameAndNot, typesXorAndNot));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Xor), typesXorAndNot)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Xor), typesXorAndNot));
EmitStvecWithUnsignedCast(context, op.Rd, 0); context.EmitStvec(op.Rd);
if (op.RegisterSize == RegisterSize.Simd64) if (op.RegisterSize == RegisterSize.Simd64)
{ {
@ -141,20 +141,20 @@ namespace ChocolArm64.Instructions
Type[] typesXorAnd = new Type[] { typeof(Vector128<byte>), typeof(Vector128<byte>) }; Type[] typesXorAnd = new Type[] { typeof(Vector128<byte>), typeof(Vector128<byte>) };
EmitLdvecWithUnsignedCast(context, op.Rm, 0); context.EmitLdvec(op.Rm);
context.Emit(OpCodes.Dup); context.Emit(OpCodes.Dup);
EmitLdvecWithUnsignedCast(context, op.Rn, 0); context.EmitLdvec(op.Rn);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Xor), typesXorAnd)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Xor), typesXorAnd));
EmitLdvecWithUnsignedCast(context, op.Rd, 0); context.EmitLdvec(op.Rd);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.And), typesXorAnd)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.And), typesXorAnd));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Xor), typesXorAnd)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Xor), typesXorAnd));
EmitStvecWithUnsignedCast(context, op.Rd, 0); context.EmitStvec(op.Rd);
if (op.RegisterSize == RegisterSize.Simd64) if (op.RegisterSize == RegisterSize.Simd64)
{ {
@ -199,14 +199,14 @@ namespace ChocolArm64.Instructions
Type[] typesSav = new Type[] { typeof(byte) }; Type[] typesSav = new Type[] { typeof(byte) };
Type[] typesAndNot = new Type[] { typeof(Vector128<byte>), typeof(Vector128<byte>) }; Type[] typesAndNot = new Type[] { typeof(Vector128<byte>), typeof(Vector128<byte>) };
EmitLdvecWithUnsignedCast(context, op.Rn, 0); context.EmitLdvec(op.Rn);
context.EmitLdc_I4(byte.MaxValue); context.EmitLdc_I4(byte.MaxValue);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), typesAndNot)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), typesAndNot));
EmitStvecWithUnsignedCast(context, op.Rd, 0); context.EmitStvec(op.Rd);
if (op.RegisterSize == RegisterSize.Simd64) if (op.RegisterSize == RegisterSize.Simd64)
{ {
@ -228,8 +228,8 @@ namespace ChocolArm64.Instructions
Type[] typesSav = new Type[] { typeof(byte) }; Type[] typesSav = new Type[] { typeof(byte) };
Type[] typesAndNotOr = new Type[] { typeof(Vector128<byte>), typeof(Vector128<byte>) }; Type[] typesAndNotOr = new Type[] { typeof(Vector128<byte>), typeof(Vector128<byte>) };
EmitLdvecWithUnsignedCast(context, op.Rn, 0); context.EmitLdvec(op.Rn);
EmitLdvecWithUnsignedCast(context, op.Rm, 0); context.EmitLdvec(op.Rm);
context.EmitLdc_I4(byte.MaxValue); context.EmitLdc_I4(byte.MaxValue);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
@ -237,7 +237,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), typesAndNotOr)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.AndNot), typesAndNotOr));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Or), typesAndNotOr)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Or), typesAndNotOr));
EmitStvecWithUnsignedCast(context, op.Rd, 0); context.EmitStvec(op.Rd);
if (op.RegisterSize == RegisterSize.Simd64) if (op.RegisterSize == RegisterSize.Simd64)
{ {
@ -305,7 +305,7 @@ namespace ChocolArm64.Instructions
Type[] typesSve = new Type[] { typeof(long), typeof(long) }; Type[] typesSve = new Type[] { typeof(long), typeof(long) };
Type[] typesSfl = new Type[] { typeof(Vector128<sbyte>), typeof(Vector128<sbyte>) }; Type[] typesSfl = new Type[] { typeof(Vector128<sbyte>), typeof(Vector128<sbyte>) };
EmitLdvecWithSignedCast(context, op.Rn, 0); // value context.EmitLdvec(op.Rn); // value
context.EmitLdc_I8(14L << 56 | 15L << 48 | 12L << 40 | 13L << 32 | 10L << 24 | 11L << 16 | 08L << 8 | 09L << 0); // maskE1 context.EmitLdc_I8(14L << 56 | 15L << 48 | 12L << 40 | 13L << 32 | 10L << 24 | 11L << 16 | 08L << 8 | 09L << 0); // maskE1
context.EmitLdc_I8(06L << 56 | 07L << 48 | 04L << 40 | 05L << 32 | 02L << 24 | 03L << 16 | 00L << 8 | 01L << 0); // maskE0 context.EmitLdc_I8(06L << 56 | 07L << 48 | 04L << 40 | 05L << 32 | 02L << 24 | 03L << 16 | 00L << 8 | 01L << 0); // maskE0
@ -314,7 +314,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Ssse3).GetMethod(nameof(Ssse3.Shuffle), typesSfl)); context.EmitCall(typeof(Ssse3).GetMethod(nameof(Ssse3.Shuffle), typesSfl));
EmitStvecWithSignedCast(context, op.Rd, 0); context.EmitStvec(op.Rd);
if (op.RegisterSize == RegisterSize.Simd64) if (op.RegisterSize == RegisterSize.Simd64)
{ {
@ -336,7 +336,7 @@ namespace ChocolArm64.Instructions
Type[] typesSve = new Type[] { typeof(long), typeof(long) }; Type[] typesSve = new Type[] { typeof(long), typeof(long) };
Type[] typesSfl = new Type[] { typeof(Vector128<sbyte>), typeof(Vector128<sbyte>) }; Type[] typesSfl = new Type[] { typeof(Vector128<sbyte>), typeof(Vector128<sbyte>) };
EmitLdvecWithSignedCast(context, op.Rn, op.Size); // value context.EmitLdvec(op.Rn); // value
if (op.Size == 0) if (op.Size == 0)
{ {
@ -353,7 +353,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Ssse3).GetMethod(nameof(Ssse3.Shuffle), typesSfl)); context.EmitCall(typeof(Ssse3).GetMethod(nameof(Ssse3.Shuffle), typesSfl));
EmitStvecWithSignedCast(context, op.Rd, op.Size); context.EmitStvec(op.Rd);
if (op.RegisterSize == RegisterSize.Simd64) if (op.RegisterSize == RegisterSize.Simd64)
{ {
@ -375,7 +375,7 @@ namespace ChocolArm64.Instructions
Type[] typesSve = new Type[] { typeof(long), typeof(long) }; Type[] typesSve = new Type[] { typeof(long), typeof(long) };
Type[] typesSfl = new Type[] { typeof(Vector128<sbyte>), typeof(Vector128<sbyte>) }; Type[] typesSfl = new Type[] { typeof(Vector128<sbyte>), typeof(Vector128<sbyte>) };
EmitLdvecWithSignedCast(context, op.Rn, op.Size); // value context.EmitLdvec(op.Rn); // value
if (op.Size == 0) if (op.Size == 0)
{ {
@ -397,7 +397,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Ssse3).GetMethod(nameof(Ssse3.Shuffle), typesSfl)); context.EmitCall(typeof(Ssse3).GetMethod(nameof(Ssse3.Shuffle), typesSfl));
EmitStvecWithSignedCast(context, op.Rd, op.Size); context.EmitStvec(op.Rd);
if (op.RegisterSize == RegisterSize.Simd64) if (op.RegisterSize == RegisterSize.Simd64)
{ {

View file

@ -59,7 +59,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
EmitStvecWithUnsignedCast(context, op.Rd, op.Size); context.EmitStvec(op.Rd);
} }
else else
{ {
@ -108,7 +108,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.SetAllVector128), typesSav));
EmitStvecWithUnsignedCast(context, op.Rd, op.Size); context.EmitStvec(op.Rd);
} }
else else
{ {
@ -138,7 +138,7 @@ namespace ChocolArm64.Instructions
Type[] typesShs = new Type[] { typeof(Vector128<byte>), typeof(byte) }; Type[] typesShs = new Type[] { typeof(Vector128<byte>), typeof(byte) };
Type[] typesOr = new Type[] { typeof(Vector128<byte>), typeof(Vector128<byte>) }; Type[] typesOr = new Type[] { typeof(Vector128<byte>), typeof(Vector128<byte>) };
EmitLdvecWithUnsignedCast(context, op.Rn, 0); context.EmitLdvec(op.Rn);
if (op.RegisterSize == RegisterSize.Simd64) if (op.RegisterSize == RegisterSize.Simd64)
{ {
@ -150,7 +150,7 @@ namespace ChocolArm64.Instructions
context.EmitLdc_I4(op.Imm4); context.EmitLdc_I4(op.Imm4);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesShs)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesShs));
EmitLdvecWithUnsignedCast(context, op.Rm, 0); context.EmitLdvec(op.Rm);
context.EmitLdc_I4((op.RegisterSize == RegisterSize.Simd64 ? 8 : 16) - op.Imm4); context.EmitLdc_I4((op.RegisterSize == RegisterSize.Simd64 ? 8 : 16) - op.Imm4);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical128BitLane), typesShs)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical128BitLane), typesShs));
@ -164,7 +164,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Or), typesOr)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Or), typesOr));
EmitStvecWithUnsignedCast(context, op.Rd, 0); context.EmitStvec(op.Rd);
} }
else else
{ {
@ -418,7 +418,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.MoveLowToHigh))); context.EmitCall(typeof(Sse).GetMethod(nameof(Sse.MoveLowToHigh)));
EmitLdvecWithSignedCast(context, op.Rn, 0); // value context.EmitLdvec(op.Rn); // value
context.EmitLdc_I8(_masksE0_TrnUzpXtn[op.Size]); // mask context.EmitLdc_I8(_masksE0_TrnUzpXtn[op.Size]); // mask
context.Emit(OpCodes.Dup); // mask context.Emit(OpCodes.Dup); // mask
@ -492,7 +492,7 @@ namespace ChocolArm64.Instructions
? nameof(Sse2.UnpackLow) ? nameof(Sse2.UnpackLow)
: nameof(Sse2.UnpackHigh); : nameof(Sse2.UnpackHigh);
EmitLdvecWithSignedCast(context, op.Rn, op.Size); // value context.EmitLdvec(op.Rn); // value
if (op.Size < 3) if (op.Size < 3)
{ {
@ -504,7 +504,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Ssse3).GetMethod(nameof(Ssse3.Shuffle), GetTypesSflUpk(0))); context.EmitCall(typeof(Ssse3).GetMethod(nameof(Ssse3.Shuffle), GetTypesSflUpk(0)));
} }
EmitLdvecWithSignedCast(context, op.Rm, op.Size); // value context.EmitLdvec(op.Rm); // value
if (op.Size < 3) if (op.Size < 3)
{ {
@ -518,7 +518,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Sse2).GetMethod(nameUpk, GetTypesSflUpk(op.Size))); context.EmitCall(typeof(Sse2).GetMethod(nameUpk, GetTypesSflUpk(op.Size)));
EmitStvecWithSignedCast(context, op.Rd, op.Size); context.EmitStvec(op.Rd);
} }
else else
{ {
@ -560,7 +560,7 @@ namespace ChocolArm64.Instructions
if (op.RegisterSize == RegisterSize.Simd128) if (op.RegisterSize == RegisterSize.Simd128)
{ {
EmitLdvecWithSignedCast(context, op.Rn, op.Size); // value context.EmitLdvec(op.Rn); // value
if (op.Size < 3) if (op.Size < 3)
{ {
@ -572,7 +572,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Ssse3).GetMethod(nameof(Ssse3.Shuffle), GetTypesSflUpk(0))); context.EmitCall(typeof(Ssse3).GetMethod(nameof(Ssse3.Shuffle), GetTypesSflUpk(0)));
} }
EmitLdvecWithSignedCast(context, op.Rm, op.Size); // value context.EmitLdvec(op.Rm); // value
if (op.Size < 3) if (op.Size < 3)
{ {
@ -586,12 +586,12 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Sse2).GetMethod(nameUpk, GetTypesSflUpk(3))); context.EmitCall(typeof(Sse2).GetMethod(nameUpk, GetTypesSflUpk(3)));
EmitStvecWithSignedCast(context, op.Rd, op.Size); context.EmitStvec(op.Rd);
} }
else else
{ {
EmitLdvecWithSignedCast(context, op.Rn, op.Size); context.EmitLdvec(op.Rn);
EmitLdvecWithSignedCast(context, op.Rm, op.Size); context.EmitLdvec(op.Rm);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), GetTypesSflUpk(op.Size))); // value context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.UnpackLow), GetTypesSflUpk(op.Size))); // value
@ -609,7 +609,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Sse2).GetMethod(nameUpk, GetTypesSflUpk(3))); context.EmitCall(typeof(Sse2).GetMethod(nameUpk, GetTypesSflUpk(3)));
EmitStvecWithSignedCast(context, op.Rd, op.Size); context.EmitStvec(op.Rd);
} }
} }
else else
@ -648,8 +648,8 @@ namespace ChocolArm64.Instructions
? nameof(Sse2.UnpackLow) ? nameof(Sse2.UnpackLow)
: nameof(Sse2.UnpackHigh); : nameof(Sse2.UnpackHigh);
EmitLdvecWithSignedCast(context, op.Rn, op.Size); context.EmitLdvec(op.Rn);
EmitLdvecWithSignedCast(context, op.Rm, op.Size); context.EmitLdvec(op.Rm);
if (op.RegisterSize == RegisterSize.Simd128) if (op.RegisterSize == RegisterSize.Simd128)
{ {
@ -663,7 +663,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Sse2).GetMethod(nameUpk, GetTypesSflUpk(3))); context.EmitCall(typeof(Sse2).GetMethod(nameUpk, GetTypesSflUpk(3)));
} }
EmitStvecWithSignedCast(context, op.Rd, op.Size); context.EmitStvec(op.Rd);
} }
else else
{ {

View file

@ -42,12 +42,12 @@ namespace ChocolArm64.Instructions
{ {
Type[] typesSll = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], typeof(byte) }; Type[] typesSll = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], typeof(byte) };
EmitLdvecWithUnsignedCast(context, op.Rn, op.Size); context.EmitLdvec(op.Rn);
context.EmitLdc_I4(shift); context.EmitLdc_I4(shift);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), typesSll)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), typesSll));
EmitStvecWithUnsignedCast(context, op.Rd, op.Size); context.EmitStvec(op.Rd);
if (op.RegisterSize == RegisterSize.Simd64) if (op.RegisterSize == RegisterSize.Simd64)
{ {
@ -82,7 +82,7 @@ namespace ChocolArm64.Instructions
int numBytes = op.RegisterSize == RegisterSize.Simd128 ? 8 : 0; int numBytes = op.RegisterSize == RegisterSize.Simd128 ? 8 : 0;
EmitLdvecWithUnsignedCast(context, op.Rn, op.Size); context.EmitLdvec(op.Rn);
context.EmitLdc_I4(numBytes); context.EmitLdc_I4(numBytes);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSll)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSll));
@ -92,7 +92,7 @@ namespace ChocolArm64.Instructions
context.EmitLdc_I4(shift); context.EmitLdc_I4(shift);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), typesSll)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), typesSll));
EmitStvecWithUnsignedCast(context, op.Rd, op.Size + 1); context.EmitStvec(op.Rd);
} }
else else
{ {
@ -280,7 +280,7 @@ namespace ChocolArm64.Instructions
int shift = GetImmShr(op); int shift = GetImmShr(op);
int eSize = 8 << op.Size; int eSize = 8 << op.Size;
EmitLdvecWithSignedCast(context, op.Rn, op.Size); context.EmitLdvec(op.Rn);
context.Emit(OpCodes.Dup); context.Emit(OpCodes.Dup);
context.EmitStvectmp(); context.EmitStvectmp();
@ -298,7 +298,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd));
EmitStvecWithSignedCast(context, op.Rd, op.Size); context.EmitStvec(op.Rd);
if (op.RegisterSize == RegisterSize.Simd64) if (op.RegisterSize == RegisterSize.Simd64)
{ {
@ -329,8 +329,8 @@ namespace ChocolArm64.Instructions
int shift = GetImmShr(op); int shift = GetImmShr(op);
int eSize = 8 << op.Size; int eSize = 8 << op.Size;
EmitLdvecWithSignedCast(context, op.Rd, op.Size); context.EmitLdvec(op.Rd);
EmitLdvecWithSignedCast(context, op.Rn, op.Size); context.EmitLdvec(op.Rn);
context.Emit(OpCodes.Dup); context.Emit(OpCodes.Dup);
context.EmitStvectmp(); context.EmitStvectmp();
@ -349,7 +349,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd));
EmitStvecWithSignedCast(context, op.Rd, op.Size); context.EmitStvec(op.Rd);
if (op.RegisterSize == RegisterSize.Simd64) if (op.RegisterSize == RegisterSize.Simd64)
{ {
@ -405,7 +405,7 @@ namespace ChocolArm64.Instructions
int numBytes = op.RegisterSize == RegisterSize.Simd128 ? 8 : 0; int numBytes = op.RegisterSize == RegisterSize.Simd128 ? 8 : 0;
EmitLdvecWithSignedCast(context, op.Rn, op.Size); context.EmitLdvec(op.Rn);
context.EmitLdc_I4(numBytes); context.EmitLdc_I4(numBytes);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSll)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSll));
@ -415,7 +415,7 @@ namespace ChocolArm64.Instructions
context.EmitLdc_I4(shift); context.EmitLdc_I4(shift);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), typesSll)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), typesSll));
EmitStvecWithSignedCast(context, op.Rd, op.Size + 1); context.EmitStvec(op.Rd);
} }
else else
{ {
@ -437,12 +437,12 @@ namespace ChocolArm64.Instructions
{ {
Type[] typesSra = new Type[] { VectorIntTypesPerSizeLog2[op.Size], typeof(byte) }; Type[] typesSra = new Type[] { VectorIntTypesPerSizeLog2[op.Size], typeof(byte) };
EmitLdvecWithSignedCast(context, op.Rn, op.Size); context.EmitLdvec(op.Rn);
context.EmitLdc_I4(GetImmShr(op)); context.EmitLdc_I4(GetImmShr(op));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightArithmetic), typesSra)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightArithmetic), typesSra));
EmitStvecWithSignedCast(context, op.Rd, op.Size); context.EmitStvec(op.Rd);
if (op.RegisterSize == RegisterSize.Simd64) if (op.RegisterSize == RegisterSize.Simd64)
{ {
@ -470,15 +470,15 @@ namespace ChocolArm64.Instructions
Type[] typesSra = new Type[] { VectorIntTypesPerSizeLog2[op.Size], typeof(byte) }; Type[] typesSra = new Type[] { VectorIntTypesPerSizeLog2[op.Size], typeof(byte) };
Type[] typesAdd = new Type[] { VectorIntTypesPerSizeLog2[op.Size], VectorIntTypesPerSizeLog2[op.Size] }; Type[] typesAdd = new Type[] { VectorIntTypesPerSizeLog2[op.Size], VectorIntTypesPerSizeLog2[op.Size] };
EmitLdvecWithSignedCast(context, op.Rd, op.Size); context.EmitLdvec(op.Rd);
EmitLdvecWithSignedCast(context, op.Rn, op.Size); context.EmitLdvec(op.Rn);
context.EmitLdc_I4(GetImmShr(op)); context.EmitLdc_I4(GetImmShr(op));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightArithmetic), typesSra)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightArithmetic), typesSra));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd));
EmitStvecWithSignedCast(context, op.Rd, op.Size); context.EmitStvec(op.Rd);
if (op.RegisterSize == RegisterSize.Simd64) if (op.RegisterSize == RegisterSize.Simd64)
{ {
@ -610,7 +610,7 @@ namespace ChocolArm64.Instructions
int shift = GetImmShr(op); int shift = GetImmShr(op);
int eSize = 8 << op.Size; int eSize = 8 << op.Size;
EmitLdvecWithUnsignedCast(context, op.Rn, op.Size); context.EmitLdvec(op.Rn);
context.Emit(OpCodes.Dup); context.Emit(OpCodes.Dup);
context.EmitStvectmp(); context.EmitStvectmp();
@ -628,7 +628,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd));
EmitStvecWithUnsignedCast(context, op.Rd, op.Size); context.EmitStvec(op.Rd);
if (op.RegisterSize == RegisterSize.Simd64) if (op.RegisterSize == RegisterSize.Simd64)
{ {
@ -658,8 +658,8 @@ namespace ChocolArm64.Instructions
int shift = GetImmShr(op); int shift = GetImmShr(op);
int eSize = 8 << op.Size; int eSize = 8 << op.Size;
EmitLdvecWithUnsignedCast(context, op.Rd, op.Size); context.EmitLdvec(op.Rd);
EmitLdvecWithUnsignedCast(context, op.Rn, op.Size); context.EmitLdvec(op.Rn);
context.Emit(OpCodes.Dup); context.Emit(OpCodes.Dup);
context.EmitStvectmp(); context.EmitStvectmp();
@ -678,7 +678,7 @@ namespace ChocolArm64.Instructions
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd));
EmitStvecWithUnsignedCast(context, op.Rd, op.Size); context.EmitStvec(op.Rd);
if (op.RegisterSize == RegisterSize.Simd64) if (op.RegisterSize == RegisterSize.Simd64)
{ {
@ -734,7 +734,7 @@ namespace ChocolArm64.Instructions
int numBytes = op.RegisterSize == RegisterSize.Simd128 ? 8 : 0; int numBytes = op.RegisterSize == RegisterSize.Simd128 ? 8 : 0;
EmitLdvecWithUnsignedCast(context, op.Rn, op.Size); context.EmitLdvec(op.Rn);
context.EmitLdc_I4(numBytes); context.EmitLdc_I4(numBytes);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSll)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical128BitLane), typesSll));
@ -744,7 +744,7 @@ namespace ChocolArm64.Instructions
context.EmitLdc_I4(shift); context.EmitLdc_I4(shift);
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), typesSll)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftLeftLogical), typesSll));
EmitStvecWithUnsignedCast(context, op.Rd, op.Size + 1); context.EmitStvec(op.Rd);
} }
else else
{ {
@ -765,12 +765,12 @@ namespace ChocolArm64.Instructions
{ {
Type[] typesSrl = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], typeof(byte) }; Type[] typesSrl = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], typeof(byte) };
EmitLdvecWithUnsignedCast(context, op.Rn, op.Size); context.EmitLdvec(op.Rn);
context.EmitLdc_I4(GetImmShr(op)); context.EmitLdc_I4(GetImmShr(op));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), typesSrl)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), typesSrl));
EmitStvecWithUnsignedCast(context, op.Rd, op.Size); context.EmitStvec(op.Rd);
if (op.RegisterSize == RegisterSize.Simd64) if (op.RegisterSize == RegisterSize.Simd64)
{ {
@ -797,15 +797,15 @@ namespace ChocolArm64.Instructions
Type[] typesSrl = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], typeof(byte) }; Type[] typesSrl = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], typeof(byte) };
Type[] typesAdd = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], VectorUIntTypesPerSizeLog2[op.Size] }; Type[] typesAdd = new Type[] { VectorUIntTypesPerSizeLog2[op.Size], VectorUIntTypesPerSizeLog2[op.Size] };
EmitLdvecWithUnsignedCast(context, op.Rd, op.Size); context.EmitLdvec(op.Rd);
EmitLdvecWithUnsignedCast(context, op.Rn, op.Size); context.EmitLdvec(op.Rn);
context.EmitLdc_I4(GetImmShr(op)); context.EmitLdc_I4(GetImmShr(op));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), typesSrl)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.ShiftRightLogical), typesSrl));
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd)); context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.Add), typesAdd));
EmitStvecWithUnsignedCast(context, op.Rd, op.Size); context.EmitStvec(op.Rd);
if (op.RegisterSize == RegisterSize.Simd64) if (op.RegisterSize == RegisterSize.Simd64)
{ {

View file

@ -565,203 +565,5 @@ namespace ChocolArm64.Instructions
throw new PlatformNotSupportedException(); throw new PlatformNotSupportedException();
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<sbyte> VectorSingleToSByte(Vector128<float> vector)
{
if (Sse.IsSupported)
{
return Sse.StaticCast<float, sbyte>(vector);
}
throw new PlatformNotSupportedException();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<short> VectorSingleToInt16(Vector128<float> vector)
{
if (Sse.IsSupported)
{
return Sse.StaticCast<float, short>(vector);
}
throw new PlatformNotSupportedException();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<int> VectorSingleToInt32(Vector128<float> vector)
{
if (Sse.IsSupported)
{
return Sse.StaticCast<float, int>(vector);
}
throw new PlatformNotSupportedException();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<long> VectorSingleToInt64(Vector128<float> vector)
{
if (Sse.IsSupported)
{
return Sse.StaticCast<float, long>(vector);
}
throw new PlatformNotSupportedException();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<byte> VectorSingleToByte(Vector128<float> vector)
{
if (Sse.IsSupported)
{
return Sse.StaticCast<float, byte>(vector);
}
throw new PlatformNotSupportedException();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<ushort> VectorSingleToUInt16(Vector128<float> vector)
{
if (Sse.IsSupported)
{
return Sse.StaticCast<float, ushort>(vector);
}
throw new PlatformNotSupportedException();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<uint> VectorSingleToUInt32(Vector128<float> vector)
{
if (Sse.IsSupported)
{
return Sse.StaticCast<float, uint>(vector);
}
throw new PlatformNotSupportedException();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<ulong> VectorSingleToUInt64(Vector128<float> vector)
{
if (Sse.IsSupported)
{
return Sse.StaticCast<float, ulong>(vector);
}
throw new PlatformNotSupportedException();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<double> VectorSingleToDouble(Vector128<float> vector)
{
if (Sse.IsSupported)
{
return Sse.StaticCast<float, double>(vector);
}
throw new PlatformNotSupportedException();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<float> VectorSByteToSingle(Vector128<sbyte> vector)
{
if (Sse.IsSupported)
{
return Sse.StaticCast<sbyte, float>(vector);
}
throw new PlatformNotSupportedException();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<float> VectorInt16ToSingle(Vector128<short> vector)
{
if (Sse.IsSupported)
{
return Sse.StaticCast<short, float>(vector);
}
throw new PlatformNotSupportedException();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<float> VectorInt32ToSingle(Vector128<int> vector)
{
if (Sse.IsSupported)
{
return Sse.StaticCast<int, float>(vector);
}
throw new PlatformNotSupportedException();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<float> VectorInt64ToSingle(Vector128<long> vector)
{
if (Sse.IsSupported)
{
return Sse.StaticCast<long, float>(vector);
}
throw new PlatformNotSupportedException();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<float> VectorByteToSingle(Vector128<byte> vector)
{
if (Sse.IsSupported)
{
return Sse.StaticCast<byte, float>(vector);
}
throw new PlatformNotSupportedException();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<float> VectorUInt16ToSingle(Vector128<ushort> vector)
{
if (Sse.IsSupported)
{
return Sse.StaticCast<ushort, float>(vector);
}
throw new PlatformNotSupportedException();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<float> VectorUInt32ToSingle(Vector128<uint> vector)
{
if (Sse.IsSupported)
{
return Sse.StaticCast<uint, float>(vector);
}
throw new PlatformNotSupportedException();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<float> VectorUInt64ToSingle(Vector128<ulong> vector)
{
if (Sse.IsSupported)
{
return Sse.StaticCast<ulong, float>(vector);
}
throw new PlatformNotSupportedException();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector128<float> VectorDoubleToSingle(Vector128<double> vector)
{
if (Sse.IsSupported)
{
return Sse.StaticCast<double, float>(vector);
}
throw new PlatformNotSupportedException();
}
} }
} }