[decompiler] support for jak 2 (#1781)

* [decompiler] suppport jak 2

* cleanpu

* remove brief from gtest options

* fix test
This commit is contained in:
water111
2022-08-22 18:53:51 -04:00
committed by GitHub
parent 5af36ac610
commit 06ef52cd25
51 changed files with 9934 additions and 4555 deletions
+48 -22
View File
@@ -1504,24 +1504,28 @@ void SimpleExpressionElement::update_from_stack_vector_float_product(
result->push_back(new_form);
}
void SimpleExpressionElement::update_from_stack_vector_dot(FixedOperatorKind kind,
const Env& env,
FormPool& pool,
FormStack& stack,
std::vector<FormElement*>* result,
bool allow_side_effects) {
std::vector<Form*> popped_args = pop_to_forms({m_expr.get_arg(0).var(), m_expr.get_arg(1).var()},
env, pool, stack, allow_side_effects);
void SimpleExpressionElement::update_from_stack_vectors_in_common(FixedOperatorKind kind,
const Env& env,
FormPool& pool,
FormStack& stack,
std::vector<FormElement*>* result,
bool allow_side_effects) {
std::vector<RegisterAccess> register_acccesses;
for (int arg_idx = 0; arg_idx < m_expr.args(); arg_idx++) {
register_acccesses.push_back(m_expr.get_arg(arg_idx).var());
}
std::vector<Form*> popped_args =
pop_to_forms(register_acccesses, env, pool, stack, allow_side_effects);
for (int i = 0; i < 2; i++) {
for (int i = 0; i < m_expr.args(); i++) {
auto arg_type = env.get_types_before_op(m_my_idx).get(m_expr.get_arg(i).var().reg());
if (arg_type.typespec() != TypeSpec("vector")) {
popped_args.at(i) = cast_form(popped_args.at(i), TypeSpec("vector"), pool, env);
}
}
auto new_form = pool.alloc_element<GenericElement>(
GenericOperator::make_fixed(kind), std::vector<Form*>{popped_args.at(0), popped_args.at(1)});
auto new_form =
pool.alloc_element<GenericElement>(GenericOperator::make_fixed(kind), popped_args);
result->push_back(new_form);
}
@@ -1606,7 +1610,14 @@ FormElement* SimpleExpressionElement::update_from_stack_logor_or_logand_helper(
FormStack& stack,
bool allow_side_effects) {
// grab the normal variable type
auto arg0_type = env.get_variable_type(m_expr.get_arg(0).var(), true);
TypeSpec arg0_type;
if (m_expr.get_arg(0).is_var()) {
arg0_type = env.get_variable_type(m_expr.get_arg(0).var(), true);
} else if (m_expr.get_arg(0).is_int(0)) {
arg0_type = TypeSpec("int"); // ??
} else {
ASSERT(false);
}
// and try to get it as a bitfield
auto type_info = env.dts->ts.lookup_type(arg0_type);
@@ -1614,7 +1625,7 @@ FormElement* SimpleExpressionElement::update_from_stack_logor_or_logand_helper(
bool had_pcpyud = false;
TypeSpec bitfield_type = arg0_type;
if (!bitfield_info) {
if (!bitfield_info && m_expr.get_arg(0).is_var()) {
// the above won't work if we're already done a pcpyud to grab the upper 64 bits.
// we need to grab the type in the register (a TP_type) and check
const auto& arg0_reg_type =
@@ -1672,15 +1683,25 @@ FormElement* SimpleExpressionElement::update_from_stack_logor_or_logand_helper(
} else {
// and, two forms
auto arg1_type = env.get_variable_type(m_expr.get_arg(1).var(), true);
auto arg0_i = is_int_type(env, m_my_idx, m_expr.get_arg(0).var());
auto arg0_u = is_uint_type(env, m_my_idx, m_expr.get_arg(0).var());
auto arg0_i =
m_expr.get_arg(0).is_var() ? is_int_type(env, m_my_idx, m_expr.get_arg(0).var()) : true;
auto arg0_u =
m_expr.get_arg(0).is_var() ? is_uint_type(env, m_my_idx, m_expr.get_arg(0).var()) : false;
auto arg1_i = is_int_type(env, m_my_idx, m_expr.get_arg(1).var());
auto arg1_u = is_uint_type(env, m_my_idx, m_expr.get_arg(1).var());
auto arg0_n = arg0_i || arg0_u;
auto arg1_n = arg1_i || arg1_u;
auto args = pop_to_forms({m_expr.get_arg(0).var(), m_expr.get_arg(1).var()}, env, pool, stack,
allow_side_effects);
std::vector<Form*> args;
if (m_expr.get_arg(0).is_var()) {
args = pop_to_forms({m_expr.get_arg(0).var(), m_expr.get_arg(1).var()}, env, pool, stack,
allow_side_effects);
} else {
args = pop_to_forms({m_expr.get_arg(1).var()}, env, pool, stack, allow_side_effects);
args.insert(args.begin(), pool.form<SimpleAtomElement>(
SimpleAtom::make_int_constant(m_expr.get_arg(0).get_int())));
}
if (bitfield_info) {
// either the immediate didn't fit in the 16-bit imm or it's with a variable
@@ -2318,12 +2339,16 @@ void SimpleExpressionElement::update_from_stack(const Env& env,
update_from_stack_subu_l32_s7(env, pool, stack, result, allow_side_effects);
break;
case SimpleExpression::Kind::VECTOR_3_DOT:
update_from_stack_vector_dot(FixedOperatorKind::VECTOR_3_DOT, env, pool, stack, result,
allow_side_effects);
update_from_stack_vectors_in_common(FixedOperatorKind::VECTOR_3_DOT, env, pool, stack, result,
allow_side_effects);
break;
case SimpleExpression::Kind::VECTOR_4_DOT:
update_from_stack_vector_dot(FixedOperatorKind::VECTOR_4_DOT, env, pool, stack, result,
allow_side_effects);
update_from_stack_vectors_in_common(FixedOperatorKind::VECTOR_4_DOT, env, pool, stack, result,
allow_side_effects);
break;
case SimpleExpression::Kind::VECTOR_LENGTH:
update_from_stack_vectors_in_common(FixedOperatorKind::VECTOR_LENGTH, env, pool, stack,
result, allow_side_effects);
break;
default:
throw std::runtime_error(
@@ -2701,7 +2726,8 @@ bool try_to_rewrite_matrix_inline_ctor(const Env& env, FormPool& pool, FormStack
} else {
matcher = Matcher::set(
Matcher::deref(Matcher::any_reg(0), false,
{DerefTokenMatcher::string("quad"), DerefTokenMatcher::integer(i)}),
{DerefTokenMatcher::string("vector"), DerefTokenMatcher::integer(i),
DerefTokenMatcher::string("quad")}),
Matcher::cast("uint128", Matcher::integer(0)));
}