Support scalar vector loads/stores on the memory fast path, and minor fixes

This commit is contained in:
gdkchan 2019-02-21 21:50:48 -03:00
commit cce27226d0
2 changed files with 52 additions and 5 deletions

View file

@ -158,7 +158,7 @@ namespace ChocolArm64.Instructions
} }
else else
{ {
throw new InvalidOperationException($"Invalid store size of {1 << op.Size} bytes."); throw new InvalidOperationException($"Invalid load size of {1 << op.Size} bytes.");
} }
} }
else else

View file

@ -51,7 +51,7 @@ namespace ChocolArm64.Instructions
if (isSimd) if (isSimd)
{ {
if (size != 4) if (context.Tier == TranslationTier.Tier0 || !Sse2.IsSupported || size < 2)
{ {
EmitReadVectorFallback(context, size); EmitReadVectorFallback(context, size);
} }
@ -118,7 +118,7 @@ namespace ChocolArm64.Instructions
if (isSimd) if (isSimd)
{ {
if (size != 4) if (context.Tier == TranslationTier.Tier0 || !Sse2.IsSupported || size < 2)
{ {
EmitWriteVectorFallback(context, size); EmitWriteVectorFallback(context, size);
} }
@ -198,7 +198,25 @@ namespace ChocolArm64.Instructions
EmitPtPointerLoad(context, lblSlowPath); EmitPtPointerLoad(context, lblSlowPath);
context.EmitCall(typeof(Sse), nameof(Sse.LoadVector128)); switch (size)
{
case 2: context.EmitCall(typeof(Sse), nameof(Sse.LoadScalarVector128)); break;
case 3:
{
Type[] types = new Type[] { typeof(double*) };
context.EmitCall(typeof(Sse2).GetMethod(nameof(Sse2.LoadScalarVector128), types));
VectorHelper.EmitCall(context, nameof(VectorHelper.VectorDoubleToSingle));
break;
}
case 4: context.EmitCall(typeof(Sse), nameof(Sse.LoadAlignedVector128)); break;
throw new InvalidOperationException($"Invalid vector load size of {1 << size} bytes.");
}
context.MarkLabel(lblEnd); context.MarkLabel(lblEnd);
} }
@ -263,7 +281,14 @@ namespace ChocolArm64.Instructions
context.EmitLdvec(_tempVecValue); context.EmitLdvec(_tempVecValue);
context.EmitCall(typeof(Sse), nameof(Sse.Store)); switch (size)
{
case 2: context.EmitCall(typeof(Sse), nameof(Sse.StoreScalar)); break;
case 3: context.EmitCall(typeof(Sse2), nameof(Sse2.StoreScalar)); break;
case 4: context.EmitCall(typeof(Sse), nameof(Sse.StoreAligned)); break;
default: throw new InvalidOperationException($"Invalid vector store size of {1 << size} bytes.");
}
context.MarkLabel(lblEnd); context.MarkLabel(lblEnd);
} }
@ -350,6 +375,11 @@ namespace ChocolArm64.Instructions
context.EmitLdarg(TranslatedSub.MemoryArgIdx); context.EmitLdarg(TranslatedSub.MemoryArgIdx);
context.EmitLdint(_tempIntAddress); context.EmitLdint(_tempIntAddress);
if (context.CurrOp.RegisterSize == RegisterSize.Int32)
{
context.Emit(OpCodes.Conv_U8);
}
string fallbackMethodName = null; string fallbackMethodName = null;
switch (size) switch (size)
@ -368,6 +398,11 @@ namespace ChocolArm64.Instructions
context.EmitLdarg(TranslatedSub.MemoryArgIdx); context.EmitLdarg(TranslatedSub.MemoryArgIdx);
context.EmitLdint(_tempIntAddress); context.EmitLdint(_tempIntAddress);
if (context.CurrOp.RegisterSize == RegisterSize.Int32)
{
context.Emit(OpCodes.Conv_U8);
}
string fallbackMethodName = null; string fallbackMethodName = null;
switch (size) switch (size)
@ -386,6 +421,12 @@ namespace ChocolArm64.Instructions
{ {
context.EmitLdarg(TranslatedSub.MemoryArgIdx); context.EmitLdarg(TranslatedSub.MemoryArgIdx);
context.EmitLdint(_tempIntAddress); context.EmitLdint(_tempIntAddress);
if (context.CurrOp.RegisterSize == RegisterSize.Int32)
{
context.Emit(OpCodes.Conv_U8);
}
context.EmitLdint(_tempIntValue); context.EmitLdint(_tempIntValue);
if (size < 3) if (size < 3)
@ -410,6 +451,12 @@ namespace ChocolArm64.Instructions
{ {
context.EmitLdarg(TranslatedSub.MemoryArgIdx); context.EmitLdarg(TranslatedSub.MemoryArgIdx);
context.EmitLdint(_tempIntAddress); context.EmitLdint(_tempIntAddress);
if (context.CurrOp.RegisterSize == RegisterSize.Int32)
{
context.Emit(OpCodes.Conv_U8);
}
context.EmitLdvec(_tempVecValue); context.EmitLdvec(_tempVecValue);
string fallbackMethodName = null; string fallbackMethodName = null;