fixup! Fix bugs in thumb decoder & have it use boost::optional

This commit is contained in:
MerryMage 2016-03-21 21:26:34 +00:00
parent e86f27ad72
commit 26c18cc21e
3 changed files with 17 additions and 8 deletions

View File

@ -21,7 +21,7 @@ class Instruction;
class Visitor; class Visitor;
boost::optional<const Instruction&> DecodeArm(u32 instruction); boost::optional<const Instruction&> DecodeArm(u32 instruction);
const Instruction& DecodeThumb(u16 instruction); boost::optional<const Instruction&> DecodeThumb(u16 instruction);
struct Matcher { struct Matcher {
u32 bit_mask; u32 bit_mask;

View File

@ -2,10 +2,11 @@
// Licensed under GPLv2 or any later version // Licensed under GPLv2 or any later version
// Refer to the license.txt file included. // Refer to the license.txt file included.
#pragma once
#include <algorithm> #include <algorithm>
#include <cstddef> #include <cstddef>
#include <cstring>
#include <boost/optional.hpp>
#include "common/assert.h" #include "common/assert.h"
#include "common/common_types.h" #include "common/common_types.h"
@ -265,7 +266,7 @@ static const std::array<Instruction, 27> thumb_instruction_table = { {
} }
})}, })},
{ "STR(B)/LDR(B)_imm", MakeMatcher("011xxxxxxxxxxxxx", [](Visitor* v, u32 instruction) { { "STR(B)/LDR(B)_imm", MakeMatcher("011xxxxxxxxxxxxx", [](Visitor* v, u32 instruction) {
bool opc = bits<11, 12>(instruction); u32 opc = bits<11, 12>(instruction);
Register offset = bits<6, 10>(instruction); Register offset = bits<6, 10>(instruction);
Register Rn = bits<3, 5>(instruction); Register Rn = bits<3, 5>(instruction);
Register Rd = bits<0, 2>(instruction); Register Rd = bits<0, 2>(instruction);
@ -374,7 +375,7 @@ static const std::array<Instruction, 27> thumb_instruction_table = { {
v->CPS(); v->CPS();
})}, })},
{ "reverse bytes", MakeMatcher("10111010ooxxxxxx", [](Visitor* v, u32 instruction) { { "reverse bytes", MakeMatcher("10111010ooxxxxxx", [](Visitor* v, u32 instruction) {
bool opc = bits<6, 7>(instruction); u32 opc = bits<6, 7>(instruction);
Register Rn = bits<3, 5>(instruction); Register Rn = bits<3, 5>(instruction);
Register Rd = bits<0, 2>(instruction); Register Rd = bits<0, 2>(instruction);
switch (opc) { switch (opc) {
@ -439,15 +440,17 @@ static const std::array<Instruction, 27> thumb_instruction_table = { {
})} })}
}}; }};
const Instruction& DecodeThumb(u16 i) { boost::optional<const Instruction&> DecodeThumb(u16 i) {
// NOTE: The reverse search direction is important. Searching forwards would result in incorrect behavior. // NOTE: The reverse search direction is important. Searching forwards would result in incorrect behavior.
// This is because the entries in thumb_instruction_table have more specific matches coming after less specific ones. // This is because the entries in thumb_instruction_table have more specific matches coming after less specific ones.
// Example: // Example:
// 000ooxxxxxxxxxxx comes before 000110oxxxxxxxxx // 000ooxxxxxxxxxxx comes before 000110oxxxxxxxxx
// with a forward search direction notice how the first one will always be matched and the latter never will be. // with a forward search direction notice how the first one will always be matched and the latter never will be.
return *std::find_if(thumb_instruction_table.crbegin(), thumb_instruction_table.crend(), [i](const Instruction& instruction) { auto iterator = std::find_if(thumb_instruction_table.crbegin(), thumb_instruction_table.crend(), [i](const Instruction& instruction) {
return instruction.Match(i); return instruction.Match(i);
}); });
return (iterator != thumb_instruction_table.crend()) ? boost::make_optional<const Instruction&>(*iterator) : boost::none;
} }
}; };

View File

@ -150,7 +150,13 @@ void JitX64::CompileSingleThumbInstruction() {
inst_u32 &= 0xFFFFF; inst_u32 &= 0xFFFFF;
u16 inst = inst_u32; u16 inst = inst_u32;
ArmDecoder::DecodeThumb(inst).Visit(this, inst); auto inst_info = ArmDecoder::DecodeThumb(inst);
if (!inst_info) {
// TODO: Log message
CompileInterpretInstruction();
} else {
inst_info->Visit(this, inst);
}
} }
// Convenience functions: // Convenience functions: