From 8309d495886d9f6cf76e791a8d3621ee622cd0ff Mon Sep 17 00:00:00 2001 From: Lioncash Date: Thu, 11 Apr 2019 17:37:32 -0400 Subject: [PATCH] A64: Handle reserved instruction cases more specifically where applicable These are cases that are defined as reserved within the ARMv8 reference manual, so we can handle them as such instead of as unallocated encodings. While this doesn't actually change emulated behavior, it does at least allow the JIT to generate the more appropriate exception. --- src/frontend/A64/translate/impl/simd_copy.cpp | 54 ++++++++++++++----- .../A64/translate/impl/simd_extract.cpp | 2 +- .../impl/simd_scalar_shift_by_immediate.cpp | 4 +- .../impl/simd_scalar_two_register_misc.cpp | 2 +- .../impl/simd_scalar_x_indexed_element.cpp | 8 +-- .../translate/impl/simd_three_same_extra.cpp | 8 +-- .../impl/simd_vector_x_indexed_element.cpp | 12 ++--- 7 files changed, 60 insertions(+), 30 deletions(-) diff --git a/src/frontend/A64/translate/impl/simd_copy.cpp b/src/frontend/A64/translate/impl/simd_copy.cpp index 6b19ce73..5916ba8a 100644 --- a/src/frontend/A64/translate/impl/simd_copy.cpp +++ b/src/frontend/A64/translate/impl/simd_copy.cpp @@ -11,7 +11,9 @@ namespace Dynarmic::A64 { bool TranslatorVisitor::DUP_elt_1(Imm<5> imm5, Vec Vn, Vec Vd) { const size_t size = Common::LowestSetBit(imm5.ZeroExtend()); - if (size > 3) return UnallocatedEncoding(); + if (size > 3) { + return ReservedValue(); + } const size_t index = imm5.ZeroExtend() >> (size + 1); const size_t idxdsize = imm5.Bit<4>() ? 128 : 64; @@ -26,8 +28,13 @@ bool TranslatorVisitor::DUP_elt_1(Imm<5> imm5, Vec Vn, Vec Vd) { bool TranslatorVisitor::DUP_elt_2(bool Q, Imm<5> imm5, Vec Vn, Vec Vd) { const size_t size = Common::LowestSetBit(imm5.ZeroExtend()); - if (size > 3) return UnallocatedEncoding(); - if (size == 3 && !Q) return ReservedValue(); + if (size > 3) { + return ReservedValue(); + } + + if (size == 3 && !Q) { + return ReservedValue(); + } const size_t index = imm5.ZeroExtend() >> (size + 1); const size_t idxdsize = imm5.Bit<4>() ? 128 : 64; @@ -43,8 +50,14 @@ bool TranslatorVisitor::DUP_elt_2(bool Q, Imm<5> imm5, Vec Vn, Vec Vd) { bool TranslatorVisitor::DUP_gen(bool Q, Imm<5> imm5, Reg Rn, Vec Vd) { const size_t size = Common::LowestSetBit(imm5.ZeroExtend()); - if (size > 3) return UnallocatedEncoding(); - if (size == 3 && !Q) return ReservedValue(); + if (size > 3) { + return ReservedValue(); + } + + if (size == 3 && !Q) { + return ReservedValue(); + } + const size_t esize = 8 << size; const size_t datasize = Q ? 128 : 64; @@ -59,8 +72,13 @@ bool TranslatorVisitor::DUP_gen(bool Q, Imm<5> imm5, Reg Rn, Vec Vd) { bool TranslatorVisitor::SMOV(bool Q, Imm<5> imm5, Vec Vn, Reg Rd) { const size_t size = Common::LowestSetBit(imm5.ZeroExtend()); - if (size == 2 && !Q) return UnallocatedEncoding(); - if (size > 2) return UnallocatedEncoding(); + if (size == 2 && !Q) { + return UnallocatedEncoding(); + } + + if (size > 2) { + return ReservedValue(); + } const size_t idxdsize = imm5.Bit<4>() ? 128 : 64; const size_t index = imm5.ZeroExtend() >> (size + 1); @@ -77,9 +95,17 @@ bool TranslatorVisitor::SMOV(bool Q, Imm<5> imm5, Vec Vn, Reg Rd) { bool TranslatorVisitor::UMOV(bool Q, Imm<5> imm5, Vec Vn, Reg Rd) { const size_t size = Common::LowestSetBit(imm5.ZeroExtend()); - if (size < 3 && Q) return UnallocatedEncoding(); - if (size == 3 && !Q) return UnallocatedEncoding(); - if (size > 3) return UnallocatedEncoding(); + if (size < 3 && Q) { + return UnallocatedEncoding(); + } + + if (size == 3 && !Q) { + return UnallocatedEncoding(); + } + + if (size > 3) { + return ReservedValue(); + } const size_t idxdsize = imm5.Bit<4>() ? 128 : 64; const size_t index = imm5.ZeroExtend() >> (size + 1); @@ -96,7 +122,9 @@ bool TranslatorVisitor::UMOV(bool Q, Imm<5> imm5, Vec Vn, Reg Rd) { bool TranslatorVisitor::INS_gen(Imm<5> imm5, Reg Rn, Vec Vd) { const size_t size = Common::LowestSetBit(imm5.ZeroExtend()); - if (size > 3) return UnallocatedEncoding(); + if (size > 3) { + return ReservedValue(); + } const size_t index = imm5.ZeroExtend() >> (size + 1); const size_t esize = 8 << size; @@ -111,7 +139,9 @@ bool TranslatorVisitor::INS_gen(Imm<5> imm5, Reg Rn, Vec Vd) { bool TranslatorVisitor::INS_elt(Imm<5> imm5, Imm<4> imm4, Vec Vn, Vec Vd) { const size_t size = Common::LowestSetBit(imm5.ZeroExtend()); - if (size > 3) return UnallocatedEncoding(); + if (size > 3) { + return ReservedValue(); + } const size_t dst_index = imm5.ZeroExtend() >> (size + 1); const size_t src_index = imm4.ZeroExtend() >> size; diff --git a/src/frontend/A64/translate/impl/simd_extract.cpp b/src/frontend/A64/translate/impl/simd_extract.cpp index 78719316..aae27ea2 100644 --- a/src/frontend/A64/translate/impl/simd_extract.cpp +++ b/src/frontend/A64/translate/impl/simd_extract.cpp @@ -10,7 +10,7 @@ namespace Dynarmic::A64 { bool TranslatorVisitor::EXT(bool Q, Vec Vm, Imm<4> imm4, Vec Vn, Vec Vd) { if (!Q && imm4.Bit<3>()) { - return UnallocatedEncoding(); + return ReservedValue(); } const size_t datasize = Q ? 128 : 64; diff --git a/src/frontend/A64/translate/impl/simd_scalar_shift_by_immediate.cpp b/src/frontend/A64/translate/impl/simd_scalar_shift_by_immediate.cpp index 2cefc899..8553bf80 100644 --- a/src/frontend/A64/translate/impl/simd_scalar_shift_by_immediate.cpp +++ b/src/frontend/A64/translate/impl/simd_scalar_shift_by_immediate.cpp @@ -157,11 +157,11 @@ bool ShiftAndInsert(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec bool ShiftRightNarrowing(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, Narrowing narrowing, Signedness signedness) { if (immh == 0b0000) { - return v.UnallocatedEncoding(); + return v.ReservedValue(); } if (immh.Bit<3>()) { - return v.UnallocatedEncoding(); + return v.ReservedValue(); } const size_t esize = 8 << Common::HighestSetBit(immh.ZeroExtend()); diff --git a/src/frontend/A64/translate/impl/simd_scalar_two_register_misc.cpp b/src/frontend/A64/translate/impl/simd_scalar_two_register_misc.cpp index d9b3e29c..623a705c 100644 --- a/src/frontend/A64/translate/impl/simd_scalar_two_register_misc.cpp +++ b/src/frontend/A64/translate/impl/simd_scalar_two_register_misc.cpp @@ -154,7 +154,7 @@ bool TranslatorVisitor::FCVTPU_2(bool sz, Vec Vn, Vec Vd) { bool TranslatorVisitor::FCVTXN_1(bool sz, Vec Vn, Vec Vd) { if (!sz) { - return UnallocatedEncoding(); + return ReservedValue(); } const IR::U64 element = V_scalar(64, Vn); diff --git a/src/frontend/A64/translate/impl/simd_scalar_x_indexed_element.cpp b/src/frontend/A64/translate/impl/simd_scalar_x_indexed_element.cpp index 2f19f23a..693cf3d3 100644 --- a/src/frontend/A64/translate/impl/simd_scalar_x_indexed_element.cpp +++ b/src/frontend/A64/translate/impl/simd_scalar_x_indexed_element.cpp @@ -27,7 +27,7 @@ enum class ExtraBehavior { bool MultiplyByElement(TranslatorVisitor& v, bool sz, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd, ExtraBehavior extra_behavior) { if (sz && L == 1) { - return v.UnallocatedEncoding(); + return v.ReservedValue(); } const size_t idxdsize = H == 1 ? 128 : 64; @@ -78,7 +78,7 @@ bool TranslatorVisitor::FMULX_elt_2(bool sz, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Im bool TranslatorVisitor::SQDMULH_elt_1(Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) { if (size == 0b00 || size == 0b11) { - return UnallocatedEncoding(); + return ReservedValue(); } const size_t esize = 8 << size.ZeroExtend(); @@ -96,7 +96,7 @@ bool TranslatorVisitor::SQDMULH_elt_1(Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vm bool TranslatorVisitor::SQRDMULH_elt_1(Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) { if (size == 0b00 || size == 0b11) { - return UnallocatedEncoding(); + return ReservedValue(); } const size_t esize = 8 << size.ZeroExtend(); @@ -114,7 +114,7 @@ bool TranslatorVisitor::SQRDMULH_elt_1(Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> V bool TranslatorVisitor::SQDMULL_elt_1(Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) { if (size == 0b00 || size == 0b11) { - return UnallocatedEncoding(); + return ReservedValue(); } const size_t esize = 8 << size.ZeroExtend(); diff --git a/src/frontend/A64/translate/impl/simd_three_same_extra.cpp b/src/frontend/A64/translate/impl/simd_three_same_extra.cpp index cc6919a0..b38a6450 100644 --- a/src/frontend/A64/translate/impl/simd_three_same_extra.cpp +++ b/src/frontend/A64/translate/impl/simd_three_same_extra.cpp @@ -55,11 +55,11 @@ bool TranslatorVisitor::UDOT_vec(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) { bool TranslatorVisitor::FCMLA_vec(bool Q, Imm<2> size, Vec Vm, Imm<2> rot, Vec Vn, Vec Vd) { if (size == 0) { - return UnallocatedEncoding(); + return ReservedValue(); } if (!Q && size == 0b11) { - return UnallocatedEncoding(); + return ReservedValue(); } const size_t esize = 8U << size.ZeroExtend(); @@ -128,11 +128,11 @@ bool TranslatorVisitor::FCMLA_vec(bool Q, Imm<2> size, Vec Vm, Imm<2> rot, Vec V bool TranslatorVisitor::FCADD_vec(bool Q, Imm<2> size, Vec Vm, Imm<1> rot, Vec Vn, Vec Vd) { if (size == 0) { - return UnallocatedEncoding(); + return ReservedValue(); } if (!Q && size == 0b11) { - return UnallocatedEncoding(); + return ReservedValue(); } const size_t esize = 8U << size.ZeroExtend(); diff --git a/src/frontend/A64/translate/impl/simd_vector_x_indexed_element.cpp b/src/frontend/A64/translate/impl/simd_vector_x_indexed_element.cpp index 2fc62bab..88bd4916 100644 --- a/src/frontend/A64/translate/impl/simd_vector_x_indexed_element.cpp +++ b/src/frontend/A64/translate/impl/simd_vector_x_indexed_element.cpp @@ -28,7 +28,7 @@ enum class ExtraBehavior { bool MultiplyByElement(TranslatorVisitor& v, bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd, ExtraBehavior extra_behavior) { if (size != 0b01 && size != 0b10) { - return v.UnallocatedEncoding(); + return v.ReservedValue(); } const auto [index, Vm] = Combine(size, H, L, M, Vmlo); @@ -54,7 +54,7 @@ bool MultiplyByElement(TranslatorVisitor& v, bool Q, Imm<2> size, Imm<1> L, Imm< bool FPMultiplyByElement(TranslatorVisitor& v, bool Q, bool sz, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd, ExtraBehavior extra_behavior) { if (sz && L == 1) { - return v.UnallocatedEncoding(); + return v.ReservedValue(); } if (sz && !Q) { return v.ReservedValue(); @@ -133,7 +133,7 @@ enum class Signedness { bool MultiplyLong(TranslatorVisitor& v, bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd, ExtraBehavior extra_behavior, Signedness sign) { if (size == 0b00 || size == 0b11) { - return v.UnallocatedEncoding(); + return v.ReservedValue(); } const size_t idxsize = H == 1 ? 128 : 64; @@ -217,7 +217,7 @@ bool TranslatorVisitor::SMULL_elt(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4 bool TranslatorVisitor::SQDMULL_elt_2(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) { if (size == 0b00 || size == 0b11) { - return UnallocatedEncoding(); + return ReservedValue(); } const size_t part = Q ? 1 : 0; @@ -237,7 +237,7 @@ bool TranslatorVisitor::SQDMULL_elt_2(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, I bool TranslatorVisitor::SQDMULH_elt_2(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) { if (size == 0b00 || size == 0b11) { - return UnallocatedEncoding(); + return ReservedValue(); } const size_t idxsize = H == 1 ? 128 : 64; @@ -256,7 +256,7 @@ bool TranslatorVisitor::SQDMULH_elt_2(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, I bool TranslatorVisitor::SQRDMULH_elt_2(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) { if (size == 0b00 || size == 0b11) { - return UnallocatedEncoding(); + return ReservedValue(); } const size_t idxsize = H == 1 ? 128 : 64;