fixup! ARM/Decoder: Misc fixes

This commit is contained in:
MerryMage 2016-04-05 09:22:53 +01:00
parent 9555adb4f1
commit ad46ecb125
3 changed files with 28 additions and 23 deletions

View File

@ -44,18 +44,19 @@ namespace Impl {
std::array<u32, NumArgs> masks = {}; std::array<u32, NumArgs> masks = {};
std::array<size_t, NumArgs> shifts = {}; std::array<size_t, NumArgs> shifts = {};
Function fn = nullptr; Function fn = nullptr;
virtual void visit(Visitor *v, u32 inst) override { void visit(Visitor *v, u32 inst) override {
std::array<u32, NumArgs> values; std::array<u32, NumArgs> values;
for (size_t i = 0; i < NumArgs; i++) { std::transform(masks.begin(), masks.begin() + NumArgs, shifts.begin(), values.begin(),
values[i] = (inst & masks[i]) >> shifts[i]; [inst](u32 mask, size_t shift) { return (inst & mask) >> shift; });
}
call<NumArgs>(v, fn, values); call<NumArgs>(v, fn, values);
} }
}; };
} }
template<size_t NumArgs, typename Function> template<size_t NumArgs, typename Function>
static std::unique_ptr<ArmMatcher> MakeMatcher(const char format[32], Function fn) { static std::unique_ptr<ArmMatcher> MakeMatcher(const char* const format, Function fn) {
ASSERT(strlen(format) == 32);
auto ret = Common::make_unique<Impl::MatcherImpl<NumArgs, Function>>(); auto ret = Common::make_unique<Impl::MatcherImpl<NumArgs, Function>>();
ret->fn = fn; ret->fn = fn;
ret->masks.fill(0); ret->masks.fill(0);
@ -64,19 +65,23 @@ static std::unique_ptr<ArmMatcher> MakeMatcher(const char format[32], Function f
char ch = 0; char ch = 0;
int arg = -1; int arg = -1;
for (int i = 0; i < 32; i++) { for (size_t i = 0; i < 32; i++) {
const u32 bit = 1 << (31 - i); const size_t bit_position = 31 - i;
const u32 bit = 1 << bit_position;
if (format[i] == '0') { if (format[i] == '0') {
// 0: A zero must be found here
ret->bit_mask |= bit; ret->bit_mask |= bit;
ch = 0; ch = 0;
continue; continue;
} else if (format[i] == '1') { } else if (format[i] == '1') {
// 1: A one must be found here
ret->bit_mask |= bit; ret->bit_mask |= bit;
ret->expected |= bit; ret->expected |= bit;
ch = 0; ch = 0;
continue; continue;
} else if (format[i] == '-') { } else if (format[i] == '-') {
// -: Ignore this bit
ch = 0; ch = 0;
continue; continue;
} }
@ -86,14 +91,17 @@ static std::unique_ptr<ArmMatcher> MakeMatcher(const char format[32], Function f
ASSERT(format[i] != 'l'); ASSERT(format[i] != 'l');
ASSERT(format[i] != 'O'); ASSERT(format[i] != 'O');
if (format[i] != ch){ // otherwise: This bit is part of a field to extract
// strings of the same character make up a field
if (format[i] != ch) {
arg++; arg++;
ASSERT(arg < NumArgs); ASSERT(arg < NumArgs);
ch = format[i]; ch = format[i];
} }
ret->masks[arg] |= bit; ret->masks[arg] |= bit;
ret->shifts[arg] = 31 - i; ret->shifts[arg] = bit_position;
} }
ASSERT(arg == NumArgs - 1); ASSERT(arg == NumArgs - 1);

View File

@ -23,14 +23,14 @@ class ThumbInstruction;
class Visitor; class Visitor;
/** /**
* This funtion identifies an ARM instruction and returns the relevant ArmInstruction. * This function identifies an ARM instruction and returns the relevant ArmInstruction.
* Returns boost::none if the instruction could not be deocoded. * Returns boost::none if the instruction was not recognised.
*/ */
boost::optional<const ArmInstruction&> DecodeArm(u32 instruction); boost::optional<const ArmInstruction&> DecodeArm(u32 instruction);
/** /**
* This funtion identifies a Thumb instruction and returns the relevant ThumbInstruction. * This function identifies a Thumb instruction and returns the relevant ThumbInstruction.
* Returns boost::none if the instruction could not be deocoded. * Returns boost::none if the instruction was not recognised.
*/ */
boost::optional<const ThumbInstruction&> DecodeThumb(u16 instruction); boost::optional<const ThumbInstruction&> DecodeThumb(u16 instruction);
@ -91,7 +91,7 @@ public:
return name; return name;
} }
bool Match(u32 instruction) const { bool Match(u16 instruction) const {
return matcher.Match(instruction); return matcher.Match(instruction);
} }

View File

@ -22,22 +22,19 @@ ThumbMatcher MakeMatcher(const char* const str, std::function<void(Visitor* v, u
u16 mask = 0; u16 mask = 0;
u16 expect = 0; u16 expect = 0;
for (int i = 0; i < 16; i++) { for (size_t i = 0; i < 16; i++) {
mask <<= 1; const size_t bit_position = 15 - i;
expect <<= 1; const u16 bit = 1 << bit_position;
switch (str[i]) { switch (str[i]) {
case '0': case '0':
mask |= 1; mask |= bit;
expect |= 0;
break; break;
case '1': case '1':
mask |= 1; mask |= bit;
expect |= 1; expect |= bit;
break; break;
default: default:
mask |= 0;
expect |= 0;
break; break;
} }
} }