Implement thumb_CMP_reg_t2
This commit is contained in:
parent
3f7290db16
commit
8920ce79b9
4 changed files with 30 additions and 7 deletions
|
@ -56,7 +56,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename V>
|
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)
|
#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_ROR_reg, "ROR (reg)", "0100000111sssddd") },
|
||||||
{ INST(&V::thumb1_TST_reg, "TST (reg)", "0100001000mmmnnn") },
|
{ INST(&V::thumb1_TST_reg, "TST (reg)", "0100001000mmmnnn") },
|
||||||
{ INST(&V::thumb1_RSB_imm, "RSB (imm)", "0100001001nnnddd") },
|
{ 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_CMN_reg, "CMN (reg)", "0100001011mmmnnn") },
|
||||||
{ INST(&V::thumb1_ORR_reg, "ORR (reg)", "0100001100mmmddd") },
|
{ INST(&V::thumb1_ORR_reg, "ORR (reg)", "0100001100mmmddd") },
|
||||||
//{ INST(&V::thumb1_MULS_rr, "MULS (rr)", "0100001101mmmddd") },
|
//{ 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
|
// Special data instructions
|
||||||
{ INST(&V::thumb1_ADD_reg_t2, "ADD (reg, T2)", "01000100Dmmmmddd") }, // v4T, Low regs: v6T2
|
{ 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
|
//{ INST(&V::thumb1_MOV_high, "MOV (high)", "01000110dmmmmddd") }, // v4T, Low regs: v6
|
||||||
|
|
||||||
// Store/Load single data item instructions
|
// Store/Load single data item instructions
|
||||||
|
|
|
@ -187,7 +187,7 @@ public:
|
||||||
return Common::StringFromFormat("rsbs %s, %s, #0", RegStr(d), RegStr(n));
|
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));
|
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));
|
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() {
|
std::string thumb1_UDF() {
|
||||||
return Common::StringFromFormat("udf");
|
return Common::StringFromFormat("udf");
|
||||||
}
|
}
|
||||||
|
|
|
@ -269,7 +269,7 @@ struct TranslatorVisitor final {
|
||||||
ir.SetVFlag(result.overflow);
|
ir.SetVFlag(result.overflow);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool thumb1_CMP_reg(Reg m, Reg n) {
|
bool thumb1_CMP_reg_t1(Reg m, Reg n) {
|
||||||
// CMP <Rn>, <Rm>
|
// CMP <Rn>, <Rm>
|
||||||
auto result = ir.SubWithCarry(ir.GetRegister(n), ir.GetRegister(m), ir.Imm1(1));
|
auto result = ir.SubWithCarry(ir.GetRegister(n), ir.GetRegister(m), ir.Imm1(1));
|
||||||
ir.SetNFlag(ir.MostSignificantBit(result.result));
|
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() {
|
bool thumb1_UDF() {
|
||||||
return TranslateThisInstruction();
|
return TranslateThisInstruction();
|
||||||
}
|
}
|
||||||
|
|
|
@ -180,8 +180,10 @@ TEST_CASE("Fuzz Thumb instructions set 1", "[JitX64][Thumb]") {
|
||||||
InstructionGenerator("001ooxxxxxxxxxxx"), // ADD/SUB/CMP/MOV_imm
|
InstructionGenerator("001ooxxxxxxxxxxx"), // ADD/SUB/CMP/MOV_imm
|
||||||
InstructionGenerator("010000ooooxxxxxx"), // Data Processing
|
InstructionGenerator("010000ooooxxxxxx"), // Data Processing
|
||||||
InstructionGenerator("010001000hxxxxxx"), // ADD (high registers)
|
InstructionGenerator("010001000hxxxxxx"), // ADD (high registers)
|
||||||
InstructionGenerator("0100010101xxxxxx"), // CMP (high registers)
|
InstructionGenerator("0100010101xxxxxx", // CMP (high registers)
|
||||||
InstructionGenerator("0100010110xxxxxx"), // 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("010001100hxxxxxx"), // MOV (high registers)
|
||||||
InstructionGenerator("10110000oxxxxxxx"), // Adjust stack pointer
|
InstructionGenerator("10110000oxxxxxxx"), // Adjust stack pointer
|
||||||
InstructionGenerator("10110010ooxxxxxx"), // SXT/UXT
|
InstructionGenerator("10110010ooxxxxxx"), // SXT/UXT
|
||||||
|
|
Loading…
Reference in a new issue