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:
Lioncash 2018-07-22 16:55:40 -04:00 committed by MerryMage
parent d65b056eba
commit 3447c82656
6 changed files with 132 additions and 268 deletions

View file

@ -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

View file

@ -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) {

View file

@ -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

View file

@ -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,
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,
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,
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,
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) {

View file

@ -18,8 +18,12 @@ enum class ExtraBehavior {
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) {
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) {

View file

@ -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) {