mirror of
https://github.com/open-goal/jak-project
synced 2026-07-11 07:25:37 -04:00
[decompiler] Detect vector*! (#3846)
Detect use of `vector*!`, which is inlined in jak 2 and jak 3. --------- Co-authored-by: water111 <awaterford1111445@gmail.com>
This commit is contained in:
@@ -353,6 +353,8 @@ std::string get_simple_expression_op_name(SimpleExpression::Kind kind) {
|
||||
return "pcypld";
|
||||
case SimpleExpression::Kind::VECTOR_PLUS:
|
||||
return "vector+!2";
|
||||
case SimpleExpression::Kind::VECTOR_XYZ_PRODUCT:
|
||||
return "vector-xyz-product!";
|
||||
case SimpleExpression::Kind::VECTOR_MINUS:
|
||||
return "vector-!2";
|
||||
case SimpleExpression::Kind::VECTOR_FLOAT_PRODUCT:
|
||||
@@ -427,6 +429,7 @@ int get_simple_expression_arg_count(SimpleExpression::Kind kind) {
|
||||
case SimpleExpression::Kind::VECTOR_MINUS:
|
||||
case SimpleExpression::Kind::VECTOR_FLOAT_PRODUCT:
|
||||
case SimpleExpression::Kind::VECTOR_CROSS:
|
||||
case SimpleExpression::Kind::VECTOR_XYZ_PRODUCT:
|
||||
return 3;
|
||||
case SimpleExpression::Kind::SUBU_L32_S7:
|
||||
return 1;
|
||||
|
||||
@@ -256,6 +256,7 @@ class SimpleExpression {
|
||||
VECTOR_PLUS,
|
||||
VECTOR_MINUS,
|
||||
VECTOR_FLOAT_PRODUCT,
|
||||
VECTOR_XYZ_PRODUCT, // vector*!, elementwise xyz, jak3 only
|
||||
VECTOR_CROSS,
|
||||
SUBU_L32_S7, // use SUBU X, src0, s7 to check if lower 32-bits are s7.
|
||||
VECTOR_3_DOT,
|
||||
|
||||
@@ -238,6 +238,7 @@ TP_Type SimpleExpression::get_type(const TypeState& input,
|
||||
case Kind::VECTOR_PLUS:
|
||||
case Kind::VECTOR_MINUS:
|
||||
case Kind::VECTOR_CROSS:
|
||||
case Kind::VECTOR_XYZ_PRODUCT:
|
||||
return TP_Type::make_from_ts("vector");
|
||||
case Kind::VECTOR_FLOAT_PRODUCT:
|
||||
return TP_Type::make_from_ts("vector");
|
||||
|
||||
@@ -1858,6 +1858,8 @@ std::string fixed_operator_to_string(FixedOperatorKind kind) {
|
||||
return "vector-!";
|
||||
case FixedOperatorKind::VECTOR_PLUS:
|
||||
return "vector+!";
|
||||
case FixedOperatorKind::VECTOR_XYZ_PRODUCT:
|
||||
return "vector*!";
|
||||
case FixedOperatorKind::VECTOR_CROSS:
|
||||
return "vector-cross!";
|
||||
case FixedOperatorKind::VECTOR_FLOAT_PRODUCT:
|
||||
|
||||
@@ -2527,6 +2527,10 @@ void SimpleExpressionElement::update_from_stack(const Env& env,
|
||||
update_from_stack_vector_plus_minus_cross(FixedOperatorKind::VECTOR_CROSS, env, pool, stack,
|
||||
result, allow_side_effects);
|
||||
break;
|
||||
case SimpleExpression::Kind::VECTOR_XYZ_PRODUCT:
|
||||
update_from_stack_vector_plus_minus_cross(FixedOperatorKind::VECTOR_XYZ_PRODUCT, env, pool,
|
||||
stack, result, allow_side_effects);
|
||||
break;
|
||||
case SimpleExpression::Kind::VECTOR_FLOAT_PRODUCT:
|
||||
update_from_stack_vector_float_product(env, pool, stack, result, allow_side_effects);
|
||||
break;
|
||||
|
||||
@@ -162,6 +162,7 @@ enum class FixedOperatorKind {
|
||||
VECTOR_MINUS,
|
||||
VECTOR_CROSS,
|
||||
VECTOR_FLOAT_PRODUCT,
|
||||
VECTOR_XYZ_PRODUCT,
|
||||
L32_NOT_FALSE_CBOOL,
|
||||
VECTOR_3_DOT,
|
||||
PROCESS_TO_PPOINTER,
|
||||
|
||||
@@ -1689,6 +1689,62 @@ std::unique_ptr<AtomicOp> convert_vector_plus(const Instruction& i0,
|
||||
idx);
|
||||
}
|
||||
|
||||
std::unique_ptr<AtomicOp> convert_vector_xyz_product(const Instruction& i0,
|
||||
const Instruction& i1,
|
||||
const Instruction& i2,
|
||||
const Instruction& i3,
|
||||
const Instruction& i4,
|
||||
int idx) {
|
||||
/*
|
||||
lqc2 vf4, 0(a1)
|
||||
lqc2 vf5, 0(a2)
|
||||
vaddx.w vf6, vf0, vf0
|
||||
vmul.xyz vf6, vf4, vf5
|
||||
sqc2 vf6, 0(a0)
|
||||
*/
|
||||
|
||||
// lqc2 vf4, 0(a1) (src1)
|
||||
if (i0.kind != InstructionKind::LQC2 || i0.get_dst(0).get_reg() != make_vf(4) ||
|
||||
!i0.get_src(0).is_imm(0)) {
|
||||
return nullptr;
|
||||
}
|
||||
Register src1 = i0.get_src(1).get_reg();
|
||||
|
||||
// lqc2 vf5, 0(a2) (src2)
|
||||
if (i1.kind != InstructionKind::LQC2 || i1.get_dst(0).get_reg() != make_vf(5) ||
|
||||
!i1.get_src(0).is_imm(0)) {
|
||||
return nullptr;
|
||||
}
|
||||
Register src2 = i1.get_src(1).get_reg();
|
||||
|
||||
// vaddx.w vf6, vf0, vf0
|
||||
if (i2.kind != InstructionKind::VADD_BC || i2.get_dst(0).get_reg() != make_vf(6) ||
|
||||
i2.get_src(0).get_reg() != make_vf(0) || i2.get_src(1).get_reg() != make_vf(0) ||
|
||||
i2.cop2_dest != 1 || i2.cop2_bc != 0) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// vmul.xyz vf6, vf4, vf5
|
||||
if (i3.kind != InstructionKind::VMUL || i3.get_dst(0).get_reg() != make_vf(6) ||
|
||||
i3.get_src(0).get_reg() != make_vf(4) || i3.get_src(1).get_reg() != make_vf(5) ||
|
||||
i3.cop2_dest != 14) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// sqc2 vf6, 0(a0) (dst)
|
||||
if (i4.kind != InstructionKind::SQC2 || i4.get_src(0).get_reg() != make_vf(6) ||
|
||||
!i4.get_src(1).is_imm(0)) {
|
||||
return nullptr;
|
||||
}
|
||||
Register dst = i4.get_src(2).get_reg();
|
||||
|
||||
return std::make_unique<SetVarOp>(
|
||||
make_dst_var(dst, idx),
|
||||
SimpleExpression(SimpleExpression::Kind::VECTOR_XYZ_PRODUCT, make_src_atom(dst, idx),
|
||||
make_src_atom(src1, idx), make_src_atom(src2, idx)),
|
||||
idx);
|
||||
}
|
||||
|
||||
std::unique_ptr<AtomicOp> convert_vector_minus(const Instruction& i0,
|
||||
const Instruction& i1,
|
||||
const Instruction& i2,
|
||||
@@ -1819,6 +1875,11 @@ std::unique_ptr<AtomicOp> convert_5(const Instruction& i0,
|
||||
return as_vector_plus;
|
||||
}
|
||||
|
||||
auto as_vector_xyz = convert_vector_xyz_product(i0, i1, i2, i3, i4, idx);
|
||||
if (as_vector_xyz) {
|
||||
return as_vector_xyz;
|
||||
}
|
||||
|
||||
auto as_vector_minus = convert_vector_minus(i0, i1, i2, i3, i4, idx);
|
||||
if (as_vector_minus) {
|
||||
return as_vector_minus;
|
||||
|
||||
@@ -4918,14 +4918,8 @@
|
||||
[96, "s5", "collide-shape-moving"]
|
||||
],
|
||||
"(anon-function 74 target-flut)": [
|
||||
[6, "gp", "target"],
|
||||
[10, "gp", "target"],
|
||||
[16, "gp", "target"],
|
||||
[24, "gp", "target"],
|
||||
[33, "gp", "target"],
|
||||
[42, "a0", "target"],
|
||||
[49, "gp", "target"],
|
||||
[56, "gp", "target"]
|
||||
[[0, 56], "gp", "target"],
|
||||
[42, "a0", "target"]
|
||||
],
|
||||
"(anon-function 21 target-flut)": [[58, "v1", "art-joint-anim"]],
|
||||
"(code target-flut-death)": [
|
||||
|
||||
@@ -173,6 +173,18 @@
|
||||
"(method 9 process-tree)": {
|
||||
"args": ["this", "active-tree", "name", "stack-pointer"]
|
||||
},
|
||||
"(method 9 align-control)": {
|
||||
"vars": {
|
||||
"s5-0":"num-chans",
|
||||
"s4-0":"chan-idx",
|
||||
"a0-4":"chan",
|
||||
"v1-7":"frame-group",
|
||||
"a0-9":"root-chan",
|
||||
"v1-18":"root-frame-group",
|
||||
"f0-0":"root-frame-num",
|
||||
"a0-10":"disable?"
|
||||
}
|
||||
},
|
||||
"(method 9 process)": {
|
||||
"args": ["this", "active-tree", "name", "stack-pointer"]
|
||||
},
|
||||
|
||||
@@ -1616,6 +1616,7 @@ void types2_for_expr(types2::Type& type_out,
|
||||
case SimpleExpression::Kind::VECTOR_CROSS:
|
||||
case SimpleExpression::Kind::VECTOR_MINUS:
|
||||
case SimpleExpression::Kind::VECTOR_PLUS:
|
||||
case SimpleExpression::Kind::VECTOR_XYZ_PRODUCT:
|
||||
types2_for_vector_in_and_out(type_out, expr, input_types, dts, extras);
|
||||
break;
|
||||
case SimpleExpression::Kind::VECTOR_FLOAT_PRODUCT:
|
||||
|
||||
Reference in New Issue
Block a user