translate: Return by bool in helpers where applicable
Gets rid of a bit of duplication regarding the early-out cases and makes all helpers functions consistent (previously some had a return type of bool, while others had a return type of void).
This commit is contained in:
parent
d65b056eba
commit
3447c82656
6 changed files with 132 additions and 268 deletions
|
@ -7,13 +7,13 @@
|
||||||
#include "frontend/A64/translate/impl/impl.h"
|
#include "frontend/A64/translate/impl/impl.h"
|
||||||
|
|
||||||
namespace Dynarmic::A64 {
|
namespace Dynarmic::A64 {
|
||||||
|
namespace {
|
||||||
enum class SM3TTVariant {
|
enum class SM3TTVariant {
|
||||||
A,
|
A,
|
||||||
B,
|
B,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void SM3TT1(TranslatorVisitor& v, Vec Vm, Imm<2> imm2, Vec Vn, Vec Vd, SM3TTVariant behavior) {
|
bool SM3TT1(TranslatorVisitor& v, Vec Vm, Imm<2> imm2, Vec Vn, Vec Vd, SM3TTVariant behavior) {
|
||||||
const IR::U128 d = v.ir.GetQ(Vd);
|
const IR::U128 d = v.ir.GetQ(Vd);
|
||||||
const IR::U128 m = v.ir.GetQ(Vm);
|
const IR::U128 m = v.ir.GetQ(Vm);
|
||||||
const IR::U128 n = v.ir.GetQ(Vn);
|
const IR::U128 n = v.ir.GetQ(Vn);
|
||||||
|
@ -45,9 +45,10 @@ static void SM3TT1(TranslatorVisitor& v, Vec Vm, Imm<2> imm2, Vec Vn, Vec Vd, SM
|
||||||
const IR::U128 result = v.ir.VectorSetElement(32, tmp3, 3, final_tt1);
|
const IR::U128 result = v.ir.VectorSetElement(32, tmp3, 3, final_tt1);
|
||||||
|
|
||||||
v.ir.SetQ(Vd, result);
|
v.ir.SetQ(Vd, result);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SM3TT2(TranslatorVisitor& v, Vec Vm, Imm<2> imm2, Vec Vn, Vec Vd, SM3TTVariant behavior) {
|
bool SM3TT2(TranslatorVisitor& v, Vec Vm, Imm<2> imm2, Vec Vn, Vec Vd, SM3TTVariant behavior) {
|
||||||
const IR::U128 d = v.ir.GetQ(Vd);
|
const IR::U128 d = v.ir.GetQ(Vd);
|
||||||
const IR::U128 m = v.ir.GetQ(Vm);
|
const IR::U128 m = v.ir.GetQ(Vm);
|
||||||
const IR::U128 n = v.ir.GetQ(Vn);
|
const IR::U128 n = v.ir.GetQ(Vn);
|
||||||
|
@ -79,26 +80,24 @@ static void SM3TT2(TranslatorVisitor& v, Vec Vm, Imm<2> imm2, Vec Vn, Vec Vd, SM
|
||||||
const IR::U128 result = v.ir.VectorSetElement(32, tmp3, 3, top_result);
|
const IR::U128 result = v.ir.VectorSetElement(32, tmp3, 3, top_result);
|
||||||
|
|
||||||
v.ir.SetQ(Vd, result);
|
v.ir.SetQ(Vd, result);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
} // Anonymous namespace
|
||||||
|
|
||||||
bool TranslatorVisitor::SM3TT1A(Vec Vm, Imm<2> imm2, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::SM3TT1A(Vec Vm, Imm<2> imm2, Vec Vn, Vec Vd) {
|
||||||
SM3TT1(*this, Vm, imm2, Vn, Vd, SM3TTVariant::A);
|
return SM3TT1(*this, Vm, imm2, Vn, Vd, SM3TTVariant::A);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::SM3TT1B(Vec Vm, Imm<2> imm2, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::SM3TT1B(Vec Vm, Imm<2> imm2, Vec Vn, Vec Vd) {
|
||||||
SM3TT1(*this, Vm, imm2, Vn, Vd, SM3TTVariant::B);
|
return SM3TT1(*this, Vm, imm2, Vn, Vd, SM3TTVariant::B);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::SM3TT2A(Vec Vm, Imm<2> imm2, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::SM3TT2A(Vec Vm, Imm<2> imm2, Vec Vn, Vec Vd) {
|
||||||
SM3TT2(*this, Vm, imm2, Vn, Vd, SM3TTVariant::A);
|
return SM3TT2(*this, Vm, imm2, Vn, Vd, SM3TTVariant::A);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::SM3TT2B(Vec Vm, Imm<2> imm2, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::SM3TT2B(Vec Vm, Imm<2> imm2, Vec Vn, Vec Vd) {
|
||||||
SM3TT2(*this, Vm, imm2, Vn, Vd, SM3TTVariant::B);
|
return SM3TT2(*this, Vm, imm2, Vn, Vd, SM3TTVariant::B);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Dynarmic::A64
|
} // namespace Dynarmic::A64
|
||||||
|
|
|
@ -14,8 +14,12 @@ enum class Transposition {
|
||||||
TRN2,
|
TRN2,
|
||||||
};
|
};
|
||||||
|
|
||||||
void VectorTranspose(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd,
|
bool VectorTranspose(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd,
|
||||||
Transposition type) {
|
Transposition type) {
|
||||||
|
if (!Q && size == 0b11) {
|
||||||
|
return v.ReservedValue();
|
||||||
|
}
|
||||||
|
|
||||||
const size_t datasize = Q ? 128 : 64;
|
const size_t datasize = Q ? 128 : 64;
|
||||||
const u8 esize = static_cast<u8>(8 << size.ZeroExtend());
|
const u8 esize = static_cast<u8>(8 << size.ZeroExtend());
|
||||||
|
|
||||||
|
@ -61,6 +65,7 @@ void VectorTranspose(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn,
|
||||||
}();
|
}();
|
||||||
|
|
||||||
v.V(datasize, Vd, result);
|
v.V(datasize, Vd, result);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class UnzipType {
|
enum class UnzipType {
|
||||||
|
@ -68,7 +73,11 @@ enum class UnzipType {
|
||||||
Odd,
|
Odd,
|
||||||
};
|
};
|
||||||
|
|
||||||
void VectorUnzip(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, UnzipType type) {
|
bool VectorUnzip(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd, UnzipType type) {
|
||||||
|
if (size == 0b11 && !Q) {
|
||||||
|
return v.ReservedValue();
|
||||||
|
}
|
||||||
|
|
||||||
const size_t datasize = Q ? 128 : 64;
|
const size_t datasize = Q ? 128 : 64;
|
||||||
const size_t esize = 8 << size.ZeroExtend();
|
const size_t esize = 8 << size.ZeroExtend();
|
||||||
|
|
||||||
|
@ -86,43 +95,24 @@ void VectorUnzip(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec
|
||||||
}
|
}
|
||||||
|
|
||||||
v.V(datasize, Vd, result);
|
v.V(datasize, Vd, result);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
bool TranslatorVisitor::TRN1(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::TRN1(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||||
if (!Q && size == 0b11) {
|
return VectorTranspose(*this, Q, size, Vm, Vn, Vd, Transposition::TRN1);
|
||||||
return ReservedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
VectorTranspose(*this, Q, size, Vm, Vn, Vd, Transposition::TRN1);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::TRN2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::TRN2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||||
if (!Q && size == 0b11) {
|
return VectorTranspose(*this, Q, size, Vm, Vn, Vd, Transposition::TRN2);
|
||||||
return ReservedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
VectorTranspose(*this, Q, size, Vm, Vn, Vd, Transposition::TRN2);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::UZP1(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::UZP1(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||||
if (size == 0b11 && !Q) {
|
return VectorUnzip(*this, Q, size, Vm, Vn, Vd, UnzipType::Even);
|
||||||
return ReservedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
VectorUnzip(*this, Q, size, Vm, Vn, Vd, UnzipType::Even);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::UZP2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::UZP2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||||
if (size == 0b11 && !Q) {
|
return VectorUnzip(*this, Q, size, Vm, Vn, Vd, UnzipType::Odd);
|
||||||
return ReservedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
VectorUnzip(*this, Q, size, Vm, Vn, Vd, UnzipType::Odd);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::ZIP1(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::ZIP1(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||||
|
|
|
@ -18,8 +18,12 @@ enum class Signedness {
|
||||||
Unsigned,
|
Unsigned,
|
||||||
};
|
};
|
||||||
|
|
||||||
void ShiftRight(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd,
|
bool ShiftRight(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd,
|
||||||
ShiftExtraBehavior behavior, Signedness signedness) {
|
ShiftExtraBehavior behavior, Signedness signedness) {
|
||||||
|
if (!immh.Bit<3>()) {
|
||||||
|
return v.ReservedValue();
|
||||||
|
}
|
||||||
|
|
||||||
const size_t esize = 64;
|
const size_t esize = 64;
|
||||||
const u8 shift_amount = static_cast<u8>((esize * 2) - concatenate(immh, immb).ZeroExtend());
|
const u8 shift_amount = static_cast<u8>((esize * 2) - concatenate(immh, immb).ZeroExtend());
|
||||||
|
|
||||||
|
@ -37,10 +41,15 @@ void ShiftRight(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd,
|
||||||
}
|
}
|
||||||
|
|
||||||
v.V_scalar(esize, Vd, result);
|
v.V_scalar(esize, Vd, result);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RoundingShiftRight(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd,
|
bool RoundingShiftRight(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd,
|
||||||
ShiftExtraBehavior behavior, Signedness signedness) {
|
ShiftExtraBehavior behavior, Signedness signedness) {
|
||||||
|
if (!immh.Bit<3>()) {
|
||||||
|
return v.ReservedValue();
|
||||||
|
}
|
||||||
|
|
||||||
const size_t esize = 64;
|
const size_t esize = 64;
|
||||||
const u8 shift_amount = static_cast<u8>((esize * 2) - concatenate(immh, immb).ZeroExtend());
|
const u8 shift_amount = static_cast<u8>((esize * 2) - concatenate(immh, immb).ZeroExtend());
|
||||||
|
|
||||||
|
@ -64,6 +73,7 @@ void RoundingShiftRight(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn,
|
||||||
}();
|
}();
|
||||||
|
|
||||||
v.V_scalar(esize, Vd, result);
|
v.V_scalar(esize, Vd, result);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class ShiftDirection {
|
enum class ShiftDirection {
|
||||||
|
@ -71,8 +81,12 @@ enum class ShiftDirection {
|
||||||
Right,
|
Right,
|
||||||
};
|
};
|
||||||
|
|
||||||
void ShiftAndInsert(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd,
|
bool ShiftAndInsert(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd,
|
||||||
ShiftDirection direction) {
|
ShiftDirection direction) {
|
||||||
|
if (!immh.Bit<3>()) {
|
||||||
|
return v.ReservedValue();
|
||||||
|
}
|
||||||
|
|
||||||
const size_t esize = 64;
|
const size_t esize = 64;
|
||||||
|
|
||||||
const u8 shift_amount = [&] {
|
const u8 shift_amount = [&] {
|
||||||
|
@ -104,6 +118,7 @@ void ShiftAndInsert(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec
|
||||||
|
|
||||||
const IR::U64 result = v.ir.Or(v.ir.And(operand2, v.ir.Not(v.ir.Imm64(mask))), shifted);
|
const IR::U64 result = v.ir.Or(v.ir.And(operand2, v.ir.Not(v.ir.Imm64(mask))), shifted);
|
||||||
v.V_scalar(esize, Vd, result);
|
v.V_scalar(esize, Vd, result);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScalarFPConvertWithRound(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, Signedness sign) {
|
bool ScalarFPConvertWithRound(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, Signedness sign) {
|
||||||
|
@ -153,57 +168,27 @@ bool TranslatorVisitor::FCVTZU_fix_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::SLI_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::SLI_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
if (!immh.Bit<3>()) {
|
return ShiftAndInsert(*this, immh, immb, Vn, Vd, ShiftDirection::Left);
|
||||||
return ReservedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
ShiftAndInsert(*this, immh, immb, Vn, Vd, ShiftDirection::Left);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::SRI_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::SRI_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
if (!immh.Bit<3>()) {
|
return ShiftAndInsert(*this, immh, immb, Vn, Vd, ShiftDirection::Right);
|
||||||
return ReservedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
ShiftAndInsert(*this, immh, immb, Vn, Vd, ShiftDirection::Right);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::SRSHR_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::SRSHR_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
if (!immh.Bit<3>()) {
|
return RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Signed);
|
||||||
return ReservedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Signed);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::SRSRA_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::SRSRA_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
if (!immh.Bit<3>()) {
|
return RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Signed);
|
||||||
return ReservedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Signed);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::SSHR_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::SSHR_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
if (!immh.Bit<3>()) {
|
return ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Signed);
|
||||||
return ReservedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Signed);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::SSRA_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::SSRA_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
if (!immh.Bit<3>()) {
|
return ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Signed);
|
||||||
return ReservedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Signed);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::SHL_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::SHL_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
|
@ -222,39 +207,19 @@ bool TranslatorVisitor::SHL_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::URSHR_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::URSHR_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
if (!immh.Bit<3>()) {
|
return RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Unsigned);
|
||||||
return ReservedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Unsigned);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::URSRA_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::URSRA_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
if (!immh.Bit<3>()) {
|
return RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Unsigned);
|
||||||
return ReservedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Unsigned);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::USHR_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::USHR_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
if (!immh.Bit<3>()) {
|
return ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Unsigned);
|
||||||
return ReservedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Unsigned);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::USRA_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::USRA_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
if (!immh.Bit<3>()) {
|
return ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Unsigned);
|
||||||
return ReservedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Unsigned);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Dynarmic::A64
|
} // namespace Dynarmic::A64
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include "frontend/A64/translate/impl/impl.h"
|
#include "frontend/A64/translate/impl/impl.h"
|
||||||
|
|
||||||
namespace Dynarmic::A64 {
|
namespace Dynarmic::A64 {
|
||||||
|
namespace {
|
||||||
enum class ShiftExtraBehavior {
|
enum class ShiftExtraBehavior {
|
||||||
None,
|
None,
|
||||||
Accumulate,
|
Accumulate,
|
||||||
|
@ -20,8 +20,16 @@ enum class Signedness {
|
||||||
Unsigned
|
Unsigned
|
||||||
};
|
};
|
||||||
|
|
||||||
static void ShiftRight(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd,
|
bool ShiftRight(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd,
|
||||||
ShiftExtraBehavior behavior, Signedness signedness) {
|
ShiftExtraBehavior behavior, Signedness signedness) {
|
||||||
|
if (immh == 0b0000) {
|
||||||
|
return v.DecodeError();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (immh.Bit<3>() && !Q) {
|
||||||
|
return v.ReservedValue();
|
||||||
|
}
|
||||||
|
|
||||||
const size_t esize = 8 << Common::HighestSetBit(immh.ZeroExtend());
|
const size_t esize = 8 << Common::HighestSetBit(immh.ZeroExtend());
|
||||||
const size_t datasize = Q ? 128 : 64;
|
const size_t datasize = Q ? 128 : 64;
|
||||||
|
|
||||||
|
@ -41,10 +49,19 @@ static void ShiftRight(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, V
|
||||||
}
|
}
|
||||||
|
|
||||||
v.V(datasize, Vd, result);
|
v.V(datasize, Vd, result);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RoundingShiftRight(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd,
|
bool RoundingShiftRight(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd,
|
||||||
ShiftExtraBehavior behavior, Signedness signedness) {
|
ShiftExtraBehavior behavior, Signedness signedness) {
|
||||||
|
if (immh == 0b0000) {
|
||||||
|
return v.DecodeError();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Q && immh.Bit<3>()) {
|
||||||
|
return v.ReservedValue();
|
||||||
|
}
|
||||||
|
|
||||||
const size_t datasize = Q ? 128 : 64;
|
const size_t datasize = Q ? 128 : 64;
|
||||||
const size_t esize = 8 << Common::HighestSetBit(immh.ZeroExtend());
|
const size_t esize = 8 << Common::HighestSetBit(immh.ZeroExtend());
|
||||||
const u8 shift_amount = static_cast<u8>((esize * 2) - concatenate(immh, immb).ZeroExtend());
|
const u8 shift_amount = static_cast<u8>((esize * 2) - concatenate(immh, immb).ZeroExtend());
|
||||||
|
@ -68,10 +85,19 @@ static void RoundingShiftRight(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3>
|
||||||
}
|
}
|
||||||
|
|
||||||
v.V(datasize, Vd, corrected_result);
|
v.V(datasize, Vd, corrected_result);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ShiftRightNarrowing(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd,
|
bool ShiftRightNarrowing(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd,
|
||||||
ShiftExtraBehavior behavior) {
|
ShiftExtraBehavior behavior) {
|
||||||
|
if (immh == 0b0000) {
|
||||||
|
return v.DecodeError();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (immh.Bit<3>()) {
|
||||||
|
return v.ReservedValue();
|
||||||
|
}
|
||||||
|
|
||||||
const size_t esize = 8 << Common::HighestSetBit(immh.ZeroExtend());
|
const size_t esize = 8 << Common::HighestSetBit(immh.ZeroExtend());
|
||||||
const size_t source_esize = 2 * esize;
|
const size_t source_esize = 2 * esize;
|
||||||
const size_t part = Q ? 1 : 0;
|
const size_t part = Q ? 1 : 0;
|
||||||
|
@ -90,10 +116,19 @@ static void ShiftRightNarrowing(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3
|
||||||
v.ir.VectorLogicalShiftRight(source_esize, operand, shift_amount));
|
v.ir.VectorLogicalShiftRight(source_esize, operand, shift_amount));
|
||||||
|
|
||||||
v.Vpart(64, Vd, part, result);
|
v.Vpart(64, Vd, part, result);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ShiftLeftLong(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd,
|
bool ShiftLeftLong(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd,
|
||||||
Signedness signedness) {
|
Signedness signedness) {
|
||||||
|
if (immh == 0b0000) {
|
||||||
|
return v.DecodeError();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (immh.Bit<3>()) {
|
||||||
|
return v.ReservedValue();
|
||||||
|
}
|
||||||
|
|
||||||
const size_t esize = 8 << Common::HighestSetBit(immh.ZeroExtend());
|
const size_t esize = 8 << Common::HighestSetBit(immh.ZeroExtend());
|
||||||
const size_t datasize = 64;
|
const size_t datasize = 64;
|
||||||
const size_t part = Q ? 1 : 0;
|
const size_t part = Q ? 1 : 0;
|
||||||
|
@ -110,56 +145,24 @@ static void ShiftLeftLong(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb
|
||||||
const IR::U128 result = v.ir.VectorLogicalShiftLeft(2 * esize, expanded_operand, shift_amount);
|
const IR::U128 result = v.ir.VectorLogicalShiftLeft(2 * esize, expanded_operand, shift_amount);
|
||||||
|
|
||||||
v.V(2 * datasize, Vd, result);
|
v.V(2 * datasize, Vd, result);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
} // Anonymous namespace
|
||||||
|
|
||||||
bool TranslatorVisitor::SSHR_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::SSHR_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
if (immh == 0b0000) {
|
return ShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Signed);
|
||||||
return DecodeError();
|
|
||||||
}
|
|
||||||
if (immh.Bit<3>() && !Q) {
|
|
||||||
return ReservedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
ShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Signed);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::SRSHR_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::SRSHR_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
if (immh == 0b0000) {
|
return RoundingShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Signed);
|
||||||
return DecodeError();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Q && immh.Bit<3>()) {
|
|
||||||
return ReservedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
RoundingShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Signed);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::SRSRA_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::SRSRA_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
if (immh == 0b0000) {
|
return RoundingShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Signed);
|
||||||
return DecodeError();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Q && immh.Bit<3>()) {
|
|
||||||
return ReservedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
RoundingShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Signed);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::SSRA_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::SSRA_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
if (immh == 0b0000) {
|
return ShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Signed);
|
||||||
return DecodeError();
|
|
||||||
}
|
|
||||||
if (immh.Bit<3>() && !Q) {
|
|
||||||
return ReservedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
ShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Signed);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::SHL_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::SHL_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
|
@ -182,103 +185,35 @@ bool TranslatorVisitor::SHL_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::SHRN(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::SHRN(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
if (immh == 0b0000) {
|
return ShiftRightNarrowing(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::None);
|
||||||
return DecodeError();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (immh.Bit<3>()) {
|
|
||||||
return ReservedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
ShiftRightNarrowing(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::None);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::RSHRN(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::RSHRN(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
if (immh == 0b0000) {
|
return ShiftRightNarrowing(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::Round);
|
||||||
return DecodeError();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (immh.Bit<3>()) {
|
|
||||||
return ReservedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
ShiftRightNarrowing(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::Round);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::SSHLL(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::SSHLL(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
if (immh == 0b0000) {
|
return ShiftLeftLong(*this, Q, immh, immb, Vn, Vd, Signedness::Signed);
|
||||||
return DecodeError();
|
|
||||||
}
|
|
||||||
if (immh.Bit<3>()) {
|
|
||||||
return ReservedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
ShiftLeftLong(*this, Q, immh, immb, Vn, Vd, Signedness::Signed);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::URSHR_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::URSHR_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
if (immh == 0b0000) {
|
return RoundingShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Unsigned);
|
||||||
return DecodeError();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Q && immh.Bit<3>()) {
|
|
||||||
return ReservedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
RoundingShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Unsigned);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::URSRA_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::URSRA_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
if (immh == 0b0000) {
|
return RoundingShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Unsigned);
|
||||||
return DecodeError();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Q && immh.Bit<3>()) {
|
|
||||||
return ReservedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
RoundingShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Unsigned);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::USHR_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::USHR_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
if (immh == 0b0000) {
|
return ShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Unsigned);
|
||||||
return DecodeError();
|
|
||||||
}
|
|
||||||
if (immh.Bit<3>() && !Q) {
|
|
||||||
return ReservedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
ShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Unsigned);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::USRA_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::USRA_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
if (immh == 0b0000) {
|
return ShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Unsigned);
|
||||||
return DecodeError();
|
|
||||||
}
|
|
||||||
if (immh.Bit<3>() && !Q) {
|
|
||||||
return ReservedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
ShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Unsigned);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::USHLL(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::USHLL(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
if (immh == 0b0000) {
|
return ShiftLeftLong(*this, Q, immh, immb, Vn, Vd, Signedness::Unsigned);
|
||||||
return DecodeError();
|
|
||||||
}
|
|
||||||
if (immh.Bit<3>()) {
|
|
||||||
return ReservedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
ShiftLeftLong(*this, Q, immh, immb, Vn, Vd, Signedness::Unsigned);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::SRI_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::SRI_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
|
|
|
@ -18,8 +18,12 @@ enum class ExtraBehavior {
|
||||||
Round
|
Round
|
||||||
};
|
};
|
||||||
|
|
||||||
static void HighNarrowingOperation(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd,
|
bool HighNarrowingOperation(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd,
|
||||||
HighNarrowingOp op, ExtraBehavior behavior) {
|
HighNarrowingOp op, ExtraBehavior behavior) {
|
||||||
|
if (size == 0b11) {
|
||||||
|
return v.ReservedValue();
|
||||||
|
}
|
||||||
|
|
||||||
const size_t part = Q;
|
const size_t part = Q;
|
||||||
const size_t esize = 8 << size.ZeroExtend();
|
const size_t esize = 8 << size.ZeroExtend();
|
||||||
const size_t doubled_esize = 2 * esize;
|
const size_t doubled_esize = 2 * esize;
|
||||||
|
@ -43,6 +47,7 @@ static void HighNarrowingOperation(TranslatorVisitor& v, bool Q, Imm<2> size, Ve
|
||||||
v.ir.VectorLogicalShiftRight(doubled_esize, wide, static_cast<u8>(esize)));
|
v.ir.VectorLogicalShiftRight(doubled_esize, wide, static_cast<u8>(esize)));
|
||||||
|
|
||||||
v.Vpart(64, Vd, part, result);
|
v.Vpart(64, Vd, part, result);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class AbsDiffExtraBehavior {
|
enum class AbsDiffExtraBehavior {
|
||||||
|
@ -252,39 +257,19 @@ bool TranslatorVisitor::MUL_vec(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::ADDHN(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::ADDHN(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||||
if (size == 0b11) {
|
return HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, HighNarrowingOp::Add, ExtraBehavior::None);
|
||||||
return ReservedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, HighNarrowingOp::Add, ExtraBehavior::None);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::RADDHN(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::RADDHN(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||||
if (size == 0b11) {
|
return HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, HighNarrowingOp::Add, ExtraBehavior::Round);
|
||||||
return ReservedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, HighNarrowingOp::Add, ExtraBehavior::Round);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::SUBHN(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::SUBHN(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||||
if (size == 0b11) {
|
return HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, HighNarrowingOp::Subtract, ExtraBehavior::None);
|
||||||
return ReservedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, HighNarrowingOp::Subtract, ExtraBehavior::None);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::RSUBHN(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::RSUBHN(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||||
if (size == 0b11) {
|
return HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, HighNarrowingOp::Subtract, ExtraBehavior::Round);
|
||||||
return ReservedValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, HighNarrowingOp::Subtract, ExtraBehavior::Round);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::SHADD(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::SHADD(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||||
|
|
|
@ -23,8 +23,12 @@ enum class ExtraBehavior {
|
||||||
Subtract,
|
Subtract,
|
||||||
};
|
};
|
||||||
|
|
||||||
void 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) {
|
||||||
|
return v.UnallocatedEncoding();
|
||||||
|
}
|
||||||
|
|
||||||
const auto [index, Vm] = Combine(size, H, L, M, Vmlo);
|
const auto [index, Vm] = Combine(size, H, L, M, Vmlo);
|
||||||
const size_t idxdsize = H == 1 ? 128 : 64;
|
const size_t idxdsize = H == 1 ? 128 : 64;
|
||||||
const size_t esize = 8 << size.ZeroExtend();
|
const size_t esize = 8 << size.ZeroExtend();
|
||||||
|
@ -42,34 +46,20 @@ void MultiplyByElement(TranslatorVisitor& v, bool Q, Imm<2> size, Imm<1> L, Imm<
|
||||||
}
|
}
|
||||||
|
|
||||||
v.V(datasize, Vd, result);
|
v.V(datasize, Vd, result);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
bool TranslatorVisitor::MLA_elt(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::MLA_elt(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) {
|
||||||
if (size != 0b01 && size != 0b10) {
|
return MultiplyByElement(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::Accumulate);
|
||||||
return UnallocatedEncoding();
|
|
||||||
}
|
|
||||||
|
|
||||||
MultiplyByElement(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::Accumulate);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::MLS_elt(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::MLS_elt(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) {
|
||||||
if (size != 0b01 && size != 0b10) {
|
return MultiplyByElement(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::Subtract);
|
||||||
return UnallocatedEncoding();
|
|
||||||
}
|
|
||||||
|
|
||||||
MultiplyByElement(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::Subtract);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::MUL_elt(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::MUL_elt(bool Q, Imm<2> size, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) {
|
||||||
if (size != 0b01 && size != 0b10) {
|
return MultiplyByElement(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::None);
|
||||||
return UnallocatedEncoding();
|
|
||||||
}
|
|
||||||
|
|
||||||
MultiplyByElement(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::None);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::FMUL_elt_4(bool Q, bool sz, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::FMUL_elt_4(bool Q, bool sz, Imm<1> L, Imm<1> M, Imm<4> Vmlo, Imm<1> H, Vec Vn, Vec Vd) {
|
||||||
|
|
Loading…
Reference in a new issue