Merged in Subv/dynarmic/arm_mem_tests (pull request #4)
Added some fuzz tests for most cases of ARM Load/Store instructions
This commit is contained in:
commit
95316b8443
2 changed files with 188 additions and 18 deletions
|
@ -181,8 +181,8 @@ boost::optional<const ArmMatcher<V>&> DecodeArm(u32 instruction) {
|
||||||
//INST(&V::arm_LDR_reg, "LDR (reg)", "cccc011pu0w1nnnnddddvvvvvrr0mmmm"),
|
//INST(&V::arm_LDR_reg, "LDR (reg)", "cccc011pu0w1nnnnddddvvvvvrr0mmmm"),
|
||||||
//INST(&V::arm_LDRB_imm, "LDRB (imm)", "cccc010pu1w1nnnnddddvvvvvvvvvvvv"),
|
//INST(&V::arm_LDRB_imm, "LDRB (imm)", "cccc010pu1w1nnnnddddvvvvvvvvvvvv"),
|
||||||
//INST(&V::arm_LDRB_reg, "LDRB (reg)", "cccc011pu1w1nnnnddddvvvvvrr0mmmm"),
|
//INST(&V::arm_LDRB_reg, "LDRB (reg)", "cccc011pu1w1nnnnddddvvvvvrr0mmmm"),
|
||||||
//INST(&V::arm_LDRBT, "LDRBT (A1)", "----0100-111--------------------"),
|
//INST(&V::arm_LDRBT, "LDRBT (A1)", "cccc0100u111nnnnttttvvvvvvvvvvvv"),
|
||||||
//INST(&V::arm_LDRBT, "LDRBT (A2)", "----0110-111---------------0----"),
|
//INST(&V::arm_LDRBT, "LDRBT (A2)", "cccc0110u111nnnnttttvvvvvrr0mmmm"),
|
||||||
//INST(&V::arm_LDRD_imm, "LDRD (imm)", "cccc000pu1w0nnnnddddvvvv1101vvvv"), // v5E
|
//INST(&V::arm_LDRD_imm, "LDRD (imm)", "cccc000pu1w0nnnnddddvvvv1101vvvv"), // v5E
|
||||||
//INST(&V::arm_LDRD_reg, "LDRD (reg)", "cccc000pu0w0nnnndddd00001101mmmm"), // v5E
|
//INST(&V::arm_LDRD_reg, "LDRD (reg)", "cccc000pu0w0nnnndddd00001101mmmm"), // v5E
|
||||||
//INST(&V::arm_LDRH_imm, "LDRH (imm)", "cccc000pu1w1nnnnddddvvvv1011vvvv"),
|
//INST(&V::arm_LDRH_imm, "LDRH (imm)", "cccc000pu1w1nnnnddddvvvv1011vvvv"),
|
||||||
|
@ -197,22 +197,22 @@ boost::optional<const ArmMatcher<V>&> DecodeArm(u32 instruction) {
|
||||||
//INST(&V::arm_LDRSH_reg, "LDRSH (reg)", "cccc000pu0w1nnnndddd00001111mmmm"),
|
//INST(&V::arm_LDRSH_reg, "LDRSH (reg)", "cccc000pu0w1nnnndddd00001111mmmm"),
|
||||||
//INST(&V::arm_LDRSHT, "LDRSHT (A1)", "----0000-111------------1111----"),
|
//INST(&V::arm_LDRSHT, "LDRSHT (A1)", "----0000-111------------1111----"),
|
||||||
//INST(&V::arm_LDRSHT, "LDRSHT (A2)", "----0000-011--------00001111----"),
|
//INST(&V::arm_LDRSHT, "LDRSHT (A2)", "----0000-011--------00001111----"),
|
||||||
//INST(&V::arm_LDRT, "LDRT (A1)", "----0100-011--------------------"),
|
//INST(&V::arm_LDRT, "LDRT (A1)", "cccc0100u011nnnnttttvvvvvvvvvvvv"),
|
||||||
//INST(&V::arm_LDRT, "LDRT (A2)", "----0110-011---------------0----"),
|
//INST(&V::arm_LDRT, "LDRT (A2)", "cccc0110u011nnnnttttvvvvvrr0mmmm"),
|
||||||
//INST(&V::arm_STR_imm, "STR (imm)", "cccc010pu0w0nnnnddddvvvvvvvvvvvv"),
|
//INST(&V::arm_STR_imm, "STR (imm)", "cccc010pu0w0nnnnddddvvvvvvvvvvvv"),
|
||||||
//INST(&V::arm_STR_reg, "STR (reg)", "cccc011pu0w0nnnnddddvvvvvrr0mmmm"),
|
//INST(&V::arm_STR_reg, "STR (reg)", "cccc011pu0w0nnnnddddvvvvvrr0mmmm"),
|
||||||
//INST(&V::arm_STRB_imm, "STRB (imm)", "cccc010pu1w0nnnnddddvvvvvvvvvvvv"),
|
//INST(&V::arm_STRB_imm, "STRB (imm)", "cccc010pu1w0nnnnddddvvvvvvvvvvvv"),
|
||||||
//INST(&V::arm_STRB_reg, "STRB (reg)", "cccc011pu1w0nnnnddddvvvvvrr0mmmm"),
|
//INST(&V::arm_STRB_reg, "STRB (reg)", "cccc011pu1w0nnnnddddvvvvvrr0mmmm"),
|
||||||
//INST(&V::arm_STRBT, "STRBT (A1)", "----0100-110--------------------"),
|
//INST(&V::arm_STRBT, "STRBT (A1)", "cccc0100u110nnnnttttvvvvvvvvvvvv"),
|
||||||
//INST(&V::arm_STRBT, "STRBT (A2)", "----0110-110---------------0----"),
|
//INST(&V::arm_STRBT, "STRBT (A2)", "cccc0110u110nnnnttttvvvvvrr0mmmm"),
|
||||||
//INST(&V::arm_STRD_imm, "STRD (imm)", "cccc000pu1w0nnnnddddvvvv1111vvvv"), // v5E
|
//INST(&V::arm_STRD_imm, "STRD (imm)", "cccc000pu1w0nnnnddddvvvv1111vvvv"), // v5E
|
||||||
//INST(&V::arm_STRD_reg, "STRD (reg)", "cccc000pu0w0nnnndddd00001111mmmm"), // v5E
|
//INST(&V::arm_STRD_reg, "STRD (reg)", "cccc000pu0w0nnnndddd00001111mmmm"), // v5E
|
||||||
//INST(&V::arm_STRH_imm, "STRH (imm)", "cccc000pu1w0nnnnddddvvvv1011vvvv"),
|
//INST(&V::arm_STRH_imm, "STRH (imm)", "cccc000pu1w0nnnnddddvvvv1011vvvv"),
|
||||||
//INST(&V::arm_STRH_reg, "STRH (reg)", "cccc000pu0w0nnnndddd00001011mmmm"),
|
//INST(&V::arm_STRH_reg, "STRH (reg)", "cccc000pu0w0nnnndddd00001011mmmm"),
|
||||||
//INST(&V::arm_STRHT, "STRHT (A1)", "----0000-110------------1011----"),
|
//INST(&V::arm_STRHT, "STRHT (A1)", "----0000-110------------1011----"),
|
||||||
//INST(&V::arm_STRHT, "STRHT (A2)", "----0000-010--------00001011----"),
|
//INST(&V::arm_STRHT, "STRHT (A2)", "----0000-010--------00001011----"),
|
||||||
//INST(&V::arm_STRT, "STRT (A1)", "----0100-010--------------------"),
|
//INST(&V::arm_STRT, "STRT (A1)", "cccc0100u010nnnnttttvvvvvvvvvvvv"),
|
||||||
//INST(&V::arm_STRT, "STRT (A2)", "----0110-010---------------0----"),
|
//INST(&V::arm_STRT, "STRT (A2)", "cccc0110u010nnnnttttvvvvvrr0mmmm"),
|
||||||
|
|
||||||
// Load/Store Multiple instructions
|
// Load/Store Multiple instructions
|
||||||
//INST(&V::arm_LDM, "LDM", "cccc100pu0w1nnnnxxxxxxxxxxxxxxxx"), // all
|
//INST(&V::arm_LDM, "LDM", "cccc100pu0w1nnnnxxxxxxxxxxxxxxxx"), // all
|
||||||
|
|
|
@ -366,29 +366,199 @@ TEST_CASE("Fuzz ARM reversal instructions", "[JitX64]") {
|
||||||
return Dynarmic::Common::Bits<0, 3>(instr) != 0b1111 && Dynarmic::Common::Bits<12, 15>(instr) != 0b1111;
|
return Dynarmic::Common::Bits<0, 3>(instr) != 0b1111 && Dynarmic::Common::Bits<12, 15>(instr) != 0b1111;
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::array<InstructionGenerator, 3> reg_instructions = {
|
const std::array<InstructionGenerator, 3> rev_instructions = {
|
||||||
{
|
{
|
||||||
InstructionGenerator("cccc011010111111dddd11110011mmmm", is_valid),
|
InstructionGenerator("0000011010111111dddd11110011mmmm", is_valid),
|
||||||
InstructionGenerator("cccc011010111111dddd11111011mmmm", is_valid),
|
InstructionGenerator("0000011010111111dddd11111011mmmm", is_valid),
|
||||||
InstructionGenerator("cccc011011111111dddd11111011mmmm", is_valid),
|
InstructionGenerator("0000011011111111dddd11111011mmmm", is_valid),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
SECTION("REV tests") {
|
SECTION("REV tests") {
|
||||||
FuzzJitArm(1, 1, 10000, [®_instructions]() -> u32 {
|
FuzzJitArm(1, 1, 10000, [&rev_instructions]() -> u32 {
|
||||||
return reg_instructions[0].Generate();
|
u32 cond = 0xE;
|
||||||
|
// Have a one-in-twenty-five chance of actually having a cond.
|
||||||
|
if (RandInt(1, 25) == 1) {
|
||||||
|
cond = RandInt<u32>(0x0, 0xD);
|
||||||
|
}
|
||||||
|
return rev_instructions[0].Generate() | (cond << 28);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("REV16 tests") {
|
SECTION("REV16 tests") {
|
||||||
FuzzJitArm(1, 1, 10000, [®_instructions]() -> u32 {
|
FuzzJitArm(1, 1, 10000, [&rev_instructions]() -> u32 {
|
||||||
return reg_instructions[1].Generate();
|
u32 cond = 0xE;
|
||||||
|
// Have a one-in-twenty-five chance of actually having a cond.
|
||||||
|
if (RandInt(1, 25) == 1) {
|
||||||
|
cond = RandInt<u32>(0x0, 0xD);
|
||||||
|
}
|
||||||
|
return rev_instructions[1].Generate() | (cond << 28);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
SECTION("REVSH tests") {
|
SECTION("REVSH tests") {
|
||||||
FuzzJitArm(1, 1, 10000, [®_instructions]() -> u32 {
|
FuzzJitArm(1, 1, 10000, [&rev_instructions]() -> u32 {
|
||||||
return reg_instructions[2].Generate();
|
u32 cond = 0xE;
|
||||||
|
// Have a one-in-twenty-five chance of actually having a cond.
|
||||||
|
if (RandInt(1, 25) == 1) {
|
||||||
|
cond = RandInt<u32>(0x0, 0xD);
|
||||||
|
}
|
||||||
|
return rev_instructions[2].Generate() | (cond << 28);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Fuzz ARM Load/Store instructions", "[JitX64]") {
|
||||||
|
auto forbid_r15 = [](u32 inst) -> bool {
|
||||||
|
return Dynarmic::Common::Bits<12, 15>(inst) != 0b1111;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto forbid_r14_and_r15 = [](u32 inst) -> bool {
|
||||||
|
return Dynarmic::Common::Bits<13, 15>(inst) != 0b111;
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::array<InstructionGenerator, 4> doubleword_instructions = {
|
||||||
|
{
|
||||||
|
// Load
|
||||||
|
InstructionGenerator("0000000pu1w0nnnnddd0vvvv1101vvvv", forbid_r14_and_r15),
|
||||||
|
InstructionGenerator("0000000pu0w0nnnnddd000001101mmmm", forbid_r14_and_r15),
|
||||||
|
|
||||||
|
// Store
|
||||||
|
InstructionGenerator("0000000pu1w0nnnnddd0vvvv1111vvvv", forbid_r14_and_r15),
|
||||||
|
InstructionGenerator("0000000pu0w0nnnnddd000001111mmmm", forbid_r14_and_r15),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::array<InstructionGenerator, 8> word_instructions = {
|
||||||
|
{
|
||||||
|
// Load
|
||||||
|
InstructionGenerator("0000010pu0w1nnnnddddvvvvvvvvvvvv", forbid_r15),
|
||||||
|
InstructionGenerator("0000011pu0w1nnnnddddvvvvvrr0mmmm", forbid_r15),
|
||||||
|
InstructionGenerator("00000100u011nnnnttttmmmmmmmmmmmm", forbid_r15),
|
||||||
|
InstructionGenerator("00000110u011nnnnttttvvvvvrr0mmmm", forbid_r15),
|
||||||
|
|
||||||
|
// Store
|
||||||
|
InstructionGenerator("0000010pu0w0nnnnddddvvvvvvvvvvvv", forbid_r15),
|
||||||
|
InstructionGenerator("0000011pu0w0nnnnddddvvvvvrr0mmmm", forbid_r15),
|
||||||
|
InstructionGenerator("00000100u010nnnnttttvvvvvvvvvvvv", forbid_r15),
|
||||||
|
InstructionGenerator("00000110u010nnnnttttvvvvvrr0mmmm", forbid_r15),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::array<InstructionGenerator, 6> halfword_instructions = {
|
||||||
|
{
|
||||||
|
// Load
|
||||||
|
InstructionGenerator("0000000pu1w1nnnnddddvvvv1011vvvv", forbid_r15),
|
||||||
|
InstructionGenerator("0000000pu0w1nnnndddd00001011mmmm", forbid_r15),
|
||||||
|
// InstructionGenerator("----0000-111------------1011----"), // LDRHT (A1) Not available in ARMv6K
|
||||||
|
// InstructionGenerator("----0000-011--------00001011----"), // LDRHT (A2) Not available in ARMv6K
|
||||||
|
InstructionGenerator("0000000pu1w1nnnnddddvvvv1111vvvv", forbid_r15),
|
||||||
|
InstructionGenerator("0000000pu0w1nnnndddd00001111mmmm", forbid_r15),
|
||||||
|
// InstructionGenerator("----0000-111------------1111----"), // LDRSHT (A1) Not available in ARMv6K
|
||||||
|
// InstructionGenerator("----0000-011--------00001111----"), // LDRSHT (A2) Not available in ARMv6K
|
||||||
|
|
||||||
|
|
||||||
|
// Store
|
||||||
|
InstructionGenerator("0000000pu1w0nnnnddddvvvv1011vvvv", forbid_r15),
|
||||||
|
InstructionGenerator("0000000pu0w0nnnndddd00001011mmmm", forbid_r15),
|
||||||
|
// InstructionGenerator("----0000-110------------1011----"), // STRHT (A1) Not available in ARMv6K
|
||||||
|
// InstructionGenerator("----0000-010--------00001011----"), // STRHT (A2) Not available in ARMv6K
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::array<InstructionGenerator, 10> byte_instructions = {
|
||||||
|
{
|
||||||
|
// Load
|
||||||
|
InstructionGenerator("0000010pu1w1nnnnddddvvvvvvvvvvvv", forbid_r15),
|
||||||
|
InstructionGenerator("0000011pu1w1nnnnddddvvvvvrr0mmmm", forbid_r15),
|
||||||
|
InstructionGenerator("00000100u111nnnnttttvvvvvvvvvvvv", forbid_r15),
|
||||||
|
InstructionGenerator("00000110u111nnnnttttvvvvvrr0mmmm", forbid_r15),
|
||||||
|
InstructionGenerator("0000000pu1w1nnnnddddvvvv1101vvvv", forbid_r15),
|
||||||
|
InstructionGenerator("0000000pu0w1nnnndddd00001101mmmm", forbid_r15),
|
||||||
|
// InstructionGenerator("----0000-111------------1101----"), // LDRSBT (A1) Not available in ARMv6K
|
||||||
|
// InstructionGenerator("----0000-011--------00001101----"), // LDRSBT (A2) Not available in ARMv6K
|
||||||
|
|
||||||
|
|
||||||
|
// Store
|
||||||
|
InstructionGenerator("0000010pu1w0nnnnddddvvvvvvvvvvvv", forbid_r15),
|
||||||
|
InstructionGenerator("0000011pu1w0nnnnddddvvvvvrr0mmmm", forbid_r15),
|
||||||
|
InstructionGenerator("00000100u110nnnnttttvvvvvvvvvvvv", forbid_r15),
|
||||||
|
InstructionGenerator("00000110u110nnnnttttvvvvvrr0mmmm", forbid_r15),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
SECTION("Doubleword tests") {
|
||||||
|
FuzzJitArm(1, 1, 10000, [&doubleword_instructions]() -> u32 {
|
||||||
|
u32 cond = 0xE;
|
||||||
|
// Have a one-in-twenty-five chance of actually having a cond.
|
||||||
|
if (RandInt(1, 25) == 1) {
|
||||||
|
cond = RandInt<u32>(0x0, 0xD);
|
||||||
|
}
|
||||||
|
|
||||||
|
return doubleword_instructions[RandInt<size_t>(0, doubleword_instructions.size() - 1)].Generate() | (cond << 28);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Word tests") {
|
||||||
|
FuzzJitArm(1, 1, 10000, [&word_instructions]() -> u32 {
|
||||||
|
u32 cond = 0xE;
|
||||||
|
// Have a one-in-twenty-five chance of actually having a cond.
|
||||||
|
if (RandInt(1, 25) == 1) {
|
||||||
|
cond = RandInt<u32>(0x0, 0xD);
|
||||||
|
}
|
||||||
|
return word_instructions[RandInt<size_t>(0, word_instructions.size() - 1)].Generate() | (cond << 28);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Halfword tests") {
|
||||||
|
FuzzJitArm(1, 1, 10000, [&halfword_instructions]() -> u32 {
|
||||||
|
u32 cond = 0xE;
|
||||||
|
// Have a one-in-twenty-five chance of actually having a cond.
|
||||||
|
if (RandInt(1, 25) == 1) {
|
||||||
|
cond = RandInt<u32>(0x0, 0xD);
|
||||||
|
}
|
||||||
|
return halfword_instructions[RandInt<size_t>(0, halfword_instructions.size() - 1)].Generate() | (cond << 28);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Byte tests") {
|
||||||
|
FuzzJitArm(1, 1, 10000, [&byte_instructions]() -> u32 {
|
||||||
|
u32 cond = 0xE;
|
||||||
|
// Have a one-in-twenty-five chance of actually having a cond.
|
||||||
|
if (RandInt(1, 25) == 1) {
|
||||||
|
cond = RandInt<u32>(0x0, 0xD);
|
||||||
|
}
|
||||||
|
return byte_instructions[RandInt<size_t>(0, byte_instructions.size() - 1)].Generate() | (cond << 28);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Mixed tests") {
|
||||||
|
FuzzJitArm(10, 10, 10000, [&]() -> u32 {
|
||||||
|
size_t selection = RandInt<size_t>(0, 3);
|
||||||
|
|
||||||
|
u32 cond = 0xE;
|
||||||
|
// Have a one-in-twenty-five chance of actually having a cond.
|
||||||
|
if (RandInt(1, 25) == 1) {
|
||||||
|
cond = RandInt<u32>(0x0, 0xD);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (selection) {
|
||||||
|
case 0:
|
||||||
|
return doubleword_instructions[RandInt<size_t>(0, doubleword_instructions.size() - 1)].Generate() | (cond << 28);
|
||||||
|
case 1:
|
||||||
|
return word_instructions[RandInt<size_t>(0, word_instructions.size() - 1)].Generate() | (cond << 28);
|
||||||
|
case 2:
|
||||||
|
return halfword_instructions[RandInt<size_t>(0, halfword_instructions.size() - 1)].Generate() | (cond << 28);
|
||||||
|
case 3:
|
||||||
|
return byte_instructions[RandInt<size_t>(0, byte_instructions.size() - 1)].Generate() | (cond << 28);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTION("Write to PC") {
|
||||||
|
// TODO
|
||||||
|
FAIL();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue