A64: Implement SIMD instructions USHLL, USHLL2
This commit is contained in:
parent
59ace60b03
commit
7ff280827b
5 changed files with 40 additions and 8 deletions
|
@ -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")
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue