Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
b9f1ff3c77 | |||
a77af4c5e9 | |||
fbcf802fbc |
@ -93,6 +93,7 @@ namespace ARMeilleure.Decoders
|
||||
SetA64("00011010110xxxxx010101xxxxxxxxxx", InstName.Crc32ch, InstEmit.Crc32ch, OpCodeAluBinary.Create);
|
||||
SetA64("00011010110xxxxx010110xxxxxxxxxx", InstName.Crc32cw, InstEmit.Crc32cw, OpCodeAluBinary.Create);
|
||||
SetA64("10011010110xxxxx010111xxxxxxxxxx", InstName.Crc32cx, InstEmit.Crc32cx, OpCodeAluBinary.Create);
|
||||
SetA64("11010101000000110010001010011111", InstName.Csdb, InstEmit.Csdb, OpCodeSystem.Create);
|
||||
SetA64("x0011010100xxxxxxxxx00xxxxxxxxxx", InstName.Csel, InstEmit.Csel, OpCodeCsel.Create);
|
||||
SetA64("x0011010100xxxxxxxxx01xxxxxxxxxx", InstName.Csinc, InstEmit.Csinc, OpCodeCsel.Create);
|
||||
SetA64("x1011010100xxxxxxxxx00xxxxxxxxxx", InstName.Csinv, InstEmit.Csinv, OpCodeCsel.Create);
|
||||
@ -107,7 +108,6 @@ namespace ARMeilleure.Decoders
|
||||
SetA64("11001010xx0xxxxxxxxxxxxxxxxxxxxx", InstName.Eor, InstEmit.Eor, OpCodeAluRs.Create);
|
||||
SetA64("00010011100xxxxx0xxxxxxxxxxxxxxx", InstName.Extr, InstEmit.Extr, OpCodeAluRs.Create);
|
||||
SetA64("10010011110xxxxxxxxxxxxxxxxxxxxx", InstName.Extr, InstEmit.Extr, OpCodeAluRs.Create);
|
||||
SetA64("11010101000000110010xxxxxxx11111", InstName.Hint, InstEmit.Hint, OpCodeSystem.Create);
|
||||
SetA64("11010101000000110011xxxx11011111", InstName.Isb, InstEmit.Isb, OpCodeSystem.Create);
|
||||
SetA64("xx001000110xxxxx1xxxxxxxxxxxxxxx", InstName.Ldar, InstEmit.Ldar, OpCodeMemEx.Create);
|
||||
SetA64("1x001000011xxxxx1xxxxxxxxxxxxxxx", InstName.Ldaxp, InstEmit.Ldaxp, OpCodeMemEx.Create);
|
||||
@ -159,6 +159,8 @@ namespace ARMeilleure.Decoders
|
||||
SetA64("00010011000xxxxx0xxxxxxxxxxxxxxx", InstName.Sbfm, InstEmit.Sbfm, OpCodeBfm.Create);
|
||||
SetA64("1001001101xxxxxxxxxxxxxxxxxxxxxx", InstName.Sbfm, InstEmit.Sbfm, OpCodeBfm.Create);
|
||||
SetA64("x0011010110xxxxx000011xxxxxxxxxx", InstName.Sdiv, InstEmit.Sdiv, OpCodeAluBinary.Create);
|
||||
SetA64("11010101000000110010000010011111", InstName.Sev, InstEmit.Nop, OpCodeSystem.Create);
|
||||
SetA64("11010101000000110010000010111111", InstName.Sevl, InstEmit.Nop, OpCodeSystem.Create);
|
||||
SetA64("10011011001xxxxx0xxxxxxxxxxxxxxx", InstName.Smaddl, InstEmit.Smaddl, OpCodeMul.Create);
|
||||
SetA64("10011011001xxxxx1xxxxxxxxxxxxxxx", InstName.Smsubl, InstEmit.Smsubl, OpCodeMul.Create);
|
||||
SetA64("10011011010xxxxx0xxxxxxxxxxxxxxx", InstName.Smulh, InstEmit.Smulh, OpCodeMul.Create);
|
||||
@ -191,6 +193,9 @@ namespace ARMeilleure.Decoders
|
||||
SetA64("10011011101xxxxx0xxxxxxxxxxxxxxx", InstName.Umaddl, InstEmit.Umaddl, OpCodeMul.Create);
|
||||
SetA64("10011011101xxxxx1xxxxxxxxxxxxxxx", InstName.Umsubl, InstEmit.Umsubl, OpCodeMul.Create);
|
||||
SetA64("10011011110xxxxx0xxxxxxxxxxxxxxx", InstName.Umulh, InstEmit.Umulh, OpCodeMul.Create);
|
||||
SetA64("11010101000000110010000001011111", InstName.Wfe, InstEmit.Nop, OpCodeSystem.Create);
|
||||
SetA64("11010101000000110010000001111111", InstName.Wfi, InstEmit.Nop, OpCodeSystem.Create);
|
||||
SetA64("11010101000000110010000000111111", InstName.Yield, InstEmit.Nop, OpCodeSystem.Create);
|
||||
|
||||
// FP & SIMD
|
||||
SetA64("0101111011100000101110xxxxxxxxxx", InstName.Abs_S, InstEmit.Abs_S, OpCodeSimd.Create);
|
||||
@ -669,6 +674,17 @@ namespace ARMeilleure.Decoders
|
||||
SetA32("<<<<0010001xxxxxxxxxxxxxxxxxxxxx", InstName.Eor, InstEmit32.Eor, OpCode32AluImm.Create);
|
||||
SetA32("<<<<0000001xxxxxxxxxxxxxxxx0xxxx", InstName.Eor, InstEmit32.Eor, OpCode32AluRsImm.Create);
|
||||
SetA32("<<<<0000001xxxxxxxxxxxxx0xx1xxxx", InstName.Eor, InstEmit32.Eor, OpCode32AluRsReg.Create);
|
||||
SetA32("<<<<0011001000001111000000010000", InstName.Esb, InstEmit32.Nop, OpCode32.Create); // Error Synchronization Barrier (FEAT_RAS)
|
||||
SetA32("<<<<001100100000111100000000011x", InstName.Hint, InstEmit32.Nop, OpCode32.Create); // Reserved Hint
|
||||
SetA32("<<<<0011001000001111000000001xxx", InstName.Hint, InstEmit32.Nop, OpCode32.Create); // Reserved Hint
|
||||
SetA32("<<<<0011001000001111000000010001", InstName.Hint, InstEmit32.Nop, OpCode32.Create); // Reserved Hint
|
||||
SetA32("<<<<0011001000001111000000010011", InstName.Hint, InstEmit32.Nop, OpCode32.Create); // Reserved Hint
|
||||
SetA32("<<<<0011001000001111000000010101", InstName.Hint, InstEmit32.Nop, OpCode32.Create); // Reserved Hint
|
||||
SetA32("<<<<001100100000111100000001011x", InstName.Hint, InstEmit32.Nop, OpCode32.Create); // Reserved Hint
|
||||
SetA32("<<<<0011001000001111000000011xxx", InstName.Hint, InstEmit32.Nop, OpCode32.Create); // Reserved Hint
|
||||
SetA32("<<<<00110010000011110000001xxxxx", InstName.Hint, InstEmit32.Nop, OpCode32.Create); // Reserved Hint
|
||||
SetA32("<<<<0011001000001111000001xxxxxx", InstName.Hint, InstEmit32.Nop, OpCode32.Create); // Reserved Hint
|
||||
SetA32("<<<<001100100000111100001xxxxxxx", InstName.Hint, InstEmit32.Nop, OpCode32.Create); // Reserved Hint
|
||||
SetA32("1111010101111111111100000110xxxx", InstName.Isb, InstEmit32.Nop, OpCode32.Create);
|
||||
SetA32("<<<<00011001xxxxxxxx110010011111", InstName.Lda, InstEmit32.Lda, OpCode32MemLdEx.Create);
|
||||
SetA32("<<<<00011101xxxxxxxx110010011111", InstName.Ldab, InstEmit32.Ldab, OpCode32MemLdEx.Create);
|
||||
@ -734,6 +750,8 @@ namespace ARMeilleure.Decoders
|
||||
SetA32("<<<<0111101xxxxxxxxxxxxxx101xxxx", InstName.Sbfx, InstEmit32.Sbfx, OpCode32AluBf.Create);
|
||||
SetA32("<<<<01110001xxxx1111xxxx0001xxxx", InstName.Sdiv, InstEmit32.Sdiv, OpCode32AluMla.Create);
|
||||
SetA32("<<<<01101000xxxxxxxx11111011xxxx", InstName.Sel, InstEmit32.Sel, OpCode32AluReg.Create);
|
||||
SetA32("<<<<0011001000001111000000000100", InstName.Sev, InstEmit32.Nop, OpCode32.Create);
|
||||
SetA32("<<<<0011001000001111000000000101", InstName.Sevl, InstEmit32.Nop, OpCode32.Create);
|
||||
SetA32("<<<<01100011xxxxxxxx11111001xxxx", InstName.Shadd8, InstEmit32.Shadd8, OpCode32AluReg.Create);
|
||||
SetA32("<<<<01100011xxxxxxxx11111111xxxx", InstName.Shsub8, InstEmit32.Shsub8, OpCode32AluReg.Create);
|
||||
SetA32("<<<<00010000xxxxxxxxxxxx1xx0xxxx", InstName.Smla__, InstEmit32.Smla__, OpCode32AluMla.Create);
|
||||
@ -779,6 +797,7 @@ namespace ARMeilleure.Decoders
|
||||
SetA32("<<<<00010011xxxx0000xxxxxxx0xxxx", InstName.Teq, InstEmit32.Teq, OpCode32AluRsImm.Create);
|
||||
SetA32("<<<<00010011xxxx0000xxxx0xx1xxxx", InstName.Teq, InstEmit32.Teq, OpCode32AluRsReg.Create);
|
||||
SetA32("<<<<0111111111111101111011111110", InstName.Trap, InstEmit32.Trap, OpCode32Exception.Create);
|
||||
SetA32("<<<<0011001000001111000000010010", InstName.Tsb, InstEmit32.Nop, OpCode32.Create); // Trace Synchronization Barrier (FEAT_TRF)
|
||||
SetA32("<<<<00110001xxxx0000xxxxxxxxxxxx", InstName.Tst, InstEmit32.Tst, OpCode32AluImm.Create);
|
||||
SetA32("<<<<00010001xxxx0000xxxxxxx0xxxx", InstName.Tst, InstEmit32.Tst, OpCode32AluRsImm.Create);
|
||||
SetA32("<<<<00010001xxxx0000xxxx0xx1xxxx", InstName.Tst, InstEmit32.Tst, OpCode32AluRsReg.Create);
|
||||
@ -796,6 +815,9 @@ namespace ARMeilleure.Decoders
|
||||
SetA32("<<<<01101110xxxxxxxxxx000111xxxx", InstName.Uxtb, InstEmit32.Uxtb, OpCode32AluUx.Create);
|
||||
SetA32("<<<<01101100xxxxxxxxxx000111xxxx", InstName.Uxtb16, InstEmit32.Uxtb16, OpCode32AluUx.Create);
|
||||
SetA32("<<<<01101111xxxxxxxxxx000111xxxx", InstName.Uxth, InstEmit32.Uxth, OpCode32AluUx.Create);
|
||||
SetA32("<<<<0011001000001111000000000010", InstName.Wfe, InstEmit32.Nop, OpCode32.Create);
|
||||
SetA32("<<<<0011001000001111000000000011", InstName.Wfi, InstEmit32.Nop, OpCode32.Create);
|
||||
SetA32("<<<<0011001000001111000000000001", InstName.Yield, InstEmit32.Nop, OpCode32.Create);
|
||||
|
||||
// VFP
|
||||
SetVfp("<<<<11101x110000xxxx101x11x0xxxx", InstName.Vabs, InstEmit32.Vabs_S, OpCode32SimdS.Create, OpCode32SimdS.CreateT32);
|
||||
@ -1085,7 +1107,14 @@ namespace ARMeilleure.Decoders
|
||||
SetT16("1011101011xxxxxx", InstName.Revsh, InstEmit32.Revsh, OpCodeT16AluRegLow.Create);
|
||||
SetT16("101110x1xxxxxxxx", InstName.Cbnz, InstEmit32.Cbnz, OpCodeT16BImmCmp.Create);
|
||||
SetT16("1011110xxxxxxxxx", InstName.Pop, InstEmit32.Ldm, OpCodeT16MemStack.Create);
|
||||
SetT16("10111111xxxx0000", InstName.Nop, InstEmit32.Nop, OpCodeT16.Create);
|
||||
SetT16("1011111100000000", InstName.Nop, InstEmit32.Nop, OpCodeT16.Create);
|
||||
SetT16("1011111100010000", InstName.Yield, InstEmit32.Nop, OpCodeT16.Create);
|
||||
SetT16("1011111100100000", InstName.Wfe, InstEmit32.Nop, OpCodeT16.Create);
|
||||
SetT16("1011111100110000", InstName.Wfi, InstEmit32.Nop, OpCodeT16.Create);
|
||||
SetT16("1011111101000000", InstName.Sev, InstEmit32.Nop, OpCodeT16.Create);
|
||||
SetT16("1011111101010000", InstName.Sevl, InstEmit32.Nop, OpCodeT16.Create);
|
||||
SetT16("10111111011x0000", InstName.Hint, InstEmit32.Nop, OpCodeT16.Create); // Hint instruction
|
||||
SetT16("101111111xxx0000", InstName.Hint, InstEmit32.Nop, OpCodeT16.Create); // Hint instruction
|
||||
SetT16("10111111xxxx>>>>", InstName.It, InstEmit32.It, OpCodeT16IfThen.Create);
|
||||
SetT16("11000xxxxxxxxxxx", InstName.Stm, InstEmit32.Stm, OpCodeT16MemMult.Create);
|
||||
SetT16("11001xxxxxxxxxxx", InstName.Ldm, InstEmit32.Ldm, OpCodeT16MemMult.Create);
|
||||
@ -1116,8 +1145,20 @@ namespace ARMeilleure.Decoders
|
||||
SetT32("11110x010001xxxx0xxx1111xxxxxxxx", InstName.Cmn, InstEmit32.Cmn, OpCodeT32AluImm.Create);
|
||||
SetT32("111010111011xxxx0xxx1111xxxxxxxx", InstName.Cmp, InstEmit32.Cmp, OpCodeT32AluRsImm.Create);
|
||||
SetT32("11110x011011xxxx0xxx1111xxxxxxxx", InstName.Cmp, InstEmit32.Cmp, OpCodeT32AluImm.Create);
|
||||
SetT32("11110011101011111000000000010100", InstName.Csdb, InstEmit32.Csdb, OpCodeT32.Create);
|
||||
SetT32("11101010100<xxxx0xxx<<<<xxxxxxxx", InstName.Eor, InstEmit32.Eor, OpCodeT32AluRsImm.Create);
|
||||
SetT32("11110x00100<xxxx0xxx<<<<xxxxxxxx", InstName.Eor, InstEmit32.Eor, OpCodeT32AluImm.Create);
|
||||
SetT32("11110011101011111000000000010000", InstName.Esb, InstEmit32.Nop, OpCodeT32.Create); // Error Synchronization Barrier (FEAT_RAS)
|
||||
SetT32("1111001110101111100000000000011x", InstName.Hint, InstEmit32.Nop, OpCodeT32.Create); // Reserved Hint
|
||||
SetT32("11110011101011111000000000001xxx", InstName.Hint, InstEmit32.Nop, OpCodeT32.Create); // Reserved Hint
|
||||
SetT32("11110011101011111000000000010001", InstName.Hint, InstEmit32.Nop, OpCodeT32.Create); // Reserved Hint
|
||||
SetT32("11110011101011111000000000010011", InstName.Hint, InstEmit32.Nop, OpCodeT32.Create); // Reserved Hint
|
||||
SetT32("11110011101011111000000000010101", InstName.Hint, InstEmit32.Nop, OpCodeT32.Create); // Reserved Hint
|
||||
SetT32("1111001110101111100000000001011x", InstName.Hint, InstEmit32.Nop, OpCodeT32.Create); // Reserved Hint
|
||||
SetT32("11110011101011111000000000011xxx", InstName.Hint, InstEmit32.Nop, OpCodeT32.Create); // Reserved Hint
|
||||
SetT32("111100111010111110000000001xxxxx", InstName.Hint, InstEmit32.Nop, OpCodeT32.Create); // Reserved Hint
|
||||
SetT32("11110011101011111000000001xxxxxx", InstName.Hint, InstEmit32.Nop, OpCodeT32.Create); // Reserved Hint
|
||||
SetT32("1111001110101111100000001xxxxxxx", InstName.Hint, InstEmit32.Nop, OpCodeT32.Create); // Reserved Hint
|
||||
SetT32("111010001101xxxxxxxx111110101111", InstName.Lda, InstEmit32.Lda, OpCodeT32MemLdEx.Create);
|
||||
SetT32("111010001101xxxxxxxx111110001111", InstName.Ldab, InstEmit32.Ldab, OpCodeT32MemLdEx.Create);
|
||||
SetT32("111010001101xxxxxxxx111111101111", InstName.Ldaex, InstEmit32.Ldaex, OpCodeT32MemLdEx.Create);
|
||||
@ -1182,6 +1223,8 @@ namespace ARMeilleure.Decoders
|
||||
SetT32("111110101010xxxx1111xxxx1000xxxx", InstName.Sel, InstEmit32.Sel, OpCodeT32AluReg.Create);
|
||||
SetT32("111110101000xxxx1111xxxx0010xxxx", InstName.Shadd8, InstEmit32.Shadd8, OpCodeT32AluReg.Create);
|
||||
SetT32("111110101100xxxx1111xxxx0010xxxx", InstName.Shsub8, InstEmit32.Shsub8, OpCodeT32AluReg.Create);
|
||||
SetT32("11110011101011111000000000000100", InstName.Sev, InstEmit32.Nop, OpCodeT32.Create);
|
||||
SetT32("11110011101011111000000000000101", InstName.Sevl, InstEmit32.Nop, OpCodeT32.Create);
|
||||
SetT32("111110110001xxxx<<<<xxxx00xxxxxx", InstName.Smla__, InstEmit32.Smla__, OpCodeT32AluMla.Create);
|
||||
SetT32("111110111100xxxxxxxxxxxx0000xxxx", InstName.Smlal, InstEmit32.Smlal, OpCodeT32AluUmull.Create);
|
||||
SetT32("111110111100xxxxxxxxxxxx10xxxxxx", InstName.Smlal__, InstEmit32.Smlal__, OpCodeT32AluUmull.Create);
|
||||
@ -1228,6 +1271,7 @@ namespace ARMeilleure.Decoders
|
||||
SetT32("111010001101xxxx111100000001xxxx", InstName.Tbh, InstEmit32.Tbh, OpCodeT32Tb.Create);
|
||||
SetT32("111010101001xxxx0xxx1111xxxxxxxx", InstName.Teq, InstEmit32.Teq, OpCodeT32AluRsImm.Create);
|
||||
SetT32("11110x001001xxxx0xxx1111xxxxxxxx", InstName.Teq, InstEmit32.Teq, OpCodeT32AluImm.Create);
|
||||
SetT32("11110011101011111000000000010010", InstName.Tsb, InstEmit32.Nop, OpCodeT32.Create); // Trace Synchronization Barrier (FEAT_TRF)
|
||||
SetT32("111010100001xxxx0xxx1111xxxxxxxx", InstName.Tst, InstEmit32.Tst, OpCodeT32AluRsImm.Create);
|
||||
SetT32("11110x000001xxxx0xxx1111xxxxxxxx", InstName.Tst, InstEmit32.Tst, OpCodeT32AluImm.Create);
|
||||
SetT32("111110101000xxxx1111xxxx0100xxxx", InstName.Uadd8, InstEmit32.Uadd8, OpCodeT32AluReg.Create);
|
||||
@ -1242,6 +1286,9 @@ namespace ARMeilleure.Decoders
|
||||
SetT32("111110100101xxxx1111xxxx10xxxxxx", InstName.Uxtb, InstEmit32.Uxtb, OpCodeT32AluUx.Create);
|
||||
SetT32("111110100011xxxx1111xxxx10xxxxxx", InstName.Uxtb16, InstEmit32.Uxtb16, OpCodeT32AluUx.Create);
|
||||
SetT32("111110100001xxxx1111xxxx10xxxxxx", InstName.Uxth, InstEmit32.Uxth, OpCodeT32AluUx.Create);
|
||||
SetT32("11110011101011111000000000000010", InstName.Wfe, InstEmit32.Nop, OpCodeT32.Create);
|
||||
SetT32("11110011101011111000000000000011", InstName.Wfi, InstEmit32.Nop, OpCodeT32.Create);
|
||||
SetT32("11110011101011111000000000000001", InstName.Yield, InstEmit32.Nop, OpCodeT32.Create);
|
||||
#endregion
|
||||
|
||||
FillFastLookupTable(InstA32FastLookup, AllInstA32, ToFastLookupIndexA);
|
||||
|
@ -26,6 +26,11 @@ namespace ARMeilleure.Instructions
|
||||
EmitClearExclusive(context);
|
||||
}
|
||||
|
||||
public static void Csdb(ArmEmitterContext context)
|
||||
{
|
||||
// Execute as no-op.
|
||||
}
|
||||
|
||||
public static void Dmb(ArmEmitterContext context) => EmitBarrier(context);
|
||||
public static void Dsb(ArmEmitterContext context) => EmitBarrier(context);
|
||||
|
||||
|
@ -1533,29 +1533,88 @@ namespace ARMeilleure.Instructions
|
||||
context.Copy(d, res);
|
||||
}
|
||||
|
||||
// TSrc (16bit, 32bit, 64bit; signed) > TDst (8bit, 16bit, 32bit; signed, unsigned).
|
||||
// long SignedSrcSignedDstSatQ(long op, int size); ulong SignedSrcUnsignedDstSatQ(long op, int size);
|
||||
public static Operand EmitSignedSrcSatQ(ArmEmitterContext context, Operand op, int sizeDst, bool signedDst)
|
||||
// long SignedSignSatQ(long op, int size);
|
||||
public static Operand EmitSignedSignSatQ(ArmEmitterContext context, Operand op, int size)
|
||||
{
|
||||
Debug.Assert(op.Type == OperandType.I64 && (uint)sizeDst <= 2u);
|
||||
int eSize = 8 << size;
|
||||
|
||||
Debug.Assert(op.Type == OperandType.I64);
|
||||
Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64);
|
||||
|
||||
Operand lbl1 = Label();
|
||||
Operand lblEnd = Label();
|
||||
|
||||
int eSize = 8 << sizeDst;
|
||||
Operand zeroL = Const(0L);
|
||||
Operand maxT = Const((1L << (eSize - 1)) - 1L);
|
||||
Operand minT = Const(-(1L << (eSize - 1)));
|
||||
|
||||
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), zeroL);
|
||||
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), op);
|
||||
|
||||
context.BranchIf(lbl1, res, maxT, Comparison.LessOrEqual);
|
||||
context.BranchIf(lbl1, op, zeroL, 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.BranchIf(lblEnd, op, zeroL, Comparison.GreaterOrEqual);
|
||||
context.Copy(res, minT);
|
||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lblEnd);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// private static ulong UnsignedSignSatQ(ulong op, int size);
|
||||
public static Operand EmitUnsignedSignSatQ(ArmEmitterContext context, Operand op, int size)
|
||||
{
|
||||
int eSize = 8 << size;
|
||||
|
||||
Debug.Assert(op.Type == OperandType.I64);
|
||||
Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64);
|
||||
|
||||
Operand lblEnd = Label();
|
||||
|
||||
Operand zeroUL = Const(0UL);
|
||||
Operand maxT = Const(ulong.MaxValue >> (64 - eSize));
|
||||
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), zeroUL);
|
||||
|
||||
context.BranchIf(lblEnd, op, zeroUL, Comparison.LessOrEqualUI);
|
||||
context.Copy(res, maxT);
|
||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lblEnd);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// TSrc (16bit, 32bit, 64bit; signed) > TDst (8bit, 16bit, 32bit; signed, unsigned).
|
||||
// long SignedSrcSignedDstSatQ(long op, int size); ulong SignedSrcUnsignedDstSatQ(long op, int size);
|
||||
public static Operand EmitSignedSrcSatQ(ArmEmitterContext context, Operand op, int sizeDst, bool signedDst)
|
||||
{
|
||||
int eSizeDst = 8 << sizeDst;
|
||||
|
||||
Debug.Assert(op.Type == OperandType.I64);
|
||||
Debug.Assert(eSizeDst == 8 || eSizeDst == 16 || eSizeDst == 32);
|
||||
|
||||
Operand lbl1 = Label();
|
||||
Operand lblEnd = Label();
|
||||
|
||||
Operand maxT = signedDst ? Const((1L << (eSizeDst - 1)) - 1L) : Const((1UL << eSizeDst) - 1UL);
|
||||
Operand minT = signedDst ? Const(-(1L << (eSizeDst - 1))) : Const(0UL);
|
||||
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), op);
|
||||
|
||||
context.BranchIf(lbl1, op, maxT, Comparison.LessOrEqual);
|
||||
context.Copy(res, maxT);
|
||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lbl1);
|
||||
context.BranchIf(lblEnd, op, minT, Comparison.GreaterOrEqual);
|
||||
context.Copy(res, minT);
|
||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||
context.Branch(lblEnd);
|
||||
@ -1569,18 +1628,19 @@ namespace ARMeilleure.Instructions
|
||||
// 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(op.Type == OperandType.I64 && (uint)sizeDst <= 2u);
|
||||
int eSizeDst = 8 << sizeDst;
|
||||
|
||||
Debug.Assert(op.Type == OperandType.I64);
|
||||
Debug.Assert(eSizeDst == 8 || eSizeDst == 16 || eSizeDst == 32);
|
||||
|
||||
Operand lblEnd = Label();
|
||||
|
||||
int eSize = 8 << sizeDst;
|
||||
|
||||
Operand maxL = signedDst ? Const((1L << (eSize - 1)) - 1L) : Const((1UL << eSize) - 1UL);
|
||||
Operand maxT = signedDst ? Const((1L << (eSizeDst - 1)) - 1L) : Const((1UL << eSizeDst) - 1UL);
|
||||
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), op);
|
||||
|
||||
context.BranchIf(lblEnd, res, maxL, Comparison.LessOrEqualUI);
|
||||
context.Copy(res, maxL);
|
||||
context.BranchIf(lblEnd, op, maxT, Comparison.LessOrEqualUI);
|
||||
context.Copy(res, maxT);
|
||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||
context.Branch(lblEnd);
|
||||
|
||||
@ -1601,7 +1661,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), op);
|
||||
|
||||
context.BranchIf(lblEnd, res, minL, Comparison.NotEqual);
|
||||
context.BranchIf(lblEnd, op, minL, Comparison.NotEqual);
|
||||
context.Copy(res, maxL);
|
||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||
context.Branch(lblEnd);
|
||||
@ -1620,15 +1680,16 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
Operand minL = Const(long.MinValue);
|
||||
Operand maxL = Const(long.MaxValue);
|
||||
Operand zero = Const(0L);
|
||||
Operand zeroL = Const(0L);
|
||||
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), context.Add(op1, op2));
|
||||
Operand add = context.Add(op1, op2);
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), add);
|
||||
|
||||
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 right = context.BitwiseExclusiveOr(op1, add);
|
||||
context.BranchIf(lblEnd, context.BitwiseAnd(left, right), zeroL, Comparison.GreaterOrEqual);
|
||||
|
||||
Operand isPositive = context.ICompareGreaterOrEqual(op1, zero);
|
||||
Operand isPositive = context.ICompareGreaterOrEqual(op1, zeroL);
|
||||
context.Copy(res, context.ConditionalSelect(isPositive, maxL, minL));
|
||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||
context.Branch(lblEnd);
|
||||
@ -1647,9 +1708,10 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
Operand maxUL = Const(ulong.MaxValue);
|
||||
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), context.Add(op1, op2));
|
||||
Operand add = context.Add(op1, op2);
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), add);
|
||||
|
||||
context.BranchIf(lblEnd, res, op1, Comparison.GreaterOrEqualUI);
|
||||
context.BranchIf(lblEnd, add, op1, Comparison.GreaterOrEqualUI);
|
||||
context.Copy(res, maxUL);
|
||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||
context.Branch(lblEnd);
|
||||
@ -1668,15 +1730,16 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
Operand minL = Const(long.MinValue);
|
||||
Operand maxL = Const(long.MaxValue);
|
||||
Operand zero = Const(0L);
|
||||
Operand zeroL = Const(0L);
|
||||
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), context.Subtract(op1, op2));
|
||||
Operand sub = context.Subtract(op1, op2);
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), sub);
|
||||
|
||||
Operand left = context.BitwiseExclusiveOr(op1, op2);
|
||||
Operand right = context.BitwiseExclusiveOr(op1, res);
|
||||
context.BranchIf(lblEnd, context.BitwiseAnd(left, right), zero, Comparison.GreaterOrEqual);
|
||||
Operand right = context.BitwiseExclusiveOr(op1, sub);
|
||||
context.BranchIf(lblEnd, context.BitwiseAnd(left, right), zeroL, Comparison.GreaterOrEqual);
|
||||
|
||||
Operand isPositive = context.ICompareGreaterOrEqual(op1, zero);
|
||||
Operand isPositive = context.ICompareGreaterOrEqual(op1, zeroL);
|
||||
context.Copy(res, context.ConditionalSelect(isPositive, maxL, minL));
|
||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||
context.Branch(lblEnd);
|
||||
@ -1693,12 +1756,13 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
Operand lblEnd = Label();
|
||||
|
||||
Operand zero = Const(0L);
|
||||
Operand zeroL = Const(0L);
|
||||
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), context.Subtract(op1, op2));
|
||||
Operand sub = context.Subtract(op1, op2);
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), sub);
|
||||
|
||||
context.BranchIf(lblEnd, op1, op2, Comparison.GreaterOrEqualUI);
|
||||
context.Copy(res, zero);
|
||||
context.Copy(res, zeroL);
|
||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||
context.Branch(lblEnd);
|
||||
|
||||
@ -1717,25 +1781,26 @@ namespace ARMeilleure.Instructions
|
||||
Operand lblEnd = Label();
|
||||
|
||||
Operand maxL = Const(long.MaxValue);
|
||||
Operand zero = Const(0L);
|
||||
Operand zeroL = Const(0L);
|
||||
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), context.Add(op1, op2));
|
||||
Operand add = context.Add(op1, op2);
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), add);
|
||||
|
||||
context.BranchIf(lbl1, op1, maxL, Comparison.GreaterUI);
|
||||
Operand notOp2AndRes = context.BitwiseAnd(context.BitwiseNot(op2), res);
|
||||
context.BranchIf(lblEnd, notOp2AndRes, zero, Comparison.GreaterOrEqual);
|
||||
Operand notOp2AndRes = context.BitwiseAnd(context.BitwiseNot(op2), add);
|
||||
context.BranchIf(lblEnd, notOp2AndRes, zeroL, 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.BranchIf(lbl2, op2, zeroL, 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.BranchIf(lblEnd, add, maxL, Comparison.LessOrEqualUI);
|
||||
context.Copy(res, maxL);
|
||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||
context.Branch(lblEnd);
|
||||
@ -1755,20 +1820,21 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
Operand maxUL = Const(ulong.MaxValue);
|
||||
Operand maxL = Const(long.MaxValue);
|
||||
Operand zero = Const(0L);
|
||||
Operand zeroL = Const(0L);
|
||||
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), context.Add(op1, op2));
|
||||
Operand add = context.Add(op1, op2);
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), add);
|
||||
|
||||
context.BranchIf(lbl1, op1, zero, Comparison.Less);
|
||||
context.BranchIf(lblEnd, res, op1, Comparison.GreaterOrEqualUI);
|
||||
context.BranchIf(lbl1, op1, zeroL, Comparison.Less);
|
||||
context.BranchIf(lblEnd, add, 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.BranchIf(lblEnd, add, zeroL, Comparison.GreaterOrEqual);
|
||||
context.Copy(res, zeroL);
|
||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||
context.Branch(lblEnd);
|
||||
|
||||
|
@ -188,23 +188,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
public static void Sqrshl_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
Operand res = context.VectorZero();
|
||||
|
||||
int elems = op.GetBytesCount() >> op.Size;
|
||||
|
||||
for (int index = 0; index < elems; index++)
|
||||
{
|
||||
Operand ne = EmitVectorExtractSx(context, op.Rn, index, op.Size);
|
||||
Operand me = EmitVectorExtractSx(context, op.Rm, index, op.Size);
|
||||
|
||||
Operand e = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShlRegSatQ)), ne, me, Const(1), Const(op.Size));
|
||||
|
||||
res = EmitVectorInsert(context, res, e, index, op.Size);
|
||||
}
|
||||
|
||||
context.Copy(GetVec(op.Rd), res);
|
||||
EmitShlRegOp(context, ShlRegFlags.Signed | ShlRegFlags.Round | ShlRegFlags.Saturating);
|
||||
}
|
||||
|
||||
public static void Sqrshrn_S(ArmEmitterContext context)
|
||||
@ -229,23 +213,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
public static void Sqshl_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
Operand res = context.VectorZero();
|
||||
|
||||
int elems = op.GetBytesCount() >> op.Size;
|
||||
|
||||
for (int index = 0; index < elems; index++)
|
||||
{
|
||||
Operand ne = EmitVectorExtractSx(context, op.Rn, index, op.Size);
|
||||
Operand me = EmitVectorExtractSx(context, op.Rm, index, op.Size);
|
||||
|
||||
Operand e = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShlRegSatQ)), ne, me, Const(0), Const(op.Size));
|
||||
|
||||
res = EmitVectorInsert(context, res, e, index, op.Size);
|
||||
}
|
||||
|
||||
context.Copy(GetVec(op.Rd), res);
|
||||
EmitShlRegOp(context, ShlRegFlags.Signed | ShlRegFlags.Saturating);
|
||||
}
|
||||
|
||||
public static void Sqshrn_S(ArmEmitterContext context)
|
||||
@ -280,23 +248,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
public static void Srshl_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
Operand res = context.VectorZero();
|
||||
|
||||
int elems = op.GetBytesCount() >> op.Size;
|
||||
|
||||
for (int index = 0; index < elems; index++)
|
||||
{
|
||||
Operand ne = EmitVectorExtractSx(context, op.Rn, index, op.Size);
|
||||
Operand me = EmitVectorExtractSx(context, op.Rm, index, op.Size);
|
||||
|
||||
Operand e = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShlReg)), ne, me, Const(1), Const(op.Size));
|
||||
|
||||
res = EmitVectorInsert(context, res, e, index, op.Size);
|
||||
}
|
||||
|
||||
context.Copy(GetVec(op.Rd), res);
|
||||
EmitShlRegOp(context, ShlRegFlags.Signed | ShlRegFlags.Round);
|
||||
}
|
||||
|
||||
public static void Srshr_S(ArmEmitterContext context)
|
||||
@ -393,12 +345,12 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
public static void Sshl_S(ArmEmitterContext context)
|
||||
{
|
||||
EmitSshlOrUshl(context, signed: true, scalar: true);
|
||||
EmitShlRegOp(context, ShlRegFlags.Scalar | ShlRegFlags.Signed);
|
||||
}
|
||||
|
||||
public static void Sshl_V(ArmEmitterContext context)
|
||||
{
|
||||
EmitSshlOrUshl(context, signed: true, scalar: false);
|
||||
EmitShlRegOp(context, ShlRegFlags.Signed);
|
||||
}
|
||||
|
||||
public static void Sshll_V(ArmEmitterContext context)
|
||||
@ -506,23 +458,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
public static void Uqrshl_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
Operand res = context.VectorZero();
|
||||
|
||||
int elems = op.GetBytesCount() >> op.Size;
|
||||
|
||||
for (int index = 0; index < elems; index++)
|
||||
{
|
||||
Operand ne = EmitVectorExtractZx(context, op.Rn, index, op.Size);
|
||||
Operand me = EmitVectorExtractZx(context, op.Rm, index, op.Size);
|
||||
|
||||
Operand e = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShlRegSatQ)), ne, me, Const(1), Const(op.Size));
|
||||
|
||||
res = EmitVectorInsert(context, res, e, index, op.Size);
|
||||
}
|
||||
|
||||
context.Copy(GetVec(op.Rd), res);
|
||||
EmitShlRegOp(context, ShlRegFlags.Round | ShlRegFlags.Saturating);
|
||||
}
|
||||
|
||||
public static void Uqrshrn_S(ArmEmitterContext context)
|
||||
@ -537,23 +473,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
public static void Uqshl_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
Operand res = context.VectorZero();
|
||||
|
||||
int elems = op.GetBytesCount() >> op.Size;
|
||||
|
||||
for (int index = 0; index < elems; index++)
|
||||
{
|
||||
Operand ne = EmitVectorExtractZx(context, op.Rn, index, op.Size);
|
||||
Operand me = EmitVectorExtractZx(context, op.Rm, index, op.Size);
|
||||
|
||||
Operand e = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShlRegSatQ)), ne, me, Const(0), Const(op.Size));
|
||||
|
||||
res = EmitVectorInsert(context, res, e, index, op.Size);
|
||||
}
|
||||
|
||||
context.Copy(GetVec(op.Rd), res);
|
||||
EmitShlRegOp(context, ShlRegFlags.Saturating);
|
||||
}
|
||||
|
||||
public static void Uqshrn_S(ArmEmitterContext context)
|
||||
@ -568,23 +488,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
public static void Urshl_V(ArmEmitterContext context)
|
||||
{
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
Operand res = context.VectorZero();
|
||||
|
||||
int elems = op.GetBytesCount() >> op.Size;
|
||||
|
||||
for (int index = 0; index < elems; index++)
|
||||
{
|
||||
Operand ne = EmitVectorExtractZx(context, op.Rn, index, op.Size);
|
||||
Operand me = EmitVectorExtractZx(context, op.Rm, index, op.Size);
|
||||
|
||||
Operand e = context.Call(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShlReg)), ne, me, Const(1), Const(op.Size));
|
||||
|
||||
res = EmitVectorInsert(context, res, e, index, op.Size);
|
||||
}
|
||||
|
||||
context.Copy(GetVec(op.Rd), res);
|
||||
EmitShlRegOp(context, ShlRegFlags.Round);
|
||||
}
|
||||
|
||||
public static void Urshr_S(ArmEmitterContext context)
|
||||
@ -677,12 +581,12 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
public static void Ushl_S(ArmEmitterContext context)
|
||||
{
|
||||
EmitSshlOrUshl(context, signed: false, scalar: true);
|
||||
EmitShlRegOp(context, ShlRegFlags.Scalar);
|
||||
}
|
||||
|
||||
public static void Ushl_V(ArmEmitterContext context)
|
||||
{
|
||||
EmitSshlOrUshl(context, signed: false, scalar: false);
|
||||
EmitShlRegOp(context, ShlRegFlags.None);
|
||||
}
|
||||
|
||||
public static void Ushll_V(ArmEmitterContext context)
|
||||
@ -872,43 +776,6 @@ namespace ARMeilleure.Instructions
|
||||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
private static Operand EmitShlRegOp(ArmEmitterContext context, Operand op, Operand shiftLsB, int size, bool signed)
|
||||
{
|
||||
Debug.Assert(op.Type == OperandType.I64);
|
||||
Debug.Assert(shiftLsB.Type == OperandType.I32);
|
||||
Debug.Assert((uint)size < 4u);
|
||||
|
||||
Operand negShiftLsB = context.Negate(shiftLsB);
|
||||
|
||||
Operand isInRange = context.BitwiseAnd(
|
||||
context.ICompareLess(shiftLsB, Const(8 << size)),
|
||||
context.ICompareLess(negShiftLsB, Const(8 << size)));
|
||||
|
||||
Operand isPositive = context.ICompareGreaterOrEqual(shiftLsB, Const(0));
|
||||
|
||||
Operand shl = context.ShiftLeft(op, shiftLsB);
|
||||
|
||||
Operand sarOrShr = signed
|
||||
? context.ShiftRightSI(op, negShiftLsB)
|
||||
: context.ShiftRightUI(op, negShiftLsB);
|
||||
|
||||
Operand res = context.ConditionalSelect(isPositive, shl, sarOrShr);
|
||||
|
||||
if (signed)
|
||||
{
|
||||
Operand isPositive2 = context.ICompareGreaterOrEqual(op, Const(0L));
|
||||
|
||||
Operand res2 = context.ConditionalSelect(isPositive2, Const(0L), Const(-1L));
|
||||
res2 = context.ConditionalSelect(isPositive, Const(0L), res2);
|
||||
|
||||
return context.ConditionalSelect(isInRange, res, res2);
|
||||
}
|
||||
else
|
||||
{
|
||||
return context.ConditionalSelect(isInRange, res, Const(0UL));
|
||||
}
|
||||
}
|
||||
|
||||
private static void EmitVectorShrImmNarrowOpZx(ArmEmitterContext context, bool round)
|
||||
{
|
||||
OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp;
|
||||
@ -1168,8 +1035,23 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
}
|
||||
|
||||
private static void EmitSshlOrUshl(ArmEmitterContext context, bool signed, bool scalar)
|
||||
[Flags]
|
||||
private enum ShlRegFlags
|
||||
{
|
||||
None = 0,
|
||||
Scalar = 1 << 0,
|
||||
Signed = 1 << 1,
|
||||
Round = 1 << 2,
|
||||
Saturating = 1 << 3
|
||||
}
|
||||
|
||||
private static void EmitShlRegOp(ArmEmitterContext context, ShlRegFlags flags = ShlRegFlags.None)
|
||||
{
|
||||
bool scalar = flags.HasFlag(ShlRegFlags.Scalar);
|
||||
bool signed = flags.HasFlag(ShlRegFlags.Signed);
|
||||
bool round = flags.HasFlag(ShlRegFlags.Round);
|
||||
bool saturating = flags.HasFlag(ShlRegFlags.Saturating);
|
||||
|
||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||
|
||||
Operand res = context.VectorZero();
|
||||
@ -1178,15 +1060,225 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
for (int index = 0; index < elems; index++)
|
||||
{
|
||||
Operand ne = EmitVectorExtract (context, op.Rn, index, op.Size, signed);
|
||||
Operand me = EmitVectorExtractSx(context, op.Rm, index << op.Size, 0);
|
||||
Operand ne = EmitVectorExtract(context, op.Rn, index, op.Size, signed);
|
||||
Operand me = EmitVectorExtractSx(context, op.Rm, index << op.Size, size: 0);
|
||||
|
||||
Operand e = EmitShlRegOp(context, ne, context.ConvertI64ToI32(me), op.Size, signed);
|
||||
Operand e = !saturating
|
||||
? EmitShlReg(context, ne, context.ConvertI64ToI32(me), round, op.Size, signed)
|
||||
: EmitShlRegSatQ(context, ne, context.ConvertI64ToI32(me), round, op.Size, signed);
|
||||
|
||||
res = EmitVectorInsert(context, res, e, index, op.Size);
|
||||
}
|
||||
|
||||
context.Copy(GetVec(op.Rd), res);
|
||||
}
|
||||
|
||||
// long SignedShlReg(long op, int shiftLsB, bool round, int size);
|
||||
// ulong UnsignedShlReg(ulong op, int shiftLsB, bool round, int size);
|
||||
private static Operand EmitShlReg(ArmEmitterContext context, Operand op, Operand shiftLsB, bool round, int size, bool signed)
|
||||
{
|
||||
int eSize = 8 << size;
|
||||
|
||||
Debug.Assert(op.Type == OperandType.I64);
|
||||
Debug.Assert(shiftLsB.Type == OperandType.I32);
|
||||
Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64);
|
||||
|
||||
Operand lbl1 = Label();
|
||||
Operand lblEnd = Label();
|
||||
|
||||
Operand eSizeOp = Const(eSize);
|
||||
Operand zero = Const(0);
|
||||
Operand zeroL = Const(0L);
|
||||
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), op);
|
||||
|
||||
context.BranchIf(lbl1, shiftLsB, zero, Comparison.GreaterOrEqual);
|
||||
context.Copy(res, signed
|
||||
? EmitSignedShrReg(context, op, context.Negate(shiftLsB), round, eSize)
|
||||
: EmitUnsignedShrReg(context, op, context.Negate(shiftLsB), round, eSize));
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lbl1);
|
||||
context.BranchIf(lblEnd, shiftLsB, zero, Comparison.LessOrEqual);
|
||||
Operand shl = context.ShiftLeft(op, shiftLsB);
|
||||
Operand isGreaterOrEqual = context.ICompareGreaterOrEqual(shiftLsB, eSizeOp);
|
||||
context.Copy(res, context.ConditionalSelect(isGreaterOrEqual, zeroL, shl));
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lblEnd);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// long SignedShlRegSatQ(long op, int shiftLsB, bool round, int size);
|
||||
// ulong UnsignedShlRegSatQ(ulong op, int shiftLsB, bool round, int size);
|
||||
private static Operand EmitShlRegSatQ(ArmEmitterContext context, Operand op, Operand shiftLsB, bool round, int size, bool signed)
|
||||
{
|
||||
int eSize = 8 << size;
|
||||
|
||||
Debug.Assert(op.Type == OperandType.I64);
|
||||
Debug.Assert(shiftLsB.Type == OperandType.I32);
|
||||
Debug.Assert(eSize == 8 || eSize == 16 || eSize == 32 || eSize == 64);
|
||||
|
||||
Operand lbl1 = Label();
|
||||
Operand lbl2 = Label();
|
||||
Operand lblEnd = Label();
|
||||
|
||||
Operand eSizeOp = Const(eSize);
|
||||
Operand zero = Const(0);
|
||||
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), op);
|
||||
|
||||
context.BranchIf(lbl1, shiftLsB, zero, Comparison.GreaterOrEqual);
|
||||
context.Copy(res, signed
|
||||
? EmitSignedShrReg(context, op, context.Negate(shiftLsB), round, eSize)
|
||||
: EmitUnsignedShrReg(context, op, context.Negate(shiftLsB), round, eSize));
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lbl1);
|
||||
context.BranchIf(lblEnd, shiftLsB, zero, Comparison.LessOrEqual);
|
||||
context.BranchIf(lbl2, shiftLsB, eSizeOp, Comparison.Less);
|
||||
context.Copy(res, signed
|
||||
? EmitSignedSignSatQ(context, op, size)
|
||||
: EmitUnsignedSignSatQ(context, op, size));
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lbl2);
|
||||
Operand shl = context.ShiftLeft(op, shiftLsB);
|
||||
if (eSize == 64)
|
||||
{
|
||||
Operand sarOrShr = signed
|
||||
? context.ShiftRightSI(shl, shiftLsB)
|
||||
: context.ShiftRightUI(shl, shiftLsB);
|
||||
context.Copy(res, shl);
|
||||
context.BranchIf(lblEnd, sarOrShr, op, Comparison.Equal);
|
||||
context.Copy(res, signed
|
||||
? EmitSignedSignSatQ(context, op, size)
|
||||
: EmitUnsignedSignSatQ(context, op, size));
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Copy(res, signed
|
||||
? EmitSignedSrcSatQ(context, shl, size, signedDst: true)
|
||||
: EmitUnsignedSrcSatQ(context, shl, size, signedDst: false));
|
||||
}
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lblEnd);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// shift := [1, 128]; eSize := {8, 16, 32, 64}.
|
||||
// long SignedShrReg(long op, int shift, bool round, int eSize);
|
||||
private static Operand EmitSignedShrReg(ArmEmitterContext context, Operand op, Operand shift, bool round, int eSize)
|
||||
{
|
||||
if (round)
|
||||
{
|
||||
Operand lblEnd = Label();
|
||||
|
||||
Operand eSizeOp = Const(eSize);
|
||||
Operand zeroL = Const(0L);
|
||||
Operand one = Const(1);
|
||||
Operand oneL = Const(1L);
|
||||
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), zeroL);
|
||||
|
||||
context.BranchIf(lblEnd, shift, eSizeOp, Comparison.GreaterOrEqual);
|
||||
Operand roundConst = context.ShiftLeft(oneL, context.Subtract(shift, one));
|
||||
Operand add = context.Add(op, roundConst);
|
||||
Operand sar = context.ShiftRightSI(add, shift);
|
||||
if (eSize == 64)
|
||||
{
|
||||
Operand shr = context.ShiftRightUI(add, shift);
|
||||
Operand left = context.BitwiseAnd(context.Negate(op), context.BitwiseExclusiveOr(op, add));
|
||||
Operand isLess = context.ICompareLess(left, zeroL);
|
||||
context.Copy(res, context.ConditionalSelect(isLess, shr, sar));
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Copy(res, sar);
|
||||
}
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lblEnd);
|
||||
|
||||
return res;
|
||||
}
|
||||
else
|
||||
{
|
||||
Operand lblEnd = Label();
|
||||
|
||||
Operand eSizeOp = Const(eSize);
|
||||
Operand zeroL = Const(0L);
|
||||
Operand negOneL = Const(-1L);
|
||||
|
||||
Operand sar = context.ShiftRightSI(op, shift);
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), sar);
|
||||
|
||||
context.BranchIf(lblEnd, shift, eSizeOp, Comparison.Less);
|
||||
Operand isLess = context.ICompareLess(op, zeroL);
|
||||
context.Copy(res, context.ConditionalSelect(isLess, negOneL, zeroL));
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lblEnd);
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
// shift := [1, 128]; eSize := {8, 16, 32, 64}.
|
||||
// ulong UnsignedShrReg(ulong op, int shift, bool round, int eSize);
|
||||
private static Operand EmitUnsignedShrReg(ArmEmitterContext context, Operand op, Operand shift, bool round, int eSize)
|
||||
{
|
||||
if (round)
|
||||
{
|
||||
Operand lblEnd = Label();
|
||||
|
||||
Operand zeroUL = Const(0UL);
|
||||
Operand one = Const(1);
|
||||
Operand oneUL = Const(1UL);
|
||||
Operand eSizeMaxOp = Const(64);
|
||||
Operand oneShl63UL = Const(1UL << 63);
|
||||
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), zeroUL);
|
||||
|
||||
context.BranchIf(lblEnd, shift, eSizeMaxOp, Comparison.Greater);
|
||||
Operand roundConst = context.ShiftLeft(oneUL, context.Subtract(shift, one));
|
||||
Operand add = context.Add(op, roundConst);
|
||||
Operand shr = context.ShiftRightUI(add, shift);
|
||||
Operand isEqual = context.ICompareEqual(shift, eSizeMaxOp);
|
||||
context.Copy(res, context.ConditionalSelect(isEqual, zeroUL, shr));
|
||||
if (eSize == 64)
|
||||
{
|
||||
context.BranchIf(lblEnd, add, op, Comparison.GreaterOrEqualUI);
|
||||
Operand right = context.BitwiseOr(shr, context.ShiftRightUI(oneShl63UL, context.Subtract(shift, one)));
|
||||
context.Copy(res, context.ConditionalSelect(isEqual, oneUL, right));
|
||||
}
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lblEnd);
|
||||
|
||||
return res;
|
||||
}
|
||||
else
|
||||
{
|
||||
Operand lblEnd = Label();
|
||||
|
||||
Operand eSizeOp = Const(eSize);
|
||||
Operand zeroUL = Const(0UL);
|
||||
|
||||
Operand shr = context.ShiftRightUI(op, shift);
|
||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), shr);
|
||||
|
||||
context.BranchIf(lblEnd, shift, eSizeOp, Comparison.Less);
|
||||
context.Copy(res, zeroUL);
|
||||
context.Branch(lblEnd);
|
||||
|
||||
context.MarkLabel(lblEnd);
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,11 +15,6 @@ namespace ARMeilleure.Instructions
|
||||
private const int DczSizeLog2 = 4; // Log2 size in words
|
||||
public const int DczSizeInBytes = 4 << DczSizeLog2;
|
||||
|
||||
public static void Hint(ArmEmitterContext context)
|
||||
{
|
||||
// Execute as no-op.
|
||||
}
|
||||
|
||||
public static void Isb(ArmEmitterContext context)
|
||||
{
|
||||
// Execute as no-op.
|
||||
|
@ -45,6 +45,7 @@ namespace ARMeilleure.Instructions
|
||||
Dsb,
|
||||
Eon,
|
||||
Eor,
|
||||
Esb,
|
||||
Extr,
|
||||
Hint,
|
||||
Isb,
|
||||
@ -82,6 +83,8 @@ namespace ARMeilleure.Instructions
|
||||
Sbfm,
|
||||
Sdiv,
|
||||
Sel,
|
||||
Sev,
|
||||
Sevl,
|
||||
Shsub8,
|
||||
Smaddl,
|
||||
Smsubl,
|
||||
@ -105,12 +108,16 @@ namespace ARMeilleure.Instructions
|
||||
Sys,
|
||||
Tbnz,
|
||||
Tbz,
|
||||
Tsb,
|
||||
Ubfm,
|
||||
Udiv,
|
||||
Umaddl,
|
||||
Umsubl,
|
||||
Umulh,
|
||||
Und,
|
||||
Wfe,
|
||||
Wfi,
|
||||
Yield,
|
||||
|
||||
// FP & SIMD (AArch64)
|
||||
Abs_S,
|
||||
|
@ -5,287 +5,6 @@ namespace ARMeilleure.Instructions
|
||||
{
|
||||
static class SoftFallback
|
||||
{
|
||||
#region "ShlReg"
|
||||
public static long SignedShlReg(long value, long shift, bool round, int size)
|
||||
{
|
||||
int eSize = 8 << size;
|
||||
|
||||
int shiftLsB = (sbyte)shift;
|
||||
|
||||
if (shiftLsB < 0)
|
||||
{
|
||||
return SignedShrReg(value, -shiftLsB, round, eSize);
|
||||
}
|
||||
else if (shiftLsB > 0)
|
||||
{
|
||||
if (shiftLsB >= eSize)
|
||||
{
|
||||
return 0L;
|
||||
}
|
||||
|
||||
return value << shiftLsB;
|
||||
}
|
||||
else /* if (shiftLsB == 0) */
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public static ulong UnsignedShlReg(ulong value, ulong shift, bool round, int size)
|
||||
{
|
||||
int eSize = 8 << size;
|
||||
|
||||
int shiftLsB = (sbyte)shift;
|
||||
|
||||
if (shiftLsB < 0)
|
||||
{
|
||||
return UnsignedShrReg(value, -shiftLsB, round, eSize);
|
||||
}
|
||||
else if (shiftLsB > 0)
|
||||
{
|
||||
if (shiftLsB >= eSize)
|
||||
{
|
||||
return 0UL;
|
||||
}
|
||||
|
||||
return value << shiftLsB;
|
||||
}
|
||||
else /* if (shiftLsB == 0) */
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public static long SignedShlRegSatQ(long value, long shift, bool round, int size)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
|
||||
int eSize = 8 << size;
|
||||
|
||||
int shiftLsB = (sbyte)shift;
|
||||
|
||||
if (shiftLsB < 0)
|
||||
{
|
||||
return SignedShrReg(value, -shiftLsB, round, eSize);
|
||||
}
|
||||
else if (shiftLsB > 0)
|
||||
{
|
||||
if (shiftLsB >= eSize)
|
||||
{
|
||||
return SignedSignSatQ(value, eSize, context);
|
||||
}
|
||||
|
||||
if (eSize == 64)
|
||||
{
|
||||
long shl = value << shiftLsB;
|
||||
long shr = shl >> shiftLsB;
|
||||
|
||||
if (shr != value)
|
||||
{
|
||||
return SignedSignSatQ(value, eSize, context);
|
||||
}
|
||||
else /* if (shr == value) */
|
||||
{
|
||||
return shl;
|
||||
}
|
||||
}
|
||||
else /* if (eSize != 64) */
|
||||
{
|
||||
return SignedSrcSignedDstSatQ(value << shiftLsB, size); // InstEmitSimdHelper.EmitSignedSrcSatQ(signedDst: true).
|
||||
}
|
||||
}
|
||||
else /* if (shiftLsB == 0) */
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public static ulong UnsignedShlRegSatQ(ulong value, ulong shift, bool round, int size)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
|
||||
int eSize = 8 << size;
|
||||
|
||||
int shiftLsB = (sbyte)shift;
|
||||
|
||||
if (shiftLsB < 0)
|
||||
{
|
||||
return UnsignedShrReg(value, -shiftLsB, round, eSize);
|
||||
}
|
||||
else if (shiftLsB > 0)
|
||||
{
|
||||
if (shiftLsB >= eSize)
|
||||
{
|
||||
return UnsignedSignSatQ(value, eSize, context);
|
||||
}
|
||||
|
||||
if (eSize == 64)
|
||||
{
|
||||
ulong shl = value << shiftLsB;
|
||||
ulong shr = shl >> shiftLsB;
|
||||
|
||||
if (shr != value)
|
||||
{
|
||||
return UnsignedSignSatQ(value, eSize, context);
|
||||
}
|
||||
else /* if (shr == value) */
|
||||
{
|
||||
return shl;
|
||||
}
|
||||
}
|
||||
else /* if (eSize != 64) */
|
||||
{
|
||||
return UnsignedSrcUnsignedDstSatQ(value << shiftLsB, size); // InstEmitSimdHelper.EmitUnsignedSrcSatQ(signedDst: false).
|
||||
}
|
||||
}
|
||||
else /* if (shiftLsB == 0) */
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
private static long SignedShrReg(long value, int shift, bool round, int eSize) // shift := [1, 128]; eSize := {8, 16, 32, 64}.
|
||||
{
|
||||
if (round)
|
||||
{
|
||||
if (shift >= eSize)
|
||||
{
|
||||
return 0L;
|
||||
}
|
||||
|
||||
long roundConst = 1L << (shift - 1);
|
||||
|
||||
long add = value + roundConst;
|
||||
|
||||
if (eSize == 64)
|
||||
{
|
||||
if ((~value & (value ^ add)) < 0L)
|
||||
{
|
||||
return (long)((ulong)add >> shift);
|
||||
}
|
||||
else
|
||||
{
|
||||
return add >> shift;
|
||||
}
|
||||
}
|
||||
else /* if (eSize != 64) */
|
||||
{
|
||||
return add >> shift;
|
||||
}
|
||||
}
|
||||
else /* if (!round) */
|
||||
{
|
||||
if (shift >= eSize)
|
||||
{
|
||||
if (value < 0L)
|
||||
{
|
||||
return -1L;
|
||||
}
|
||||
else /* if (value >= 0L) */
|
||||
{
|
||||
return 0L;
|
||||
}
|
||||
}
|
||||
|
||||
return value >> shift;
|
||||
}
|
||||
}
|
||||
|
||||
private static ulong UnsignedShrReg(ulong value, int shift, bool round, int eSize) // shift := [1, 128]; eSize := {8, 16, 32, 64}.
|
||||
{
|
||||
if (round)
|
||||
{
|
||||
if (shift > 64)
|
||||
{
|
||||
return 0UL;
|
||||
}
|
||||
|
||||
ulong roundConst = 1UL << (shift - 1);
|
||||
|
||||
ulong add = value + roundConst;
|
||||
|
||||
if (eSize == 64)
|
||||
{
|
||||
if ((add < value) && (add < roundConst))
|
||||
{
|
||||
if (shift == 64)
|
||||
{
|
||||
return 1UL;
|
||||
}
|
||||
|
||||
return (add >> shift) | (0x8000000000000000UL >> (shift - 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (shift == 64)
|
||||
{
|
||||
return 0UL;
|
||||
}
|
||||
|
||||
return add >> shift;
|
||||
}
|
||||
}
|
||||
else /* if (eSize != 64) */
|
||||
{
|
||||
if (shift == 64)
|
||||
{
|
||||
return 0UL;
|
||||
}
|
||||
|
||||
return add >> shift;
|
||||
}
|
||||
}
|
||||
else /* if (!round) */
|
||||
{
|
||||
if (shift >= eSize)
|
||||
{
|
||||
return 0UL;
|
||||
}
|
||||
|
||||
return value >> shift;
|
||||
}
|
||||
}
|
||||
|
||||
private static long SignedSignSatQ(long op, int eSize, ExecutionContext context) // eSize := {8, 16, 32, 64}.
|
||||
{
|
||||
long tMaxValue = (1L << (eSize - 1)) - 1L;
|
||||
long tMinValue = -(1L << (eSize - 1));
|
||||
|
||||
if (op > 0L)
|
||||
{
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
return tMaxValue;
|
||||
}
|
||||
else if (op < 0L)
|
||||
{
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
return tMinValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0L;
|
||||
}
|
||||
}
|
||||
|
||||
private static ulong UnsignedSignSatQ(ulong op, int eSize, ExecutionContext context) // eSize := {8, 16, 32, 64}.
|
||||
{
|
||||
ulong tMaxValue = ulong.MaxValue >> (64 - eSize);
|
||||
|
||||
if (op > 0UL)
|
||||
{
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
return tMaxValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0UL;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region "ShrImm64"
|
||||
public static long SignedShrImm64(long value, long roundConst, int shift)
|
||||
{
|
||||
@ -508,55 +227,6 @@ namespace ARMeilleure.Instructions
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region "Saturating"
|
||||
private static long SignedSrcSignedDstSatQ(long op, int size)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
|
||||
int eSize = 8 << size;
|
||||
|
||||
long tMaxValue = (1L << (eSize - 1)) - 1L;
|
||||
long tMinValue = -(1L << (eSize - 1));
|
||||
|
||||
if (op > tMaxValue)
|
||||
{
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
return tMaxValue;
|
||||
}
|
||||
else if (op < tMinValue)
|
||||
{
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
return tMinValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return op;
|
||||
}
|
||||
}
|
||||
|
||||
private static ulong UnsignedSrcUnsignedDstSatQ(ulong op, int size)
|
||||
{
|
||||
ExecutionContext context = NativeInterface.GetContext();
|
||||
|
||||
int eSize = 8 << size;
|
||||
|
||||
ulong tMaxValue = (1UL << eSize) - 1UL;
|
||||
|
||||
if (op > tMaxValue)
|
||||
{
|
||||
context.Fpsr |= FPSR.Qc;
|
||||
|
||||
return tMaxValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
return op;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region "Count"
|
||||
public static ulong CountLeadingSigns(ulong value, int size) // size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.).
|
||||
{
|
||||
|
@ -179,8 +179,6 @@ namespace ARMeilleure.Translation
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha1SchedulePart2)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart1)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart2)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShlReg)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShlRegSatQ)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.SignedShrImm64)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl1)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbl2)));
|
||||
@ -190,8 +188,6 @@ namespace ARMeilleure.Translation
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx2)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx3)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Tbx4)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShlReg)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShlRegSatQ)));
|
||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShrImm64)));
|
||||
|
||||
SetDelegateInfo(typeof(SoftFloat16_32).GetMethod(nameof(SoftFloat16_32.FPConvert)));
|
||||
|
@ -27,7 +27,7 @@ namespace ARMeilleure.Translation.PTC
|
||||
private const string OuterHeaderMagicString = "PTCohd\0\0";
|
||||
private const string InnerHeaderMagicString = "PTCihd\0\0";
|
||||
|
||||
private const uint InternalVersion = 3695; //! To be incremented manually for each change to the ARMeilleure project.
|
||||
private const uint InternalVersion = 3700; //! To be incremented manually for each change to the ARMeilleure project.
|
||||
|
||||
private const string ActualDir = "0";
|
||||
private const string BackupDir = "1";
|
||||
|
Reference in New Issue
Block a user