Merge pull request #467 from lioncash/reserved
A64: Handle reserved instruction cases more specifically where applicable
This commit is contained in:
commit
9a4e3b24e4
7 changed files with 60 additions and 30 deletions
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue