[Decompiler] IR2 form implementation (#197)

* begin ir2 form implementation

* temp

* small fixes

* fix test
This commit is contained in:
water111
2021-01-17 18:08:18 -05:00
committed by GitHub
parent 1071ff6003
commit d6bbca5620
17 changed files with 2516 additions and 211 deletions
+5 -111
View File
@@ -254,6 +254,7 @@ std::string get_simple_expression_op_name(SimpleExpression::Kind kind) {
assert(false);
}
}
} // namespace
int get_simple_expression_arg_count(SimpleExpression::Kind kind) {
switch (kind) {
@@ -302,7 +303,6 @@ int get_simple_expression_arg_count(SimpleExpression::Kind kind) {
assert(false);
}
}
} // namespace
SimpleExpression::SimpleExpression(Kind kind, const SimpleAtom& arg0) : n_args(1) {
m_args[0] = arg0;
@@ -372,10 +372,6 @@ bool SetVarOp::operator==(const AtomicOp& other) const {
return m_dst == po->m_dst && m_src == po->m_src;
}
bool SetVarOp::is_variable_set() const {
return true;
}
bool SetVarOp::is_sequence_point() const {
if (m_src.is_identity()) {
auto& atom = m_src.get_arg(0);
@@ -394,14 +390,6 @@ Variable SetVarOp::get_set_destination() const {
return m_dst;
}
std::unique_ptr<Expr> SetVarOp::get_set_source_as_expr() const {
throw std::runtime_error("get_set_source_as_expr NYI for SetVarOp");
}
std::unique_ptr<Expr> SetVarOp::get_as_expr() const {
throw std::runtime_error("get_as_expr NYI for SetVarOp");
}
void SetVarOp::update_register_info() {
m_write_regs.push_back(m_dst.reg());
m_src.get_regs(&m_read_regs);
@@ -474,10 +462,6 @@ bool AsmOp::operator==(const AtomicOp& other) const {
(m_src[1] == po->m_src[1]) && (m_src[2] == po->m_src[2]);
}
bool AsmOp::is_variable_set() const {
return false;
}
bool AsmOp::is_sequence_point() const {
return true;
}
@@ -486,14 +470,6 @@ Variable AsmOp::get_set_destination() const {
throw std::runtime_error("AsmOp cannot be treated as a set! operation");
}
std::unique_ptr<Expr> AsmOp::get_set_source_as_expr() const {
throw std::runtime_error("AsmOp cannot be treated as a set! operation");
}
std::unique_ptr<Expr> AsmOp::get_as_expr() const {
throw std::runtime_error("AsmOp::get_as_expr is not implemented.");
}
void AsmOp::update_register_info() {
if (m_dst.has_value()) {
m_write_regs.push_back(m_dst->reg());
@@ -510,7 +486,6 @@ void AsmOp::update_register_info() {
// Condition
/////////////////////////////
namespace {
std::string get_condition_kind_name(IR2_Condition::Kind kind) {
switch (kind) {
case IR2_Condition::Kind::NOT_EQUAL:
@@ -694,7 +669,6 @@ IR2_Condition::Kind get_condition_opposite(IR2_Condition::Kind kind) {
assert(false);
}
}
} // namespace
IR2_Condition::IR2_Condition(Kind kind) : m_kind(kind) {
assert(get_condition_num_args(m_kind) == 0);
@@ -774,10 +748,6 @@ bool SetVarConditionOp::operator==(const AtomicOp& other) const {
return m_dst == po->m_dst && m_condition == po->m_condition;
}
bool SetVarConditionOp::is_variable_set() const {
return true;
}
bool SetVarConditionOp::is_sequence_point() const {
return true;
}
@@ -786,14 +756,6 @@ Variable SetVarConditionOp::get_set_destination() const {
return m_dst;
}
std::unique_ptr<Expr> SetVarConditionOp::get_set_source_as_expr() const {
throw std::runtime_error("SetVarConditionOp::get_source_as_expr is not yet implemented.");
}
std::unique_ptr<Expr> SetVarConditionOp::get_as_expr() const {
throw std::runtime_error("SetVarConditionOp::get_as_expr is not yet implemented.");
}
void SetVarConditionOp::update_register_info() {
m_write_regs.push_back(m_dst.reg());
m_condition.get_regs(&m_read_regs);
@@ -849,10 +811,6 @@ bool StoreOp::operator==(const AtomicOp& other) const {
return m_addr == po->m_addr && m_value == po->m_value;
}
bool StoreOp::is_variable_set() const {
return false;
}
bool StoreOp::is_sequence_point() const {
return true;
}
@@ -861,14 +819,6 @@ Variable StoreOp::get_set_destination() const {
throw std::runtime_error("StoreOp cannot be treated as a set! operation");
}
std::unique_ptr<Expr> StoreOp::get_set_source_as_expr() const {
throw std::runtime_error("StoreOp cannot be treated as a set! operation");
}
std::unique_ptr<Expr> StoreOp::get_as_expr() const {
throw std::runtime_error("StoreOp::get_as_expr is not yet implemented");
}
void StoreOp::update_register_info() {
m_addr.get_regs(&m_read_regs);
m_value.get_regs(&m_read_regs);
@@ -939,10 +889,6 @@ bool LoadVarOp::operator==(const AtomicOp& other) const {
return m_dst == po->m_dst && m_src == po->m_src;
}
bool LoadVarOp::is_variable_set() const {
return true;
}
bool LoadVarOp::is_sequence_point() const {
return true;
}
@@ -951,14 +897,6 @@ Variable LoadVarOp::get_set_destination() const {
return m_dst;
}
std::unique_ptr<Expr> LoadVarOp::get_set_source_as_expr() const {
throw std::runtime_error("LoadVarOp::get_set_source_as_expr is not yet implemented");
}
std::unique_ptr<Expr> LoadVarOp::get_as_expr() const {
throw std::runtime_error("LoadVarOp::get_as_expr is not yet implemented");
}
void LoadVarOp::update_register_info() {
m_src.get_regs(&m_read_regs);
m_write_regs.push_back(m_dst.reg());
@@ -1113,10 +1051,6 @@ bool BranchOp::operator==(const AtomicOp& other) const {
m_branch_delay == po->m_branch_delay;
}
bool BranchOp::is_variable_set() const {
return false;
}
bool BranchOp::is_sequence_point() const {
return true;
}
@@ -1125,14 +1059,6 @@ Variable BranchOp::get_set_destination() const {
throw std::runtime_error("BranchOp cannot be treated as a set! operation");
}
std::unique_ptr<Expr> BranchOp::get_set_source_as_expr() const {
throw std::runtime_error("BranchOp cannot be treated as a set! operation");
}
std::unique_ptr<Expr> BranchOp::get_as_expr() const {
throw std::runtime_error("BranchOp::get_as_expr is not yet implemented");
}
void BranchOp::update_register_info() {
m_condition.get_regs(&m_read_regs);
m_branch_delay.get_regs(&m_write_regs, &m_read_regs);
@@ -1172,10 +1098,6 @@ bool SpecialOp::operator==(const AtomicOp& other) const {
return m_kind == po->m_kind;
}
bool SpecialOp::is_variable_set() const {
return false;
}
bool SpecialOp::is_sequence_point() const {
return true;
}
@@ -1184,14 +1106,6 @@ Variable SpecialOp::get_set_destination() const {
throw std::runtime_error("SpecialOp cannot be treated as a set! operation");
}
std::unique_ptr<Expr> SpecialOp::get_set_source_as_expr() const {
throw std::runtime_error("SpecialOp cannot be treated as a set! operation");
}
std::unique_ptr<Expr> SpecialOp::get_as_expr() const {
throw std::runtime_error("SpecialOp::get_as_expr not yet implemented");
}
void SpecialOp::update_register_info() {
switch (m_kind) {
case Kind::NOP:
@@ -1232,10 +1146,6 @@ bool CallOp::operator==(const AtomicOp& other) const {
return true;
}
bool CallOp::is_variable_set() const {
return false;
}
bool CallOp::is_sequence_point() const {
return true;
}
@@ -1244,17 +1154,13 @@ Variable CallOp::get_set_destination() const {
throw std::runtime_error("CallOp cannot be treated as a set! operation");
}
std::unique_ptr<Expr> CallOp::get_set_source_as_expr() const {
throw std::runtime_error("CallOp cannot be treated as a set! operation");
}
std::unique_ptr<Expr> CallOp::get_as_expr() const {
throw std::runtime_error("CallOp::get_as_expr not yet implemented");
}
void CallOp::update_register_info() {
// throw std::runtime_error("CallOp::update_register_info cannot be done until types are known");
m_read_regs.push_back(Register(Reg::GPR, Reg::T9));
// if the type analysis succeeds, it will remove this if the function doesn't return a value.
// but, in the case we want to keep running without type information, we may need a
// renamed variable here, so we add this.
m_write_regs.push_back(Register(Reg::GPR, Reg::V0));
clobber_temps();
}
@@ -1282,10 +1188,6 @@ bool ConditionalMoveFalseOp::operator==(const AtomicOp& other) const {
return m_dst == po->m_dst && m_src == po->m_src && m_on_zero == po->m_on_zero;
}
bool ConditionalMoveFalseOp::is_variable_set() const {
return false;
}
bool ConditionalMoveFalseOp::is_sequence_point() const {
return true;
}
@@ -1294,14 +1196,6 @@ Variable ConditionalMoveFalseOp::get_set_destination() const {
throw std::runtime_error("ConditionalMoveFalseOp cannot be treated as a set! operation");
}
std::unique_ptr<Expr> ConditionalMoveFalseOp::get_set_source_as_expr() const {
throw std::runtime_error("ConditionalMoveFalseOp cannot be treated as a set! operation");
}
std::unique_ptr<Expr> ConditionalMoveFalseOp::get_as_expr() const {
throw std::runtime_error("ConditionalMoveFalseOp::get_as_expr is not yet implemented");
}
void ConditionalMoveFalseOp::update_register_info() {
m_write_regs.push_back(m_dst.reg());
m_read_regs.push_back(m_src.reg());