thumb32: Implement SHADD8/UHADD8

This commit is contained in:
Lioncash 2021-02-01 17:23:40 -05:00
parent afad76078d
commit 9d2570470e
4 changed files with 34 additions and 2 deletions

View file

@ -251,7 +251,7 @@ std::optional<std::reference_wrapper<const Thumb32Matcher<V>>> DecodeThumb32(u32
INST(&V::thumb32_SHASX, "SHASX", "111110101010nnnn1111dddd0010mmmm"), INST(&V::thumb32_SHASX, "SHASX", "111110101010nnnn1111dddd0010mmmm"),
INST(&V::thumb32_SHSAX, "SHSAX", "111110101110nnnn1111dddd0010mmmm"), INST(&V::thumb32_SHSAX, "SHSAX", "111110101110nnnn1111dddd0010mmmm"),
INST(&V::thumb32_SHSUB16, "SHSUB16", "111110101101nnnn1111dddd0010mmmm"), INST(&V::thumb32_SHSUB16, "SHSUB16", "111110101101nnnn1111dddd0010mmmm"),
//INST(&V::thumb32_SHADD8, "SHADD8", "111110101000----1111----0010----"), INST(&V::thumb32_SHADD8, "SHADD8", "111110101000nnnn1111dddd0010mmmm"),
//INST(&V::thumb32_SHSUB8, "SHSUB8", "111110101100----1111----0010----"), //INST(&V::thumb32_SHSUB8, "SHSUB8", "111110101100----1111----0010----"),
// Parallel Addition and Subtraction (unsigned) // Parallel Addition and Subtraction (unsigned)
@ -271,7 +271,7 @@ std::optional<std::reference_wrapper<const Thumb32Matcher<V>>> DecodeThumb32(u32
INST(&V::thumb32_UHASX, "UHASX", "111110101010nnnn1111dddd0110mmmm"), INST(&V::thumb32_UHASX, "UHASX", "111110101010nnnn1111dddd0110mmmm"),
INST(&V::thumb32_UHSAX, "UHSAX", "111110101110nnnn1111dddd0110mmmm"), INST(&V::thumb32_UHSAX, "UHSAX", "111110101110nnnn1111dddd0110mmmm"),
INST(&V::thumb32_UHSUB16, "UHSUB16", "111110101101nnnn1111dddd0110mmmm"), INST(&V::thumb32_UHSUB16, "UHSUB16", "111110101101nnnn1111dddd0110mmmm"),
//INST(&V::thumb32_UHADD8, "UHADD8", "111110101000----1111----0110----"), INST(&V::thumb32_UHADD8, "UHADD8", "111110101000nnnn1111dddd0110mmmm"),
//INST(&V::thumb32_UHSUB8, "UHSUB8", "111110101100----1111----0110----"), //INST(&V::thumb32_UHSUB8, "UHSUB8", "111110101100----1111----0110----"),
// Miscellaneous Operations // Miscellaneous Operations

View file

@ -362,6 +362,19 @@ bool ThumbTranslatorVisitor::thumb32_UQSUB16(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_SHADD8(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction();
}
const auto reg_m = ir.GetRegister(m);
const auto reg_n = ir.GetRegister(n);
const auto result = ir.PackedHalvingAddS8(reg_n, reg_m);
ir.SetRegister(d, result);
return true;
}
bool ThumbTranslatorVisitor::thumb32_SHADD16(Reg n, Reg d, Reg m) { bool ThumbTranslatorVisitor::thumb32_SHADD16(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();
@ -414,6 +427,19 @@ bool ThumbTranslatorVisitor::thumb32_SHSUB16(Reg n, Reg d, Reg m) {
return true; return true;
} }
bool ThumbTranslatorVisitor::thumb32_UHADD8(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction();
}
const auto reg_m = ir.GetRegister(m);
const auto reg_n = ir.GetRegister(n);
const auto result = ir.PackedHalvingAddU8(reg_n, reg_m);
ir.SetRegister(d, result);
return true;
}
bool ThumbTranslatorVisitor::thumb32_UHADD16(Reg n, Reg d, Reg m) { bool ThumbTranslatorVisitor::thumb32_UHADD16(Reg n, Reg d, Reg m) {
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) { if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction(); return UnpredictableInstruction();

View file

@ -155,10 +155,12 @@ struct ThumbTranslatorVisitor final {
bool thumb32_UQSUB8(Reg n, Reg d, Reg m); bool thumb32_UQSUB8(Reg n, Reg d, Reg m);
bool thumb32_UQSUB16(Reg n, Reg d, Reg m); bool thumb32_UQSUB16(Reg n, Reg d, Reg m);
bool thumb32_SHADD8(Reg n, Reg d, Reg m);
bool thumb32_SHADD16(Reg n, Reg d, Reg m); bool thumb32_SHADD16(Reg n, Reg d, Reg m);
bool thumb32_SHASX(Reg n, Reg d, Reg m); bool thumb32_SHASX(Reg n, Reg d, Reg m);
bool thumb32_SHSAX(Reg n, Reg d, Reg m); bool thumb32_SHSAX(Reg n, Reg d, Reg m);
bool thumb32_SHSUB16(Reg n, Reg d, Reg m); bool thumb32_SHSUB16(Reg n, Reg d, Reg m);
bool thumb32_UHADD8(Reg n, Reg d, Reg m);
bool thumb32_UHADD16(Reg n, Reg d, Reg m); bool thumb32_UHADD16(Reg n, Reg d, Reg m);
bool thumb32_UHASX(Reg n, Reg d, Reg m); bool thumb32_UHASX(Reg n, Reg d, Reg m);
bool thumb32_UHSAX(Reg n, Reg d, Reg m); bool thumb32_UHSAX(Reg n, Reg d, Reg m);

View file

@ -432,6 +432,8 @@ TEST_CASE("Fuzz Thumb32 instructions set", "[JitX64][Thumb][Thumb32]") {
three_reg_not_r15), three_reg_not_r15),
ThumbInstGen("111110101010nnnn1111dddd1000mmmm", // SEL ThumbInstGen("111110101010nnnn1111dddd1000mmmm", // SEL
three_reg_not_r15), three_reg_not_r15),
ThumbInstGen("111110101000nnnn1111dddd0010mmmm", // SHADD8
three_reg_not_r15),
ThumbInstGen("111110101001nnnn1111dddd0010mmmm", // SHADD16 ThumbInstGen("111110101001nnnn1111dddd0010mmmm", // SHADD16
three_reg_not_r15), three_reg_not_r15),
ThumbInstGen("111110101010nnnn1111dddd0010mmmm", // SHASX ThumbInstGen("111110101010nnnn1111dddd0010mmmm", // SHASX
@ -452,6 +454,8 @@ TEST_CASE("Fuzz Thumb32 instructions set", "[JitX64][Thumb][Thumb32]") {
three_reg_not_r15), three_reg_not_r15),
ThumbInstGen("111110101010nnnn1111dddd0100mmmm", // UASX ThumbInstGen("111110101010nnnn1111dddd0100mmmm", // UASX
three_reg_not_r15), three_reg_not_r15),
ThumbInstGen("111110101000nnnn1111dddd0110mmmm", // UHADD8
three_reg_not_r15),
ThumbInstGen("111110101001nnnn1111dddd0110mmmm", // UHADD16 ThumbInstGen("111110101001nnnn1111dddd0110mmmm", // UHADD16
three_reg_not_r15), three_reg_not_r15),
ThumbInstGen("111110101010nnnn1111dddd0110mmmm", // UHASX ThumbInstGen("111110101010nnnn1111dddd0110mmmm", // UHASX