A32: Implement ARM-mode MLS
This commit is contained in:
parent
8b338b7def
commit
7fc3bd689d
5 changed files with 25 additions and 0 deletions
|
@ -199,6 +199,7 @@ INST(arm_UDIV, "UDIV", "cccc01110011dddd1111mmmm0001nnnn
|
||||||
|
|
||||||
// Multiply (Normal) instructions
|
// Multiply (Normal) instructions
|
||||||
INST(arm_MLA, "MLA", "cccc0000001Sddddaaaammmm1001nnnn") // v2
|
INST(arm_MLA, "MLA", "cccc0000001Sddddaaaammmm1001nnnn") // v2
|
||||||
|
INST(arm_MLS, "MLS", "cccc00000110ddddaaaammmm1001nnnn") // v6T2
|
||||||
INST(arm_MUL, "MUL", "cccc0000000Sdddd0000mmmm1001nnnn") // v2
|
INST(arm_MUL, "MUL", "cccc0000000Sdddd0000mmmm1001nnnn") // v2
|
||||||
|
|
||||||
// Multiply (Long) instructions
|
// Multiply (Long) instructions
|
||||||
|
|
|
@ -664,6 +664,9 @@ public:
|
||||||
std::string arm_MLA(Cond cond, bool S, Reg d, Reg a, Reg m, Reg n) {
|
std::string arm_MLA(Cond cond, bool S, Reg d, Reg a, Reg m, Reg n) {
|
||||||
return fmt::format("mla{}{} {}, {}, {}, {}", S ? "s" : "", CondToString(cond), d, n, m, a);
|
return fmt::format("mla{}{} {}, {}, {}, {}", S ? "s" : "", CondToString(cond), d, n, m, a);
|
||||||
}
|
}
|
||||||
|
std::string arm_MLS(Cond cond, Reg d, Reg a, Reg m, Reg n) {
|
||||||
|
return fmt::format("mls{} {}, {}, {}, {}", CondToString(cond), d, n, m, a);
|
||||||
|
}
|
||||||
std::string arm_MUL(Cond cond, bool S, Reg d, Reg m, Reg n) {
|
std::string arm_MUL(Cond cond, bool S, Reg d, Reg m, Reg n) {
|
||||||
return fmt::format("mul{}{} {}, {}, {}", S ? "s" : "", CondToString(cond), d, n, m);
|
return fmt::format("mul{}{} {}, {}, {}", S ? "s" : "", CondToString(cond), d, n, m);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,25 @@ bool ArmTranslatorVisitor::arm_MLA(Cond cond, bool S, Reg d, Reg a, Reg m, Reg n
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MLS<c> <Rd>, <Rn>, <Rm>, <Ra>
|
||||||
|
bool ArmTranslatorVisitor::arm_MLS(Cond cond, Reg d, Reg a, Reg m, Reg n) {
|
||||||
|
if (d == Reg::PC || a == Reg::PC || m == Reg::PC || n == Reg::PC) {
|
||||||
|
return UnpredictableInstruction();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ConditionPassed(cond)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const IR::U32 operand1 = ir.GetRegister(n);
|
||||||
|
const IR::U32 operand2 = ir.GetRegister(m);
|
||||||
|
const IR::U32 operand3 = ir.GetRegister(a);
|
||||||
|
const IR::U32 result = ir.Sub(operand3, ir.Mul(operand1, operand2));
|
||||||
|
|
||||||
|
ir.SetRegister(d, result);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// MUL{S}<c> <Rd>, <Rn>, <Rm>
|
// MUL{S}<c> <Rd>, <Rn>, <Rm>
|
||||||
bool ArmTranslatorVisitor::arm_MUL(Cond cond, bool S, Reg d, Reg m, Reg n) {
|
bool ArmTranslatorVisitor::arm_MUL(Cond cond, bool S, Reg d, Reg m, Reg n) {
|
||||||
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
|
if (d == Reg::PC || n == Reg::PC || m == Reg::PC) {
|
||||||
|
|
|
@ -242,6 +242,7 @@ struct ArmTranslatorVisitor final {
|
||||||
|
|
||||||
// Multiply (Normal) instructions
|
// Multiply (Normal) instructions
|
||||||
bool arm_MLA(Cond cond, bool S, Reg d, Reg a, Reg m, Reg n);
|
bool arm_MLA(Cond cond, bool S, Reg d, Reg a, Reg m, Reg n);
|
||||||
|
bool arm_MLS(Cond cond, Reg d, Reg a, Reg m, Reg n);
|
||||||
bool arm_MUL(Cond cond, bool S, Reg d, Reg m, Reg n);
|
bool arm_MUL(Cond cond, bool S, Reg d, Reg m, Reg n);
|
||||||
|
|
||||||
// Multiply (Long) instructions
|
// Multiply (Long) instructions
|
||||||
|
|
|
@ -848,6 +848,7 @@ TEST_CASE("Fuzz ARM multiply instructions", "[JitX64][A32]") {
|
||||||
|
|
||||||
const std::array instructions = {
|
const std::array instructions = {
|
||||||
InstructionGenerator("cccc0000001Sddddaaaammmm1001nnnn", validate_d_a_m_n), // MLA
|
InstructionGenerator("cccc0000001Sddddaaaammmm1001nnnn", validate_d_a_m_n), // MLA
|
||||||
|
InstructionGenerator("cccc00000110ddddaaaammmm1001nnnn", validate_d_a_m_n), // MLS
|
||||||
InstructionGenerator("cccc0000000Sdddd0000mmmm1001nnnn", validate_d_m_n), // MUL
|
InstructionGenerator("cccc0000000Sdddd0000mmmm1001nnnn", validate_d_m_n), // MUL
|
||||||
|
|
||||||
InstructionGenerator("cccc0000111Sddddaaaammmm1001nnnn", validate_h_l_m_n), // SMLAL
|
InstructionGenerator("cccc0000111Sddddaaaammmm1001nnnn", validate_h_l_m_n), // SMLAL
|
||||||
|
|
Loading…
Reference in a new issue