A64: Implement SIMD instruction SHL

This commit is contained in:
MerryMage 2018-02-10 09:49:55 +00:00
parent f6247125c0
commit 1d0cd95b23
5 changed files with 100 additions and 50 deletions

View file

@ -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

View file

@ -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")

View file

@ -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{}});

View file

@ -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);

View file

@ -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<u8>() - static_cast<u8>(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