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.
This commit is contained in:
Lioncash 2019-04-11 17:37:32 -04:00 committed by MerryMage
parent e7361148db
commit 8309d49588
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) {
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 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_t>() >> (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_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) {
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_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) {
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 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_t>() >> (size + 1);
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) {
if (!Q && imm4.Bit<3>()) {
return UnallocatedEncoding();
return ReservedValue();
}
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,
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());

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) {
if (!sz) {
return UnallocatedEncoding();
return ReservedValue();
}
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,
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();

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) {
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();

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,
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;