From 7969871aa35452d5a8ca4452387d4ef6939358d5 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Wed, 4 Apr 2018 10:28:52 +0100 Subject: [PATCH] A64: Implement FMOV (vector, immediate) and mark other SIMD modified immediate instructions as unallocated --- src/frontend/A64/decoder/a64.h | 1 + src/frontend/A64/decoder/a64.inc | 4 ++- src/frontend/A64/translate/impl/impl.h | 3 +- .../impl/simd_modified_immediate.cpp | 34 ++++++++++++++++++- 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/frontend/A64/decoder/a64.h b/src/frontend/A64/decoder/a64.h index 73752659..d049155e 100644 --- a/src/frontend/A64/decoder/a64.h +++ b/src/frontend/A64/decoder/a64.h @@ -40,6 +40,7 @@ std::vector> GetDecodeTable() { const std::set comes_first { "MOVI, MVNI, ORR, BIC (vector, immediate)", "FMOV (vector, immediate)", + "Unallocated SIMD modified immediate", }; std::stable_partition(table.begin(), table.end(), [&](const auto& matcher) { diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index 9fcc5f6d..3c2bc28c 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -784,7 +784,9 @@ INST(BIF, "BIF", "0Q101 // Data Processing - FP and SIMD - SIMD modified immediate INST(MOVI, "MOVI, MVNI, ORR, BIC (vector, immediate)", "0Qo0111100000abcmmmm01defghddddd") -//INST(FMOV_2, "FMOV (vector, immediate)", "0Q00111100000abc111111defghddddd") +INST(FMOV_2, "FMOV (vector, immediate)", "0Qo0111100000abc111101defghddddd") +INST(FMOV_3, "FMOV (vector, immediate)", "0Q00111100000abc111111defghddddd") +INST(UnallocatedEncoding, "Unallocated SIMD modified immediate", "0--0111100000-------11----------") // Data Processing - FP and SIMD - SIMD Shift by immediate INST(SSHR_2, "SSHR", "0Q0011110IIIIiii000001nnnnnddddd") diff --git a/src/frontend/A64/translate/impl/impl.h b/src/frontend/A64/translate/impl/impl.h index 5d0ad3f8..2a6295a6 100644 --- a/src/frontend/A64/translate/impl/impl.h +++ b/src/frontend/A64/translate/impl/impl.h @@ -865,7 +865,8 @@ struct TranslatorVisitor final { // Data Processing - FP and SIMD - SIMD modified immediate 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, Vec Vd); + bool FMOV_2(bool Q, bool op, Imm<1> a, Imm<1> b, Imm<1> c, Imm<1> d, Imm<1> e, Imm<1> f, Imm<1> g, Imm<1> h, Vec Vd); + bool FMOV_3(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, Vec Vd); // Data Processing - FP and SIMD - SIMD Shift by immediate bool SSHR_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd); diff --git a/src/frontend/A64/translate/impl/simd_modified_immediate.cpp b/src/frontend/A64/translate/impl/simd_modified_immediate.cpp index e9f24249..41ca7332 100644 --- a/src/frontend/A64/translate/impl/simd_modified_immediate.cpp +++ b/src/frontend/A64/translate/impl/simd_modified_immediate.cpp @@ -76,4 +76,36 @@ bool TranslatorVisitor::MOVI(bool Q, bool op, Imm<1> a, Imm<1> b, Imm<1> c, Imm< return true; } -} // namespace Dynarmic::A64 +bool TranslatorVisitor::FMOV_2(bool Q, bool op, Imm<1> a, Imm<1> b, Imm<1> c, Imm<1> d, Imm<1> e, Imm<1> f, Imm<1> g, Imm<1> h, Vec Vd) { + const size_t datasize = Q ? 128 : 64; + + if (op && !Q) { + return UnallocatedEncoding(); + } + + const u64 imm64 = AdvSIMDExpandImm(op, Imm<4>{0b1111}, concatenate(a, b, c, d, e, f, g, h)); + + const IR::U128 imm = datasize == 64 ? ir.ZeroExtendToQuad(ir.Imm64(imm64)) : ir.VectorBroadcast(64, ir.Imm64(imm64)); + V(128, Vd, imm); + return true; +} + +bool TranslatorVisitor::FMOV_3(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, Vec Vd) { + const size_t datasize = Q ? 128 : 64; + + const Imm<8> imm8 = concatenate(a, b, c, d, e, f, g, h); + const u16 imm16 = [&imm8]{ + u16 imm16 = 0; + imm16 |= imm8.Bit<7>() ? 0x8000 : 0; + imm16 |= imm8.Bit<6>() ? 0x3000 : 0x4000; + imm16 |= imm8.Bits<0, 5, u16>() << 6; + return imm16; + }(); + const u64 imm64 = Common::Replicate(imm16, 16); + + const IR::U128 imm = datasize == 64 ? ir.ZeroExtendToQuad(ir.Imm64(imm64)) : ir.VectorBroadcast(64, ir.Imm64(imm64)); + V(128, Vd, imm); + return true; +} + +} // namespace Dynarmic::A6