A64: Implement FMOV (vector, immediate) and mark other SIMD modified immediate instructions as unallocated

This commit is contained in:
MerryMage 2018-04-04 10:28:52 +01:00
parent 5c95e28ed0
commit 7969871aa3
4 changed files with 39 additions and 3 deletions

View file

@ -40,6 +40,7 @@ std::vector<Matcher<Visitor>> GetDecodeTable() {
const std::set<std::string> 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) {

View file

@ -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")

View file

@ -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);

View file

@ -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<u64>(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