Allow IR blocks to require a cond for block entry.

* IR: Add cond, cond_failed.
* backend_x64/EmitX64: Implement EmitCondPrelude
This commit is contained in:
MerryMage 2016-07-14 12:52:53 +01:00
parent 4ab4ca58f9
commit 7d7751c157
4 changed files with 178 additions and 7 deletions

View file

@ -60,16 +60,15 @@ enum class SignExtendRotation {
};
struct LocationDescriptor {
LocationDescriptor(u32 arm_pc, bool TFlag, bool EFlag, Cond cond = Cond::AL)
: arm_pc(arm_pc), TFlag(TFlag), EFlag(EFlag), cond(cond) {}
LocationDescriptor(u32 arm_pc, bool TFlag, bool EFlag)
: arm_pc(arm_pc), TFlag(TFlag), EFlag(EFlag) {}
u32 arm_pc;
bool TFlag; ///< Thumb / ARM
bool EFlag; ///< Big / Little Endian
Cond cond;
bool operator == (const LocationDescriptor& o) const {
return std::tie(arm_pc, TFlag, EFlag, cond) == std::tie(o.arm_pc, o.TFlag, o.EFlag, o.cond);
return std::tie(arm_pc, TFlag, EFlag) == std::tie(o.arm_pc, o.TFlag, o.EFlag);
}
};

View file

@ -11,6 +11,7 @@
#include <vector>
#include <boost/variant.hpp>
#include <boost/optional.hpp>
#include "common/common_types.h"
#include "frontend/arm_types.h"
@ -246,9 +247,19 @@ class Block final {
public:
explicit Block(const Arm::LocationDescriptor& location) : location(location) {}
/// Description of the starting location of this block
Arm::LocationDescriptor location;
/// Conditional to pass in order to execute this block
Arm::Cond cond = Arm::Cond::AL;
/// Block to execute next if `cond` did not pass.
boost::optional<Arm::LocationDescriptor> cond_failed = {};
/// List of instructions in this block.
std::list<ValuePtr> instructions;
/// Terminal instruction of this block.
Terminal terminal = Term::Invalid{};
/// Number of cycles this block takes to execute.
size_t cycle_count = 0;
};