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("00011010110xxxxx010101xxxxxxxxxx", InstName.Crc32ch, InstEmit.Crc32ch, OpCodeAluBinary.Create);
|
||||||
SetA64("00011010110xxxxx010110xxxxxxxxxx", InstName.Crc32cw, InstEmit.Crc32cw, OpCodeAluBinary.Create);
|
SetA64("00011010110xxxxx010110xxxxxxxxxx", InstName.Crc32cw, InstEmit.Crc32cw, OpCodeAluBinary.Create);
|
||||||
SetA64("10011010110xxxxx010111xxxxxxxxxx", InstName.Crc32cx, InstEmit.Crc32cx, 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("x0011010100xxxxxxxxx00xxxxxxxxxx", InstName.Csel, InstEmit.Csel, OpCodeCsel.Create);
|
||||||
SetA64("x0011010100xxxxxxxxx01xxxxxxxxxx", InstName.Csinc, InstEmit.Csinc, OpCodeCsel.Create);
|
SetA64("x0011010100xxxxxxxxx01xxxxxxxxxx", InstName.Csinc, InstEmit.Csinc, OpCodeCsel.Create);
|
||||||
SetA64("x1011010100xxxxxxxxx00xxxxxxxxxx", InstName.Csinv, InstEmit.Csinv, 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("11001010xx0xxxxxxxxxxxxxxxxxxxxx", InstName.Eor, InstEmit.Eor, OpCodeAluRs.Create);
|
||||||
SetA64("00010011100xxxxx0xxxxxxxxxxxxxxx", InstName.Extr, InstEmit.Extr, OpCodeAluRs.Create);
|
SetA64("00010011100xxxxx0xxxxxxxxxxxxxxx", InstName.Extr, InstEmit.Extr, OpCodeAluRs.Create);
|
||||||
SetA64("10010011110xxxxxxxxxxxxxxxxxxxxx", 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("11010101000000110011xxxx11011111", InstName.Isb, InstEmit.Isb, OpCodeSystem.Create);
|
||||||
SetA64("xx001000110xxxxx1xxxxxxxxxxxxxxx", InstName.Ldar, InstEmit.Ldar, OpCodeMemEx.Create);
|
SetA64("xx001000110xxxxx1xxxxxxxxxxxxxxx", InstName.Ldar, InstEmit.Ldar, OpCodeMemEx.Create);
|
||||||
SetA64("1x001000011xxxxx1xxxxxxxxxxxxxxx", InstName.Ldaxp, InstEmit.Ldaxp, 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("00010011000xxxxx0xxxxxxxxxxxxxxx", InstName.Sbfm, InstEmit.Sbfm, OpCodeBfm.Create);
|
||||||
SetA64("1001001101xxxxxxxxxxxxxxxxxxxxxx", InstName.Sbfm, InstEmit.Sbfm, OpCodeBfm.Create);
|
SetA64("1001001101xxxxxxxxxxxxxxxxxxxxxx", InstName.Sbfm, InstEmit.Sbfm, OpCodeBfm.Create);
|
||||||
SetA64("x0011010110xxxxx000011xxxxxxxxxx", InstName.Sdiv, InstEmit.Sdiv, OpCodeAluBinary.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("10011011001xxxxx0xxxxxxxxxxxxxxx", InstName.Smaddl, InstEmit.Smaddl, OpCodeMul.Create);
|
||||||
SetA64("10011011001xxxxx1xxxxxxxxxxxxxxx", InstName.Smsubl, InstEmit.Smsubl, OpCodeMul.Create);
|
SetA64("10011011001xxxxx1xxxxxxxxxxxxxxx", InstName.Smsubl, InstEmit.Smsubl, OpCodeMul.Create);
|
||||||
SetA64("10011011010xxxxx0xxxxxxxxxxxxxxx", InstName.Smulh, InstEmit.Smulh, 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("10011011101xxxxx0xxxxxxxxxxxxxxx", InstName.Umaddl, InstEmit.Umaddl, OpCodeMul.Create);
|
||||||
SetA64("10011011101xxxxx1xxxxxxxxxxxxxxx", InstName.Umsubl, InstEmit.Umsubl, OpCodeMul.Create);
|
SetA64("10011011101xxxxx1xxxxxxxxxxxxxxx", InstName.Umsubl, InstEmit.Umsubl, OpCodeMul.Create);
|
||||||
SetA64("10011011110xxxxx0xxxxxxxxxxxxxxx", InstName.Umulh, InstEmit.Umulh, 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
|
// FP & SIMD
|
||||||
SetA64("0101111011100000101110xxxxxxxxxx", InstName.Abs_S, InstEmit.Abs_S, OpCodeSimd.Create);
|
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("<<<<0010001xxxxxxxxxxxxxxxxxxxxx", InstName.Eor, InstEmit32.Eor, OpCode32AluImm.Create);
|
||||||
SetA32("<<<<0000001xxxxxxxxxxxxxxxx0xxxx", InstName.Eor, InstEmit32.Eor, OpCode32AluRsImm.Create);
|
SetA32("<<<<0000001xxxxxxxxxxxxxxxx0xxxx", InstName.Eor, InstEmit32.Eor, OpCode32AluRsImm.Create);
|
||||||
SetA32("<<<<0000001xxxxxxxxxxxxx0xx1xxxx", InstName.Eor, InstEmit32.Eor, OpCode32AluRsReg.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("1111010101111111111100000110xxxx", InstName.Isb, InstEmit32.Nop, OpCode32.Create);
|
||||||
SetA32("<<<<00011001xxxxxxxx110010011111", InstName.Lda, InstEmit32.Lda, OpCode32MemLdEx.Create);
|
SetA32("<<<<00011001xxxxxxxx110010011111", InstName.Lda, InstEmit32.Lda, OpCode32MemLdEx.Create);
|
||||||
SetA32("<<<<00011101xxxxxxxx110010011111", InstName.Ldab, InstEmit32.Ldab, 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("<<<<0111101xxxxxxxxxxxxxx101xxxx", InstName.Sbfx, InstEmit32.Sbfx, OpCode32AluBf.Create);
|
||||||
SetA32("<<<<01110001xxxx1111xxxx0001xxxx", InstName.Sdiv, InstEmit32.Sdiv, OpCode32AluMla.Create);
|
SetA32("<<<<01110001xxxx1111xxxx0001xxxx", InstName.Sdiv, InstEmit32.Sdiv, OpCode32AluMla.Create);
|
||||||
SetA32("<<<<01101000xxxxxxxx11111011xxxx", InstName.Sel, InstEmit32.Sel, OpCode32AluReg.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("<<<<01100011xxxxxxxx11111001xxxx", InstName.Shadd8, InstEmit32.Shadd8, OpCode32AluReg.Create);
|
||||||
SetA32("<<<<01100011xxxxxxxx11111111xxxx", InstName.Shsub8, InstEmit32.Shsub8, OpCode32AluReg.Create);
|
SetA32("<<<<01100011xxxxxxxx11111111xxxx", InstName.Shsub8, InstEmit32.Shsub8, OpCode32AluReg.Create);
|
||||||
SetA32("<<<<00010000xxxxxxxxxxxx1xx0xxxx", InstName.Smla__, InstEmit32.Smla__, OpCode32AluMla.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("<<<<00010011xxxx0000xxxxxxx0xxxx", InstName.Teq, InstEmit32.Teq, OpCode32AluRsImm.Create);
|
||||||
SetA32("<<<<00010011xxxx0000xxxx0xx1xxxx", InstName.Teq, InstEmit32.Teq, OpCode32AluRsReg.Create);
|
SetA32("<<<<00010011xxxx0000xxxx0xx1xxxx", InstName.Teq, InstEmit32.Teq, OpCode32AluRsReg.Create);
|
||||||
SetA32("<<<<0111111111111101111011111110", InstName.Trap, InstEmit32.Trap, OpCode32Exception.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("<<<<00110001xxxx0000xxxxxxxxxxxx", InstName.Tst, InstEmit32.Tst, OpCode32AluImm.Create);
|
||||||
SetA32("<<<<00010001xxxx0000xxxxxxx0xxxx", InstName.Tst, InstEmit32.Tst, OpCode32AluRsImm.Create);
|
SetA32("<<<<00010001xxxx0000xxxxxxx0xxxx", InstName.Tst, InstEmit32.Tst, OpCode32AluRsImm.Create);
|
||||||
SetA32("<<<<00010001xxxx0000xxxx0xx1xxxx", InstName.Tst, InstEmit32.Tst, OpCode32AluRsReg.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("<<<<01101110xxxxxxxxxx000111xxxx", InstName.Uxtb, InstEmit32.Uxtb, OpCode32AluUx.Create);
|
||||||
SetA32("<<<<01101100xxxxxxxxxx000111xxxx", InstName.Uxtb16, InstEmit32.Uxtb16, OpCode32AluUx.Create);
|
SetA32("<<<<01101100xxxxxxxxxx000111xxxx", InstName.Uxtb16, InstEmit32.Uxtb16, OpCode32AluUx.Create);
|
||||||
SetA32("<<<<01101111xxxxxxxxxx000111xxxx", InstName.Uxth, InstEmit32.Uxth, 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
|
// VFP
|
||||||
SetVfp("<<<<11101x110000xxxx101x11x0xxxx", InstName.Vabs, InstEmit32.Vabs_S, OpCode32SimdS.Create, OpCode32SimdS.CreateT32);
|
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("1011101011xxxxxx", InstName.Revsh, InstEmit32.Revsh, OpCodeT16AluRegLow.Create);
|
||||||
SetT16("101110x1xxxxxxxx", InstName.Cbnz, InstEmit32.Cbnz, OpCodeT16BImmCmp.Create);
|
SetT16("101110x1xxxxxxxx", InstName.Cbnz, InstEmit32.Cbnz, OpCodeT16BImmCmp.Create);
|
||||||
SetT16("1011110xxxxxxxxx", InstName.Pop, InstEmit32.Ldm, OpCodeT16MemStack.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("10111111xxxx>>>>", InstName.It, InstEmit32.It, OpCodeT16IfThen.Create);
|
||||||
SetT16("11000xxxxxxxxxxx", InstName.Stm, InstEmit32.Stm, OpCodeT16MemMult.Create);
|
SetT16("11000xxxxxxxxxxx", InstName.Stm, InstEmit32.Stm, OpCodeT16MemMult.Create);
|
||||||
SetT16("11001xxxxxxxxxxx", InstName.Ldm, InstEmit32.Ldm, 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("11110x010001xxxx0xxx1111xxxxxxxx", InstName.Cmn, InstEmit32.Cmn, OpCodeT32AluImm.Create);
|
||||||
SetT32("111010111011xxxx0xxx1111xxxxxxxx", InstName.Cmp, InstEmit32.Cmp, OpCodeT32AluRsImm.Create);
|
SetT32("111010111011xxxx0xxx1111xxxxxxxx", InstName.Cmp, InstEmit32.Cmp, OpCodeT32AluRsImm.Create);
|
||||||
SetT32("11110x011011xxxx0xxx1111xxxxxxxx", InstName.Cmp, InstEmit32.Cmp, OpCodeT32AluImm.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("11101010100<xxxx0xxx<<<<xxxxxxxx", InstName.Eor, InstEmit32.Eor, OpCodeT32AluRsImm.Create);
|
||||||
SetT32("11110x00100<xxxx0xxx<<<<xxxxxxxx", InstName.Eor, InstEmit32.Eor, OpCodeT32AluImm.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("111010001101xxxxxxxx111110101111", InstName.Lda, InstEmit32.Lda, OpCodeT32MemLdEx.Create);
|
||||||
SetT32("111010001101xxxxxxxx111110001111", InstName.Ldab, InstEmit32.Ldab, OpCodeT32MemLdEx.Create);
|
SetT32("111010001101xxxxxxxx111110001111", InstName.Ldab, InstEmit32.Ldab, OpCodeT32MemLdEx.Create);
|
||||||
SetT32("111010001101xxxxxxxx111111101111", InstName.Ldaex, InstEmit32.Ldaex, 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("111110101010xxxx1111xxxx1000xxxx", InstName.Sel, InstEmit32.Sel, OpCodeT32AluReg.Create);
|
||||||
SetT32("111110101000xxxx1111xxxx0010xxxx", InstName.Shadd8, InstEmit32.Shadd8, OpCodeT32AluReg.Create);
|
SetT32("111110101000xxxx1111xxxx0010xxxx", InstName.Shadd8, InstEmit32.Shadd8, OpCodeT32AluReg.Create);
|
||||||
SetT32("111110101100xxxx1111xxxx0010xxxx", InstName.Shsub8, InstEmit32.Shsub8, 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("111110110001xxxx<<<<xxxx00xxxxxx", InstName.Smla__, InstEmit32.Smla__, OpCodeT32AluMla.Create);
|
||||||
SetT32("111110111100xxxxxxxxxxxx0000xxxx", InstName.Smlal, InstEmit32.Smlal, OpCodeT32AluUmull.Create);
|
SetT32("111110111100xxxxxxxxxxxx0000xxxx", InstName.Smlal, InstEmit32.Smlal, OpCodeT32AluUmull.Create);
|
||||||
SetT32("111110111100xxxxxxxxxxxx10xxxxxx", 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("111010001101xxxx111100000001xxxx", InstName.Tbh, InstEmit32.Tbh, OpCodeT32Tb.Create);
|
||||||
SetT32("111010101001xxxx0xxx1111xxxxxxxx", InstName.Teq, InstEmit32.Teq, OpCodeT32AluRsImm.Create);
|
SetT32("111010101001xxxx0xxx1111xxxxxxxx", InstName.Teq, InstEmit32.Teq, OpCodeT32AluRsImm.Create);
|
||||||
SetT32("11110x001001xxxx0xxx1111xxxxxxxx", InstName.Teq, InstEmit32.Teq, OpCodeT32AluImm.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("111010100001xxxx0xxx1111xxxxxxxx", InstName.Tst, InstEmit32.Tst, OpCodeT32AluRsImm.Create);
|
||||||
SetT32("11110x000001xxxx0xxx1111xxxxxxxx", InstName.Tst, InstEmit32.Tst, OpCodeT32AluImm.Create);
|
SetT32("11110x000001xxxx0xxx1111xxxxxxxx", InstName.Tst, InstEmit32.Tst, OpCodeT32AluImm.Create);
|
||||||
SetT32("111110101000xxxx1111xxxx0100xxxx", InstName.Uadd8, InstEmit32.Uadd8, OpCodeT32AluReg.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("111110100101xxxx1111xxxx10xxxxxx", InstName.Uxtb, InstEmit32.Uxtb, OpCodeT32AluUx.Create);
|
||||||
SetT32("111110100011xxxx1111xxxx10xxxxxx", InstName.Uxtb16, InstEmit32.Uxtb16, OpCodeT32AluUx.Create);
|
SetT32("111110100011xxxx1111xxxx10xxxxxx", InstName.Uxtb16, InstEmit32.Uxtb16, OpCodeT32AluUx.Create);
|
||||||
SetT32("111110100001xxxx1111xxxx10xxxxxx", InstName.Uxth, InstEmit32.Uxth, 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
|
#endregion
|
||||||
|
|
||||||
FillFastLookupTable(InstA32FastLookup, AllInstA32, ToFastLookupIndexA);
|
FillFastLookupTable(InstA32FastLookup, AllInstA32, ToFastLookupIndexA);
|
||||||
|
@@ -26,6 +26,11 @@ namespace ARMeilleure.Instructions
|
|||||||
EmitClearExclusive(context);
|
EmitClearExclusive(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void Csdb(ArmEmitterContext context)
|
||||||
|
{
|
||||||
|
// Execute as no-op.
|
||||||
|
}
|
||||||
|
|
||||||
public static void Dmb(ArmEmitterContext context) => EmitBarrier(context);
|
public static void Dmb(ArmEmitterContext context) => EmitBarrier(context);
|
||||||
public static void Dsb(ArmEmitterContext context) => EmitBarrier(context);
|
public static void Dsb(ArmEmitterContext context) => EmitBarrier(context);
|
||||||
|
|
||||||
|
@@ -1533,29 +1533,88 @@ namespace ARMeilleure.Instructions
|
|||||||
context.Copy(d, res);
|
context.Copy(d, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TSrc (16bit, 32bit, 64bit; signed) > TDst (8bit, 16bit, 32bit; signed, unsigned).
|
// long SignedSignSatQ(long op, int size);
|
||||||
// long SignedSrcSignedDstSatQ(long op, int size); ulong SignedSrcUnsignedDstSatQ(long op, int size);
|
public static Operand EmitSignedSignSatQ(ArmEmitterContext context, Operand op, int size)
|
||||||
public static Operand EmitSignedSrcSatQ(ArmEmitterContext context, Operand op, int sizeDst, bool signedDst)
|
|
||||||
{
|
{
|
||||||
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 lbl1 = Label();
|
||||||
Operand lblEnd = 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 res = context.Copy(context.AllocateLocal(OperandType.I64), zeroL);
|
||||||
Operand minT = signedDst ? Const(-(1L << (eSize - 1))) : Const(0UL);
|
|
||||||
|
|
||||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), op);
|
context.BranchIf(lbl1, op, zeroL, Comparison.LessOrEqual);
|
||||||
|
|
||||||
context.BranchIf(lbl1, res, maxT, Comparison.LessOrEqual);
|
|
||||||
context.Copy(res, maxT);
|
context.Copy(res, maxT);
|
||||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||||
context.Branch(lblEnd);
|
context.Branch(lblEnd);
|
||||||
|
|
||||||
context.MarkLabel(lbl1);
|
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.Copy(res, minT);
|
||||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||||
context.Branch(lblEnd);
|
context.Branch(lblEnd);
|
||||||
@@ -1569,18 +1628,19 @@ namespace ARMeilleure.Instructions
|
|||||||
// long UnsignedSrcSignedDstSatQ(ulong op, int size); ulong UnsignedSrcUnsignedDstSatQ(ulong op, int size);
|
// long UnsignedSrcSignedDstSatQ(ulong op, int size); ulong UnsignedSrcUnsignedDstSatQ(ulong op, int size);
|
||||||
public static Operand EmitUnsignedSrcSatQ(ArmEmitterContext context, Operand op, int sizeDst, bool signedDst)
|
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();
|
Operand lblEnd = Label();
|
||||||
|
|
||||||
int eSize = 8 << sizeDst;
|
Operand maxT = signedDst ? Const((1L << (eSizeDst - 1)) - 1L) : Const((1UL << eSizeDst) - 1UL);
|
||||||
|
|
||||||
Operand maxL = signedDst ? Const((1L << (eSize - 1)) - 1L) : Const((1UL << eSize) - 1UL);
|
|
||||||
|
|
||||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), op);
|
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), op);
|
||||||
|
|
||||||
context.BranchIf(lblEnd, res, maxL, Comparison.LessOrEqualUI);
|
context.BranchIf(lblEnd, op, maxT, Comparison.LessOrEqualUI);
|
||||||
context.Copy(res, maxL);
|
context.Copy(res, maxT);
|
||||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||||
context.Branch(lblEnd);
|
context.Branch(lblEnd);
|
||||||
|
|
||||||
@@ -1601,7 +1661,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
Operand res = context.Copy(context.AllocateLocal(OperandType.I64), op);
|
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.Copy(res, maxL);
|
||||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||||
context.Branch(lblEnd);
|
context.Branch(lblEnd);
|
||||||
@@ -1620,15 +1680,16 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
Operand minL = Const(long.MinValue);
|
Operand minL = Const(long.MinValue);
|
||||||
Operand maxL = Const(long.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);
|
||||||
|
|
||||||
Operand left = context.BitwiseNot(context.BitwiseExclusiveOr(op1, op2));
|
Operand left = context.BitwiseNot(context.BitwiseExclusiveOr(op1, op2));
|
||||||
Operand right = context.BitwiseExclusiveOr(op1, res);
|
Operand right = context.BitwiseExclusiveOr(op1, add);
|
||||||
context.BranchIf(lblEnd, context.BitwiseAnd(left, right), zero, Comparison.GreaterOrEqual);
|
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.Copy(res, context.ConditionalSelect(isPositive, maxL, minL));
|
||||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||||
context.Branch(lblEnd);
|
context.Branch(lblEnd);
|
||||||
@@ -1647,9 +1708,10 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
Operand maxUL = Const(ulong.MaxValue);
|
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.Copy(res, maxUL);
|
||||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||||
context.Branch(lblEnd);
|
context.Branch(lblEnd);
|
||||||
@@ -1668,15 +1730,16 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
Operand minL = Const(long.MinValue);
|
Operand minL = Const(long.MinValue);
|
||||||
Operand maxL = Const(long.MaxValue);
|
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 left = context.BitwiseExclusiveOr(op1, op2);
|
||||||
Operand right = context.BitwiseExclusiveOr(op1, res);
|
Operand right = context.BitwiseExclusiveOr(op1, sub);
|
||||||
context.BranchIf(lblEnd, context.BitwiseAnd(left, right), zero, Comparison.GreaterOrEqual);
|
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.Copy(res, context.ConditionalSelect(isPositive, maxL, minL));
|
||||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||||
context.Branch(lblEnd);
|
context.Branch(lblEnd);
|
||||||
@@ -1693,12 +1756,13 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
Operand lblEnd = Label();
|
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.BranchIf(lblEnd, op1, op2, Comparison.GreaterOrEqualUI);
|
||||||
context.Copy(res, zero);
|
context.Copy(res, zeroL);
|
||||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||||
context.Branch(lblEnd);
|
context.Branch(lblEnd);
|
||||||
|
|
||||||
@@ -1717,25 +1781,26 @@ namespace ARMeilleure.Instructions
|
|||||||
Operand lblEnd = Label();
|
Operand lblEnd = Label();
|
||||||
|
|
||||||
Operand maxL = Const(long.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, maxL, Comparison.GreaterUI);
|
context.BranchIf(lbl1, op1, maxL, Comparison.GreaterUI);
|
||||||
Operand notOp2AndRes = context.BitwiseAnd(context.BitwiseNot(op2), res);
|
Operand notOp2AndRes = context.BitwiseAnd(context.BitwiseNot(op2), add);
|
||||||
context.BranchIf(lblEnd, notOp2AndRes, zero, Comparison.GreaterOrEqual);
|
context.BranchIf(lblEnd, notOp2AndRes, zeroL, Comparison.GreaterOrEqual);
|
||||||
context.Copy(res, maxL);
|
context.Copy(res, maxL);
|
||||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||||
context.Branch(lblEnd);
|
context.Branch(lblEnd);
|
||||||
|
|
||||||
context.MarkLabel(lbl1);
|
context.MarkLabel(lbl1);
|
||||||
context.BranchIf(lbl2, op2, zero, Comparison.Less);
|
context.BranchIf(lbl2, op2, zeroL, Comparison.Less);
|
||||||
context.Copy(res, maxL);
|
context.Copy(res, maxL);
|
||||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||||
context.Branch(lblEnd);
|
context.Branch(lblEnd);
|
||||||
|
|
||||||
context.MarkLabel(lbl2);
|
context.MarkLabel(lbl2);
|
||||||
context.BranchIf(lblEnd, res, maxL, Comparison.LessOrEqualUI);
|
context.BranchIf(lblEnd, add, maxL, Comparison.LessOrEqualUI);
|
||||||
context.Copy(res, maxL);
|
context.Copy(res, maxL);
|
||||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||||
context.Branch(lblEnd);
|
context.Branch(lblEnd);
|
||||||
@@ -1755,20 +1820,21 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
Operand maxUL = Const(ulong.MaxValue);
|
Operand maxUL = Const(ulong.MaxValue);
|
||||||
Operand maxL = Const(long.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(lbl1, op1, zeroL, Comparison.Less);
|
||||||
context.BranchIf(lblEnd, res, op1, Comparison.GreaterOrEqualUI);
|
context.BranchIf(lblEnd, add, op1, Comparison.GreaterOrEqualUI);
|
||||||
context.Copy(res, maxUL);
|
context.Copy(res, maxUL);
|
||||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||||
context.Branch(lblEnd);
|
context.Branch(lblEnd);
|
||||||
|
|
||||||
context.MarkLabel(lbl1);
|
context.MarkLabel(lbl1);
|
||||||
context.BranchIf(lblEnd, op2, maxL, Comparison.GreaterUI);
|
context.BranchIf(lblEnd, op2, maxL, Comparison.GreaterUI);
|
||||||
context.BranchIf(lblEnd, res, zero, Comparison.GreaterOrEqual);
|
context.BranchIf(lblEnd, add, zeroL, Comparison.GreaterOrEqual);
|
||||||
context.Copy(res, zero);
|
context.Copy(res, zeroL);
|
||||||
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
context.Call(typeof(NativeInterface).GetMethod(nameof(NativeInterface.SetFpsrQc)));
|
||||||
context.Branch(lblEnd);
|
context.Branch(lblEnd);
|
||||||
|
|
||||||
|
@@ -188,23 +188,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
public static void Sqrshl_V(ArmEmitterContext context)
|
public static void Sqrshl_V(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
EmitShlRegOp(context, ShlRegFlags.Signed | ShlRegFlags.Round | ShlRegFlags.Saturating);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Sqrshrn_S(ArmEmitterContext context)
|
public static void Sqrshrn_S(ArmEmitterContext context)
|
||||||
@@ -229,23 +213,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
public static void Sqshl_V(ArmEmitterContext context)
|
public static void Sqshl_V(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
EmitShlRegOp(context, ShlRegFlags.Signed | ShlRegFlags.Saturating);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Sqshrn_S(ArmEmitterContext context)
|
public static void Sqshrn_S(ArmEmitterContext context)
|
||||||
@@ -280,23 +248,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
public static void Srshl_V(ArmEmitterContext context)
|
public static void Srshl_V(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
EmitShlRegOp(context, ShlRegFlags.Signed | ShlRegFlags.Round);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Srshr_S(ArmEmitterContext context)
|
public static void Srshr_S(ArmEmitterContext context)
|
||||||
@@ -393,12 +345,12 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
public static void Sshl_S(ArmEmitterContext context)
|
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)
|
public static void Sshl_V(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
EmitSshlOrUshl(context, signed: true, scalar: false);
|
EmitShlRegOp(context, ShlRegFlags.Signed);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Sshll_V(ArmEmitterContext context)
|
public static void Sshll_V(ArmEmitterContext context)
|
||||||
@@ -506,23 +458,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
public static void Uqrshl_V(ArmEmitterContext context)
|
public static void Uqrshl_V(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
EmitShlRegOp(context, ShlRegFlags.Round | ShlRegFlags.Saturating);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Uqrshrn_S(ArmEmitterContext context)
|
public static void Uqrshrn_S(ArmEmitterContext context)
|
||||||
@@ -537,23 +473,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
public static void Uqshl_V(ArmEmitterContext context)
|
public static void Uqshl_V(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
EmitShlRegOp(context, ShlRegFlags.Saturating);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Uqshrn_S(ArmEmitterContext context)
|
public static void Uqshrn_S(ArmEmitterContext context)
|
||||||
@@ -568,23 +488,7 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
public static void Urshl_V(ArmEmitterContext context)
|
public static void Urshl_V(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
EmitShlRegOp(context, ShlRegFlags.Round);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Urshr_S(ArmEmitterContext context)
|
public static void Urshr_S(ArmEmitterContext context)
|
||||||
@@ -677,12 +581,12 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
public static void Ushl_S(ArmEmitterContext context)
|
public static void Ushl_S(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
EmitSshlOrUshl(context, signed: false, scalar: true);
|
EmitShlRegOp(context, ShlRegFlags.Scalar);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Ushl_V(ArmEmitterContext context)
|
public static void Ushl_V(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
EmitSshlOrUshl(context, signed: false, scalar: false);
|
EmitShlRegOp(context, ShlRegFlags.None);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Ushll_V(ArmEmitterContext context)
|
public static void Ushll_V(ArmEmitterContext context)
|
||||||
@@ -872,43 +776,6 @@ namespace ARMeilleure.Instructions
|
|||||||
context.Copy(GetVec(op.Rd), res);
|
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)
|
private static void EmitVectorShrImmNarrowOpZx(ArmEmitterContext context, bool round)
|
||||||
{
|
{
|
||||||
OpCodeSimdShImm op = (OpCodeSimdShImm)context.CurrOp;
|
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;
|
OpCodeSimdReg op = (OpCodeSimdReg)context.CurrOp;
|
||||||
|
|
||||||
Operand res = context.VectorZero();
|
Operand res = context.VectorZero();
|
||||||
@@ -1178,15 +1060,225 @@ namespace ARMeilleure.Instructions
|
|||||||
|
|
||||||
for (int index = 0; index < elems; index++)
|
for (int index = 0; index < elems; index++)
|
||||||
{
|
{
|
||||||
Operand ne = EmitVectorExtract (context, op.Rn, index, op.Size, signed);
|
Operand ne = EmitVectorExtract(context, op.Rn, index, op.Size, signed);
|
||||||
Operand me = EmitVectorExtractSx(context, op.Rm, index << op.Size, 0);
|
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);
|
res = EmitVectorInsert(context, res, e, index, op.Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
context.Copy(GetVec(op.Rd), res);
|
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
|
private const int DczSizeLog2 = 4; // Log2 size in words
|
||||||
public const int DczSizeInBytes = 4 << DczSizeLog2;
|
public const int DczSizeInBytes = 4 << DczSizeLog2;
|
||||||
|
|
||||||
public static void Hint(ArmEmitterContext context)
|
|
||||||
{
|
|
||||||
// Execute as no-op.
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Isb(ArmEmitterContext context)
|
public static void Isb(ArmEmitterContext context)
|
||||||
{
|
{
|
||||||
// Execute as no-op.
|
// Execute as no-op.
|
||||||
|
@@ -45,6 +45,7 @@ namespace ARMeilleure.Instructions
|
|||||||
Dsb,
|
Dsb,
|
||||||
Eon,
|
Eon,
|
||||||
Eor,
|
Eor,
|
||||||
|
Esb,
|
||||||
Extr,
|
Extr,
|
||||||
Hint,
|
Hint,
|
||||||
Isb,
|
Isb,
|
||||||
@@ -82,6 +83,8 @@ namespace ARMeilleure.Instructions
|
|||||||
Sbfm,
|
Sbfm,
|
||||||
Sdiv,
|
Sdiv,
|
||||||
Sel,
|
Sel,
|
||||||
|
Sev,
|
||||||
|
Sevl,
|
||||||
Shsub8,
|
Shsub8,
|
||||||
Smaddl,
|
Smaddl,
|
||||||
Smsubl,
|
Smsubl,
|
||||||
@@ -105,12 +108,16 @@ namespace ARMeilleure.Instructions
|
|||||||
Sys,
|
Sys,
|
||||||
Tbnz,
|
Tbnz,
|
||||||
Tbz,
|
Tbz,
|
||||||
|
Tsb,
|
||||||
Ubfm,
|
Ubfm,
|
||||||
Udiv,
|
Udiv,
|
||||||
Umaddl,
|
Umaddl,
|
||||||
Umsubl,
|
Umsubl,
|
||||||
Umulh,
|
Umulh,
|
||||||
Und,
|
Und,
|
||||||
|
Wfe,
|
||||||
|
Wfi,
|
||||||
|
Yield,
|
||||||
|
|
||||||
// FP & SIMD (AArch64)
|
// FP & SIMD (AArch64)
|
||||||
Abs_S,
|
Abs_S,
|
||||||
|
@@ -5,287 +5,6 @@ namespace ARMeilleure.Instructions
|
|||||||
{
|
{
|
||||||
static class SoftFallback
|
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"
|
#region "ShrImm64"
|
||||||
public static long SignedShrImm64(long value, long roundConst, int shift)
|
public static long SignedShrImm64(long value, long roundConst, int shift)
|
||||||
{
|
{
|
||||||
@@ -508,55 +227,6 @@ namespace ARMeilleure.Instructions
|
|||||||
}
|
}
|
||||||
#endregion
|
#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"
|
#region "Count"
|
||||||
public static ulong CountLeadingSigns(ulong value, int size) // size is 8, 16, 32 or 64 (SIMD&FP or Base Inst.).
|
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.Sha1SchedulePart2)));
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart1)));
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart1)));
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.Sha256SchedulePart2)));
|
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.SignedShrImm64)));
|
||||||
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)));
|
||||||
@@ -190,8 +188,6 @@ 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.UnsignedShlReg)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShlRegSatQ)));
|
|
||||||
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShrImm64)));
|
SetDelegateInfo(typeof(SoftFallback).GetMethod(nameof(SoftFallback.UnsignedShrImm64)));
|
||||||
|
|
||||||
SetDelegateInfo(typeof(SoftFloat16_32).GetMethod(nameof(SoftFloat16_32.FPConvert)));
|
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 OuterHeaderMagicString = "PTCohd\0\0";
|
||||||
private const string InnerHeaderMagicString = "PTCihd\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 ActualDir = "0";
|
||||||
private const string BackupDir = "1";
|
private const string BackupDir = "1";
|
||||||
|
@@ -27,7 +27,7 @@
|
|||||||
</a>
|
</a>
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
<img src="https://raw.githubusercontent.com/Ryujinx/Ryujinx-Website/master/static/public/shell_fullsize.png">
|
<img src="https://raw.githubusercontent.com/Ryujinx/Ryujinx-Website/master/public/assets/images/shell.png">
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h5 align="center">
|
<h5 align="center">
|
||||||
|
Reference in New Issue
Block a user