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(SQRSHRUN_2, "SQRSHRUN, SQRSHRUN2", "0Q1011110IIIIiii100011nnnnnddddd")
|
||||||
//INST(UQSHRN_2, "UQSHRN, UQSHRN2", "0Q1011110IIIIiii100101nnnnnddddd")
|
//INST(UQSHRN_2, "UQSHRN, UQSHRN2", "0Q1011110IIIIiii100101nnnnnddddd")
|
||||||
//INST(UQRSHRN_2, "UQRSHRN, UQRSHRN2", "0Q1011110IIIIiii100111nnnnnddddd")
|
//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(UCVTF_fix_2, "UCVTF (vector, fixed-point)", "0Q1011110IIIIiii111001nnnnnddddd")
|
||||||
//INST(FCVTZU_fix_2, "FCVTZU (vector, fixed-point)", "0Q1011110IIIIiii111111nnnnnddddd")
|
//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) {
|
if (integer_to_float) {
|
||||||
IR::U32U64 intval = X(intsize, static_cast<Reg>(n));
|
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 {
|
} 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);
|
IR::U32U64 intval = ZeroExtend(fltval, intsize);
|
||||||
X(intsize, static_cast<Reg>(d), intval);
|
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.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);
|
ASSERT(part == 0 || part == 1);
|
||||||
if (part == 0) {
|
if (part == 0) {
|
||||||
ASSERT(bitsize == 8 || bitsize == 16 || bitsize == 32 || bitsize == 64);
|
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);
|
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);
|
ASSERT(part == 0 || part == 1);
|
||||||
if (part == 0) {
|
if (part == 0) {
|
||||||
ASSERT(bitsize == 8 || bitsize == 16 || bitsize == 32 || bitsize == 64);
|
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);
|
IR::UAny V_scalar(size_t bitsize, Vec vec);
|
||||||
void V_scalar(size_t bitsize, Vec vec, IR::UAny value);
|
void V_scalar(size_t bitsize, Vec vec, IR::UAny value);
|
||||||
|
|
||||||
IR::UAny Vpart(size_t bitsize, Vec vec, size_t part);
|
IR::U128 Vpart(size_t bitsize, Vec vec, size_t part);
|
||||||
void Vpart(size_t bitsize, Vec vec, size_t part, IR::UAny value);
|
|
||||||
|
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);
|
IR::UAnyU128 Mem(IR::U64 address, size_t size, AccType acctype);
|
||||||
void Mem(IR::U64 address, size_t size, AccType acctype, IR::UAnyU128 value);
|
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 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 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 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 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);
|
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;
|
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
|
} // namespace Dynarmic::A64
|
||||||
|
|
Loading…
Reference in a new issue