From 26c18cc21e54e4c615047974793c66b907217a58 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Mon, 21 Mar 2016 21:26:34 +0000 Subject: [PATCH] fixup! Fix bugs in thumb decoder & have it use boost::optional --- src/core/arm/decoder/decoder.h | 2 +- src/core/arm/decoder/thumb.cpp | 15 +++++++++------ src/core/arm/jit_x64/jit_x64.cpp | 8 +++++++- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/core/arm/decoder/decoder.h b/src/core/arm/decoder/decoder.h index 22f70670a..8b5080d99 100644 --- a/src/core/arm/decoder/decoder.h +++ b/src/core/arm/decoder/decoder.h @@ -21,7 +21,7 @@ class Instruction; class Visitor; boost::optional DecodeArm(u32 instruction); -const Instruction& DecodeThumb(u16 instruction); +boost::optional DecodeThumb(u16 instruction); struct Matcher { u32 bit_mask; diff --git a/src/core/arm/decoder/thumb.cpp b/src/core/arm/decoder/thumb.cpp index a6b02dfa4..0a7a65e63 100644 --- a/src/core/arm/decoder/thumb.cpp +++ b/src/core/arm/decoder/thumb.cpp @@ -2,10 +2,11 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#pragma once - #include #include +#include + +#include #include "common/assert.h" #include "common/common_types.h" @@ -265,7 +266,7 @@ static const std::array thumb_instruction_table = { { } })}, { "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 Rn = bits<3, 5>(instruction); Register Rd = bits<0, 2>(instruction); @@ -374,7 +375,7 @@ static const std::array thumb_instruction_table = { { v->CPS(); })}, { "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 Rd = bits<0, 2>(instruction); switch (opc) { @@ -439,15 +440,17 @@ static const std::array thumb_instruction_table = { { })} }}; -const Instruction& DecodeThumb(u16 i) { +boost::optional DecodeThumb(u16 i) { // 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. // Example: // 000ooxxxxxxxxxxx comes before 000110oxxxxxxxxx // 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 (iterator != thumb_instruction_table.crend()) ? boost::make_optional(*iterator) : boost::none; } }; diff --git a/src/core/arm/jit_x64/jit_x64.cpp b/src/core/arm/jit_x64/jit_x64.cpp index 850dfee2f..4a5006664 100644 --- a/src/core/arm/jit_x64/jit_x64.cpp +++ b/src/core/arm/jit_x64/jit_x64.cpp @@ -150,7 +150,13 @@ void JitX64::CompileSingleThumbInstruction() { inst_u32 &= 0xFFFFF; 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: