Skip to content

Commit

Permalink
[decompiler] Detect vector*! (#3846)
Browse files Browse the repository at this point in the history
Detect use of `vector*!`, which is inlined in jak 2 and jak 3.

---------

Co-authored-by: water111 <[email protected]>
  • Loading branch information
water111 and water111 authored Jan 20, 2025
1 parent 3ee2b44 commit 98d6618
Show file tree
Hide file tree
Showing 37 changed files with 2,339 additions and 3,075 deletions.
3 changes: 3 additions & 0 deletions decompiler/IR2/AtomicOp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions decompiler/IR2/AtomicOp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions decompiler/IR2/AtomicOpTypeAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
2 changes: 2 additions & 0 deletions decompiler/IR2/Form.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
4 changes: 4 additions & 0 deletions decompiler/IR2/FormExpressionAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions decompiler/IR2/IR2_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
61 changes: 61 additions & 0 deletions decompiler/analysis/atomic_op_builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down
10 changes: 2 additions & 8 deletions decompiler/config/jak3/ntsc_v1/type_casts.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -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)": [
Expand Down
12 changes: 12 additions & 0 deletions decompiler/config/jak3/ntsc_v1/var_names.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
},
Expand Down
1 change: 1 addition & 0 deletions decompiler/types2/ForwardProp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
Loading

0 comments on commit 98d6618

Please sign in to comment.