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"
|
||||
|
||||
namespace Dynarmic::A64 {
|
||||
|
||||
namespace {
|
||||
enum class SM3TTVariant {
|
||||
A,
|
||||
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 m = v.ir.GetQ(Vm);
|
||||
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);
|
||||
|
||||
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 m = v.ir.GetQ(Vm);
|
||||
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);
|
||||
|
||||
v.ir.SetQ(Vd, result);
|
||||
return true;
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
bool TranslatorVisitor::SM3TT1A(Vec Vm, Imm<2> imm2, Vec Vn, Vec Vd) {
|
||||
SM3TT1(*this, Vm, imm2, Vn, Vd, SM3TTVariant::A);
|
||||
return true;
|
||||
return SM3TT1(*this, Vm, imm2, Vn, Vd, SM3TTVariant::A);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SM3TT1B(Vec Vm, Imm<2> imm2, Vec Vn, Vec Vd) {
|
||||
SM3TT1(*this, Vm, imm2, Vn, Vd, SM3TTVariant::B);
|
||||
return true;
|
||||
return SM3TT1(*this, Vm, imm2, Vn, Vd, SM3TTVariant::B);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SM3TT2A(Vec Vm, Imm<2> imm2, Vec Vn, Vec Vd) {
|
||||
SM3TT2(*this, Vm, imm2, Vn, Vd, SM3TTVariant::A);
|
||||
return true;
|
||||
return SM3TT2(*this, Vm, imm2, Vn, Vd, SM3TTVariant::A);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SM3TT2B(Vec Vm, Imm<2> imm2, Vec Vn, Vec Vd) {
|
||||
SM3TT2(*this, Vm, imm2, Vn, Vd, SM3TTVariant::B);
|
||||
return true;
|
||||
return SM3TT2(*this, Vm, imm2, Vn, Vd, SM3TTVariant::B);
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::A64
|
||||
|
|
|
@ -14,8 +14,12 @@ enum class Transposition {
|
|||
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) {
|
||||
if (!Q && size == 0b11) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
||||
const size_t datasize = Q ? 128 : 64;
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
||||
enum class UnzipType {
|
||||
|
@ -68,7 +73,11 @@ enum class UnzipType {
|
|||
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 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);
|
||||
return true;
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
bool TranslatorVisitor::TRN1(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
if (!Q && size == 0b11) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
VectorTranspose(*this, Q, size, Vm, Vn, Vd, Transposition::TRN1);
|
||||
return true;
|
||||
return VectorTranspose(*this, Q, size, Vm, Vn, Vd, Transposition::TRN1);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::TRN2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
if (!Q && size == 0b11) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
VectorTranspose(*this, Q, size, Vm, Vn, Vd, Transposition::TRN2);
|
||||
return true;
|
||||
return VectorTranspose(*this, Q, size, Vm, Vn, Vd, Transposition::TRN2);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::UZP1(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
if (size == 0b11 && !Q) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
VectorUnzip(*this, Q, size, Vm, Vn, Vd, UnzipType::Even);
|
||||
return true;
|
||||
return VectorUnzip(*this, Q, size, Vm, Vn, Vd, UnzipType::Even);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::UZP2(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
if (size == 0b11 && !Q) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
VectorUnzip(*this, Q, size, Vm, Vn, Vd, UnzipType::Odd);
|
||||
return true;
|
||||
return VectorUnzip(*this, Q, size, Vm, Vn, Vd, UnzipType::Odd);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::ZIP1(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
|
|
|
@ -18,8 +18,12 @@ enum class Signedness {
|
|||
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) {
|
||||
if (!immh.Bit<3>()) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
||||
const size_t esize = 64;
|
||||
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);
|
||||
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) {
|
||||
if (!immh.Bit<3>()) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
||||
const size_t esize = 64;
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
||||
enum class ShiftDirection {
|
||||
|
@ -71,8 +81,12 @@ enum class ShiftDirection {
|
|||
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) {
|
||||
if (!immh.Bit<3>()) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
||||
const size_t esize = 64;
|
||||
|
||||
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);
|
||||
v.V_scalar(esize, Vd, result);
|
||||
return true;
|
||||
}
|
||||
|
||||
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) {
|
||||
if (!immh.Bit<3>()) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
ShiftAndInsert(*this, immh, immb, Vn, Vd, ShiftDirection::Left);
|
||||
return true;
|
||||
return ShiftAndInsert(*this, immh, immb, Vn, Vd, ShiftDirection::Left);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SRI_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
if (!immh.Bit<3>()) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
ShiftAndInsert(*this, immh, immb, Vn, Vd, ShiftDirection::Right);
|
||||
return true;
|
||||
return ShiftAndInsert(*this, immh, immb, Vn, Vd, ShiftDirection::Right);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SRSHR_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
if (!immh.Bit<3>()) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Signed);
|
||||
return true;
|
||||
return RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SRSRA_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
if (!immh.Bit<3>()) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Signed);
|
||||
return true;
|
||||
return RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SSHR_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
if (!immh.Bit<3>()) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Signed);
|
||||
return true;
|
||||
return ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SSRA_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
if (!immh.Bit<3>()) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Signed);
|
||||
return true;
|
||||
return ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Signed);
|
||||
}
|
||||
|
||||
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) {
|
||||
if (!immh.Bit<3>()) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Unsigned);
|
||||
return true;
|
||||
return RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::URSRA_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
if (!immh.Bit<3>()) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Unsigned);
|
||||
return true;
|
||||
return RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::USHR_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
if (!immh.Bit<3>()) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Unsigned);
|
||||
return true;
|
||||
return ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::USRA_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
if (!immh.Bit<3>()) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Unsigned);
|
||||
return true;
|
||||
return ShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Unsigned);
|
||||
}
|
||||
|
||||
} // namespace Dynarmic::A64
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include "frontend/A64/translate/impl/impl.h"
|
||||
|
||||
namespace Dynarmic::A64 {
|
||||
|
||||
namespace {
|
||||
enum class ShiftExtraBehavior {
|
||||
None,
|
||||
Accumulate,
|
||||
|
@ -20,8 +20,16 @@ enum class Signedness {
|
|||
Unsigned
|
||||
};
|
||||
|
||||
static void ShiftRight(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd,
|
||||
ShiftExtraBehavior behavior, Signedness signedness) {
|
||||
bool ShiftRight(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd,
|
||||
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 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);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void RoundingShiftRight(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd,
|
||||
ShiftExtraBehavior behavior, Signedness signedness) {
|
||||
bool RoundingShiftRight(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd,
|
||||
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 esize = 8 << Common::HighestSetBit(immh.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);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ShiftRightNarrowing(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd,
|
||||
ShiftExtraBehavior behavior) {
|
||||
bool ShiftRightNarrowing(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd,
|
||||
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 source_esize = 2 * esize;
|
||||
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.Vpart(64, Vd, part, result);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ShiftLeftLong(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd,
|
||||
Signedness signedness) {
|
||||
bool ShiftLeftLong(TranslatorVisitor& v, bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd,
|
||||
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 datasize = 64;
|
||||
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);
|
||||
|
||||
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) {
|
||||
if (immh == 0b0000) {
|
||||
return DecodeError();
|
||||
}
|
||||
if (immh.Bit<3>() && !Q) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
ShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Signed);
|
||||
return true;
|
||||
return ShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SRSHR_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
if (immh == 0b0000) {
|
||||
return DecodeError();
|
||||
}
|
||||
|
||||
if (!Q && immh.Bit<3>()) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
RoundingShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Signed);
|
||||
return true;
|
||||
return RoundingShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SRSRA_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
if (immh == 0b0000) {
|
||||
return DecodeError();
|
||||
}
|
||||
|
||||
if (!Q && immh.Bit<3>()) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
RoundingShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Signed);
|
||||
return true;
|
||||
return RoundingShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SSRA_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
if (immh == 0b0000) {
|
||||
return DecodeError();
|
||||
}
|
||||
if (immh.Bit<3>() && !Q) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
ShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Signed);
|
||||
return true;
|
||||
return ShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Signed);
|
||||
}
|
||||
|
||||
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) {
|
||||
if (immh == 0b0000) {
|
||||
return DecodeError();
|
||||
}
|
||||
|
||||
if (immh.Bit<3>()) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
ShiftRightNarrowing(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::None);
|
||||
return true;
|
||||
return ShiftRightNarrowing(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::None);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::RSHRN(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
if (immh == 0b0000) {
|
||||
return DecodeError();
|
||||
}
|
||||
|
||||
if (immh.Bit<3>()) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
ShiftRightNarrowing(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::Round);
|
||||
return true;
|
||||
return ShiftRightNarrowing(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::Round);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SSHLL(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
if (immh == 0b0000) {
|
||||
return DecodeError();
|
||||
}
|
||||
if (immh.Bit<3>()) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
ShiftLeftLong(*this, Q, immh, immb, Vn, Vd, Signedness::Signed);
|
||||
return true;
|
||||
return ShiftLeftLong(*this, Q, immh, immb, Vn, Vd, Signedness::Signed);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::URSHR_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
if (immh == 0b0000) {
|
||||
return DecodeError();
|
||||
}
|
||||
|
||||
if (!Q && immh.Bit<3>()) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
RoundingShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Unsigned);
|
||||
return true;
|
||||
return RoundingShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::URSRA_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
if (immh == 0b0000) {
|
||||
return DecodeError();
|
||||
}
|
||||
|
||||
if (!Q && immh.Bit<3>()) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
RoundingShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Unsigned);
|
||||
return true;
|
||||
return RoundingShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::USHR_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
if (immh == 0b0000) {
|
||||
return DecodeError();
|
||||
}
|
||||
if (immh.Bit<3>() && !Q) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
ShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Unsigned);
|
||||
return true;
|
||||
return ShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::USRA_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
if (immh == 0b0000) {
|
||||
return DecodeError();
|
||||
}
|
||||
if (immh.Bit<3>() && !Q) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
ShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Unsigned);
|
||||
return true;
|
||||
return ShiftRight(*this, Q, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Unsigned);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
ShiftLeftLong(*this, Q, immh, immb, Vn, Vd, Signedness::Unsigned);
|
||||
return true;
|
||||
return ShiftLeftLong(*this, Q, immh, immb, Vn, Vd, Signedness::Unsigned);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SRI_2(bool Q, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
|
|
|
@ -18,8 +18,12 @@ enum class ExtraBehavior {
|
|||
Round
|
||||
};
|
||||
|
||||
static void HighNarrowingOperation(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd,
|
||||
HighNarrowingOp op, ExtraBehavior behavior) {
|
||||
bool HighNarrowingOperation(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd,
|
||||
HighNarrowingOp op, ExtraBehavior behavior) {
|
||||
if (size == 0b11) {
|
||||
return v.ReservedValue();
|
||||
}
|
||||
|
||||
const size_t part = Q;
|
||||
const size_t esize = 8 << size.ZeroExtend();
|
||||
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.Vpart(64, Vd, part, result);
|
||||
return true;
|
||||
}
|
||||
|
||||
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) {
|
||||
if (size == 0b11) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, HighNarrowingOp::Add, ExtraBehavior::None);
|
||||
return true;
|
||||
return HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, HighNarrowingOp::Add, ExtraBehavior::None);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::RADDHN(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
if (size == 0b11) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, HighNarrowingOp::Add, ExtraBehavior::Round);
|
||||
return true;
|
||||
return HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, HighNarrowingOp::Add, ExtraBehavior::Round);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SUBHN(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
if (size == 0b11) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, HighNarrowingOp::Subtract, ExtraBehavior::None);
|
||||
return true;
|
||||
return HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, HighNarrowingOp::Subtract, ExtraBehavior::None);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::RSUBHN(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
if (size == 0b11) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, HighNarrowingOp::Subtract, ExtraBehavior::Round);
|
||||
return true;
|
||||
return HighNarrowingOperation(*this, Q, size, Vm, Vn, Vd, HighNarrowingOp::Subtract, ExtraBehavior::Round);
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::SHADD(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) {
|
||||
|
|
|
@ -23,8 +23,12 @@ enum class ExtraBehavior {
|
|||
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) {
|
||||
if (size != 0b01 && size != 0b10) {
|
||||
return v.UnallocatedEncoding();
|
||||
}
|
||||
|
||||
const auto [index, Vm] = Combine(size, H, L, M, Vmlo);
|
||||
const size_t idxdsize = H == 1 ? 128 : 64;
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
} // 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) {
|
||||
if (size != 0b01 && size != 0b10) {
|
||||
return UnallocatedEncoding();
|
||||
}
|
||||
|
||||
MultiplyByElement(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::Accumulate);
|
||||
return true;
|
||||
return MultiplyByElement(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::Accumulate);
|
||||
}
|
||||
|
||||
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 UnallocatedEncoding();
|
||||
}
|
||||
|
||||
MultiplyByElement(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::Subtract);
|
||||
return true;
|
||||
return MultiplyByElement(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::Subtract);
|
||||
}
|
||||
|
||||
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 UnallocatedEncoding();
|
||||
}
|
||||
|
||||
MultiplyByElement(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::None);
|
||||
return true;
|
||||
return MultiplyByElement(*this, Q, size, L, M, Vmlo, H, Vn, Vd, ExtraBehavior::None);
|
||||
}
|
||||
|
||||
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