Implement thumb_CMP_reg_t2

This commit is contained in:
MerryMage 2016-07-10 12:23:16 +08:00
parent 3f7290db16
commit 8920ce79b9
4 changed files with 30 additions and 7 deletions

View file

@ -56,7 +56,7 @@ private:
};
template <typename V>
static const std::array<Thumb1Matcher<V>, 28> g_thumb1_instruction_table {{
static const std::array<Thumb1Matcher<V>, 29> g_thumb1_instruction_table {{
#define INST(fn, name, bitstring) detail::detail<Thumb1Matcher, u16, 16>::GetMatcher<decltype(fn), fn>(name, bitstring)
@ -84,7 +84,7 @@ static const std::array<Thumb1Matcher<V>, 28> g_thumb1_instruction_table {{
{ INST(&V::thumb1_ROR_reg, "ROR (reg)", "0100000111sssddd") },
{ INST(&V::thumb1_TST_reg, "TST (reg)", "0100001000mmmnnn") },
{ INST(&V::thumb1_RSB_imm, "RSB (imm)", "0100001001nnnddd") },
{ INST(&V::thumb1_CMP_reg, "CMP (reg)", "0100001010mmmnnn") },
{ INST(&V::thumb1_CMP_reg_t1, "CMP (reg, T1)", "0100001010mmmnnn") },
{ INST(&V::thumb1_CMN_reg, "CMN (reg)", "0100001011mmmnnn") },
{ INST(&V::thumb1_ORR_reg, "ORR (reg)", "0100001100mmmddd") },
//{ INST(&V::thumb1_MULS_rr, "MULS (rr)", "0100001101mmmddd") },
@ -93,7 +93,7 @@ static const std::array<Thumb1Matcher<V>, 28> g_thumb1_instruction_table {{
// Special data instructions
{ INST(&V::thumb1_ADD_reg_t2, "ADD (reg, T2)", "01000100Dmmmmddd") }, // v4T, Low regs: v6T2
//{ INST(&V::thumb1_CMP_high, "CMP (high)", "01000101dmmmmddd") }, // v4T
{ INST(&V::thumb1_CMP_reg_t2, "CMP (reg, T2)", "01000101Nmmmmnnn") }, // v4T
//{ INST(&V::thumb1_MOV_high, "MOV (high)", "01000110dmmmmddd") }, // v4T, Low regs: v6
// Store/Load single data item instructions

View file

@ -187,7 +187,7 @@ public:
return Common::StringFromFormat("rsbs %s, %s, #0", RegStr(d), RegStr(n));
}
std::string thumb1_CMP_reg(Reg m, Reg n) {
std::string thumb1_CMP_reg_t1(Reg m, Reg n) {
return Common::StringFromFormat("cmp %s, %s", RegStr(n), RegStr(m));
}
@ -212,6 +212,11 @@ public:
return Common::StringFromFormat("add %s, %s", RegStr(d_n), RegStr(m));
}
std::string thumb1_CMP_reg_t2(bool n_hi, Reg m, Reg n_lo) {
Reg n = n_hi ? (n_lo + 8) : n_lo;
return Common::StringFromFormat("cmp %s, %s", RegStr(n), RegStr(m));
}
std::string thumb1_UDF() {
return Common::StringFromFormat("udf");
}

View file

@ -269,7 +269,7 @@ struct TranslatorVisitor final {
ir.SetVFlag(result.overflow);
return true;
}
bool thumb1_CMP_reg(Reg m, Reg n) {
bool thumb1_CMP_reg_t1(Reg m, Reg n) {
// CMP <Rn>, <Rm>
auto result = ir.SubWithCarry(ir.GetRegister(n), ir.GetRegister(m), ir.Imm1(1));
ir.SetNFlag(ir.MostSignificantBit(result.result));
@ -336,6 +336,22 @@ struct TranslatorVisitor final {
}
}
bool thumb1_CMP_reg_t2(bool n_hi, Reg m, Reg n_lo) {
Reg n = n_hi ? (n_lo + 8) : n_lo;
if (n < Reg::R8 && m < Reg::R8) {
return UnpredictableInstruction();
} else if (n == Reg::PC || m == Reg::PC) {
return UnpredictableInstruction();
}
// CMP <Rn>, <Rm>
auto result = ir.SubWithCarry(ir.GetRegister(n), ir.GetRegister(m), ir.Imm1(1));
ir.SetNFlag(ir.MostSignificantBit(result.result));
ir.SetZFlag(ir.IsZero(result.result));
ir.SetCFlag(result.carry);
ir.SetVFlag(result.overflow);
return true;
}
bool thumb1_UDF() {
return TranslateThisInstruction();
}

View file

@ -180,8 +180,10 @@ TEST_CASE("Fuzz Thumb instructions set 1", "[JitX64][Thumb]") {
InstructionGenerator("001ooxxxxxxxxxxx"), // ADD/SUB/CMP/MOV_imm
InstructionGenerator("010000ooooxxxxxx"), // Data Processing
InstructionGenerator("010001000hxxxxxx"), // ADD (high registers)
InstructionGenerator("0100010101xxxxxx"), // CMP (high registers)
InstructionGenerator("0100010110xxxxxx"), // CMP (high registers)
InstructionGenerator("0100010101xxxxxx", // CMP (high registers)
[](u16 inst){ return Dynarmic::Common::Bits<3, 5>(inst) != 0b111; }), // R15 is UNPREDICTABLE
InstructionGenerator("0100010110xxxxxx", // CMP (high registers)
[](u16 inst){ return Dynarmic::Common::Bits<0, 2>(inst) != 0b111; }), // R15 is UNPREDICTABLE
InstructionGenerator("010001100hxxxxxx"), // MOV (high registers)
InstructionGenerator("10110000oxxxxxxx"), // Adjust stack pointer
InstructionGenerator("10110010ooxxxxxx"), // SXT/UXT