mirror of
https://github.com/open-goal/jak-project
synced 2026-08-08 18:44:15 -04:00
[decompiler] support for jak 2 (#1781)
* [decompiler] suppport jak 2 * cleanpu * remove brief from gtest options * fix test
This commit is contained in:
@@ -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)));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user