A64: Implement SIMD instructions USHLL, USHLL2

This commit is contained in:
MerryMage 2018-02-10 10:29:07 +00:00
parent 59ace60b03
commit 7ff280827b
5 changed files with 40 additions and 8 deletions

View file

@ -803,7 +803,7 @@ INST(SHL_2, "SHL", "0Q001
//INST(SQRSHRUN_2, "SQRSHRUN, SQRSHRUN2", "0Q1011110IIIIiii100011nnnnnddddd")
//INST(UQSHRN_2, "UQSHRN, UQSHRN2", "0Q1011110IIIIiii100101nnnnnddddd")
//INST(UQRSHRN_2, "UQRSHRN, UQRSHRN2", "0Q1011110IIIIiii100111nnnnnddddd")
//INST(USHLL, "USHLL, USHLL2", "0Q1011110IIIIiii101001nnnnnddddd")
INST(USHLL, "USHLL, USHLL2", "0Q1011110IIIIiii101001nnnnnddddd")
//INST(UCVTF_fix_2, "UCVTF (vector, fixed-point)", "0Q1011110IIIIiii111001nnnnnddddd")
//INST(FCVTZU_fix_2, "FCVTZU (vector, fixed-point)", "0Q1011110IIIIiii111111nnnnnddddd")

View file

@ -125,9 +125,9 @@ bool TranslatorVisitor::FMOV_float_gen(bool sf, Imm<2> type, Imm<1> rmode_0, Imm
if (integer_to_float) {
IR::U32U64 intval = X(intsize, static_cast<Reg>(n));
Vpart(fltsize, static_cast<Vec>(d), part, intval);
Vpart_scalar(fltsize, static_cast<Vec>(d), part, intval);
} else {
IR::UAny fltval = Vpart(fltsize, static_cast<Vec>(n), part);
IR::UAny fltval = Vpart_scalar(fltsize, static_cast<Vec>(n), part);
IR::U32U64 intval = ZeroExtend(fltval, intsize);
X(intsize, static_cast<Reg>(d), intval);
}

View file

@ -220,7 +220,16 @@ void TranslatorVisitor::V_scalar(size_t /*bitsize*/, Vec vec, IR::UAny value) {
ir.SetQ(vec, ir.ZeroExtendToQuad(value));
}
IR::UAny TranslatorVisitor::Vpart(size_t bitsize, Vec vec, size_t part) {
IR::U128 TranslatorVisitor::Vpart(size_t bitsize, Vec vec, size_t part) {
ASSERT(part == 0 || part == 1);
ASSERT(bitsize == 64);
if (part == 0) {
return V(64, vec);
}
return ir.ZeroExtendToQuad(ir.VectorGetElement(bitsize, V(128, vec), part));
}
IR::UAny TranslatorVisitor::Vpart_scalar(size_t bitsize, Vec vec, size_t part) {
ASSERT(part == 0 || part == 1);
if (part == 0) {
ASSERT(bitsize == 8 || bitsize == 16 || bitsize == 32 || bitsize == 64);
@ -230,7 +239,7 @@ IR::UAny TranslatorVisitor::Vpart(size_t bitsize, Vec vec, size_t part) {
return ir.VectorGetElement(bitsize, V(128, vec), part);
}
void TranslatorVisitor::Vpart(size_t bitsize, Vec vec, size_t part, IR::UAny value) {
void TranslatorVisitor::Vpart_scalar(size_t bitsize, Vec vec, size_t part, IR::UAny value) {
ASSERT(part == 0 || part == 1);
if (part == 0) {
ASSERT(bitsize == 8 || bitsize == 16 || bitsize == 32 || bitsize == 64);

View file

@ -55,8 +55,10 @@ struct TranslatorVisitor final {
IR::UAny V_scalar(size_t bitsize, Vec vec);
void V_scalar(size_t bitsize, Vec vec, IR::UAny value);
IR::UAny Vpart(size_t bitsize, Vec vec, size_t part);
void Vpart(size_t bitsize, Vec vec, size_t part, IR::UAny value);
IR::U128 Vpart(size_t bitsize, Vec vec, size_t part);
IR::UAny Vpart_scalar(size_t bitsize, Vec vec, size_t part);
void Vpart_scalar(size_t bitsize, Vec vec, size_t part, IR::UAny value);
IR::UAnyU128 Mem(IR::U64 address, size_t size, AccType acctype);
void Mem(IR::U64 address, size_t size, AccType acctype, IR::UAnyU128 value);
@ -877,7 +879,7 @@ struct TranslatorVisitor final {
bool SQRSHRUN_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Reg Rd);
bool UQSHRN_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Reg Rd);
bool UQRSHRN_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Reg Rd);
bool USHLL(bool Q, Imm<4> immh, Imm<3> immb, Reg Rn, Vec Vd);
bool USHLL(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd);
bool UCVTF_fix_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd);
bool FCVTZU_fix_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd);

View file

@ -28,4 +28,25 @@ bool TranslatorVisitor::SHL_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd)
return true;
}
bool TranslatorVisitor::USHLL(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
if (immh == 0b0000) {
return DecodeError();
}
if (immh.Bit<3>()) {
return ReservedValue();
}
const size_t esize = 8 << Common::HighestSetBit(immh.ZeroExtend());
const size_t datasize = 64;
const size_t part = Q ? 1 : 0;
const u8 shift_amount = concatenate(immh, immb).ZeroExtend<u8>() - static_cast<u8>(esize);
const IR::U128 operand = Vpart(datasize, Vn, part);
const IR::U128 expanded_operand = ir.VectorZeroExtend(esize, operand);
const IR::U128 result = ir.VectorLogicalShiftLeft(2 * esize, expanded_operand, shift_amount);
V(2 * datasize, Vd, result);
return true;
}
} // namespace Dynarmic::A64