mirror of
https://github.com/open-goal/jak-project
synced 2026-08-16 13:17:34 -04:00
[Decompiler] Remove most IR1 Analysis (#207)
* temp * remove some of ir1
This commit is contained in:
@@ -49,64 +49,6 @@ void add_regs_to_str(const T& regs, std::string& str) {
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::string IR_Atomic::print_with_reguse(const LinkedObjectFile& file) const {
|
||||
std::string result = print(file);
|
||||
if (result.length() < 40) {
|
||||
result.append(40 - result.length(), ' ');
|
||||
}
|
||||
result += " ;;";
|
||||
if (!write_regs.empty()) {
|
||||
result += "write: [";
|
||||
add_regs_to_str(write_regs, result);
|
||||
result += "] ";
|
||||
}
|
||||
if (!read_regs.empty()) {
|
||||
result += "read: [";
|
||||
add_regs_to_str(read_regs, result);
|
||||
result += "] ";
|
||||
}
|
||||
if (!clobber_regs.empty()) {
|
||||
result += "clobber: [";
|
||||
add_regs_to_str(clobber_regs, result);
|
||||
result += "] ";
|
||||
}
|
||||
if (!consumed.empty()) {
|
||||
result += "consumed: [";
|
||||
add_regs_to_str(consumed, result);
|
||||
result += "] ";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string IR_Atomic::print_with_types(const TypeState& init_types,
|
||||
const LinkedObjectFile& file) const {
|
||||
std::string result;
|
||||
|
||||
for (auto& warning : warnings) {
|
||||
result += ";; warn: " + warning + "\n";
|
||||
}
|
||||
result += print(file);
|
||||
if (result.length() < 40) {
|
||||
result.append(40 - result.length(), ' ');
|
||||
}
|
||||
result += " ;; ";
|
||||
|
||||
auto read_mask = regs_to_gpr_mask(read_regs);
|
||||
auto write_mask = regs_to_gpr_mask(write_regs);
|
||||
|
||||
result += fmt::format("[{}] -> [{}]", init_types.print_gpr_masked(read_mask),
|
||||
end_types.print_gpr_masked(write_mask));
|
||||
|
||||
if (!consumed.empty()) {
|
||||
result += "c:";
|
||||
for (auto x : consumed) {
|
||||
result += " ";
|
||||
result += x.to_charp();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
goos::Object IR_Failed::to_form(const LinkedObjectFile& file) const {
|
||||
(void)file;
|
||||
return pretty_print::build_list("INVALID-OPERATION");
|
||||
@@ -996,189 +938,6 @@ void IR_Breakpoint_Atomic::get_children(std::vector<std::shared_ptr<IR>>* output
|
||||
(void)output;
|
||||
}
|
||||
|
||||
goos::Object IR_Begin::to_form(const LinkedObjectFile& file) const {
|
||||
if (forms.size() == 1 && inline_single_begins) {
|
||||
return forms.front()->to_form(file);
|
||||
}
|
||||
std::vector<goos::Object> list;
|
||||
list.push_back(pretty_print::to_symbol("begin"));
|
||||
for (auto& x : forms) {
|
||||
list.push_back(x->to_form(file));
|
||||
}
|
||||
return pretty_print::build_list(list);
|
||||
}
|
||||
|
||||
void IR_Begin::get_children(std::vector<std::shared_ptr<IR>>* output) const {
|
||||
for (auto& x : forms) {
|
||||
output->push_back(x);
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
void print_inlining_begin(std::vector<goos::Object>* output, IR* ir, const LinkedObjectFile& file) {
|
||||
auto as_begin = dynamic_cast<IR_Begin*>(ir);
|
||||
if (as_begin) {
|
||||
for (auto& x : as_begin->forms) {
|
||||
output->push_back(x->to_form(file));
|
||||
}
|
||||
} else {
|
||||
output->push_back(ir->to_form(file));
|
||||
}
|
||||
}
|
||||
|
||||
bool is_single_expression(IR* in) {
|
||||
return !dynamic_cast<IR_Begin*>(in);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
goos::Object IR_WhileLoop::to_form(const LinkedObjectFile& file) const {
|
||||
std::vector<goos::Object> list;
|
||||
list.push_back(pretty_print::to_symbol("while"));
|
||||
list.push_back(condition->to_form(file));
|
||||
print_inlining_begin(&list, body.get(), file);
|
||||
return pretty_print::build_list(list);
|
||||
}
|
||||
|
||||
void IR_WhileLoop::get_children(std::vector<std::shared_ptr<IR>>* output) const {
|
||||
output->push_back(condition);
|
||||
output->push_back(body);
|
||||
}
|
||||
|
||||
goos::Object IR_UntilLoop::to_form(const LinkedObjectFile& file) const {
|
||||
std::vector<goos::Object> list;
|
||||
list.push_back(pretty_print::to_symbol("until"));
|
||||
list.push_back(condition->to_form(file));
|
||||
print_inlining_begin(&list, body.get(), file);
|
||||
return pretty_print::build_list(list);
|
||||
}
|
||||
|
||||
void IR_UntilLoop::get_children(std::vector<std::shared_ptr<IR>>* output) const {
|
||||
output->push_back(condition);
|
||||
output->push_back(body);
|
||||
}
|
||||
|
||||
goos::Object IR_CondWithElse::to_form(const LinkedObjectFile& file) const {
|
||||
// for now we only turn it into an if statement if both cases won't require a begin at the top
|
||||
// level. I think it is more common to write these as a two-case cond instead of an if with begin.
|
||||
if (entries.size() == 1 && is_single_expression(entries.front().body.get()) &&
|
||||
is_single_expression(else_ir.get())) {
|
||||
std::vector<goos::Object> list;
|
||||
list.push_back(pretty_print::to_symbol("if"));
|
||||
list.push_back(entries.front().condition->to_form(file));
|
||||
list.push_back(entries.front().body->to_form(file));
|
||||
list.push_back(else_ir->to_form(file));
|
||||
return pretty_print::build_list(list);
|
||||
} else {
|
||||
std::vector<goos::Object> list;
|
||||
list.push_back(pretty_print::to_symbol("cond"));
|
||||
for (auto& e : entries) {
|
||||
std::vector<goos::Object> entry;
|
||||
entry.push_back(e.condition->to_form(file));
|
||||
print_inlining_begin(&entry, e.body.get(), file);
|
||||
list.push_back(pretty_print::build_list(entry));
|
||||
}
|
||||
std::vector<goos::Object> else_form;
|
||||
else_form.push_back(pretty_print::to_symbol("else"));
|
||||
print_inlining_begin(&else_form, else_ir.get(), file);
|
||||
list.push_back(pretty_print::build_list(else_form));
|
||||
return pretty_print::build_list(list);
|
||||
}
|
||||
}
|
||||
|
||||
void IR_CondWithElse::get_children(std::vector<std::shared_ptr<IR>>* output) const {
|
||||
for (auto& e : entries) {
|
||||
output->push_back(e.condition);
|
||||
output->push_back(e.body);
|
||||
}
|
||||
output->push_back(else_ir);
|
||||
}
|
||||
|
||||
goos::Object IR_GetRuntimeType::to_form(const LinkedObjectFile& file) const {
|
||||
std::vector<goos::Object> list = {pretty_print::to_symbol("type-of"), object->to_form(file)};
|
||||
return pretty_print::build_list(list);
|
||||
}
|
||||
|
||||
void IR_GetRuntimeType::get_children(std::vector<std::shared_ptr<IR>>* output) const {
|
||||
output->push_back(object);
|
||||
}
|
||||
|
||||
goos::Object IR_Cond::to_form(const LinkedObjectFile& file) const {
|
||||
if (entries.size() == 1 && is_single_expression(entries.front().body.get())) {
|
||||
// print as an if statement if we can put the body in a single form.
|
||||
std::vector<goos::Object> list;
|
||||
list.push_back(pretty_print::to_symbol("if"));
|
||||
list.push_back(entries.front().condition->to_form(file));
|
||||
list.push_back(entries.front().body->to_form(file));
|
||||
return pretty_print::build_list(list);
|
||||
} else if (entries.size() == 1) {
|
||||
// turn into a when if the body requires multiple forms
|
||||
// todo check to see if the condition starts with a NOT and this can be simplified to an
|
||||
// unless.
|
||||
std::vector<goos::Object> list;
|
||||
list.push_back(pretty_print::to_symbol("when"));
|
||||
list.push_back(entries.front().condition->to_form(file));
|
||||
print_inlining_begin(&list, entries.front().body.get(), file);
|
||||
return pretty_print::build_list(list);
|
||||
} else {
|
||||
std::vector<goos::Object> list;
|
||||
list.push_back(pretty_print::to_symbol("cond"));
|
||||
for (auto& e : entries) {
|
||||
std::vector<goos::Object> entry;
|
||||
entry.push_back(e.condition->to_form(file));
|
||||
print_inlining_begin(&entry, e.body.get(), file);
|
||||
list.push_back(pretty_print::build_list(entry));
|
||||
}
|
||||
return pretty_print::build_list(list);
|
||||
}
|
||||
}
|
||||
|
||||
void IR_Cond::get_children(std::vector<std::shared_ptr<IR>>* output) const {
|
||||
for (auto& e : entries) {
|
||||
output->push_back(e.condition);
|
||||
output->push_back(e.body);
|
||||
}
|
||||
}
|
||||
|
||||
goos::Object IR_ShortCircuit::to_form(const LinkedObjectFile& file) const {
|
||||
std::vector<goos::Object> forms;
|
||||
switch (kind) {
|
||||
case UNKNOWN:
|
||||
forms.push_back(pretty_print::to_symbol("unknown-sc"));
|
||||
break;
|
||||
case AND:
|
||||
forms.push_back(pretty_print::to_symbol("and"));
|
||||
break;
|
||||
case OR:
|
||||
forms.push_back(pretty_print::to_symbol("or"));
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
for (auto& x : entries) {
|
||||
forms.push_back(x.condition->to_form(file));
|
||||
}
|
||||
return pretty_print::build_list(forms);
|
||||
}
|
||||
|
||||
void IR_ShortCircuit::get_children(std::vector<std::shared_ptr<IR>>* output) const {
|
||||
for (auto& x : entries) {
|
||||
output->push_back(x.condition);
|
||||
if (x.output) {
|
||||
output->push_back(x.output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
goos::Object IR_Ash::to_form(const LinkedObjectFile& file) const {
|
||||
return pretty_print::build_list(pretty_print::to_symbol(is_signed ? "ash.si" : "ash.ui"),
|
||||
value->to_form(file), shift_amount->to_form(file));
|
||||
}
|
||||
|
||||
void IR_Ash::get_children(std::vector<std::shared_ptr<IR>>* output) const {
|
||||
output->push_back(value);
|
||||
output->push_back(shift_amount);
|
||||
}
|
||||
|
||||
goos::Object IR_AsmOp::to_form(const LinkedObjectFile& file) const {
|
||||
std::vector<goos::Object> forms;
|
||||
forms.push_back(pretty_print::to_symbol(name));
|
||||
@@ -1240,29 +999,4 @@ void IR_AsmReg::get_children(std::vector<std::shared_ptr<IR>>* output) const {
|
||||
(void)output;
|
||||
}
|
||||
|
||||
goos::Object IR_Return::to_form(const LinkedObjectFile& file) const {
|
||||
std::vector<goos::Object> forms;
|
||||
forms.push_back(pretty_print::to_symbol("return"));
|
||||
forms.push_back(pretty_print::build_list(return_code->to_form(file)));
|
||||
forms.push_back(pretty_print::build_list(dead_code->to_form(file)));
|
||||
return pretty_print::build_list(forms);
|
||||
}
|
||||
|
||||
void IR_Return::get_children(std::vector<std::shared_ptr<IR>>* output) const {
|
||||
output->push_back(return_code);
|
||||
output->push_back(dead_code);
|
||||
}
|
||||
|
||||
goos::Object IR_Break::to_form(const LinkedObjectFile& file) const {
|
||||
std::vector<goos::Object> forms;
|
||||
forms.push_back(pretty_print::to_symbol("break")); // todo break destination...
|
||||
forms.push_back(pretty_print::build_list(return_code->to_form(file)));
|
||||
forms.push_back(pretty_print::build_list(dead_code->to_form(file)));
|
||||
return pretty_print::build_list(forms);
|
||||
}
|
||||
|
||||
void IR_Break::get_children(std::vector<std::shared_ptr<IR>>* output) const {
|
||||
output->push_back(return_code);
|
||||
output->push_back(dead_code);
|
||||
}
|
||||
} // namespace decompiler
|
||||
Reference in New Issue
Block a user