Merge pull request #467 from lioncash/reserved

A64: Handle reserved instruction cases more specifically where applicable
This commit is contained in:
Merry 2019-04-12 19:13:08 +01:00 committed by MerryMage
commit 9a4e3b24e4
7 changed files with 60 additions and 30 deletions

View file

@ -11,7 +11,9 @@ namespace Dynarmic::A64 {
bool TranslatorVisitor::DUP_elt_1(Imm<5> imm5, Vec Vn, Vec Vd) { bool TranslatorVisitor::DUP_elt_1(Imm<5> imm5, Vec Vn, Vec Vd) {
const size_t size = Common::LowestSetBit(imm5.ZeroExtend()); 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_t>() >> (size + 1); const size_t index = imm5.ZeroExtend<size_t>() >> (size + 1);
const size_t idxdsize = imm5.Bit<4>() ? 128 : 64; 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) { bool TranslatorVisitor::DUP_elt_2(bool Q, Imm<5> imm5, Vec Vn, Vec Vd) {
const size_t size = Common::LowestSetBit(imm5.ZeroExtend()); const size_t size = Common::LowestSetBit(imm5.ZeroExtend());
if (size > 3) return UnallocatedEncoding(); if (size > 3) {
if (size == 3 && !Q) return ReservedValue(); return ReservedValue();
}
if (size == 3 && !Q) {
return ReservedValue();
}
const size_t index = imm5.ZeroExtend<size_t>() >> (size + 1); const size_t index = imm5.ZeroExtend<size_t>() >> (size + 1);
const size_t idxdsize = imm5.Bit<4>() ? 128 : 64; 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) { bool TranslatorVisitor::DUP_gen(bool Q, Imm<5> imm5, Reg Rn, Vec Vd) {
const size_t size = Common::LowestSetBit(imm5.ZeroExtend()); const size_t size = Common::LowestSetBit(imm5.ZeroExtend());
if (size > 3) return UnallocatedEncoding(); if (size > 3) {
if (size == 3 && !Q) return ReservedValue(); return ReservedValue();
}
if (size == 3 && !Q) {
return ReservedValue();
}
const size_t esize = 8 << size; const size_t esize = 8 << size;
const size_t datasize = Q ? 128 : 64; 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) { bool TranslatorVisitor::SMOV(bool Q, Imm<5> imm5, Vec Vn, Reg Rd) {
const size_t size = Common::LowestSetBit(imm5.ZeroExtend()); const size_t size = Common::LowestSetBit(imm5.ZeroExtend());
if (size == 2 && !Q) return UnallocatedEncoding(); if (size == 2 && !Q) {
if (size > 2) return UnallocatedEncoding(); return UnallocatedEncoding();
}
if (size > 2) {
return ReservedValue();
}
const size_t idxdsize = imm5.Bit<4>() ? 128 : 64; const size_t idxdsize = imm5.Bit<4>() ? 128 : 64;
const size_t index = imm5.ZeroExtend<size_t>() >> (size + 1); const size_t index = imm5.ZeroExtend<size_t>() >> (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) { bool TranslatorVisitor::UMOV(bool Q, Imm<5> imm5, Vec Vn, Reg Rd) {
const size_t size = Common::LowestSetBit(imm5.ZeroExtend()); const size_t size = Common::LowestSetBit(imm5.ZeroExtend());
if (size < 3 && Q) return UnallocatedEncoding(); if (size < 3 && Q) {
if (size == 3 && !Q) return UnallocatedEncoding(); return UnallocatedEncoding();
if (size > 3) 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 idxdsize = imm5.Bit<4>() ? 128 : 64;
const size_t index = imm5.ZeroExtend<size_t>() >> (size + 1); const size_t index = imm5.ZeroExtend<size_t>() >> (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) { bool TranslatorVisitor::INS_gen(Imm<5> imm5, Reg Rn, Vec Vd) {
const size_t size = Common::LowestSetBit(imm5.ZeroExtend()); 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_t>() >> (size + 1); const size_t index = imm5.ZeroExtend<size_t>() >> (size + 1);
const size_t esize = 8 << size; 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) { bool TranslatorVisitor::INS_elt(Imm<5> imm5, Imm<4> imm4, Vec Vn, Vec Vd) {
const size_t size = Common::LowestSetBit(imm5.ZeroExtend()); 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_t>() >> (size + 1); const size_t dst_index = imm5.ZeroExtend<size_t>() >> (size + 1);
const size_t src_index = imm4.ZeroExtend<size_t>() >> size; const size_t src_index = imm4.ZeroExtend<size_t>() >> size;

View file

@ -10,7 +10,7 @@ namespace Dynarmic::A64 {
bool TranslatorVisitor::EXT(bool Q, Vec Vm, Imm<4> imm4, Vec Vn, Vec Vd) { bool TranslatorVisitor::EXT(bool Q, Vec Vm, Imm<4> imm4, Vec Vn, Vec Vd) {
if (!Q && imm4.Bit<3>()) { if (!Q && imm4.Bit<3>()) {
return UnallocatedEncoding(); return ReservedValue();
} }
const size_t datasize = Q ? 128 : 64; const size_t datasize = Q ? 128 : 64;

View file

@ -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, bool ShiftRightNarrowing(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd,
Narrowing narrowing, Signedness signedness) { Narrowing narrowing, Signedness signedness) {
if (immh == 0b0000) { if (immh == 0b0000) {
return v.UnallocatedEncoding(); return v.ReservedValue();
} }
if (immh.Bit<3>()) { if (immh.Bit<3>()) {
return v.UnallocatedEncoding(); return v.ReservedValue();
} }
const size_t esize = 8 << Common::HighestSetBit(immh.ZeroExtend()); const size_t esize = 8 << Common::HighestSetBit(immh.ZeroExtend());

View file

@ -154,7 +154,7 @@ bool TranslatorVisitor::FCVTPU_2(bool sz, Vec Vn, Vec Vd) {
bool TranslatorVisitor::FCVTXN_1(bool sz, Vec Vn, Vec Vd) { bool TranslatorVisitor::FCVTXN_1(bool sz, Vec Vn, Vec Vd) {
if (!sz) { if (!sz) {
return UnallocatedEncoding(); return ReservedValue();
} }
const IR::U64 element = V_scalar(64, Vn); const IR::U64 element = V_scalar(64, Vn);

View file

@ -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, 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) { Vec Vn, Vec Vd, ExtraBehavior extra_behavior) {
if (sz && L == 1) { if (sz && L == 1) {
return v.UnallocatedEncoding(); return v.ReservedValue();
} }
const size_t idxdsize = H == 1 ? 128 : 64; 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) { 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) { if (size == 0b00 || size == 0b11) {
return UnallocatedEncoding(); return ReservedValue();
} }
const size_t esize = 8 << size.ZeroExtend(); 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) { 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) { if (size == 0b00 || size == 0b11) {
return UnallocatedEncoding(); return ReservedValue();
} }
const size_t esize = 8 << size.ZeroExtend(); 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) { 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) { if (size == 0b00 || size == 0b11) {
return UnallocatedEncoding(); return ReservedValue();
} }
const size_t esize = 8 << size.ZeroExtend(); const size_t esize = 8 << size.ZeroExtend();

View file

@ -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) { bool TranslatorVisitor::FCMLA_vec(bool Q, Imm<2> size, Vec Vm, Imm<2> rot, Vec Vn, Vec Vd) {
if (size == 0) { if (size == 0) {
return UnallocatedEncoding(); return ReservedValue();
} }
if (!Q && size == 0b11) { if (!Q && size == 0b11) {
return UnallocatedEncoding(); return ReservedValue();
} }
const size_t esize = 8U << size.ZeroExtend(); 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) { bool TranslatorVisitor::FCADD_vec(bool Q, Imm<2> size, Vec Vm, Imm<1> rot, Vec Vn, Vec Vd) {
if (size == 0) { if (size == 0) {
return UnallocatedEncoding(); return ReservedValue();
} }
if (!Q && size == 0b11) { if (!Q && size == 0b11) {
return UnallocatedEncoding(); return ReservedValue();
} }
const size_t esize = 8U << size.ZeroExtend(); const size_t esize = 8U << size.ZeroExtend();

View file

@ -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, 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) { ExtraBehavior extra_behavior) {
if (size != 0b01 && size != 0b10) { if (size != 0b01 && size != 0b10) {
return v.UnallocatedEncoding(); return v.ReservedValue();
} }
const auto [index, Vm] = Combine(size, H, L, M, Vmlo); 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, 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) { ExtraBehavior extra_behavior) {
if (sz && L == 1) { if (sz && L == 1) {
return v.UnallocatedEncoding(); return v.ReservedValue();
} }
if (sz && !Q) { if (sz && !Q) {
return v.ReservedValue(); 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, 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) { Imm<1> H, Vec Vn, Vec Vd, ExtraBehavior extra_behavior, Signedness sign) {
if (size == 0b00 || size == 0b11) { if (size == 0b00 || size == 0b11) {
return v.UnallocatedEncoding(); return v.ReservedValue();
} }
const size_t idxsize = H == 1 ? 128 : 64; const size_t idxsize = H == 1 ? 128 : 64;
@ -306,7 +306,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) { 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) { if (size == 0b00 || size == 0b11) {
return UnallocatedEncoding(); return ReservedValue();
} }
const size_t part = Q ? 1 : 0; const size_t part = Q ? 1 : 0;
@ -326,7 +326,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) { 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) { if (size == 0b00 || size == 0b11) {
return UnallocatedEncoding(); return ReservedValue();
} }
const size_t idxsize = H == 1 ? 128 : 64; const size_t idxsize = H == 1 ? 128 : 64;
@ -345,7 +345,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) { 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) { if (size == 0b00 || size == 0b11) {
return UnallocatedEncoding(); return ReservedValue();
} }
const size_t idxsize = H == 1 ? 128 : 64; const size_t idxsize = H == 1 ? 128 : 64;