Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
7baa08dcb4 |
@@ -1352,7 +1352,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
if (op.Size <= 2)
|
if (op.Size <= 2)
|
||||||
{
|
{
|
||||||
de = EmitSatQ(context, emit(ne), op.Size, signedSrc: true, signedDst: true);
|
de = EmitSignedSrcSatQ(context, emit(ne), op.Size, signedDst: true);
|
||||||
}
|
}
|
||||||
else /* if (op.Size == 3) */
|
else /* if (op.Size == 3) */
|
||||||
{
|
{
|
||||||
@@ -1419,15 +1419,18 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
Operand temp = add ? context.Add(ne, me) : context.Subtract(ne, me);
|
Operand temp = add ? context.Add(ne, me) : context.Subtract(ne, me);
|
||||||
|
|
||||||
de = EmitSatQ(context, temp, op.Size, signedSrc: true, signedDst: signed);
|
de = EmitSignedSrcSatQ(context, temp, op.Size, signedDst: signed);
|
||||||
}
|
}
|
||||||
else if (add) /* if (op.Size == 3) */
|
else /* if (op.Size == 3) */
|
||||||
{
|
{
|
||||||
de = EmitBinarySatQAdd(context, ne, me, signed);
|
if (add)
|
||||||
}
|
{
|
||||||
else /* if (sub) */
|
de = signed ? EmitBinarySignedSatQAdd(context, ne, me) : EmitBinaryUnsignedSatQAdd(context, ne, me);
|
||||||
{
|
}
|
||||||
de = EmitBinarySatQSub(context, ne, me, signed);
|
else /* if (sub) */
|
||||||
|
{
|
||||||
|
de = signed ? EmitBinarySignedSatQSub(context, ne, me) : EmitBinaryUnsignedSatQSub(context, ne, me);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
res = EmitVectorInsert(context, res, de, index, op.Size);
|
res = EmitVectorInsert(context, res, de, index, op.Size);
|
||||||
@@ -1445,11 +1448,11 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
Operand temp = context.Add(ne, me);
|
Operand temp = context.Add(ne, me);
|
||||||
|
|
||||||
de = EmitSatQ(context, temp, op.Size, signedSrc: true, signedDst: signed);
|
de = EmitSignedSrcSatQ(context, temp, op.Size, signedDst: signed);
|
||||||
}
|
}
|
||||||
else /* if (op.Size == 3) */
|
else /* if (op.Size == 3) */
|
||||||
{
|
{
|
||||||
de = EmitBinarySatQAccumulate(context, ne, me, signed);
|
de = signed ? EmitBinarySignedSatQAcc(context, ne, me) : EmitBinaryUnsignedSatQAcc(context, ne, me);
|
||||||
}
|
}
|
||||||
|
|
||||||
res = EmitVectorInsert(context, res, de, index, op.Size);
|
res = EmitVectorInsert(context, res, de, index, op.Size);
|
||||||
@@ -1475,7 +1478,7 @@ namespace ARMeilleure.Instructions
|
|||||||
me = EmitVectorExtract(context, ((OpCodeSimdReg)op).Rm, index, op.Size, signed);
|
me = EmitVectorExtract(context, ((OpCodeSimdReg)op).Rm, index, op.Size, signed);
|
||||||
}
|
}
|
||||||
|
|
||||||
Operand de = EmitSatQ(context, emit(ne, me), op.Size, true, signed);
|
Operand de = EmitSignedSrcSatQ(context, emit(ne, me), op.Size, signedDst: signed);
|
||||||
|
|
||||||
res = EmitVectorInsert(context, res, de, index, op.Size);
|
res = EmitVectorInsert(context, res, de, index, op.Size);
|
||||||
}
|
}
|
||||||
@@ -1520,7 +1523,9 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
Operand ne = EmitVectorExtract(context, op.Rn, index, op.Size + 1, signedSrc);
|
Operand ne = EmitVectorExtract(context, op.Rn, index, op.Size + 1, signedSrc);
|
||||||
|
|
||||||
Operand temp = EmitSatQ(context, ne, op.Size, signedSrc, signedDst);
|
Operand temp = signedSrc
|
||||||
|
? EmitSignedSrcSatQ(context, ne, op.Size, signedDst)
|
||||||
|
: EmitUnsignedSrcSatQ(context, ne, op.Size, signedDst);
|
||||||
|
|
||||||
res = EmitVectorInsert(context, res, temp, part + index, op.Size);
|
res = EmitVectorInsert(context, res, temp, part + index, op.Size);
|
||||||
}
|
}
|
||||||
@@ -1528,74 +1533,248 @@ namespace ARMeilleure.Instructions
|
|||||||
context.Copy(d, res);
|
context.Copy(d, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TSrc (16bit, 32bit, 64bit; signed, unsigned) > TDst (8bit, 16bit, 32bit; signed, unsigned).
|
// TSrc (16bit, 32bit, 64bit; signed) > TDst (8bit, 16bit, 32bit; signed, unsigned).
|
||||||
public static Operand EmitSatQ(ArmEmitterContext context, Operand op, int sizeDst, bool signedSrc, bool signedDst)
|
// long SignedSrcSignedDstSatQ(long op, int size); ulong SignedSrcUnsignedDstSatQ(long op, int size);
|
||||||
|
public static Operand EmitSignedSrcSatQ(ArmEmitterContext context, Operand op, int sizeDst, bool signedDst)
|
||||||
{
|
{
|
||||||
if ((uint)sizeDst > 2u)
|
Debug.Assert(op.Type == OperandType.I64 && (uint)sizeDst <= 2u);
|
||||||
{
|
|
||||||
throw new ArgumentOutOfRangeException(nameof(sizeDst));
|
|
||||||
}
|
|
||||||
|
|
||||||
MethodInfo info;
|
Operand lbl1 = Label();
|
||||||
|
Operand lblEnd = Label();
|
||||||
|
|
||||||
if (signedSrc)
|
int eSize = 8 << sizeDst;
|
||||||
{
|
|
||||||
info = signedDst
|
|
||||||
? typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedSrcSignedDstSatQ))
|
|
||||||
: typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedSrcUnsignedDstSatQ));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
info = signedDst
|
|
||||||
? typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedSrcSignedDstSatQ))
|
|
||||||
: typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedSrcUnsignedDstSatQ));
|
|
||||||
}
|
|
||||||
|
|
||||||
return context.Call(info, op, Const(sizeDst));
|
Operand maxT = signedDst ? Const((1L << (eSize - 1)) - 1L) : Const((1UL << eSize) - 1UL);
|
||||||
|
Operand minT = signedDst ? Const(-(1L << (eSize - 1))) : Const(0UL);
|
||||||
|
|
||||||
|
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), op);
|
||||||
|
|
||||||
|
context.BranchIf(lbl1, res, maxT, Comparison.LessOrEqual);
|
||||||
|
context.Copy(res, maxT);
|
||||||
|
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||||
|
context.Branch(lblEnd);
|
||||||
|
|
||||||
|
context.MarkLabel(lbl1);
|
||||||
|
context.BranchIf(lblEnd, res, minT, Comparison.GreaterOrEqual);
|
||||||
|
context.Copy(res, minT);
|
||||||
|
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||||
|
context.Branch(lblEnd);
|
||||||
|
|
||||||
|
context.MarkLabel(lblEnd);
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TSrc (64bit) == TDst (64bit); signed.
|
// TSrc (16bit, 32bit, 64bit; unsigned) > TDst (8bit, 16bit, 32bit; signed, unsigned).
|
||||||
public static Operand EmitUnarySignedSatQAbsOrNeg(ArmEmitterContext context, Operand op)
|
// long UnsignedSrcSignedDstSatQ(ulong op, int size); ulong UnsignedSrcUnsignedDstSatQ(ulong op, int size);
|
||||||
|
public static Operand EmitUnsignedSrcSatQ(ArmEmitterContext context, Operand op, int sizeDst, bool signedDst)
|
||||||
{
|
{
|
||||||
Debug.Assert(((OpCodeSimd)context.CurrOp).Size == 3, "Invalid element size.");
|
Debug.Assert(op.Type == OperandType.I64 && (uint)sizeDst <= 2u);
|
||||||
|
|
||||||
return context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnarySignedSatQAbsOrNeg)), op);
|
Operand lblEnd = Label();
|
||||||
|
|
||||||
|
int eSize = 8 << sizeDst;
|
||||||
|
|
||||||
|
Operand maxL = signedDst ? Const((1L << (eSize - 1)) - 1L) : Const((1UL << eSize) - 1UL);
|
||||||
|
|
||||||
|
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), op);
|
||||||
|
|
||||||
|
context.BranchIf(lblEnd, res, maxL, Comparison.LessOrEqualUI);
|
||||||
|
context.Copy(res, maxL);
|
||||||
|
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||||
|
context.Branch(lblEnd);
|
||||||
|
|
||||||
|
context.MarkLabel(lblEnd);
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TSrcs (64bit) == TDst (64bit); signed, unsigned.
|
// long UnarySignedSatQAbsOrNeg(long op);
|
||||||
public static Operand EmitBinarySatQAdd(ArmEmitterContext context, Operand op1, Operand op2, bool signed)
|
private static Operand EmitUnarySignedSatQAbsOrNeg(ArmEmitterContext context, Operand op)
|
||||||
{
|
{
|
||||||
Debug.Assert(((OpCodeSimd)context.CurrOp).Size == 3, "Invalid element size.");
|
Debug.Assert(op.Type == OperandType.I64);
|
||||||
|
|
||||||
MethodInfo info = signed
|
Operand lblEnd = Label();
|
||||||
? typeof(SoftFallback).GetMethod(nameof(SoftFallback.BinarySignedSatQAdd))
|
|
||||||
: typeof(SoftFallback).GetMethod(nameof(SoftFallback.BinaryUnsignedSatQAdd));
|
|
||||||
|
|
||||||
return context.Call(info, op1, op2);
|
Operand minL = Const(long.MinValue);
|
||||||
|
Operand maxL = Const(long.MaxValue);
|
||||||
|
|
||||||
|
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), op);
|
||||||
|
|
||||||
|
context.BranchIf(lblEnd, res, minL, Comparison.NotEqual);
|
||||||
|
context.Copy(res, maxL);
|
||||||
|
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||||
|
context.Branch(lblEnd);
|
||||||
|
|
||||||
|
context.MarkLabel(lblEnd);
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TSrcs (64bit) == TDst (64bit); signed, unsigned.
|
// long BinarySignedSatQAdd(long op1, long op2);
|
||||||
public static Operand EmitBinarySatQSub(ArmEmitterContext context, Operand op1, Operand op2, bool signed)
|
private static Operand EmitBinarySignedSatQAdd(ArmEmitterContext context, Operand op1, Operand op2)
|
||||||
{
|
{
|
||||||
Debug.Assert(((OpCodeSimd)context.CurrOp).Size == 3, "Invalid element size.");
|
Debug.Assert(op1.Type == OperandType.I64 && op2.Type == OperandType.I64);
|
||||||
|
|
||||||
MethodInfo info = signed
|
Operand lblEnd = Label();
|
||||||
? typeof(SoftFallback).GetMethod(nameof(SoftFallback.BinarySignedSatQSub))
|
|
||||||
: typeof(SoftFallback).GetMethod(nameof(SoftFallback.BinaryUnsignedSatQSub));
|
|
||||||
|
|
||||||
return context.Call(info, op1, op2);
|
Operand minL = Const(long.MinValue);
|
||||||
|
Operand maxL = Const(long.MaxValue);
|
||||||
|
Operand zero = Const(0L);
|
||||||
|
|
||||||
|
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), context.Add(op1, op2));
|
||||||
|
|
||||||
|
Operand left = context.BitwiseNot(context.BitwiseExclusiveOr(op1, op2));
|
||||||
|
Operand right = context.BitwiseExclusiveOr(op1, res);
|
||||||
|
context.BranchIf(lblEnd, context.BitwiseAnd(left, right), zero, Comparison.GreaterOrEqual);
|
||||||
|
|
||||||
|
Operand isPositive = context.ICompareGreaterOrEqual(op1, zero);
|
||||||
|
context.Copy(res, context.ConditionalSelect(isPositive, maxL, minL));
|
||||||
|
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||||
|
context.Branch(lblEnd);
|
||||||
|
|
||||||
|
context.MarkLabel(lblEnd);
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TSrcs (64bit) == TDst (64bit); signed, unsigned.
|
// ulong BinaryUnsignedSatQAdd(ulong op1, ulong op2);
|
||||||
public static Operand EmitBinarySatQAccumulate(ArmEmitterContext context, Operand op1, Operand op2, bool signed)
|
private static Operand EmitBinaryUnsignedSatQAdd(ArmEmitterContext context, Operand op1, Operand op2)
|
||||||
{
|
{
|
||||||
Debug.Assert(((OpCodeSimd)context.CurrOp).Size == 3, "Invalid element size.");
|
Debug.Assert(op1.Type == OperandType.I64 && op2.Type == OperandType.I64);
|
||||||
|
|
||||||
MethodInfo info = signed
|
Operand lblEnd = Label();
|
||||||
? typeof(SoftFallback).GetMethod(nameof(SoftFallback.BinarySignedSatQAcc))
|
|
||||||
: typeof(SoftFallback).GetMethod(nameof(SoftFallback.BinaryUnsignedSatQAcc));
|
|
||||||
|
|
||||||
return context.Call(info, op1, op2);
|
Operand maxUL = Const(ulong.MaxValue);
|
||||||
|
|
||||||
|
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), context.Add(op1, op2));
|
||||||
|
|
||||||
|
context.BranchIf(lblEnd, res, op1, Comparison.GreaterOrEqualUI);
|
||||||
|
context.Copy(res, maxUL);
|
||||||
|
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||||
|
context.Branch(lblEnd);
|
||||||
|
|
||||||
|
context.MarkLabel(lblEnd);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// long BinarySignedSatQSub(long op1, long op2);
|
||||||
|
private static Operand EmitBinarySignedSatQSub(ArmEmitterContext context, Operand op1, Operand op2)
|
||||||
|
{
|
||||||
|
Debug.Assert(op1.Type == OperandType.I64 && op2.Type == OperandType.I64);
|
||||||
|
|
||||||
|
Operand lblEnd = Label();
|
||||||
|
|
||||||
|
Operand minL = Const(long.MinValue);
|
||||||
|
Operand maxL = Const(long.MaxValue);
|
||||||
|
Operand zero = Const(0L);
|
||||||
|
|
||||||
|
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), context.Subtract(op1, op2));
|
||||||
|
|
||||||
|
Operand left = context.BitwiseExclusiveOr(op1, op2);
|
||||||
|
Operand right = context.BitwiseExclusiveOr(op1, res);
|
||||||
|
context.BranchIf(lblEnd, context.BitwiseAnd(left, right), zero, Comparison.GreaterOrEqual);
|
||||||
|
|
||||||
|
Operand isPositive = context.ICompareGreaterOrEqual(op1, zero);
|
||||||
|
context.Copy(res, context.ConditionalSelect(isPositive, maxL, minL));
|
||||||
|
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||||
|
context.Branch(lblEnd);
|
||||||
|
|
||||||
|
context.MarkLabel(lblEnd);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ulong BinaryUnsignedSatQSub(ulong op1, ulong op2);
|
||||||
|
private static Operand EmitBinaryUnsignedSatQSub(ArmEmitterContext context, Operand op1, Operand op2)
|
||||||
|
{
|
||||||
|
Debug.Assert(op1.Type == OperandType.I64 && op2.Type == OperandType.I64);
|
||||||
|
|
||||||
|
Operand lblEnd = Label();
|
||||||
|
|
||||||
|
Operand zero = Const(0L);
|
||||||
|
|
||||||
|
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), context.Subtract(op1, op2));
|
||||||
|
|
||||||
|
context.BranchIf(lblEnd, op1, op2, Comparison.GreaterOrEqualUI);
|
||||||
|
context.Copy(res, zero);
|
||||||
|
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||||
|
context.Branch(lblEnd);
|
||||||
|
|
||||||
|
context.MarkLabel(lblEnd);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// long BinarySignedSatQAcc(ulong op1, long op2);
|
||||||
|
private static Operand EmitBinarySignedSatQAcc(ArmEmitterContext context, Operand op1, Operand op2)
|
||||||
|
{
|
||||||
|
Debug.Assert(op1.Type == OperandType.I64 && op2.Type == OperandType.I64);
|
||||||
|
|
||||||
|
Operand lbl1 = Label();
|
||||||
|
Operand lbl2 = Label();
|
||||||
|
Operand lblEnd = Label();
|
||||||
|
|
||||||
|
Operand maxL = Const(long.MaxValue);
|
||||||
|
Operand zero = Const(0L);
|
||||||
|
|
||||||
|
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), context.Add(op1, op2));
|
||||||
|
|
||||||
|
context.BranchIf(lbl1, op1, maxL, Comparison.GreaterUI);
|
||||||
|
Operand notOp2AndRes = context.BitwiseAnd(context.BitwiseNot(op2), res);
|
||||||
|
context.BranchIf(lblEnd, notOp2AndRes, zero, Comparison.GreaterOrEqual);
|
||||||
|
context.Copy(res, maxL);
|
||||||
|
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||||
|
context.Branch(lblEnd);
|
||||||
|
|
||||||
|
context.MarkLabel(lbl1);
|
||||||
|
context.BranchIf(lbl2, op2, zero, Comparison.Less);
|
||||||
|
context.Copy(res, maxL);
|
||||||
|
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||||
|
context.Branch(lblEnd);
|
||||||
|
|
||||||
|
context.MarkLabel(lbl2);
|
||||||
|
context.BranchIf(lblEnd, res, maxL, Comparison.LessOrEqualUI);
|
||||||
|
context.Copy(res, maxL);
|
||||||
|
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||||
|
context.Branch(lblEnd);
|
||||||
|
|
||||||
|
context.MarkLabel(lblEnd);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ulong BinaryUnsignedSatQAcc(long op1, ulong op2);
|
||||||
|
private static Operand EmitBinaryUnsignedSatQAcc(ArmEmitterContext context, Operand op1, Operand op2)
|
||||||
|
{
|
||||||
|
Debug.Assert(op1.Type == OperandType.I64 && op2.Type == OperandType.I64);
|
||||||
|
|
||||||
|
Operand lbl1 = Label();
|
||||||
|
Operand lblEnd = Label();
|
||||||
|
|
||||||
|
Operand maxUL = Const(ulong.MaxValue);
|
||||||
|
Operand maxL = Const(long.MaxValue);
|
||||||
|
Operand zero = Const(0L);
|
||||||
|
|
||||||
|
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), context.Add(op1, op2));
|
||||||
|
|
||||||
|
context.BranchIf(lbl1, op1, zero, Comparison.Less);
|
||||||
|
context.BranchIf(lblEnd, res, op1, Comparison.GreaterOrEqualUI);
|
||||||
|
context.Copy(res, maxUL);
|
||||||
|
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||||
|
context.Branch(lblEnd);
|
||||||
|
|
||||||
|
context.MarkLabel(lbl1);
|
||||||
|
context.BranchIf(lblEnd, op2, maxL, Comparison.GreaterUI);
|
||||||
|
context.BranchIf(lblEnd, res, zero, Comparison.GreaterOrEqual);
|
||||||
|
context.Copy(res, zero);
|
||||||
|
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||||
|
context.Branch(lblEnd);
|
||||||
|
|
||||||
|
context.MarkLabel(lblEnd);
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Operand EmitFloatAbs(ArmEmitterContext context, Operand value, bool single, bool vector)
|
public static Operand EmitFloatAbs(ArmEmitterContext context, Operand value, bool single, bool vector)
|
||||||
|
@@ -1004,7 +1004,7 @@ namespace ARMeilleure.Instructions
|
|||||||
e = EmitShrImm64(context, e, signedSrc, roundConst, shift); // shift <= 32
|
e = EmitShrImm64(context, e, signedSrc, roundConst, shift); // shift <= 32
|
||||||
}
|
}
|
||||||
|
|
||||||
e = EmitSatQ(context, e, op.Size, signedSrc, signedDst);
|
e = signedSrc ? EmitSignedSrcSatQ(context, e, op.Size, signedDst) : EmitUnsignedSrcSatQ(context, e, op.Size, signedDst);
|
||||||
|
|
||||||
res = EmitVectorInsert(context, res, e, part + index, op.Size);
|
res = EmitVectorInsert(context, res, e, part + index, op.Size);
|
||||||
}
|
}
|
||||||
|
@@ -91,7 +91,7 @@ namespace ARMeilleure.Instructions
|
|||||||
}
|
}
|
||||||
else /* if (eSize != 64) */
|
else /* if (eSize != 64) */
|
||||||
{
|
{
|
||||||
return SignedSrcSignedDstSatQ(value << shiftLsB, size);
|
return SignedSrcSignedDstSatQ(value << shiftLsB, size); // InstEmitSimdHelper.EmitSignedSrcSatQ(signedDst: true).
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else /* if (shiftLsB == 0) */
|
else /* if (shiftLsB == 0) */
|
||||||
@@ -135,7 +135,7 @@ namespace ARMeilleure.Instructions
|
|||||||
}
|
}
|
||||||
else /* if (eSize != 64) */
|
else /* if (eSize != 64) */
|
||||||
{
|
{
|
||||||
return UnsignedSrcUnsignedDstSatQ(value << shiftLsB, size);
|
return UnsignedSrcUnsignedDstSatQ(value << shiftLsB, size); // InstEmitSimdHelper.EmitUnsignedSrcSatQ(signedDst: false).
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else /* if (shiftLsB == 0) */
|
else /* if (shiftLsB == 0) */
|
||||||
@@ -509,7 +509,7 @@ namespace ARMeilleure.Instructions
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region "Saturating"
|
#region "Saturating"
|
||||||
public static long SignedSrcSignedDstSatQ(long op, int size)
|
private static long SignedSrcSignedDstSatQ(long op, int size)
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
|
|
||||||
@@ -536,54 +536,7 @@ namespace ARMeilleure.Instructions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ulong SignedSrcUnsignedDstSatQ(long op, int size)
|
private static ulong UnsignedSrcUnsignedDstSatQ(ulong op, int size)
|
||||||
{
|
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
|
||||||
|
|
||||||
int eSize = 8 << size;
|
|
||||||
|
|
||||||
ulong tMaxValue = (1UL << eSize) - 1UL;
|
|
||||||
ulong tMinValue = 0UL;
|
|
||||||
|
|
||||||
if (op > (long)tMaxValue)
|
|
||||||
{
|
|
||||||
context.Fpsr |= FPSR.Qc;
|
|
||||||
|
|
||||||
return tMaxValue;
|
|
||||||
}
|
|
||||||
else if (op < (long)tMinValue)
|
|
||||||
{
|
|
||||||
context.Fpsr |= FPSR.Qc;
|
|
||||||
|
|
||||||
return tMinValue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return (ulong)op;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long UnsignedSrcSignedDstSatQ(ulong op, int size)
|
|
||||||
{
|
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
|
||||||
|
|
||||||
int eSize = 8 << size;
|
|
||||||
|
|
||||||
long tMaxValue = (1L << (eSize - 1)) - 1L;
|
|
||||||
|
|
||||||
if (op > (ulong)tMaxValue)
|
|
||||||
{
|
|
||||||
context.Fpsr |= FPSR.Qc;
|
|
||||||
|
|
||||||
return tMaxValue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return (long)op;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ulong UnsignedSrcUnsignedDstSatQ(ulong op, int size)
|
|
||||||
{
|
{
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
ExecutionContext context = NativeInterface.GetContext();
|
||||||
|
|
||||||
@@ -602,208 +555,6 @@ namespace ARMeilleure.Instructions
|
|||||||
return op;
|
return op;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long UnarySignedSatQAbsOrNeg(long op)
|
|
||||||
{
|
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
|
||||||
|
|
||||||
if (op == long.MinValue)
|
|
||||||
{
|
|
||||||
context.Fpsr |= FPSR.Qc;
|
|
||||||
|
|
||||||
return long.MaxValue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return op;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long BinarySignedSatQAdd(long op1, long op2)
|
|
||||||
{
|
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
|
||||||
|
|
||||||
long add = op1 + op2;
|
|
||||||
|
|
||||||
if ((~(op1 ^ op2) & (op1 ^ add)) < 0L)
|
|
||||||
{
|
|
||||||
context.Fpsr |= FPSR.Qc;
|
|
||||||
|
|
||||||
if (op1 < 0L)
|
|
||||||
{
|
|
||||||
return long.MinValue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return long.MaxValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return add;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ulong BinaryUnsignedSatQAdd(ulong op1, ulong op2)
|
|
||||||
{
|
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
|
||||||
|
|
||||||
ulong add = op1 + op2;
|
|
||||||
|
|
||||||
if ((add < op1) && (add < op2))
|
|
||||||
{
|
|
||||||
context.Fpsr |= FPSR.Qc;
|
|
||||||
|
|
||||||
return ulong.MaxValue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return add;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long BinarySignedSatQSub(long op1, long op2)
|
|
||||||
{
|
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
|
||||||
|
|
||||||
long sub = op1 - op2;
|
|
||||||
|
|
||||||
if (((op1 ^ op2) & (op1 ^ sub)) < 0L)
|
|
||||||
{
|
|
||||||
context.Fpsr |= FPSR.Qc;
|
|
||||||
|
|
||||||
if (op1 < 0L)
|
|
||||||
{
|
|
||||||
return long.MinValue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return long.MaxValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return sub;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ulong BinaryUnsignedSatQSub(ulong op1, ulong op2)
|
|
||||||
{
|
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
|
||||||
|
|
||||||
ulong sub = op1 - op2;
|
|
||||||
|
|
||||||
if (op1 < op2)
|
|
||||||
{
|
|
||||||
context.Fpsr |= FPSR.Qc;
|
|
||||||
|
|
||||||
return ulong.MinValue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return sub;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long BinarySignedSatQAcc(ulong op1, long op2)
|
|
||||||
{
|
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
|
||||||
|
|
||||||
if (op1 <= (ulong)long.MaxValue)
|
|
||||||
{
|
|
||||||
// op1 from ulong.MinValue to (ulong)long.MaxValue
|
|
||||||
// op2 from long.MinValue to long.MaxValue
|
|
||||||
|
|
||||||
long add = (long)op1 + op2;
|
|
||||||
|
|
||||||
if ((~op2 & add) < 0L)
|
|
||||||
{
|
|
||||||
context.Fpsr |= FPSR.Qc;
|
|
||||||
|
|
||||||
return long.MaxValue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return add;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (op2 >= 0L)
|
|
||||||
{
|
|
||||||
// op1 from (ulong)long.MaxValue + 1UL to ulong.MaxValue
|
|
||||||
// op2 from (long)ulong.MinValue to long.MaxValue
|
|
||||||
|
|
||||||
context.Fpsr |= FPSR.Qc;
|
|
||||||
|
|
||||||
return long.MaxValue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// op1 from (ulong)long.MaxValue + 1UL to ulong.MaxValue
|
|
||||||
// op2 from long.MinValue to (long)ulong.MinValue - 1L
|
|
||||||
|
|
||||||
ulong add = op1 + (ulong)op2;
|
|
||||||
|
|
||||||
if (add > (ulong)long.MaxValue)
|
|
||||||
{
|
|
||||||
context.Fpsr |= FPSR.Qc;
|
|
||||||
|
|
||||||
return long.MaxValue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return (long)add;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ulong BinaryUnsignedSatQAcc(long op1, ulong op2)
|
|
||||||
{
|
|
||||||
ExecutionContext context = NativeInterface.GetContext();
|
|
||||||
|
|
||||||
if (op1 >= 0L)
|
|
||||||
{
|
|
||||||
// op1 from (long)ulong.MinValue to long.MaxValue
|
|
||||||
// op2 from ulong.MinValue to ulong.MaxValue
|
|
||||||
|
|
||||||
ulong add = (ulong)op1 + op2;
|
|
||||||
|
|
||||||
if ((add < (ulong)op1) && (add < op2))
|
|
||||||
{
|
|
||||||
context.Fpsr |= FPSR.Qc;
|
|
||||||
|
|
||||||
return ulong.MaxValue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return add;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (op2 > (ulong)long.MaxValue)
|
|
||||||
{
|
|
||||||
// op1 from long.MinValue to (long)ulong.MinValue - 1L
|
|
||||||
// op2 from (ulong)long.MaxValue + 1UL to ulong.MaxValue
|
|
||||||
|
|
||||||
return (ulong)op1 + op2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// op1 from long.MinValue to (long)ulong.MinValue - 1L
|
|
||||||
// op2 from ulong.MinValue to (ulong)long.MaxValue
|
|
||||||
|
|
||||||
long add = op1 + (long)op2;
|
|
||||||
|
|
||||||
if (add < (long)ulong.MinValue)
|
|
||||||
{
|
|
||||||
context.Fpsr |= FPSR.Qc;
|
|
||||||
|
|
||||||
return ulong.MinValue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return (ulong)add;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region "Count"
|
#region "Count"
|
||||||
|
@@ -127,7 +127,7 @@ namespace ARMeilleure.Translation
|
|||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpcr)));
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpcr)));
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpscr))); // A32 only.
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpscr))); // A32 only.
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsr)));
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsr)));
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc))); // A32 only.
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetTpidrEl0)));
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetTpidrEl0)));
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetTpidrEl032))); // A32 only.
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetTpidrEl032))); // A32 only.
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SignalMemoryTracking)));
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SignalMemoryTracking)));
|
||||||
@@ -140,12 +140,6 @@ namespace ARMeilleure.Translation
|
|||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt64)));
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteUInt64)));
|
||||||
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteVector128)));
|
SetDelegateInfo(typeof(NativeInterface).GetMethod(nameof(NativeInterface.WriteVector128)));
|
||||||
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.BinarySignedSatQAcc)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.BinarySignedSatQAdd)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.BinarySignedSatQSub)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.BinaryUnsignedSatQAcc)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.BinaryUnsignedSatQAdd)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.BinaryUnsignedSatQSub)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.CountLeadingSigns)));
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.CountLeadingSigns)));
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.CountLeadingZeros)));
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.CountLeadingZeros)));
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32b)));
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Crc32b)));
|
||||||
@@ -188,8 +182,6 @@ namespace ARMeilleure.Translation
|
|||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShlReg)));
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShlReg)));
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShlRegSatQ)));
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShlRegSatQ)));
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShrImm64)));
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShrImm64)));
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedSrcSignedDstSatQ)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedSrcUnsignedDstSatQ)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl1)));
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl1)));
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl2)));
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl2)));
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl3)));
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl3)));
|
||||||
@@ -198,12 +190,9 @@ namespace ARMeilleure.Translation
|
|||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx2)));
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx2)));
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx3)));
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx3)));
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx4)));
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx4)));
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnarySignedSatQAbsOrNeg)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShlReg)));
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShlReg)));
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShlRegSatQ)));
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShlRegSatQ)));
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShrImm64)));
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShrImm64)));
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedSrcSignedDstSatQ)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedSrcUnsignedDstSatQ)));
|
|
||||||
|
|
||||||
SetDelegateInfo(typeof(SoftFloat16_32).GetMethod(nameof(SoftFloat16_32.FPConvert)));
|
SetDelegateInfo(typeof(SoftFloat16_32).GetMethod(nameof(SoftFloat16_32.FPConvert)));
|
||||||
SetDelegateInfo(typeof(SoftFloat16_64).GetMethod(nameof(SoftFloat16_64.FPConvert)));
|
SetDelegateInfo(typeof(SoftFloat16_64).GetMethod(nameof(SoftFloat16_64.FPConvert)));
|
||||||
|
@@ -27,7 +27,7 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
private const string OuterHeaderMagicString = "PTCohd\0\0";
|
private const string OuterHeaderMagicString = "PTCohd\0\0";
|
||||||
private const string InnerHeaderMagicString = "PTCihd\0\0";
|
private const string InnerHeaderMagicString = "PTCihd\0\0";
|
||||||
|
|
||||||
private const uint InternalVersion = 3585; //! To be incremented manually for each change to the ARMeilleure project.
|
private const uint InternalVersion = 3666; //! To be incremented manually for each change to the ARMeilleure project.
|
||||||
|
|
||||||
private const string ActualDir = "0";
|
private const string ActualDir = "0";
|
||||||
private const string BackupDir = "1";
|
private const string BackupDir = "1";
|
||||||
|
Reference in New Issue
Block a user