diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1986898a..24bc27cb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -97,6 +97,7 @@ add_library(dynarmic frontend/A64/translate/impl/simd_modified_immediate.cpp frontend/A64/translate/impl/simd_permute.cpp frontend/A64/translate/impl/simd_scalar_three_same.cpp + frontend/A64/translate/impl/simd_shift_by_immediate.cpp frontend/A64/translate/impl/simd_three_same.cpp frontend/A64/translate/impl/system.cpp frontend/A64/translate/translate.cpp diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index 99a5fe6b..5fb3eb0f 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -511,53 +511,29 @@ INST(SUB_1, "SUB (vector)", "01111 // Data Processing - FP and SIMD - SIMD Scalar shift by immediate //INST(SSHR_1, "SSHR", "010111110IIIIiii000001nnnnnddddd") -//INST(SSHR_2, "SSHR", "0Q0011110IIIIiii000001nnnnnddddd") //INST(SSRA_1, "SSRA", "010111110IIIIiii000101nnnnnddddd") -//INST(SSRA_2, "SSRA", "0Q0011110IIIIiii000101nnnnnddddd") //INST(SRSHR_1, "SRSHR", "010111110IIIIiii001001nnnnnddddd") -//INST(SRSHR_2, "SRSHR", "0Q0011110IIIIiii001001nnnnnddddd") //INST(SRSRA_1, "SRSRA", "010111110IIIIiii001101nnnnnddddd") -//INST(SRSRA_2, "SRSRA", "0Q0011110IIIIiii001101nnnnnddddd") //INST(SHL_1, "SHL", "010111110IIIIiii010101nnnnnddddd") -//INST(SHL_2, "SHL", "0Q0011110IIIIiii010101nnnnnddddd") //INST(SQSHL_imm_1, "SQSHL (immediate)", "010111110IIIIiii011101nnnnnddddd") -//INST(SQSHL_imm_2, "SQSHL (immediate)", "0Q0011110IIIIiii011101nnnnnddddd") //INST(SQSHRN_1, "SQSHRN, SQSHRN2", "010111110IIIIiii100101nnnnnddddd") -//INST(SQSHRN_2, "SQSHRN, SQSHRN2", "0Q0011110IIIIiii100101nnnnnddddd") //INST(SQRSHRN_1, "SQRSHRN, SQRSHRN2", "010111110IIIIiii100111nnnnnddddd") -//INST(SQRSHRN_2, "SQRSHRN, SQRSHRN2", "0Q0011110IIIIiii100111nnnnnddddd") //INST(SCVTF_fix_1, "SCVTF (vector, fixed-point)", "010111110IIIIiii111001nnnnnddddd") -//INST(SCVTF_fix_2, "SCVTF (vector, fixed-point)", "0Q0011110IIIIiii111001nnnnnddddd") //INST(FCVTZS_fix_1, "FCVTZS (vector, fixed-point)", "010111110IIIIiii111111nnnnnddddd") -//INST(FCVTZS_fix_2, "FCVTZS (vector, fixed-point)", "0Q0011110IIIIiii111111nnnnnddddd") //INST(USHR_1, "USHR", "011111110IIIIiii000001nnnnnddddd") -//INST(USHR_2, "USHR", "0Q1011110IIIIiii000001nnnnnddddd") //INST(USRA_1, "USRA", "011111110IIIIiii000101nnnnnddddd") -//INST(USRA_2, "USRA", "0Q1011110IIIIiii000101nnnnnddddd") //INST(URSHR_1, "URSHR", "011111110IIIIiii001001nnnnnddddd") -//INST(URSHR_2, "URSHR", "0Q1011110IIIIiii001001nnnnnddddd") //INST(URSRA_1, "URSRA", "011111110IIIIiii001101nnnnnddddd") -//INST(URSRA_2, "URSRA", "0Q1011110IIIIiii001101nnnnnddddd") //INST(SRI_1, "SRI", "011111110IIIIiii010001nnnnnddddd") -//INST(SRI_2, "SRI", "0Q1011110IIIIiii010001nnnnnddddd") //INST(SLI_1, "SLI", "011111110IIIIiii010101nnnnnddddd") -//INST(SLI_2, "SLI", "0Q1011110IIIIiii010101nnnnnddddd") //INST(SQSHLU_1, "SQSHLU", "011111110IIIIiii011001nnnnnddddd") -//INST(SQSHLU_2, "SQSHLU", "0Q1011110IIIIiii011001nnnnnddddd") //INST(UQSHL_imm_1, "UQSHL (immediate)", "011111110IIIIiii011101nnnnnddddd") -//INST(UQSHL_imm_2, "UQSHL (immediate)", "0Q1011110IIIIiii011101nnnnnddddd") //INST(SQSHRUN_1, "SQSHRUN, SQSHRUN2", "011111110IIIIiii100001nnnnnddddd") -//INST(SQSHRUN_2, "SQSHRUN, SQSHRUN2", "0Q1011110IIIIiii100001nnnnnddddd") //INST(SQRSHRUN_1, "SQRSHRUN, SQRSHRUN2", "011111110IIIIiii100011nnnnnddddd") -//INST(SQRSHRUN_2, "SQRSHRUN, SQRSHRUN2", "0Q1011110IIIIiii100011nnnnnddddd") //INST(UQSHRN_1, "UQSHRN, UQSHRN2", "011111110IIIIiii100101nnnnnddddd") -//INST(UQSHRN_2, "UQSHRN, UQSHRN2", "0Q1011110IIIIiii100101nnnnnddddd") //INST(UQRSHRN_1, "UQRSHRN, UQRSHRN2", "011111110IIIIiii100111nnnnnddddd") -//INST(UQRSHRN_2, "UQRSHRN, UQRSHRN2", "0Q1011110IIIIiii100111nnnnnddddd") //INST(UCVTF_fix_1, "UCVTF (vector, fixed-point)", "011111110IIIIiii111001nnnnnddddd") -//INST(UCVTF_fix_2, "UCVTF (vector, fixed-point)", "0Q1011110IIIIiii111001nnnnnddddd") //INST(FCVTZU_fix_1, "FCVTZU (vector, fixed-point)", "011111110IIIIiii111111nnnnnddddd") -//INST(FCVTZU_fix_2, "FCVTZU (vector, fixed-point)", "0Q1011110IIIIiii111111nnnnnddddd") // Data Processing - FP and SIMD - SIMD Scalar x indexed element //INST(SQDMLAL_elt_1, "SQDMLAL, SQDMLAL2 (by element)", "01011111zzLMmmmm0011H0nnnnnddddd") @@ -801,11 +777,35 @@ INST(BIF, "BIF", "0Q101 INST(MOVI, "MOVI, MVNI, ORR, BIC (vector, immediate)", "0Qo0111100000abcmmmm01defghddddd") //INST(FMOV_2, "FMOV (vector, immediate)", "0Q00111100000abc111111defghddddd") -// Data Processing - FP and SIMD - SIMD Shfit by immediate +// Data Processing - FP and SIMD - SIMD Shift by immediate +//INST(SSHR_2, "SSHR", "0Q0011110IIIIiii000001nnnnnddddd") +//INST(SSRA_2, "SSRA", "0Q0011110IIIIiii000101nnnnnddddd") +//INST(SRSHR_2, "SRSHR", "0Q0011110IIIIiii001001nnnnnddddd") +//INST(SRSRA_2, "SRSRA", "0Q0011110IIIIiii001101nnnnnddddd") +INST(SHL_2, "SHL", "0Q0011110IIIIiii010101nnnnnddddd") +//INST(SQSHL_imm_2, "SQSHL (immediate)", "0Q0011110IIIIiii011101nnnnnddddd") //INST(SHRN, "SHRN, SHRN2", "0Q0011110IIIIiii100001nnnnnddddd") //INST(RSHRN, "RSHRN, RSHRN2", "0Q0011110IIIIiii100011nnnnnddddd") +//INST(SQSHRN_2, "SQSHRN, SQSHRN2", "0Q0011110IIIIiii100101nnnnnddddd") +//INST(SQRSHRN_2, "SQRSHRN, SQRSHRN2", "0Q0011110IIIIiii100111nnnnnddddd") //INST(SSHLL, "SSHLL, SSHLL2", "0Q0011110IIIIiii101001nnnnnddddd") +//INST(SCVTF_fix_2, "SCVTF (vector, fixed-point)", "0Q0011110IIIIiii111001nnnnnddddd") +//INST(FCVTZS_fix_2, "FCVTZS (vector, fixed-point)", "0Q0011110IIIIiii111111nnnnnddddd") +//INST(USHR_2, "USHR", "0Q1011110IIIIiii000001nnnnnddddd") +//INST(USRA_2, "USRA", "0Q1011110IIIIiii000101nnnnnddddd") +//INST(URSHR_2, "URSHR", "0Q1011110IIIIiii001001nnnnnddddd") +//INST(URSRA_2, "URSRA", "0Q1011110IIIIiii001101nnnnnddddd") +//INST(SRI_2, "SRI", "0Q1011110IIIIiii010001nnnnnddddd") +//INST(SLI_2, "SLI", "0Q1011110IIIIiii010101nnnnnddddd") +//INST(SQSHLU_2, "SQSHLU", "0Q1011110IIIIiii011001nnnnnddddd") +//INST(UQSHL_imm_2, "UQSHL (immediate)", "0Q1011110IIIIiii011101nnnnnddddd") +//INST(SQSHRUN_2, "SQSHRUN, SQSHRUN2", "0Q1011110IIIIiii100001nnnnnddddd") +//INST(SQRSHRUN_2, "SQRSHRUN, SQRSHRUN2", "0Q1011110IIIIiii100011nnnnnddddd") +//INST(UQSHRN_2, "UQSHRN, UQSHRN2", "0Q1011110IIIIiii100101nnnnnddddd") +//INST(UQRSHRN_2, "UQRSHRN, UQRSHRN2", "0Q1011110IIIIiii100111nnnnnddddd") //INST(USHLL, "USHLL, USHLL2", "0Q1011110IIIIiii101001nnnnnddddd") +//INST(UCVTF_fix_2, "UCVTF (vector, fixed-point)", "0Q1011110IIIIiii111001nnnnnddddd") +//INST(FCVTZU_fix_2, "FCVTZU (vector, fixed-point)", "0Q1011110IIIIiii111111nnnnnddddd") // Data Processing - FP and SIMD - SIMD x indexed element //INST(SMLAL_elt, "SMLAL, SMLAL2 (by element)", "0Q001111zzLMmmmm0010H0nnnnnddddd") diff --git a/src/frontend/A64/translate/impl/impl.cpp b/src/frontend/A64/translate/impl/impl.cpp index 973ed45b..6a9d0f4a 100644 --- a/src/frontend/A64/translate/impl/impl.cpp +++ b/src/frontend/A64/translate/impl/impl.cpp @@ -21,6 +21,11 @@ bool TranslatorVisitor::UnpredictableInstruction() { return false; } +bool TranslatorVisitor::DecodeError() { + // TODO: This is an internal error. + return UnallocatedEncoding(); +} + bool TranslatorVisitor::ReservedValue() { ir.ExceptionRaised(Exception::ReservedValue); ir.SetTerm(IR::Term::CheckHalt{IR::Term::ReturnToDispatch{}}); diff --git a/src/frontend/A64/translate/impl/impl.h b/src/frontend/A64/translate/impl/impl.h index e25f7f0b..6cc852ef 100644 --- a/src/frontend/A64/translate/impl/impl.h +++ b/src/frontend/A64/translate/impl/impl.h @@ -32,6 +32,7 @@ struct TranslatorVisitor final { bool InterpretThisInstruction(); bool UnpredictableInstruction(); + bool DecodeError(); bool ReservedValue(); bool UnallocatedEncoding(); @@ -609,53 +610,29 @@ struct TranslatorVisitor final { // Data Processing - FP and SIMD - SIMD Scalar shift by immediate bool SSHR_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); - bool SSHR_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); bool SSRA_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); - bool SSRA_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); bool SRSHR_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); - bool SRSHR_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); bool SRSRA_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); - bool SRSRA_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); bool SHL_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); - bool SHL_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); bool SQSHL_imm_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); - bool SQSHL_imm_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); bool SQSHRN_1(Imm<4> immh, Imm<3> immb, Vec Vn, Reg Rd); - bool SQSHRN_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Reg Rd); bool SQRSHRN_1(Imm<4> immh, Imm<3> immb, Vec Vn, Reg Rd); - bool SQRSHRN_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Reg Rd); bool SCVTF_fix_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); - bool SCVTF_fix_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); bool FCVTZS_fix_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); - bool FCVTZS_fix_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); bool USHR_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); - bool USHR_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); bool USRA_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); - bool USRA_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); bool URSHR_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); - bool URSHR_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); bool URSRA_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); - bool URSRA_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); bool SRI_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); - bool SRI_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); bool SLI_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); - bool SLI_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); bool SQSHLU_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); - bool SQSHLU_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); bool UQSHL_imm_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); - bool UQSHL_imm_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); bool SQSHRUN_1(Imm<4> immh, Imm<3> immb, Vec Vn, Reg Rd); - bool SQSHRUN_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Reg Rd); bool SQRSHRUN_1(Imm<4> immh, Imm<3> immb, Vec Vn, Reg Rd); - bool SQRSHRUN_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Reg Rd); bool UQSHRN_1(Imm<4> immh, Imm<3> immb, Vec Vn, Reg Rd); - bool UQSHRN_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Reg Rd); bool UQRSHRN_1(Imm<4> immh, Imm<3> immb, Vec Vn, Reg Rd); - bool UQRSHRN_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Reg Rd); bool UCVTF_fix_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); - bool UCVTF_fix_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); bool FCVTZU_fix_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); - bool FCVTZU_fix_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); // Data Processing - FP and SIMD - SIMD Scalar x indexed element bool SQDMLAL_elt_1(Imm<2> size, bool L, bool M, Vec Vm, bool H, Reg Rn, Vec Vd); @@ -874,11 +851,35 @@ struct TranslatorVisitor final { bool MOVI(bool Q, bool op, Imm<1> a, Imm<1> b, Imm<1> c, Imm<4> cmode, Imm<1> d, Imm<1> e, Imm<1> f, Imm<1> g, Imm<1> h, Vec Vd); bool FMOV_2(bool Q, Imm<1> a, Imm<1> b, Imm<1> c, Imm<1> d, Imm<1> e, Imm<1> f, Imm<1> g, Imm<1> h, Reg Rd); - // Data Processing - FP and SIMD - SIMD Shfit by immediate + // Data Processing - FP and SIMD - SIMD Shift by immediate + bool SSHR_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); + bool SSRA_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); + bool SRSHR_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); + bool SRSRA_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); + bool SHL_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); + bool SQSHL_imm_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); bool SHRN(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Reg Rd); bool RSHRN(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Reg Rd); + bool SQSHRN_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Reg Rd); + bool SQRSHRN_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Reg Rd); bool SSHLL(bool Q, Imm<4> immh, Imm<3> immb, Reg Rn, Vec Vd); + bool SCVTF_fix_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); + bool FCVTZS_fix_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); + bool USHR_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); + bool USRA_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); + bool URSHR_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); + bool URSRA_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); + bool SRI_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); + bool SLI_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); + bool SQSHLU_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); + bool UQSHL_imm_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); + bool SQSHRUN_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Reg Rd); + bool SQRSHRUN_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Reg Rd); + bool UQSHRN_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Reg Rd); + bool UQRSHRN_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Reg Rd); bool USHLL(bool Q, Imm<4> immh, Imm<3> immb, Reg Rn, Vec Vd); + bool UCVTF_fix_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); + bool FCVTZU_fix_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); // Data Processing - FP and SIMD - SIMD x indexed element bool SMLAL_elt(bool Q, Imm<2> size, bool L, bool M, Vec Vm, bool H, Reg Rn, Vec Vd); diff --git a/src/frontend/A64/translate/impl/simd_shift_by_immediate.cpp b/src/frontend/A64/translate/impl/simd_shift_by_immediate.cpp new file mode 100644 index 00000000..85b77938 --- /dev/null +++ b/src/frontend/A64/translate/impl/simd_shift_by_immediate.cpp @@ -0,0 +1,43 @@ +/* This file is part of the dynarmic project. + * Copyright (c) 2018 MerryMage + * This software may be used and distributed according to the terms of the GNU + * General Public License version 2 or any later version. + */ + +#include "common/bit_util.h" +#include "frontend/A64/translate/impl/impl.h" + +namespace Dynarmic::A64 { + +bool TranslatorVisitor::SHL_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) { + if (immh == 0b0000) { + return DecodeError(); + } + if (immh.Bit<3>() && !Q) { + return ReservedValue(); + } + const size_t esize = 8 << Common::HighestSetBit(immh.ZeroExtend()); + const size_t datasize = Q ? 128 : 64; + + const u8 shift_amount = concatenate(immh, immb).ZeroExtend() - static_cast(esize); + + const IR::U128 operand = V(datasize, Vn); + const IR::U128 result = [&]{ + switch (esize) { + case 8: + return ir.VectorLogicalShiftLeft8(operand, shift_amount); + case 16: + return ir.VectorLogicalShiftLeft16(operand, shift_amount); + case 32: + return ir.VectorLogicalShiftLeft32(operand, shift_amount); + case 64: + default: + return ir.VectorLogicalShiftLeft64(operand, shift_amount); + } + }(); + + V(datasize, Vd, result); + return true; +} + +} // namespace Dynarmic::A64