mirror of
https://github.com/open-goal/jak-project.git
synced 2024-10-20 11:26:18 -04:00
support vector 4 (#803)
This commit is contained in:
parent
c74520398b
commit
b58d9ec65d
|
@ -304,6 +304,8 @@ std::string get_simple_expression_op_name(SimpleExpression::Kind kind) {
|
|||
return "subu-s7";
|
||||
case SimpleExpression::Kind::VECTOR_3_DOT:
|
||||
return "vec3dot";
|
||||
case SimpleExpression::Kind::VECTOR_4_DOT:
|
||||
return "vec4dot";
|
||||
default:
|
||||
assert(false);
|
||||
return {};
|
||||
|
@ -363,6 +365,7 @@ int get_simple_expression_arg_count(SimpleExpression::Kind kind) {
|
|||
case SimpleExpression::Kind::SUBU_L32_S7:
|
||||
return 1;
|
||||
case SimpleExpression::Kind::VECTOR_3_DOT:
|
||||
case SimpleExpression::Kind::VECTOR_4_DOT:
|
||||
return 2;
|
||||
default:
|
||||
assert(false);
|
||||
|
|
|
@ -235,6 +235,7 @@ class SimpleExpression {
|
|||
VECTOR_CROSS,
|
||||
SUBU_L32_S7, // use SUBU X, src0, s7 to check if lower 32-bits are s7.
|
||||
VECTOR_3_DOT,
|
||||
VECTOR_4_DOT
|
||||
};
|
||||
|
||||
// how many arguments?
|
||||
|
|
|
@ -228,6 +228,7 @@ TP_Type SimpleExpression::get_type(const TypeState& input,
|
|||
case Kind::SUBU_L32_S7:
|
||||
return TP_Type::make_from_ts("int");
|
||||
case Kind::VECTOR_3_DOT:
|
||||
case Kind::VECTOR_4_DOT:
|
||||
return TP_Type::make_from_ts("float");
|
||||
default:
|
||||
throw std::runtime_error("Simple expression cannot get_type: " +
|
||||
|
|
|
@ -1828,6 +1828,8 @@ std::string fixed_operator_to_string(FixedOperatorKind kind) {
|
|||
return "l32-false-check";
|
||||
case FixedOperatorKind::VECTOR_3_DOT:
|
||||
return "vector-dot";
|
||||
case FixedOperatorKind::VECTOR_4_DOT:
|
||||
return "vector4-dot";
|
||||
case FixedOperatorKind::PROCESS_TO_PPOINTER:
|
||||
return "process->ppointer";
|
||||
case FixedOperatorKind::PPOINTER_TO_HANDLE:
|
||||
|
|
|
@ -224,11 +224,12 @@ class SimpleExpressionElement : public FormElement {
|
|||
FormStack& stack,
|
||||
std::vector<FormElement*>* result,
|
||||
bool allow_side_effects);
|
||||
void update_from_stack_vector_3_dot(const Env& env,
|
||||
FormPool& pool,
|
||||
FormStack& stack,
|
||||
std::vector<FormElement*>* result,
|
||||
bool allow_side_effects);
|
||||
void update_from_stack_vector_dot(FixedOperatorKind kind,
|
||||
const Env& env,
|
||||
FormPool& pool,
|
||||
FormStack& stack,
|
||||
std::vector<FormElement*>* result,
|
||||
bool allow_side_effects);
|
||||
|
||||
const SimpleExpression& expr() const { return m_expr; }
|
||||
|
||||
|
|
|
@ -1321,11 +1321,12 @@ void SimpleExpressionElement::update_from_stack_vector_float_product(
|
|||
result->push_back(new_form);
|
||||
}
|
||||
|
||||
void SimpleExpressionElement::update_from_stack_vector_3_dot(const Env& env,
|
||||
FormPool& pool,
|
||||
FormStack& stack,
|
||||
std::vector<FormElement*>* result,
|
||||
bool allow_side_effects) {
|
||||
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);
|
||||
|
||||
|
@ -1337,8 +1338,7 @@ void SimpleExpressionElement::update_from_stack_vector_3_dot(const Env& env,
|
|||
}
|
||||
|
||||
auto new_form = pool.alloc_element<GenericElement>(
|
||||
GenericOperator::make_fixed(FixedOperatorKind::VECTOR_3_DOT),
|
||||
std::vector<Form*>{popped_args.at(0), popped_args.at(1)});
|
||||
GenericOperator::make_fixed(kind), std::vector<Form*>{popped_args.at(0), popped_args.at(1)});
|
||||
result->push_back(new_form);
|
||||
}
|
||||
|
||||
|
@ -2116,7 +2116,12 @@ 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_3_dot(env, pool, stack, result, allow_side_effects);
|
||||
update_from_stack_vector_dot(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);
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error(
|
||||
|
@ -4290,8 +4295,9 @@ void push_asm_srl_to_stack(const AsmOp* op,
|
|||
stack.push_value_to_reg(*dst, pool.alloc_single_form(nullptr, other), true,
|
||||
env.get_variable_type(*dst, true));
|
||||
} else {
|
||||
throw std::runtime_error(fmt::format("Got invalid bitfield manip for srl: {} type was {}",
|
||||
src_var->to_string(env), arg0_type.print()));
|
||||
throw std::runtime_error(
|
||||
fmt::format("Got invalid bitfield manip for srl at op {}: {} type was {}", op->op_id(),
|
||||
src_var->to_string(env), arg0_type.print()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -164,6 +164,7 @@ enum class FixedOperatorKind {
|
|||
PPOINTER_TO_HANDLE,
|
||||
PROCESS_TO_HANDLE,
|
||||
PPOINTER_TO_PROCESS,
|
||||
VECTOR_4_DOT,
|
||||
INVALID
|
||||
};
|
||||
|
||||
|
|
|
@ -1888,6 +1888,110 @@ std::unique_ptr<AtomicOp> convert_vector3_dot(const Instruction* instrs, int idx
|
|||
idx);
|
||||
}
|
||||
|
||||
// 12 instructions
|
||||
std::unique_ptr<AtomicOp> convert_vector4_dot(const Instruction* instrs, int idx) {
|
||||
// lwc1 f0, 0(a0)
|
||||
if (!is_lwc(instrs[0], 0)) {
|
||||
return nullptr;
|
||||
}
|
||||
auto t0 = instrs[0].get_dst(0).get_reg();
|
||||
|
||||
// lwc1 f1, 4(a0)
|
||||
if (!is_lwc(instrs[1], 4)) {
|
||||
return nullptr;
|
||||
}
|
||||
auto t1 = instrs[1].get_dst(0).get_reg();
|
||||
|
||||
// lwc1 f2, 8(a0)
|
||||
if (!is_lwc(instrs[2], 8)) {
|
||||
return nullptr;
|
||||
}
|
||||
auto t2 = instrs[2].get_dst(0).get_reg();
|
||||
|
||||
// lwc1 f3, 12(a0)
|
||||
if (!is_lwc(instrs[3], 12)) {
|
||||
return nullptr;
|
||||
}
|
||||
auto t3 = instrs[3].get_dst(0).get_reg();
|
||||
|
||||
// lwc1 f3, 0(v1)
|
||||
if (!is_lwc(instrs[4], 0)) {
|
||||
return nullptr;
|
||||
}
|
||||
auto t4 = instrs[4].get_dst(0).get_reg();
|
||||
|
||||
// lwc1 f5, 4(v1)
|
||||
if (!is_lwc(instrs[5], 4)) {
|
||||
return nullptr;
|
||||
}
|
||||
auto t5 = instrs[5].get_dst(0).get_reg();
|
||||
|
||||
// lwc1 f5, 8(v1)
|
||||
if (!is_lwc(instrs[6], 8)) {
|
||||
return nullptr;
|
||||
}
|
||||
auto t6 = instrs[6].get_dst(0).get_reg();
|
||||
|
||||
// lwc1 f5, 12(v1)
|
||||
if (!is_lwc(instrs[7], 12)) {
|
||||
return nullptr;
|
||||
}
|
||||
auto t7 = instrs[7].get_dst(0).get_reg();
|
||||
|
||||
auto src0 = instrs[0].get_src(1).get_reg();
|
||||
auto src1 = instrs[4].get_src(1).get_reg();
|
||||
if (instrs[1].get_src(1).get_reg() != src0) {
|
||||
return nullptr;
|
||||
}
|
||||
if (instrs[2].get_src(1).get_reg() != src0) {
|
||||
return nullptr;
|
||||
}
|
||||
if (instrs[3].get_src(1).get_reg() != src0) {
|
||||
return nullptr;
|
||||
}
|
||||
if (instrs[5].get_src(1).get_reg() != src1) {
|
||||
return nullptr;
|
||||
}
|
||||
if (instrs[6].get_src(1).get_reg() != src1) {
|
||||
return nullptr;
|
||||
}
|
||||
if (instrs[7].get_src(1).get_reg() != src1) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// mula.s f0, f4
|
||||
if (instrs[8].kind != InstructionKind::MULAS || instrs[8].get_src(0).get_reg() != t0 ||
|
||||
instrs[8].get_src(1).get_reg() != t4) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// madda.s f1, f5
|
||||
if (instrs[9].kind != InstructionKind::MADDAS || instrs[9].get_src(0).get_reg() != t1 ||
|
||||
instrs[9].get_src(1).get_reg() != t5) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// madda.s f2, f6
|
||||
if (instrs[10].kind != InstructionKind::MADDAS || instrs[10].get_src(0).get_reg() != t2 ||
|
||||
instrs[10].get_src(1).get_reg() != t6) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// madd.s f0, f3, f7
|
||||
if (instrs[11].kind != InstructionKind::MADDS || instrs[11].get_src(0).get_reg() != t3 ||
|
||||
instrs[11].get_src(1).get_reg() != t7) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto dst = instrs[11].get_dst(0).get_reg();
|
||||
|
||||
return std::make_unique<SetVarOp>(
|
||||
make_dst_var(dst, idx),
|
||||
SimpleExpression(SimpleExpression::Kind::VECTOR_4_DOT, make_src_atom(src0, idx),
|
||||
make_src_atom(src1, idx)),
|
||||
idx);
|
||||
}
|
||||
|
||||
std::unique_ptr<AtomicOp> convert_9(const Instruction* instrs, int idx) {
|
||||
auto as_vector3_dot = convert_vector3_dot(instrs, idx);
|
||||
if (as_vector3_dot) {
|
||||
|
@ -1896,6 +2000,14 @@ std::unique_ptr<AtomicOp> convert_9(const Instruction* instrs, int idx) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
std::unique_ptr<AtomicOp> convert_12(const Instruction* instrs, int idx) {
|
||||
auto as_vector4_dot = convert_vector4_dot(instrs, idx);
|
||||
if (as_vector4_dot) {
|
||||
return as_vector4_dot;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
/*!
|
||||
|
@ -1929,7 +2041,15 @@ int convert_block_to_atomic_ops(int begin_idx,
|
|||
warnings.warn_sq_lq();
|
||||
}
|
||||
|
||||
if (n_instr >= 9) {
|
||||
if (!converted && n_instr >= 12) {
|
||||
op = convert_12(&instr[0], op_idx);
|
||||
if (op) {
|
||||
converted = true;
|
||||
length = 12;
|
||||
}
|
||||
}
|
||||
|
||||
if (!converted && n_instr >= 9) {
|
||||
op = convert_9(&instr[0], op_idx);
|
||||
if (op) {
|
||||
converted = true;
|
||||
|
|
|
@ -826,27 +826,8 @@
|
|||
)
|
||||
|
||||
;; definition for function vector4-dot
|
||||
;; WARN: Unsupported inline assembly instruction kind - [mula.s f0, f4]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [madda.s f1, f5]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [madda.s f2, f6]
|
||||
;; WARN: Unsupported inline assembly instruction kind - [madd.s f0, f3, f7]
|
||||
(defun vector4-dot ((arg0 vector) (arg1 vector))
|
||||
(local-vars (f0-1 float))
|
||||
(let ((f0-0 (-> arg0 x))
|
||||
(f1-0 (-> arg0 y))
|
||||
(f2-0 (-> arg0 z))
|
||||
(f3-0 (-> arg0 w))
|
||||
(f4-0 (-> arg1 x))
|
||||
(f5-0 (-> arg1 y))
|
||||
(f6-0 (-> arg1 z))
|
||||
(f7-0 (-> arg1 w))
|
||||
)
|
||||
(.mula.s f0-0 f4-0)
|
||||
(.madda.s f1-0 f5-0)
|
||||
(.madda.s f2-0 f6-0)
|
||||
(.madd.s f0-1 f3-0 f7-0)
|
||||
)
|
||||
f0-1
|
||||
(vector4-dot arg0 arg1)
|
||||
)
|
||||
|
||||
;; definition for function vector4-dot-vu
|
||||
|
|
Loading…
Reference in a new issue