diff --git a/decompiler/Disasm/Register.cpp b/decompiler/Disasm/Register.cpp index 5277648bbd..c4df14f07c 100644 --- a/decompiler/Disasm/Register.cpp +++ b/decompiler/Disasm/Register.cpp @@ -269,4 +269,11 @@ bool Register::operator==(const Register& other) const { bool Register::operator!=(const Register& other) const { return id != other.id; } + +bool Register::allowed_local_gpr() const { + if (get_kind() != Reg::GPR) { + return false; + } + return Reg::allowed_local_gprs[get_gpr()]; +} } // namespace decompiler \ No newline at end of file diff --git a/decompiler/Disasm/Register.h b/decompiler/Disasm/Register.h index 78e9719a88..8f08bb895b 100644 --- a/decompiler/Disasm/Register.h +++ b/decompiler/Disasm/Register.h @@ -150,6 +150,7 @@ class Register { Reg::Cop0 get_cop0() const; uint32_t get_pcr() const; Reg::Cop2MacroSpecial get_cop2_macro_special() const; + bool allowed_local_gpr() const; bool operator==(const Register& other) const; bool operator!=(const Register& other) const; diff --git a/decompiler/IR2/AtomicOpForm.cpp b/decompiler/IR2/AtomicOpForm.cpp index 50134f7dc0..68dcba5527 100644 --- a/decompiler/IR2/AtomicOpForm.cpp +++ b/decompiler/IR2/AtomicOpForm.cpp @@ -85,23 +85,48 @@ FormElement* SetVarOp::get_as_form(FormPool& pool, const Env& env) const { // do some analysis to look for coloring moves which are already eliminated, // dead sets, and dead set falses. - if (m_src.kind() == SimpleExpression::Kind::IDENTITY && env.has_local_vars() && - env.has_reg_use()) { - if (env.op_id_is_eliminated_coloring_move(m_my_idx)) { - result->eliminate_as_coloring_move(); - } else if (m_src.get_arg(0).is_var()) { - auto& src_var = m_src.get_arg(0).var(); - auto& ri = env.reg_use().op.at(m_my_idx); - if (ri.consumes.find(src_var.reg()) != ri.consumes.end() && - ri.written_and_unused.find(dst().reg()) != ri.written_and_unused.end()) { - result->mark_as_dead_set(); - // fmt::print("marked {} as dead set\n", to_string(env)); + if (env.has_local_vars() && env.has_reg_use()) { + if (m_src.kind() == SimpleExpression::Kind::IDENTITY) { + if (env.op_id_is_eliminated_coloring_move(m_my_idx)) { + result->eliminate_as_coloring_move(); + } else if (m_src.get_arg(0).is_var()) { + auto& src_var = m_src.get_arg(0).var(); + auto& ri = env.reg_use().op.at(m_my_idx); + // Note: we don't technically need to require consumes here. + // however, the coloring used by the GOAL compiler seems to always satisfy this, so until + // I find a counterexample, I'm going to leave it like this. + if (ri.written_and_unused.find(dst().reg()) != ri.written_and_unused.end() && + src_var.reg().allowed_local_gpr() && m_dst.reg().allowed_local_gpr()) { + result->mark_as_dead_set(); + auto menv = const_cast(&env); + + if (ri.consumes.find(src_var.reg()) == ri.consumes.end()) { + menv->disable_use(src_var); + } + + // fmt::print("marked {} as dead set\n", to_string(env)); + } + } else if (m_src.get_arg(0).is_sym_val() && m_src.get_arg(0).get_str() == "#f" && + m_dst.reg().allowed_local_gpr()) { + auto& ri = env.reg_use().op.at(m_my_idx); + if (ri.written_and_unused.find(dst().reg()) != ri.written_and_unused.end()) { + result->mark_as_dead_false(); + // fmt::print("marked {} as dead set false\n", to_string(env)); + } } - } else if (m_src.get_arg(0).is_sym_val() && m_src.get_arg(0).get_str() == "#f") { + } + + if (m_src.kind() == SimpleExpression::Kind::FPR_TO_GPR) { auto& ri = env.reg_use().op.at(m_my_idx); - if (ri.written_and_unused.find(dst().reg()) != ri.written_and_unused.end()) { - result->mark_as_dead_false(); - // fmt::print("marked {} as dead set false\n", to_string(env)); + // Note: unlike the GPR case, there are sometimes dead moves that don't consume. + if (ri.written_and_unused.find(dst().reg()) != ri.written_and_unused.end() && + m_dst.reg().allowed_local_gpr()) { + result->mark_as_dead_set(); + auto& src_var = m_src.get_arg(0).var(); + auto menv = const_cast(&env); + if (ri.consumes.find(src_var.reg()) == ri.consumes.end()) { + menv->disable_use(src_var); + } } } } diff --git a/decompiler/IR2/AtomicOpTypeAnalysis.cpp b/decompiler/IR2/AtomicOpTypeAnalysis.cpp index a0892d20e0..84bcaf7cd2 100644 --- a/decompiler/IR2/AtomicOpTypeAnalysis.cpp +++ b/decompiler/IR2/AtomicOpTypeAnalysis.cpp @@ -189,6 +189,8 @@ TP_Type SimpleExpression::get_type(const TypeState& input, case Kind::NEG: case Kind::LOGNOT: return get_type_int1(input, env, dts); + case Kind::MOD_UNSIGNED: + return TP_Type::make_from_ts("uint"); default: throw std::runtime_error("Simple expression can't get_type: " + to_form(env.file->labels, env).print()); @@ -541,6 +543,13 @@ TypeState AsmOp::propagate_types_internal(const TypeState& input, (void)env; (void)dts; TypeState result = input; + + if (m_instr.kind == InstructionKind::QMFC2) { + assert(m_dst); + result.get(m_dst->reg()) = TP_Type::make_from_ts("float"); + return result; + } + if (m_dst.has_value()) { auto kind = m_dst->reg().get_kind(); if (kind == Reg::FPR) { diff --git a/decompiler/IR2/Form.cpp b/decompiler/IR2/Form.cpp index ae12995f65..ad29961aff 100644 --- a/decompiler/IR2/Form.cpp +++ b/decompiler/IR2/Form.cpp @@ -1438,7 +1438,7 @@ std::string fixed_operator_to_string(FixedOperatorKind kind) { case FixedOperatorKind::MULTIPLICATION: return "*"; case FixedOperatorKind::SQRT: - return "sqrt"; + return "sqrtf"; case FixedOperatorKind::ARITH_SHIFT: return "ash"; case FixedOperatorKind::MOD: @@ -2302,4 +2302,17 @@ std::optional form_as_atom(const Form* f) { return {}; } + +FormElement* make_cast_using_existing(FormElement* elt, const TypeSpec& type, FormPool& pool) { + auto as_cast = dynamic_cast(elt); + if (as_cast) { + if (as_cast->type() != type) { + as_cast->set_type(type); + } + return as_cast; + } else { + return pool.alloc_element(type, pool.alloc_single_form(nullptr, elt)); + } +} + } // namespace decompiler diff --git a/decompiler/IR2/Form.h b/decompiler/IR2/Form.h index fd6b3d7160..47a6775574 100644 --- a/decompiler/IR2/Form.h +++ b/decompiler/IR2/Form.h @@ -932,6 +932,7 @@ class CastElement : public FormElement { bool allow_side_effects) override; const TypeSpec& type() const { return m_type; } const Form* source() const { return m_source; } + void set_type(const TypeSpec& ts) { m_type = ts; } Form* source() { return m_source; } private: @@ -1430,4 +1431,6 @@ class FormPool { }; std::optional form_as_atom(const Form* f); +FormElement* make_cast_using_existing(Form* form, const TypeSpec& type, FormPool& pool); +FormElement* make_cast_using_existing(FormElement* elt, const TypeSpec& type, FormPool& pool); } // namespace decompiler diff --git a/decompiler/IR2/FormExpressionAnalysis.cpp b/decompiler/IR2/FormExpressionAnalysis.cpp index 8750701263..b73d86b30f 100644 --- a/decompiler/IR2/FormExpressionAnalysis.cpp +++ b/decompiler/IR2/FormExpressionAnalysis.cpp @@ -342,6 +342,12 @@ Form* make_cast(Form* in, const TypeSpec& in_type, const TypeSpec& out_type, For if (in_type == out_type) { return in; } + + auto in_as_cast = dynamic_cast(in->try_as_single_element()); + if (in_as_cast && in_as_cast->type() == out_type) { + return in; + } + return pool.alloc_single_element_form(nullptr, out_type, in); } @@ -378,7 +384,10 @@ void SimpleExpressionElement::update_from_stack_identity(const Env& env, bool allow_side_effects) { auto& arg = m_expr.get_arg(0); if (arg.is_var()) { - pop_helper({arg.var()}, env, pool, stack, {result}, allow_side_effects); + auto forms = pop_to_forms({arg.var()}, env, pool, stack, allow_side_effects); + for (auto x : forms.at(0)->elts()) { + result->push_back(x); + } } else if (arg.is_static_addr()) { auto lab = env.file->labels.at(arg.label()); if (env.file->is_string(lab.target_segment, lab.offset)) { @@ -422,7 +431,10 @@ void SimpleExpressionElement::update_from_stack_gpr_to_fpr(const Env& env, auto src_type = env.get_types_before_op(src.var().idx()).get(src.var().reg()); std::vector src_fes; if (src.is_var()) { - pop_helper({src.var()}, env, pool, stack, {&src_fes}, allow_side_effects); + auto forms = pop_to_forms({src.var()}, env, pool, stack, allow_side_effects); + for (auto x : forms.at(0)->elts()) { + src_fes.push_back(x); + } } else { src_fes = {this}; } @@ -966,6 +978,10 @@ void SimpleExpressionElement::update_from_stack(const Env& env, update_from_stack_force_si_2(env, FixedOperatorKind::MOD, pool, stack, result, allow_side_effects, false); break; + case SimpleExpression::Kind::MOD_UNSIGNED: + update_from_stack_force_ui_2(env, FixedOperatorKind::MOD, pool, stack, result, + allow_side_effects); + break; case SimpleExpression::Kind::MIN_SIGNED: update_from_stack_force_si_2(env, FixedOperatorKind::MIN, pool, stack, result, allow_side_effects, false); @@ -1145,6 +1161,11 @@ void StoreInPairElement::push_to_stack(const Env& env, FormPool& pool, FormStack namespace { Form* make_optional_cast(const std::optional& cast_type, Form* in, FormPool& pool) { if (cast_type) { + auto in_as_cast = dynamic_cast(in->try_as_single_element()); + if (in_as_cast && in_as_cast->type() == cast_type) { + return in; + } + return pool.alloc_single_element_form(nullptr, *cast_type, in); } else { return in; @@ -1768,6 +1789,7 @@ void CondWithElseElement::push_to_stack(const Env& env, FormPool& pool, FormStac // check all to see if they write the value. std::vector dest_sets; + std::vector source_types; // only explicit accesses that aren't move-eliminated for (auto form : write_output_forms) { auto last_in_body = dynamic_cast(form->elts().back()); if (last_in_body) { @@ -1777,6 +1799,7 @@ void CondWithElseElement::push_to_stack(const Env& env, FormPool& pool, FormStac rewrite_as_set = false; break; } + source_types.push_back(last_in_body->src_type()); } last_var = last_in_body->dst(); } // For now, I am fine with letting this fail. For example, if the set is eliminated by a @@ -1822,7 +1845,31 @@ void CondWithElseElement::push_to_stack(const Env& env, FormPool& pool, FormStac if (set_unused) { stack.push_form_element(this, true); } else { - stack.push_value_to_reg(*last_var, pool.alloc_single_form(nullptr, this), true, + // We may need to insert a cast here. + + // Note: + // I think this might skip a cast if you have something like + // (set! x (if y z (expr))) and z requires a cast, but the move from z to x is + // eliminated by GOAL's register allocator. + + // fmt::print("checking:\n"); + // for (auto& t : source_types) { + // fmt::print(" {}\n", t.print()); + // } + + auto expected_type = env.get_variable_type(*last_var, true); + // fmt::print("The expected type is {}\n", expected_type.print()); + auto result_type = + source_types.empty() ? expected_type : env.dts->ts.lowest_common_ancestor(source_types); + // fmt::print("but we actually got {}\n", result_type.print()); + + Form* result_value = pool.alloc_single_form(nullptr, this); + if (!env.dts->ts.tc(expected_type, result_type)) { + result_value = + pool.alloc_single_element_form(nullptr, expected_type, result_value); + } + + stack.push_value_to_reg(*last_var, result_value, true, env.get_variable_type(*last_var, false)); } } else { diff --git a/decompiler/IR2/FormStack.cpp b/decompiler/IR2/FormStack.cpp index d465034730..3840534ed6 100644 --- a/decompiler/IR2/FormStack.cpp +++ b/decompiler/IR2/FormStack.cpp @@ -344,6 +344,10 @@ std::vector FormStack::rewrite(FormPool& pool, const Env& env) { result.push_back(e.elt); } } + + if (result.empty()) { + result.push_back(pool.alloc_element()); + } return result; } diff --git a/decompiler/analysis/cfg_builder.cpp b/decompiler/analysis/cfg_builder.cpp index bc6edb04dd..74675310e1 100644 --- a/decompiler/analysis/cfg_builder.cpp +++ b/decompiler/analysis/cfg_builder.cpp @@ -1354,6 +1354,7 @@ void convert_and_inline(FormPool& pool, Function& f, const BlockVtx* as_block, T auto op_as_set = dynamic_cast(op); if (op_as_set) { // check for deadness + if (op_as_set->is_dead_set()) { // we want to eliminate, but we should we fix up the register info. // now adding. @@ -1362,30 +1363,34 @@ void convert_and_inline(FormPool& pool, Function& f, const BlockVtx* as_block, T dynamic_cast(op_as_set->src()->try_as_single_element()); assert(consumed_expr); auto& consumed = consumed_expr->expr().get_arg(0).var(); - for (int j = i; j-- > start_op;) { - auto& ri = f.ir2.env.reg_use().op.at(j); - auto& ao = f.ir2.atomic_ops->ops.at(j); - if (contains(ao->write_regs(), consumed.reg())) { - ri.written_and_unused.insert(consumed.reg()); - // fmt::print("GOT 3, making {} wau by {}\n", consumed.reg().to_charp(), - // ao->to_string(f.ir2.env)); - // HACK - regenerate: - if (add_map.at(j - start_op) != -1) { - // fmt::print("regenerating {} to ", output->at(add_map.at(j - - // start_op))->to_string(f.ir2.env)); - output->at(add_map.at(j - start_op)) = - f.ir2.atomic_ops->ops.at(j)->get_as_form(pool, f.ir2.env); - // fmt::print("{}\n", output->at(add_map.at(j - - // start_op))->to_string(f.ir2.env)); + auto& ri_outer = f.ir2.env.reg_use().op.at(consumed.idx()); // meh + if (ri_outer.consumes.find(consumed.reg()) != ri_outer.consumes.end()) { + for (int j = i; j-- > start_op;) { + auto& ri = f.ir2.env.reg_use().op.at(j); + auto& ao = f.ir2.atomic_ops->ops.at(j); + if (contains(ao->write_regs(), consumed.reg())) { + ri.written_and_unused.insert(consumed.reg()); + // fmt::print("GOT 3, making {} wau by {}\n", consumed.reg().to_charp(), + // ao->to_string(f.ir2.env)); + // HACK - regenerate: + if (add_map.at(j - start_op) != -1) { + // fmt::print("regenerating {} to ", output->at(add_map.at(j - + // start_op))->to_string(f.ir2.env)); + output->at(add_map.at(j - start_op)) = + f.ir2.atomic_ops->ops.at(j)->get_as_form(pool, f.ir2.env); + // fmt::print("{}\n", output->at(add_map.at(j - + // start_op))->to_string(f.ir2.env)); + } + break; } - break; - } - if (contains(ao->read_regs(), consumed.reg())) { - // fmt::print("GOT 2, making {} consumed by {}\n", consumed.reg().to_charp(), - // ao->to_string(f.ir2.env)); - ri.consumes.insert(consumed.reg()); - break; + if (contains(ao->read_regs(), consumed.reg())) { + // fmt::print("GOT 2, making {} consumed by {}\n", + // consumed.reg().to_charp(), + // ao->to_string(f.ir2.env)); + ri.consumes.insert(consumed.reg()); + break; + } } } } diff --git a/decompiler/analysis/insert_lets.cpp b/decompiler/analysis/insert_lets.cpp index 28ef0fd693..7cabeee1b0 100644 --- a/decompiler/analysis/insert_lets.cpp +++ b/decompiler/analysis/insert_lets.cpp @@ -2,6 +2,7 @@ #include "insert_lets.h" #include "decompiler/IR2/GenericElementMatcher.h" +#include "decompiler/util/DecompilerTypeSystem.h" namespace decompiler { @@ -290,7 +291,21 @@ Form* insert_cast_for_let(RegisterAccess dst, auto dst_type = env.get_variable_type(dst, true); if (src_type != dst_type) { - // fmt::print("inserting let cast because {} != {}\n", dst_type.print(), src_type.print()); + /*auto src_as_cast = dynamic_cast(src->try_as_single_element()); + if (src_as_cast) { + if (env.dts->ts.tc(dst_type, src_as_cast->type())) { + return src; // no need to cast again. + } else { + // don't nest casts + src_as_cast->set_type(dst_type); + return src; + } + }*/ + auto as_single = src->try_as_single_element(); + if (as_single) { + return pool.alloc_single_form(nullptr, make_cast_using_existing(as_single, dst_type, pool)); + } + return pool.alloc_single_element_form(nullptr, dst_type, src); } diff --git a/decompiler/analysis/reg_usage.cpp b/decompiler/analysis/reg_usage.cpp index f34ef05ed5..b1119620e2 100644 --- a/decompiler/analysis/reg_usage.cpp +++ b/decompiler/analysis/reg_usage.cpp @@ -212,6 +212,7 @@ RegUsageInfo analyze_ir2_register_usage(const Function& function) { // also useful to know, written and unused. for (auto reg : op->write_regs()) { if (op_info.live.find(reg) == op_info.live.end()) { + // fmt::print("op {} wau {}\n", op->to_string(function.ir2.env), reg.to_string()); op_info.written_and_unused.insert(reg); } } diff --git a/decompiler/config/all-types.gc b/decompiler/config/all-types.gc index dfd89d51df..faae573bef 100644 --- a/decompiler/config/all-types.gc +++ b/decompiler/config/all-types.gc @@ -1238,11 +1238,11 @@ ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; (deftype quaternion (structure) - ((data float 4 :do-not-decompile :offset-assert 0) - (x float :offset 0) - (y float :offset 4) - (z float :offset 8) - (w float :offset 12) + ((x float :offset-assert 0) + (y float :offset-assert 4) + (z float :offset-assert 8) + (w float :offset-assert 12) + (data float 4 :do-not-decompile :offset 0) (vec vector :inline :offset 0) (quad uint128 :offset 0) ) @@ -1290,6 +1290,9 @@ (rot vector :inline :offset-assert 32) (scale vector :inline :offset-assert 48) ) + (:methods + (new (symbol type) _type_ 0) + ) :method-count-assert 9 :size-assert #x40 :flag-assert #x900000040 @@ -1447,9 +1450,78 @@ (define-extern matrix-axis-sin-cos-vu! (function matrix vector float float none)) -(define-extern trs-matrix-calc! function) -(define-extern transform-matrix-parent-calc! function) -(define-extern transform-matrix-calc! function) + +;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; TRANSFORM ;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; + +(define-extern transform-matrix-calc! (function transform matrix matrix)) +(define-extern transform-matrix-parent-calc! (function transform matrix vector matrix)) +(define-extern trs-matrix-calc! (function trs matrix matrix)) + +;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; QUATERNION ;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; + +(define-extern quaternion-axis-angle! (function quaternion float float float float quaternion)) +(define-extern quaternion-vector-angle! (function quaternion vector float quaternion)) +(define-extern vector-angle<-quaternion! (function vector quaternion vector)) +(define-extern quaternion-zero! (function quaternion quaternion)) +(define-extern quaternion-identity! (function quaternion quaternion)) +(define-extern quaternion-i! (function quaternion quaternion)) +(define-extern quaternion-j! (function quaternion quaternion)) +(define-extern quaternion-k! (function quaternion quaternion)) +(define-extern quaternion-copy! (function quaternion quaternion quaternion)) +(define-extern quaternion-set! (function quaternion float float float float quaternion)) +(define-extern quaternion+! (function quaternion quaternion quaternion quaternion)) +(define-extern quaternion-! (function quaternion quaternion quaternion quaternion)) +(define-extern quaternion-negate! (function quaternion quaternion quaternion)) +(define-extern quaternion-conjugate! (function quaternion quaternion quaternion)) +(define-extern quaternion-float*! (function quaternion quaternion float quaternion)) +(define-extern quaternion-float/! (function quaternion quaternion float quaternion)) +(define-extern quaternion-norm2 (function quaternion float)) +(define-extern quaternion-norm (function quaternion float)) +(define-extern quaternion-normalize! (function quaternion quaternion)) +(define-extern quaternion-inverse! (function quaternion quaternion quaternion)) +(define-extern quaternion-dot (function quaternion quaternion float)) +(define-extern quaternion*! (function quaternion quaternion quaternion quaternion)) +(define-extern quaternion-right-mult-matrix! (function matrix quaternion matrix)) +(define-extern quaternion-left-mult-matrix! (function matrix quaternion matrix)) +(define-extern quaternion->matrix (function matrix quaternion matrix)) +(define-extern matrix->quaternion (function quaternion matrix quaternion)) +(define-extern matrix-with-scale->quaternion (function quaternion matrix quaternion)) +(define-extern quaternion-vector-len (function quaternion float)) +(define-extern quaternion-log! (function quaternion quaternion quaternion)) +(define-extern quaternion-exp! (function quaternion quaternion quaternion)) +(define-extern quaternion-slerp! (function quaternion quaternion quaternion float quaternion)) +(define-extern quaternion-pseudo-slerp! (function quaternion quaternion quaternion float quaternion)) +(define-extern quaternion-zxy! (function quaternion vector quaternion)) + +(define-extern vector-x-quaternion! (function vector quaternion vector)) +(define-extern vector-y-quaternion! (function vector quaternion vector)) +(define-extern vector-z-quaternion! (function vector quaternion vector)) + +(define-extern quaternion-y-angle (function quaternion float)) +(define-extern quaternion-vector-y-angle (function quaternion vector float)) +(define-extern quaternion-rotate-local-x! (function quaternion quaternion float quaternion)) +(define-extern quaternion-rotate-local-y! (function quaternion quaternion float quaternion)) +(define-extern quaternion-rotate-local-z! (function quaternion quaternion float quaternion)) +(define-extern quaternion-rotate-y! (function quaternion quaternion float quaternion)) +(define-extern quaternion-rotate-x! (function quaternion quaternion float quaternion)) +(define-extern quaternion-rotate-z! (function quaternion quaternion float quaternion)) +(define-extern quaternion-delta-y (function quaternion quaternion float)) +(define-extern quaternion-rotate-y-to-vector! (function quaternion quaternion quaternion float quaternion)) +(define-extern vector-rotate-y! (function vector vector float vector)) +(define-extern vector-y-angle (function vector float)) +(define-extern vector-x-angle (function vector float)) +(define-extern quaterion<-rotate-y-vector (function quaternion vector quaternion)) +(define-extern quaternion-xz-angle (function quaternion float)) + +(define-extern quaternion-validate (function quaternion none)) ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1458,12 +1530,63 @@ ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; (define-extern set-eul! (function euler-angles float float float int euler-angles)) -(define-extern eul->matrix function) -(define-extern quat->eul function) +(define-extern eul->matrix (function matrix euler-angles matrix)) +(define-extern matrix->eul (function euler-angles matrix int euler-angles)) +(define-extern eul->quat (function quaternion euler-angles quaternion)) +(define-extern quat->eul (function euler-angles quaternion int euler-angles)) -(define-extern eul->quat function) -(define-extern matrix->eul function) + +;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;;; GEOMETERY ;;;;;;;;;;;;;;;;;;;;;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; + +(define-extern vector-flatten! (function vector vector vector vector)) +(define-extern vector-reflect! (function vector vector vector vector)) +(define-extern vector-reflect-flat! (function vector vector vector vector)) +(define-extern vector-reflect-true-flat! (function vector vector vector vector)) +(define-extern vector-reflect-flat-above! (function vector vector vector vector)) +(define-extern vector-segment-distance-point! (function vector vector vector vector float)) +(define-extern vector-line-distance (function vector vector vector float)) +(define-extern vector-line-distance-point! (function vector vector vector vector float)) +(define-extern vector-orient-by-quat! (function vector vector vector vector)) +(define-extern forward-down->inv-matrix (function matrix vector vector matrix)) +(define-extern forward-down-nopitch->inv-matrix (function matrix vector vector matrix)) +(define-extern forward-up-nopitch->inv-matrix (function matrix vector vector matrix)) +(define-extern forward-up-nopitch->quaternion (function quaternion vector vector quaternion)) +(define-extern forward-up->quaternion (function quaternion vector vector quaternion)) +(define-extern quaternion-from-two-vectors! (function quaternion vector vector quaternion)) +(define-extern quaternion-from-two-vectors-max-angle! (function quaternion vector vector float quaternion)) +(define-extern matrix-from-two-vectors! (function matrix vector vector none)) +(define-extern matrix-from-two-vectors-max-angle! (function matrix vector vector none)) +(define-extern matrix-from-two-vectors-max-angle-partial! (function matrix vector vector float float none)) +(define-extern matrix-from-two-vectors-partial-linear! (function matrix vector vector float float none)) +(define-extern matrix-remove-z-rot (function matrix matrix)) +(define-extern matrix-rot-diff! (function matrix matrix matrix float)) +(define-extern quaternion-seek (function quaternion quaternion quaternion float quaternion)) +(define-extern vector-deg-seek (function vector vector vector none)) +(define-extern vector-deg-slerp (function vector vector vector float float vector)) +(define-extern vector-vector-deg-slerp! function) ;; stack spills! +(define-extern normal-of-plane (function vector vector vector vector vector)) +(define-extern vector-3pt-cross! (function vector vector vector vector)) +(define-extern closest-pt-in-triangle function) ;; asm branches +(define-extern point-in-triangle-cross (function vector vector vector vector vector symbol)) +(define-extern point-in-plane-<-point+normal! (function vector vector vector vector)) +(define-extern circle-circle-xz-intersect (function vector vector vector vector int)) +(define-extern circle-test (function none)) + +(define-extern curve-evaluate! function) +(define-extern find-knot-span function) +(define-extern curve-length function) +(define-extern calculate-basis-functions-vector! function) +(define-extern vector-circle-tangent function) +(define-extern vector-plane-distance function) +(define-extern curve-copy! function) +(define-extern curve-get-pos! function) +(define-extern curve-closest-point function) +(define-extern vector-circle-tangent-new function) ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -32506,110 +32629,10 @@ ;;(define-extern trsqv object) ;; unknown type ;;(define-extern trsq object) ;; unknown type -(define-extern vector-y-angle (function vector float)) - - -(define-extern quaternion-zero! function) -(define-extern quaternion-set! function) -(define-extern matrix->quaternion (function quaternion matrix quaternion)) -(define-extern quaternion-exp! function) -(define-extern quaternion-axis-angle! function) -(define-extern quaternion-rotate-x! function) -(define-extern quaternion-validate function) -(define-extern quaternion-dot function) -(define-extern quaternion-normalize! function) -(define-extern vector-x-angle function) -(define-extern quaternion-k! function) -(define-extern quaternion-vector-len function) -(define-extern quaternion-rotate-local-x! function) -(define-extern matrix-with-scale->quaternion function) -(define-extern quaternion-rotate-y! function) -(define-extern vector-x-quaternion! function) -(define-extern quaternion-xz-angle function) -(define-extern quaternion-j! function) -(define-extern quaternion*! function) -(define-extern quaternion-right-mult-matrix! function) -(define-extern quaternion-left-mult-matrix! function) -(define-extern quaternion-negate! function) -(define-extern quaternion+! function) -(define-extern quaternion-norm function) -(define-extern quaternion-log! function) -(define-extern quaternion-rotate-local-z! function) -(define-extern quaternion-float*! function) -(define-extern quaternion-float/! function) -(define-extern quaternion-inverse! function) -(define-extern quaternion-pseudo-slerp! function) -(define-extern quaternion-vector-angle! function) -(define-extern quaterion<-rotate-y-vector function) -(define-extern quaternion-rotate-y-to-vector! function) -(define-extern quaternion-! function) -(define-extern vector-z-quaternion! function) -(define-extern quaternion-rotate-z! function) -(define-extern quaternion-slerp! function) -(define-extern quaternion->matrix function) -(define-extern quaternion-zxy! function) -(define-extern quaternion-delta-y function) -(define-extern vector-angle<-quaternion! function) -(define-extern quaternion-rotate-local-y! function) -(define-extern quaternion-norm2 function) -(define-extern quaternion-identity! (function quaternion quaternion)) -(define-extern quaternion-y-angle function) -(define-extern quaternion-vector-y-angle function) -(define-extern quaternion-copy! function) -(define-extern quaternion-conjugate! function) -(define-extern vector-y-quaternion! function) -(define-extern vector-rotate-y! function) -(define-extern quaternion-i! function) -(define-extern quaternion-from-two-vectors-max-angle! function) - - -(define-extern vector-reflect-flat! function) -(define-extern forward-down->inv-matrix function) -(define-extern circle-test function) -(define-extern vector-line-distance-point! function) -(define-extern curve-evaluate! function) -(define-extern vector-reflect! function) -(define-extern matrix-from-two-vectors! function) -(define-extern matrix-from-two-vectors-partial-linear! function) -(define-extern forward-up->quaternion function) -(define-extern find-knot-span function) -(define-extern vector-vector-deg-slerp! function) -(define-extern matrix-from-two-vectors-max-angle! function) -(define-extern curve-length function) -(define-extern matrix-from-two-vectors-max-angle-partial! function) -(define-extern vector-deg-slerp function) -(define-extern vector-segment-distance-point! function) -(define-extern forward-up-nopitch->inv-matrix function) -(define-extern normal-of-plane function) -(define-extern vector-line-distance function) -(define-extern calculate-basis-functions-vector! function) -(define-extern vector-deg-seek function) -(define-extern point-in-plane-<-point+normal! function) -(define-extern matrix-rot-diff! function) -(define-extern point-in-triangle-cross function) -(define-extern matrix-remove-z-rot function) -(define-extern quaternion-seek function) -(define-extern vector-3pt-cross! function) -(define-extern vector-circle-tangent function) -(define-extern circle-circle-xz-intersect function) -(define-extern vector-plane-distance function) -(define-extern quaternion-from-two-vectors! function) -(define-extern closest-pt-in-triangle function) -(define-extern vector-flatten! function) -(define-extern vector-orient-by-quat! function) -(define-extern vector-reflect-true-flat! function) -(define-extern forward-up-nopitch->quaternion function) -(define-extern curve-copy! function) -(define-extern curve-get-pos! function) -(define-extern curve-closest-point function) -(define-extern forward-down-nopitch->inv-matrix function) -(define-extern vector-reflect-flat-above! function) -(define-extern vector-circle-tangent-new function) - (define-extern *level-load-list* pair) diff --git a/decompiler/config/jak1_ntsc_black_label/label_types.jsonc b/decompiler/config/jak1_ntsc_black_label/label_types.jsonc index b382aedc93..8bfca90d05 100644 --- a/decompiler/config/jak1_ntsc_black_label/label_types.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/label_types.jsonc @@ -38,15 +38,49 @@ ["L26", "vector", true] ], - "quaternion-h": [["L1", "quaternion", true]], - "euler-h": [ ["L3", "_auto_", true], ["L2", "_auto_", true] ], - "matrix":[ - ["L60", "float", true] + "matrix": [["L60", "float", true]], + + "transform": [["L11", "float", true]], + "quaternion-h": [["L1", "quaternion", true]], + "quaternion": [ + ["L67", "vector", true], + ["L68", "vector", true], + ["L69", "vector", true], + ["L70", "vector", true], + ["L71", "vector", true], + ["L72", "vector", true], + ["L77", "float", true], + ["L78", "float", true], + ["L79", "float", true], + ["L80", "float", true], + ["L81", "float", true], + ["L82", "float", true], + ["L93", "float", true], + ["L94", "float", true] + ], + + "euler": [["L18", "float", true]], + + "geometry": [ + ["L115", "float", true], + ["L116", "float", true], + ["L117", "float", true], + ["L118", "float", true], + ["L119", "float", true], + ["L120", "float", true], + ["L121", "float", true], + ["L122", "float", true], + ["L123", "float", true], + ["L124", "float", true], + ["L125", "float", true], + ["L126", "float", true], + ["L127", "float", true], + ["L128", "float", true] ], "trigonometry": [ @@ -153,8 +187,6 @@ ["L59", "float", true] ], - "quaternion": [["L80", "float", true]], - "font-h": [ ["L18", "matrix", true], ["L19", "float", true], diff --git a/decompiler/config/jak1_ntsc_black_label/stack_vars.jsonc b/decompiler/config/jak1_ntsc_black_label/stack_vars.jsonc index 5a9d2a8133..6d241f5288 100644 --- a/decompiler/config/jak1_ntsc_black_label/stack_vars.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/stack_vars.jsonc @@ -30,13 +30,107 @@ [80, "matrix"] ], - "matrix-rotate-yxy!":[ - [16, "vector"], - [32, "vector"], - [48, "vector"] + "matrix-rotate-yxy!": [ + [16, "vector"], + [32, "vector"], + [48, "vector"] ], - "matrix-rotate-yx!":[ - [16, "matrix"] - ] -} + "matrix-rotate-yx!": [[16, "matrix"]], + + "transform-matrix-calc!": [ + [16, "matrix"], + [80, "matrix"] + ], + + "transform-matrix-parent-calc!": [ + [16, "matrix"], + [80, "matrix"] + ], + + "matrix-with-scale->quaternion": [[16, "matrix"]], + + "quaternion-exp!": [[16, "vector"]], + "quaternion-slerp!": [[16, "vector"]], + "quaternion-zxy!": [ + [16, "vector"], + [32, "vector"], + [48, "vector"] + ], + + "vector-x-quaternion!": [[16, "matrix"]], + "vector-y-quaternion!": [[16, "matrix"]], + "vector-z-quaternion!": [[16, "matrix"]], + + "quaternion-y-angle": [[16, "vector"]], + "quaternion-rotate-local-x!": [[16, "quaternion"]], + "quaternion-rotate-local-y!": [[16, "quaternion"]], + "quaternion-rotate-local-z!": [[16, "quaternion"]], + "quaternion-rotate-y!": [[16, "quaternion"]], + "quaternion-rotate-x!": [ + [16, "quaternion"], + [32, "vector"] + ], + "quaternion-rotate-z!": [ + [16, "quaternion"], + [32, "vector"] + ], + "quaternion-delta-y": [ + [16, "vector"], + [32, "vector"] + ], + "quaternion-rotate-y-to-vector!": [ + [16, "quaternion"], + [32, "vector"], + [48, "quaternion"] + ], + "quaternion-xz-angle": [ + [16, "matrix"], + [80, "vector"] + ], + "vector-rotate-y!": [ + [16, "quaternion"], + [32, "matrix"] + ], + + "eul->matrix": [[16, "vector"]], + "eul->quat": [[16, "matrix"]], + "quat->eul": [[16, "matrix"]], + + "vector-line-distance": [ + [16, "vector"], + [32, "vector"], + [48, "vector"], + [64, "vector"] + ], + "vector-line-distance-point!": [ + [16, "vector"], + [32, "vector"], + [48, "vector"], + [64, "vector"] + ], + + "forward-up-nopitch->inv-matrix": [[16, "vector"]], + + "forward-up-nopitch->quaternion": [[16, "matrix"]], + + "forward-up->quaternion": [[16, "matrix"], [80, "vector"]], + + "quaternion-from-two-vectors!": [[16, "vector"]], + + "quaternion-from-two-vectors-max-angle!": [[16, "vector"]], + + "matrix-from-two-vectors!": [[16, "vector"]], + "matrix-from-two-vectors-max-angle!": [[16, "vector"]], + "matrix-from-two-vectors-max-angle-partial!": [[16, "vector"]], + "matrix-from-two-vectors-partial-linear!": [[16, "vector"]], + "matrix-remove-z-rot": [[16, "vector"], [32, "matrix"]], + + "matrix-rot-diff!": [[16, "quaternion"], [32, "quaternion"], [48, "quaternion"]], + + "quaternion-seek": [[16, "matrix"], [80, "matrix"], [144, "quaternion"]], + "vector-deg-seek": [[16, "matrix"]], + "vector-deg-slerp": [[16, "matrix"], [80, "vector"], [96, "vector"]], + + "circle-test": [[16, "sphere"], [32, "sphere"], [48, "vector"], [64, "vector"]] +} diff --git a/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc b/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc index cd8fba906c..20b465eac6 100644 --- a/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/type_casts.jsonc @@ -89,8 +89,8 @@ "(method 9 process)": [[43, "s5", "process"]], "(method 14 dead-pool)": [ - [[24, 25], "v1", "(pointer process-tree)"], - [[30, 39], "s4", "(pointer process-tree)"] + [[24, 25], "v1", "(pointer process)"], + [[30, 39], "s4", "(pointer process)"] ], "inspect-process-heap": [ @@ -110,21 +110,21 @@ ], // GSTATE - "enter-state":[ - [68, "s0", "protect-frame"] - ], + "enter-state": [[68, "s0", "protect-frame"]], // MATH - "log2":[ - [3, "v1", "int"] - ], + "log2": [[3, "v1", "int"]], + + // QUATERNION + "vector-x-quaternion!": [[10, "v1", "(pointer uint128)"]], + "vector-y-quaternion!": [[10, "v1", "(pointer uint128)"]], + "vector-z-quaternion!": [[10, "v1", "(pointer uint128)"]], // LEVEL - "lookup-level-info":[ + "lookup-level-info": [ [3, "a1", "symbol"], [4, "a1", "level-load-info"], [8, "a1", "level-load-info"], [12, "a1", "level-load-info"] ] - } diff --git a/decompiler/config/jak1_ntsc_black_label/var_names.jsonc b/decompiler/config/jak1_ntsc_black_label/var_names.jsonc index 9015a3fa2e..9da10fa8f9 100644 --- a/decompiler/config/jak1_ntsc_black_label/var_names.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/var_names.jsonc @@ -562,6 +562,30 @@ "vars": { "v1-0": "z-row" } }, + "(method 0 trs)": { + "vars": { "gp-0": "obj" } + }, + + "transform-matrix-calc!": { + "args": ["tf", "dst-mat"] + }, + + "transform-matrix-parent-calc!": { + "args": ["tf", "dst-mat", "inv-scale"] + }, + + "trs-matrix-calc!": { + "args": ["tf", "dst-mat"] + }, + + "quaternion-axis-angle!":{ + "args": ["quat", "x", "y", "z", "angle"] + }, + + "quaternion-vector-angle!":{ + "args": ["quat", "axis", "angle"] + }, + "deg-seek": { "args": ["in", "target", "max-diff"], "vars": { diff --git a/goal_src/engine/geometry/geometry-h.gc b/goal_src/engine/geometry/geometry-h.gc index a4106cb795..9e7ad2eb6a 100644 --- a/goal_src/engine/geometry/geometry-h.gc +++ b/goal_src/engine/geometry/geometry-h.gc @@ -33,4 +33,6 @@ (dummy-9 () none 9) (dummy-10 () none 10) ) - ) \ No newline at end of file + ) + +(defun-extern quaternion-from-two-vectors-max-angle! quaternion vector vector float quaternion) diff --git a/goal_src/engine/math/quaternion-h.gc b/goal_src/engine/math/quaternion-h.gc index a0cad56963..15e2518731 100644 --- a/goal_src/engine/math/quaternion-h.gc +++ b/goal_src/engine/math/quaternion-h.gc @@ -6,11 +6,11 @@ ;; dgos: GAME, ENGINE (deftype quaternion (structure) - ((data float 4 :do-not-decompile :offset-assert 0) - (x float :offset 0) - (y float :offset 4) - (z float :offset 8) - (w float :offset 12) + ((x float :offset-assert 0) + (y float :offset-assert 4) + (z float :offset-assert 8) + (w float :offset-assert 12) + (data float 4 :do-not-decompile :offset 0) (vec vector :inline :offset 0) (quad uint128 :offset 0) ) diff --git a/goal_src/engine/math/quaternion.gc b/goal_src/engine/math/quaternion.gc index b7ef5f9080..448734c489 100644 --- a/goal_src/engine/math/quaternion.gc +++ b/goal_src/engine/math/quaternion.gc @@ -5,12 +5,1097 @@ ;; name in dgo: quaternion ;; dgos: GAME, ENGINE - -(defun quaternion-identity! ((dst quaternion)) - (rlet ((r0 :class vf)) - (.xor.vf r0 r0 r0) - (.svf dst r0) +(defmethod inspect quaternion ((obj quaternion)) + "Print a quaternion. Prints the values and axis-angle" + (format #t "[~8x] quaternion~%" obj) + (format #t "~T[~F] [~F] [~F] [~F]~%" + (-> obj x) + (-> obj y) + (-> obj z) + (-> obj w) + ) + (let ((f0-5 (/ 1.0 (sqrtf + (+ (* (-> obj x) (-> obj x)) + (* (-> obj y) (-> obj y)) + (* (-> obj z) (-> obj z)) + ) + ) + ) + ) + ) + (format #t "~Taxis: ~F ~F ~F" + (* f0-5 (-> obj x)) + (* f0-5 (-> obj y)) + (* f0-5 (-> obj z)) + ) + ) + (let ((f0-9 (* 2.0 (acos (-> obj w))))) + (format #t "~T~Tangle: (deg ~R)~%" f0-9) + ) + obj + ) + +(defun quaternion-axis-angle! ((quat quaternion) (x float) (y float) (z float) (angle float)) + "Construct a quaternion from an axis and angle. The axis should be normalized." + (let* ((f28-0 (* 0.5 angle)) + (f30-0 (sin f28-0)) + (f0-1 (cos f28-0)) + ) + (set! (-> quat x) (* x f30-0)) + (set! (-> quat y) (* y f30-0)) + (set! (-> quat z) (* z f30-0)) + (set! (-> quat w) f0-1) + ) + quat + ) + +(defun quaternion-vector-angle! ((quat quaternion) (axis vector) (angle float)) + "Construct a quaternion from an axis and angle. The axis should be normalized." + (let* ((f28-0 (* 0.5 angle)) + (f30-0 (sin f28-0)) + (f0-1 (cos f28-0)) + ) + (set! (-> quat x) (* (-> axis data 0) f30-0)) + (set! (-> quat y) (* (-> axis data 1) f30-0)) + (set! (-> quat z) (* (-> axis data 2) f30-0)) + (set! (-> quat w) f0-1) + ) + quat + ) + +(defun vector-angle<-quaternion! ((arg0 vector) (arg1 quaternion)) + "Convert the quaternion arg1 to axis-angle form and store in arg0 (angle goes in w)" + (let* ((f0-0 1.0) + (f1-0 1.0) + (f2-0 (-> arg1 w)) + (f30-0 (/ f0-0 (sqrtf (- f1-0 (* f2-0 f2-0))))) + (f0-3 (* 2.0 (acos-rad (-> arg1 w)))) + ) + (set! (-> arg0 data 0) (* (-> arg1 x) f30-0)) + (set! (-> arg0 data 1) (* (-> arg1 y) f30-0)) + (set! (-> arg0 data 2) (* (-> arg1 z) f30-0)) + (set! (-> arg0 data 3) f0-3) + ) + arg0 + ) + +(defun quaternion-zero! ((arg0 quaternion)) + "Set quaternion to all 0's" + (set! (-> arg0 vec quad) (the-as uint128 0)) + arg0 + ) + +(defun quaternion-identity! ((arg0 quaternion)) + "Set quaternion to 0,0,0,1 (identity)" + (set! (-> arg0 vec quad) (the-as uint128 0)) + (set! (-> arg0 w) 1.0) + arg0 + ) + +(defun quaternion-i! ((arg0 quaternion)) + "Create unit i quaternion" + (set! (-> arg0 vec quad) (the-as uint128 0)) + (set! (-> arg0 x) 1.0) + arg0 + ) + +(defun quaternion-j! ((arg0 quaternion)) + "Create unit j quaternion." + (set! (-> arg0 vec quad) (the-as uint128 0)) + (set! (-> arg0 y) 1.0) + arg0 + ) + +(defun quaternion-k! ((arg0 quaternion)) + "Create unit k quaternion" + (set! (-> arg0 vec quad) (the-as uint128 0)) + (set! (-> arg0 z) 1.0) + arg0 + ) + +(defun quaternion-copy! ((arg0 quaternion) (arg1 quaternion)) + "Set arg0 = arg1" + (set! (-> arg0 vec quad) (-> arg1 vec quad)) + arg0 + ) + +(defun quaternion-set! ((arg0 quaternion) (arg1 float) (arg2 float) (arg3 float) (arg4 float)) + "Set arg0 = [arg1, arg2, arg3, arg4]" + (set! (-> arg0 x) arg1) + (set! (-> arg0 y) arg2) + (set! (-> arg0 z) arg3) + (set! (-> arg0 w) arg4) + arg0 + ) + +(defun quaternion+! ((arg0 quaternion) (arg1 quaternion) (arg2 quaternion)) + "Add quaternions as vectors." + (rlet ((vf1 :class vf) + (vf2 :class vf) + ) + (.lvf vf1 (&-> arg1 vec quad)) + (.lvf vf2 (&-> arg2 vec quad)) + (.add.vf vf1 vf1 vf2) + (.svf (&-> arg0 vec quad) vf1) + arg0 + ) + ) + +(defun quaternion-! ((arg0 quaternion) (arg1 quaternion) (arg2 quaternion)) + "Subtract quaternions as vectors." + (rlet ((vf1 :class vf) + (vf2 :class vf) + ) + (.lvf vf1 (&-> arg1 vec quad)) + (.lvf vf2 (&-> arg2 vec quad)) + (.sub.vf vf1 vf1 vf2) + (.svf (&-> arg0 vec quad) vf1) + arg0 + ) + ) + +(defun quaternion-negate! ((arg0 quaternion) (arg1 quaternion)) + "Set arg0 = -arg1." + (rlet ((vf1 :class vf) + (vf2 :class vf) + ) + (.lvf vf1 (&-> arg1 vec quad)) + ;;(.sub.vf vf2 vf2 vf2) + (.xor.vf vf2 vf2 vf2) + (.sub.vf vf1 vf2 vf1) + (.svf (&-> arg0 vec quad) vf1) + arg0 + ) + ) + +(defun quaternion-conjugate! ((arg0 quaternion) (arg1 quaternion)) + "Set arg0 to the conjugate of arg1 (negate only ijk). + If arg1 is normalized, this is equivalent to the inverse + NOTE: this gives you the inverse rotation." + (rlet ((vf1 :class vf) + (vf2 :class vf) + ) + (.lvf vf1 (&-> arg1 vec quad)) + ;;(.sub.vf vf2 vf2 vf2) + (.xor.vf vf2 vf2 vf2) + (.sub.vf vf2 vf2 vf1 :mask #b111) + (.add.vf vf2 vf2 vf1 :mask #b1000) + (.svf (&-> arg0 vec quad) vf2) + arg0 + ) + ) + +(defun quaternion-float*! ((arg0 quaternion) (arg1 quaternion) (arg2 float)) + "Multiply each element" + (rlet ((vf1 :class vf) + (vf2 :class vf) + ) + (.lvf vf1 (&-> arg1 vec quad)) + (.mov vf2 arg2) + (.mul.x.vf vf1 vf1 vf2) + (.svf (&-> arg0 vec quad) vf1) + arg0 + ) + ) + +(defun quaternion-float/! ((arg0 quaternion) (arg1 quaternion) (arg2 float)) + "Divide each element" + (let ((f0-1 (/ 1.0 arg2))) + (quaternion-float*! arg0 arg1 f0-1) + ) + arg0 + ) + +(defun quaternion-norm2 ((arg0 quaternion)) + "Get the squared norm of a quaternion" + (local-vars (v0-0 float)) + (rlet ((acc :class vf) + (vf0 :class vf) + (vf1 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg0 vec quad)) + (.mul.vf vf1 vf1 vf1) + (.add.z.vf acc vf1 vf1 :mask #b1000) + (.add.mul.y.vf acc vf0 vf1 acc :mask #b1000) + (.add.mul.x.vf vf1 vf0 vf1 acc :mask #b1000) + (.add.w.vf vf1 vf0 vf1) + (.mov v0-0 vf1) + v0-0 + ) + ) + +(defun quaternion-norm ((arg0 quaternion)) + "Get the norm of a quaternion." + (local-vars (v1-1 float)) + (rlet ((acc :class vf) + (vf0 :class vf) + (vf1 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg0 vec quad)) + (.mul.vf vf1 vf1 vf1) + (.add.z.vf acc vf1 vf1 :mask #b1000) + (.add.mul.y.vf acc vf0 vf1 acc :mask #b1000) + (.add.mul.x.vf vf1 vf0 vf1 acc :mask #b1000) + (.add.w.vf vf1 vf0 vf1) + (.mov v1-1 vf1) + (sqrtf v1-1) + ) + ) + +(defun quaternion-normalize! ((arg0 quaternion)) + "Normalize a quaternion" + (rlet ((acc :class vf) + (Q :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg0 vec quad)) + (.mul.vf vf2 vf1 vf1) + (.add.z.vf acc vf2 vf2 :mask #b1000) + (.add.mul.y.vf acc vf0 vf2 acc :mask #b1000) + (.add.mul.x.vf vf2 vf0 vf2 acc :mask #b1000) + (.isqrt.vf Q vf0 vf2 :fsf #b11 :ftf #b11) + ;;(.wait.vf) + (.mul.vf vf2 vf1 Q) + ;;(.nop.vf) + ;;(.nop.vf) + (.svf (&-> arg0 vec quad) vf2) + arg0 + ) + ) + +(defun quaternion-inverse! ((arg0 quaternion) (arg1 quaternion)) + "Invert a quaternion. The inverse will satisfy q * q^-1 = identity, even if q is not normalized. + If your quaternion is normalized, it is faster/more accurate to do quaternion-conjugate!" + (rlet ((acc :class vf) + (Q :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg1 vec quad)) + (.mul.vf vf2 vf1 vf1) + (.sub.vf vf3 vf3 vf3) + (.add.z.vf acc vf2 vf2 :mask #b1000) + (.add.mul.y.vf acc vf0 vf2 acc :mask #b1000) + (.add.mul.x.vf vf2 vf0 vf2 acc :mask #b1000) + (.sub.vf vf3 vf3 vf1 :mask #b111) + (.div.vf Q vf0 vf2 :fsf #b11 :ftf #b11) + (.add.vf vf3 vf3 vf1 :mask #b1000) + (.wait.vf) + (.mul.vf vf3 vf3 Q) + (.nop.vf) + (.nop.vf) + (.svf (&-> arg0 vec quad) vf3) + arg0 + ) + ) + +(defun quaternion-dot ((arg0 quaternion) (arg1 quaternion)) + "Treat quaternions as vectors and take the dot product." + (local-vars (v0-0 float)) + (rlet ((acc :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg0 vec quad)) + (.lvf vf2 (&-> arg1 vec quad)) + (.mul.vf vf1 vf1 vf2) + (.add.z.vf acc vf1 vf1 :mask #b1000) + (.add.mul.y.vf acc vf0 vf1 acc :mask #b1000) + (.add.mul.x.vf vf1 vf0 vf1 acc :mask #b1000) + (.add.w.vf vf1 vf0 vf1) + (.mov v0-0 vf1) + v0-0 + ) + ) + +(defun quaternion*! ((arg0 quaternion) (arg1 quaternion) (arg2 quaternion)) + "Real quaternion multiplication" + (rlet ((acc :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg1 vec quad)) + (.lvf vf2 (&-> arg2 vec quad)) + (.sub.vf vf4 vf0 vf0 :mask #b1000) + (.mul.vf vf3 vf1 vf2) + (.outer.product.vf vf4 vf1 vf2) + (.mul.w.vf acc vf1 vf2) + (.add.mul.w.vf acc vf2 vf1 acc) + (.sub.mul.w.vf acc vf0 vf3 acc :mask #b1000) + (.sub.mul.z.vf acc vf0 vf3 acc :mask #b1000) + (.sub.mul.y.vf acc vf0 vf3 acc :mask #b1000) + (.sub.mul.x.vf acc vf0 vf3 acc :mask #b1000) + (.add.mul.w.vf vf1 vf4 vf0 acc) + (.svf (&-> arg0 vec quad) vf1) + arg0 + ) + ) + +(defun quaternion-right-mult-matrix! ((arg0 matrix) (arg1 quaternion)) + "Place quaternion coefficients into a matrix. + You can convert a quaternion to a matrix by taking the product of this + right-mult and left-mult matrix, but this method is not used. + Instead, quaternion->matrix is a more efficient implementation." + (let ((f3-0 (-> arg1 x)) + (f2-0 (-> arg1 y)) + (f1-0 (-> arg1 z)) + (f0-0 (-> arg1 w)) + ) + (set! (-> arg0 data 0) f0-0) + (set! (-> arg0 data 1) f1-0) + (set! (-> arg0 data 2) (- f2-0)) + (set! (-> arg0 data 3) f3-0) + (set! (-> arg0 data 4) (- f1-0)) + (set! (-> arg0 data 5) f0-0) + (set! (-> arg0 data 6) f3-0) + (set! (-> arg0 data 7) f2-0) + (set! (-> arg0 data 8) f2-0) + (set! (-> arg0 data 9) (- f3-0)) + (set! (-> arg0 data 10) f0-0) + (set! (-> arg0 data 11) f1-0) + (set! (-> arg0 data 12) (- f3-0)) + (set! (-> arg0 data 13) (- f2-0)) + (set! (-> arg0 data 14) (- f1-0)) + (set! (-> arg0 data 15) f0-0) + ) + arg0 + ) + +(defun quaternion-left-mult-matrix! ((arg0 matrix) (arg1 quaternion)) + "Place quaternion coefficients into a matrix. Unused." + (let ((f2-0 (-> arg1 x)) + (f1-0 (-> arg1 y)) + (f0-0 (-> arg1 z)) + ) + (let ((f3-0 (-> arg1 w))) + (set! (-> arg0 data 0) f2-0) + (set! (-> arg0 data 1) f3-0) + (set! (-> arg0 data 2) (- f0-0)) + (set! (-> arg0 data 3) f1-0) + (set! (-> arg0 data 4) f1-0) + (set! (-> arg0 data 5) f0-0) + (set! (-> arg0 data 6) f3-0) + (set! (-> arg0 data 7) (- f3-0)) + (set! (-> arg0 data 8) f0-0) + (set! (-> arg0 data 9) (- f1-0)) + (set! (-> arg0 data 10) f2-0) + (set! (-> arg0 data 11) f3-0) + (set! (-> arg0 data 12) f3-0) + ) + (set! (-> arg0 data 13) (- f2-0)) + (set! (-> arg0 data 14) (- f1-0)) + (set! (-> arg0 data 15) (- f0-0)) + ) + arg0 + ) + +(defun quaternion->matrix ((arg0 matrix) (arg1 quaternion)) + "Convert quaternion to matrix." + (rlet ((acc :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + (vf5 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg1 vec quad)) + (.add.vf vf5 vf1 vf1) + (.add.w.vf vf2 vf0 vf1 :mask #b1) + (.add.z.vf vf2 vf0 vf1 :mask #b10) + (.sub.y.vf vf2 vf0 vf1 :mask #b100) + (.sub.w.vf vf2 vf0 vf0 :mask #b1000) + (.sub.z.vf vf3 vf0 vf1 :mask #b1) + (.add.w.vf vf3 vf0 vf1 :mask #b10) + (.add.x.vf vf3 vf0 vf1 :mask #b100) + (.sub.w.vf vf3 vf0 vf0 :mask #b1000) + (.add.y.vf vf4 vf0 vf1 :mask #b1) + (.sub.x.vf vf4 vf0 vf1 :mask #b10) + (.add.w.vf vf4 vf0 vf1 :mask #b100) + (.sub.w.vf vf4 vf0 vf0 :mask #b1000) + (.outer.product.vf vf2 vf5 vf2) + (.outer.product.vf vf3 vf5 vf3) + (.outer.product.vf vf4 vf5 vf4) + (.add.w.vf vf2 vf2 vf0 :mask #b1) + (.add.w.vf vf3 vf3 vf0 :mask #b10) + (.add.w.vf vf4 vf4 vf0 :mask #b100) + (.svf (&-> arg0 vector 3 quad) vf0) + (.svf (&-> arg0 vector 0 quad) vf2) + (.svf (&-> arg0 vector 1 quad) vf3) + (.svf (&-> arg0 vector 2 quad) vf4) + arg0 + ) + ) + +(defun matrix->quaternion ((arg0 quaternion) (arg1 matrix)) + (let ((f0-2 (+ (+ (-> arg1 data 0) (-> arg1 data 5)) (-> arg1 data 10)))) + (if (< 0.0 f0-2) + (let ((f0-4 (sqrtf (+ 1.0 f0-2)))) + (set! (-> arg0 w) (* 0.5 f0-4)) + (let ((f0-5 (/ 0.5 f0-4))) + (set! (-> arg0 x) (* f0-5 (- (-> arg1 data 6) (-> arg1 data 9)))) + (set! (-> arg0 y) (* f0-5 (- (-> arg1 data 8) (-> arg1 data 2)))) + (let ((f0-6 (* f0-5 (- (-> arg1 data 1) (-> arg1 data 4))))) + (set! (-> arg0 z) f0-6) + (let ((v1-0 f0-6)) + ) + ) + ) + ) + (let ((a2-0 0) + (a3-0 1) + (v1-1 2) + ) + (when (< (-> arg1 data 0) (-> arg1 data 5)) + (set! a2-0 1) + (set! a3-0 2) + (set! v1-1 0) + (let ((t0-1 v1-1)) + ) + ) + (when + (< + (-> + (the-as + (pointer float) + (+ (+ (shl a2-0 2) (shl a2-0 4)) (the-as int arg1)) + ) + ) + (-> arg1 data 10) + ) + (set! a2-0 2) + (set! a3-0 0) + (set! v1-1 1) + (let ((t0-6 v1-1)) + ) + ) + (let + ((f0-12 + (sqrtf + (+ + (- + 1.0 + (+ + (-> + (the-as + (pointer float) + (+ (+ (shl a3-0 2) (shl a3-0 4)) (the-as int arg1)) + ) + ) + (-> + (the-as + (pointer float) + (+ (+ (shl v1-1 2) (shl v1-1 4)) (the-as int arg1)) + ) + ) + ) + ) + (-> + (the-as + (pointer float) + (+ (+ (shl a2-0 2) (shl a2-0 4)) (the-as int arg1)) + ) + ) + ) + ) + ) + ) + (set! (-> arg0 data a2-0) (* 0.5 f0-12)) + (when (!= f0-12 0.0) + (set! f0-12 (/ 0.5 f0-12)) + (let ((t0-19 f0-12)) + ) + ) + (set! + (-> arg0 w) + (* + (- + (-> + (the-as + (pointer float) + (+ (+ (shl v1-1 2) (shl a3-0 4)) (the-as int arg1)) + ) + ) + (-> + (the-as + (pointer float) + (+ (+ (shl a3-0 2) (shl v1-1 4)) (the-as int arg1)) + ) + ) + ) + f0-12 + ) + ) + (set! + (-> arg0 data a3-0) + (* + (+ + (-> + (the-as + (pointer float) + (+ (+ (shl a3-0 2) (shl a2-0 4)) (the-as int arg1)) + ) + ) + (-> + (the-as + (pointer float) + (+ (+ (shl a2-0 2) (shl a3-0 4)) (the-as int arg1)) + ) + ) + ) + f0-12 + ) + ) + (let + ((f0-13 + (* + (+ + (-> + (the-as + (pointer float) + (+ (+ (shl v1-1 2) (shl a2-0 4)) (the-as int arg1)) + ) + ) + (-> + (the-as + (pointer float) + (+ (+ (shl a2-0 2) (shl v1-1 4)) (the-as int arg1)) + ) + ) + ) + f0-12 + ) + ) + ) + (set! (-> arg0 data v1-1) f0-13) + (let ((v1-4 f0-13)) + ) + ) + ) + ) + ) + ) + arg0 + ) + +(defun matrix-with-scale->quaternion ((arg0 quaternion) (arg1 matrix)) + "Convert a matrix with a rotation and scale into a quaternion (just the rotation)" + (rlet ((vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + (vf5 :class vf) + (vf6 :class vf) + (vf7 :class vf) + ) + (let ((v1-0 (new 'stack 'matrix))) + (set! (-> v1-0 vector 0 quad) (the-as uint128 0)) + (set! (-> v1-0 vector 1 quad) (the-as uint128 0)) + (set! (-> v1-0 vector 2 quad) (the-as uint128 0)) + (set! (-> v1-0 vector 3 quad) (the-as uint128 0)) + + ;; compute norm of rows of rotation matrix (vector-dot does only xyz) + (let ((f0-2 (vector-dot (-> arg1 vector 0) (-> arg1 vector 0)))) + (let ((f1-3 (vector-dot (-> arg1 vector 1) (-> arg1 vector 1)))) + (let* ((f2-4 (vector-dot (-> arg1 vector 2) (-> arg1 vector 2))) + ;; compute scaling factors. + (f0-4 (/ 1.0 (sqrtf f0-2))) + (f1-5 (/ 1.0 (sqrtf f1-3))) + (f2-6 (/ 1.0 (sqrtf f2-4))) + ) + ;; load the origin matrix. + (.lvf vf1 (&-> arg1 vector 0 quad)) + (.lvf vf2 (&-> arg1 vector 1 quad)) + (.lvf vf3 (&-> arg1 vector 2 quad)) + (.lvf vf4 (&-> arg1 vector 3 quad)) + ;; move scaling factors into vector regs + (let ((a1-1 f0-4)) + (.mov vf5 a1-1) + ) + (let ((a1-2 f1-5)) + (.mov vf6 a1-2) + ) + (let ((a1-3 f2-6)) + (.mov vf7 a1-3) + ) + ) + ) + ) + ;; scale! + (.mul.x.vf vf1 vf1 vf5) + (.mul.x.vf vf2 vf2 vf6) + (.mul.x.vf vf3 vf3 vf7) + ;; store in temp matrix + (.svf (&-> v1-0 vector 0 quad) vf1) + (.svf (&-> v1-0 vector 1 quad) vf2) + (.svf (&-> v1-0 vector 2 quad) vf3) + (.svf (&-> v1-0 vector 3 quad) vf4) + ;; and convert! + (matrix->quaternion arg0 v1-0) + ) + ) + ) + +(defun quaternion-vector-len ((arg0 quaternion)) + "Assuming quaternion is normalized, get the length of the xyz part." + (let ((f0-0 1.0) + (f1-0 (-> arg0 w)) + ) + ;; sqrt(1 - w^2) = sqrt(x^2 + y^2 + z^2) = length + (sqrtf (- f0-0 (* f1-0 f1-0))) + ) + ) + +(defun quaternion-log! ((arg0 quaternion) (arg1 quaternion)) + "Take the log of a quaternion. Unused." + (cond + ((= (-> arg1 w) 0.0) + (set! (-> arg0 x) (* 1.5707963 (-> arg1 x))) + (set! (-> arg0 y) (* 1.5707963 (-> arg1 y))) + (set! (-> arg0 z) (* 1.5707963 (-> arg1 z))) + ) + (else + (let* ((f30-0 (quaternion-vector-len arg1)) + (f0-9 (/ (atan2-rad (-> arg1 w) f30-0) f30-0)) + ) + (set! (-> arg0 x) (* (-> arg1 x) f0-9)) + (set! (-> arg0 y) (* (-> arg1 y) f0-9)) + (let ((f0-10 (* (-> arg1 z) f0-9))) + (set! (-> arg0 z) f0-10) + (let ((v1-0 f0-10)) + ) + ) + ) + ) + ) + arg0 + ) + +(defun quaternion-exp! ((arg0 quaternion) (arg1 quaternion)) + (let ((f30-0 (vector-length (the-as vector arg1)))) + (cond + ((= f30-0 0.0) + (set! (-> arg0 x) 0.0) + (set! (-> arg0 y) 0.0) + (set! (-> arg0 z) 0.0) + (set! (-> arg0 w) 1.0) + ) + (else + (let ((s5-0 (new 'stack 'vector))) + (sincos-rad! (the-as (pointer float) s5-0) f30-0) + (let ((f0-6 (/ (-> s5-0 data 0) f30-0))) + (set! (-> arg0 x) (* (-> arg1 x) f0-6)) + (set! (-> arg0 y) (* (-> arg1 y) f0-6)) + (set! (-> arg0 z) (* (-> arg1 z) f0-6)) + (set! (-> arg0 w) (-> s5-0 data 1)) + ) + ) + ) + ) + ) + arg0 + ) + +(defun quaternion-slerp! ((arg0 quaternion) (arg1 quaternion) (arg2 quaternion) (arg3 float)) + "Real quaternion slerp. Spherical-linear interpolation is a nice way to interpolate + between quaternions." + (local-vars (v1-7 float)) + (rlet ((acc :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + ) + (let ((f0-0 (quaternion-dot arg1 arg2)) + (f30-0 1.0) + ) + (when (< f0-0 0.0) + (set! f0-0 (- f0-0)) + (set! f30-0 -1.0) + (let ((v1-1 f30-0)) + ) + ) + (cond + ((< (- 1.0 f0-0) 0.0001) + (let ((v1-2 (- 1.0 arg3))) + (.mov vf1 v1-2) + ) + (let ((v1-3 (* arg3 f30-0))) + (.mov vf2 v1-3) + ) + (.lvf vf3 (&-> arg1 vec quad)) + (.lvf vf4 (&-> arg2 vec quad)) + (.mul.x.vf acc vf3 vf1) + (.add.mul.x.vf vf3 vf4 vf2 acc) + (.svf (&-> arg0 vec quad) vf3) + (quaternion-normalize! arg0) + ) + (else + (let* ((f1-4 1.0) + (f2-1 f0-0) + (f1-6 (sqrtf (- f1-4 (* f2-1 f2-1)))) + (f0-6 (/ (- f1-6 f0-0) (+ f1-6 f0-0))) + (f28-0 (/ 1.0 f1-6)) + ) + (let ((f0-7 (atan-series-rad f0-6)) + (s2-0 (new 'stack 'vector)) + ) + (set! (-> s2-0 data 0) (* (- 1.0 arg3) f0-7)) + (set! (-> s2-0 data 1) (* (* arg3 f0-7) f30-0)) + (vector-sin-rad! s2-0 s2-0) + (.lvf vf1 (&-> s2-0 quad)) + ) + (let ((v1-6 f28-0)) + (.mov vf2 v1-6) + ) + ) + (.mul.x.vf vf1 vf1 vf2) + (.lvf vf3 (&-> arg1 vec quad)) + (.lvf vf4 (&-> arg2 vec quad)) + (.mul.x.vf acc vf3 vf1) + (.add.mul.y.vf vf3 vf4 vf1 acc) + (.svf (&-> arg0 vec quad) vf3) + (.mov v1-7 vf3) + ) + ) + ) + arg0 + ) + ) + +(defun quaternion-pseudo-slerp! ((arg0 quaternion) (arg1 quaternion) (arg2 quaternion) (arg3 float)) + "This is a bad interpolation between quaternions. It lerps then normalizes. + It will behave extremely poorly for 180 rotations. + It is unused." + (rlet ((acc :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + ) + (let ((f1-0 (quaternion-dot arg1 arg2)) + (f0-0 1.0) + ) + (when (< f1-0 0.0) + (let ((f0-1 (- f1-0))) + ) + (set! f0-0 -1.0) + (let ((v1-1 f0-0)) + ) + ) + (let ((v1-2 (- 1.0 arg3))) + (.mov vf1 v1-2) + ) + (let ((v1-3 (* arg3 f0-0))) + (.mov vf2 v1-3) + ) + ) + (.lvf vf3 (&-> arg1 vec quad)) + (.lvf vf4 (&-> arg2 vec quad)) + (.mul.x.vf acc vf3 vf1) + (.add.mul.x.vf vf3 vf4 vf2 acc) + (.svf (&-> arg0 vec quad) vf3) + (quaternion-normalize! arg0) + arg0 + ) + ) + +(defun quaternion-zxy! ((arg0 quaternion) (arg1 vector)) + (rlet ((acc :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + (vf5 :class vf) + (vf6 :class vf) + (vf7 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (let ((s4-0 (new 'stack 'vector)) + (gp-0 (new 'stack 'vector)) + (s5-0 (new 'stack 'vector)) + ) + (vector-rad<-vector-deg/2! s4-0 arg1) + (vector-sincos-rad! gp-0 s5-0 s4-0) + (.lvf vf1 (&-> gp-0 quad)) + (.lvf vf2 (&-> s5-0 quad)) + ) + (.mul.x.vf vf4 vf0 vf1 :mask #b1000) + (.add.vf vf4 vf0 vf2 :mask #b111) + (.sub.vf vf4 vf0 vf4 :mask #b110) + (.add.vf vf3 vf0 vf1 :mask #b111) + (.mul.x.vf vf3 vf0 vf2 :mask #b1000) + (.outer.product.vf vf6 vf0 vf0) + (.outer.product.vf vf5 vf0 vf0) + (.mul.x.vf vf6 vf0 vf6 :mask #b1000) + (.mul.x.vf vf5 vf0 vf5 :mask #b1000) + (.mul.vf acc vf6 vf4) + (.add.mul.vf vf7 vf5 vf3 acc) + (.svf (&-> arg0 vec quad) vf7) + arg0 + ) + ) + +(defun vector-x-quaternion! ((arg0 vector) (arg1 quaternion)) + "Get the first row of the rotation matrix for this quaternion" + (let ((s5-0 (new 'stack 'matrix))) + (set! (-> s5-0 vector 0 quad) (the-as uint128 0)) + (set! (-> s5-0 vector 1 quad) (the-as uint128 0)) + (set! (-> s5-0 vector 2 quad) (the-as uint128 0)) + (set! (-> s5-0 vector 3 quad) (the-as uint128 0)) + (quaternion->matrix s5-0 arg1) + (set! (-> arg0 quad) (-> (the-as (pointer uint128) (-> s5-0 data)) 0)) + ) + arg0 + ) + +(defun vector-y-quaternion! ((arg0 vector) (arg1 quaternion)) + "Get the second row of the rotation matrix for this quaternion" + (let ((s5-0 (new 'stack 'matrix))) + (set! (-> s5-0 vector 0 quad) (the-as uint128 0)) + (set! (-> s5-0 vector 1 quad) (the-as uint128 0)) + (set! (-> s5-0 vector 2 quad) (the-as uint128 0)) + (set! (-> s5-0 vector 3 quad) (the-as uint128 0)) + (quaternion->matrix s5-0 arg1) + (set! (-> arg0 quad) (-> (the-as (pointer uint128) (&-> s5-0 data 4)) 0)) + ) + arg0 + ) + +(defun vector-z-quaternion! ((arg0 vector) (arg1 quaternion)) + "Get the third row of the rotation matrix for this quaternion" + (let ((s5-0 (new 'stack 'matrix))) + (set! (-> s5-0 vector 0 quad) (the-as uint128 0)) + (set! (-> s5-0 vector 1 quad) (the-as uint128 0)) + (set! (-> s5-0 vector 2 quad) (the-as uint128 0)) + (set! (-> s5-0 vector 3 quad) (the-as uint128 0)) + (quaternion->matrix s5-0 arg1) + (set! (-> arg0 quad) (-> (the-as (pointer uint128) (&-> s5-0 data 8)) 0)) + ) + arg0 + ) + +(defun quaternion-y-angle ((arg0 quaternion)) + "Not 100% sure, but get the y rotation angle?" + (let ((v1-1 (vector-z-quaternion! (new 'stack 'vector) arg0))) + (atan (-> v1-1 data 0) (-> v1-1 data 2)) + ) + ) + +(defun quaternion-vector-y-angle ((arg0 quaternion) (arg1 vector)) + "Not sure. Angle between quaternion and axis, projected in xz plane?" + (let ((f30-0 (quaternion-y-angle arg0)) + (f0-2 (atan (-> arg1 data 0) (-> arg1 data 2))) + ) + (deg-diff f30-0 f0-2) + ) + ) + +(defun quaternion-rotate-local-x! ((arg0 quaternion) (arg1 quaternion) (arg2 float)) + "Rotate existing quaternion along x axis." + (let ((t9-0 quaternion-vector-angle!) + (a0-1 (new 'stack 'quaternion)) + ) + (set! (-> a0-1 vec quad) (the-as uint128 0)) + (let ((a2-1 (t9-0 a0-1 (new 'static 'vector :x 1.0 :w 1.0) arg2))) + (quaternion-normalize! (quaternion*! arg0 arg1 a2-1)) + ) + ) + ) + +(defun quaternion-rotate-local-y! ((arg0 quaternion) (arg1 quaternion) (arg2 float)) + "Rotate existing quaternion along y axis" + (let ((t9-0 quaternion-vector-angle!) + (a0-1 (new 'stack 'quaternion)) + ) + (set! (-> a0-1 vec quad) (the-as uint128 0)) + (let ((a2-1 (t9-0 a0-1 (new 'static 'vector :y 1.0 :w 1.0) arg2))) + (quaternion-normalize! (quaternion*! arg0 arg1 a2-1)) + ) + ) + ) + +(defun quaternion-rotate-local-z! ((arg0 quaternion) (arg1 quaternion) (arg2 float)) + "Rotate existing quaternion along z axis." + (let ((t9-0 quaternion-vector-angle!) + (a0-1 (new 'stack 'quaternion)) + ) + (set! (-> a0-1 vec quad) (the-as uint128 0)) + (let ((a2-1 (t9-0 a0-1 (new 'static 'vector :z 1.0 :w 1.0) arg2))) + (quaternion-normalize! (quaternion*! arg0 arg1 a2-1)) + ) + ) + ) + +(defun quaternion-rotate-y! ((arg0 quaternion) (arg1 quaternion) (arg2 float)) + "Rotate existing quaternion along y axis (right multiply)" + (let ((t9-0 quaternion-vector-angle!) + (a0-1 (new 'stack 'quaternion)) + ) + (set! (-> a0-1 vec quad) (the-as uint128 0)) + (let ((a1-2 (t9-0 a0-1 (new 'static 'vector :y 1.0 :w 1.0) arg2))) + (quaternion-normalize! (quaternion*! arg0 a1-2 arg1)) + ) + ) + ) + +(defun quaternion-rotate-x! ((arg0 quaternion) (arg1 quaternion) (arg2 float)) + "Rotate existing quaternion along x axis. This has a different implementation + from the others for some reason." + (let ((s4-0 quaternion-vector-angle!) + (s3-0 (new 'stack 'quaternion)) + ) + (set! (-> s3-0 vec quad) (the-as uint128 0)) + (let ((t9-0 vector-x-quaternion!) + (a0-1 (new 'stack 'vector)) + ) + (set! (-> a0-1 quad) (the-as uint128 0)) + (let ((a1-3 (s4-0 s3-0 (t9-0 a0-1 arg1) arg2))) + (quaternion-normalize! (quaternion*! arg0 a1-3 arg1)) + ) + ) + ) + ) + +(defun quaternion-rotate-z! ((arg0 quaternion) (arg1 quaternion) (arg2 float)) + "Rotate existing quaternion along z axis. Has the weird implementation too." + (let ((s4-0 quaternion-vector-angle!) + (s3-0 (new 'stack 'quaternion)) + ) + (set! (-> s3-0 vec quad) (the-as uint128 0)) + (let ((t9-0 vector-z-quaternion!) + (a0-1 (new 'stack 'vector)) + ) + (set! (-> a0-1 quad) (the-as uint128 0)) + (let ((a1-3 (s4-0 s3-0 (t9-0 a0-1 arg1) arg2))) + (quaternion-normalize! (quaternion*! arg0 a1-3 arg1)) + ) + ) + ) + ) + +(defun quaternion-delta-y ((arg0 quaternion) (arg1 quaternion)) + (acos (vector-dot (vector-z-quaternion! (new 'stack 'vector) arg0) + (vector-z-quaternion! (new 'stack 'vector) arg1) + ) + ) + ) + +;; (local-vars (f0-1 float)) +;; (let ((gp-0 acos)) +;; (let* ((s5-0 (vector-z-quaternion! (new 'stack 'vector) arg0)) +;; (v1-1 (vector-z-quaternion! (new 'stack 'vector) arg1)) +;; (f0-0 (-> s5-0 data 0)) +;; (f1-0 (-> s5-0 data 1)) +;; (f2-0 (-> s5-0 data 2)) +;; (f3-0 (-> v1-1 data 0)) +;; (f4-0 (-> v1-1 data 1)) +;; (f5-0 (-> v1-1 data 2)) +;; ) +;; (.mula.s f0-0 f3-0) +;; (.madda.s f1-0 f4-0) +;; (.madd.s f0-1 f2-0 f5-0) +;; ) +;; (gp-0 f0-1) +;; ) + + +(defun quaternion-rotate-y-to-vector! ((arg0 quaternion) (arg1 quaternion) (arg2 quaternion) (arg3 float)) + (let ((s5-0 (new 'stack 'quaternion))) + (let ((t9-0 vector-xz-normalize!) + (a0-1 (new 'stack 'vector)) + ) + (set! (-> a0-1 data 0) (-> arg2 x)) + (set! (-> a0-1 data 1) 0.0) + (set! (-> a0-1 data 2) (-> arg2 z)) + (set! (-> a0-1 data 3) 1.0) + (let ((s0-0 (t9-0 a0-1 1.0))) + (quaternion-from-two-vectors-max-angle! + s5-0 + (vector-z-quaternion! (the-as vector (new 'stack 'quaternion)) arg1) + s0-0 + arg3 + ) + ) + ) + (quaternion-normalize! (quaternion*! arg0 s5-0 arg1)) + ) + ) + + +(defun vector-rotate-y! ((arg0 vector) (arg1 vector) (arg2 float)) + (let ((a1-2 (quaternion-vector-angle! + (new 'stack 'quaternion) + (new 'static 'vector :y 1.0 :w 1.0) + arg2 + ) + ) + (s4-0 (new 'stack 'matrix)) + ) + (quaternion->matrix s4-0 a1-2) + (vector-matrix*! arg0 arg1 s4-0) + ) + ) + +(defun vector-y-angle ((arg0 vector)) + (atan (-> arg0 data 0) (-> arg0 data 2)) + ) + +(defun vector-x-angle ((arg0 vector)) + (atan (-> arg0 data 1) (vector-xz-length arg0)) + ) + +(defun quaterion<-rotate-y-vector ((arg0 quaternion) (arg1 vector)) + (quaternion-vector-angle! + arg0 + (new 'static 'vector :y 1.0 :w 1.0) + (vector-y-angle arg1) + ) + ) + +(defun quaternion-xz-angle ((arg0 quaternion)) + (let ((gp-0 (new 'stack 'matrix)) + (s5-0 (new 'stack 'vector)) + ) + (quaternion->matrix gp-0 arg0) + (let ((v1-1 s5-0)) + (set! (-> v1-1 data 0) 0.0) + (set! (-> v1-1 data 1) 0.0) + (set! (-> v1-1 data 2) 1.0) + (set! (-> v1-1 data 3) 1.0) + ) + (vector-matrix*! s5-0 s5-0 gp-0) + (vector-y-angle s5-0) + ) + ) + +(defun-debug quaternion-validate ((arg0 quaternion)) + (with-pp + (let ((f0-0 (quaternion-norm arg0))) + (when (or (< 1.01 f0-0) (< f0-0 0.99)) + (format #t "WARNING: bad quaternion (magnitude ~F) process is " f0-0) + (if (and pp (type-type? (-> pp type) process-tree)) + (format #t "~A~%" (-> pp name)) + (format #t "#f~%") + ) + ) + ) + (none) ) - (set! (-> dst w) 1.0) - dst ) diff --git a/goal_src/engine/math/transform-h.gc b/goal_src/engine/math/transform-h.gc index 9a19be0a1c..f773cffd5e 100644 --- a/goal_src/engine/math/transform-h.gc +++ b/goal_src/engine/math/transform-h.gc @@ -22,7 +22,10 @@ (rot vector :inline :offset-assert 32) (scale vector :inline :offset-assert 48) ) + (:methods + (new (symbol type) _type_ 0) + ) :method-count-assert 9 :size-assert #x40 :flag-assert #x900000040 - ) \ No newline at end of file + ) diff --git a/goal_src/engine/math/transform.gc b/goal_src/engine/math/transform.gc index cec96747ff..97ccfafd34 100644 --- a/goal_src/engine/math/transform.gc +++ b/goal_src/engine/math/transform.gc @@ -5,3 +5,101 @@ ;; name in dgo: transform ;; dgos: GAME, ENGINE +(defmethod print transform ((obj transform)) + (format #t "# obj trans data 0) + (-> obj trans data 1) + (-> obj trans data 2) + (-> obj trans data 3) + ) + (format #t "~T~Trot: ~F ~F ~F ~F ~%" + (-> obj rot data 0) + (-> obj rot data 1) + (-> obj rot data 2) + (-> obj rot data 3) + ) + (format #t "~T~Tscale:~F ~F ~F ~F>" + (-> obj scale data 0) + (-> obj scale data 1) + (-> obj scale data 2) + (-> obj scale data 3) + ) + obj + ) + +(defmethod new trs ((allocation symbol) (type-to-make type)) + "Create a new trs and set it equal to identity." + (let ((obj (object-new allocation type-to-make (the-as int (-> type-to-make size))))) + (set! (-> obj trans data 3) 1.0) + (set! (-> obj rot data 3) 1.0) + (vector-identity! (-> obj scale)) + obj + ) + ) + +(defun transform-matrix-calc! ((tf transform) (dst-mat matrix)) + "Convert a transform to a matrix. This is not particularly efficient." + (let ((s4-0 (new 'stack 'matrix))) + (set! (-> s4-0 vector 0 quad) (the-as uint128 0)) + (set! (-> s4-0 vector 1 quad) (the-as uint128 0)) + (set! (-> s4-0 vector 2 quad) (the-as uint128 0)) + (set! (-> s4-0 vector 3 quad) (the-as uint128 0)) + (let ((s3-0 (new 'stack 'matrix))) + (set! (-> s3-0 vector 0 quad) (the-as uint128 0)) + (set! (-> s3-0 vector 1 quad) (the-as uint128 0)) + (set! (-> s3-0 vector 2 quad) (the-as uint128 0)) + (set! (-> s3-0 vector 3 quad) (the-as uint128 0)) + ;; start with identity + (matrix-identity! dst-mat) + ;; set translation (which also sets identity...) + (matrix-translate! dst-mat (-> tf trans)) + ;; rotate y axis (this is first, so yaw is "world aligned" + (matrix-rotate-y! s4-0 (-> tf rot data 1)) + (matrix*! s3-0 s4-0 dst-mat) + ;; rotate x axis + (matrix-rotate-x! s4-0 (-> tf rot data 0)) + (matrix*! dst-mat s4-0 s3-0) + ;; rotate z axis + (matrix-rotate-z! s4-0 (-> tf rot data 2)) + (matrix*! s3-0 s4-0 dst-mat) + ;; apply scale + (matrix-scale! s4-0 (-> tf scale)) + (matrix*! dst-mat s4-0 s3-0) + ) + ) + ) + +(defun transform-matrix-parent-calc! ((tf transform) (dst-mat matrix) (inv-scale vector)) + "Convert a transform to a matrix, applying an inverse scaling." + (let ((s4-0 (new 'stack 'matrix))) + (set! (-> s4-0 vector 0 quad) (the-as uint128 0)) + (set! (-> s4-0 vector 1 quad) (the-as uint128 0)) + (set! (-> s4-0 vector 2 quad) (the-as uint128 0)) + (set! (-> s4-0 vector 3 quad) (the-as uint128 0)) + (let ((s3-0 (new 'stack 'matrix))) + (set! (-> s3-0 vector 0 quad) (the-as uint128 0)) + (set! (-> s3-0 vector 1 quad) (the-as uint128 0)) + (set! (-> s3-0 vector 2 quad) (the-as uint128 0)) + (set! (-> s3-0 vector 3 quad) (the-as uint128 0)) + (matrix-identity! s3-0) + (matrix-translate! s3-0 (-> tf trans)) + (matrix-inv-scale! s4-0 inv-scale) + (matrix*! dst-mat s4-0 s3-0) + (matrix-rotate-y! s4-0 (-> tf rot data 1)) + (matrix*! s3-0 s4-0 dst-mat) + (matrix-rotate-x! s4-0 (-> tf rot data 0)) + (matrix*! dst-mat s4-0 s3-0) + (matrix-rotate-z! s4-0 (-> tf rot data 2)) + (matrix*! s3-0 s4-0 dst-mat) + (matrix-scale! s4-0 (-> tf scale)) + (matrix*! dst-mat s4-0 s3-0) + ) + ) + ) + +(defun trs-matrix-calc! ((tf trs) (dst-mat matrix)) + "Convert a trs to a matrix" + ;; this relies on the fact that trs and transform both have the same memory layout. + (transform-matrix-calc! (the-as transform (-> tf trans)) dst-mat) + ) diff --git a/goal_src/engine/math/trigonometry-h.gc b/goal_src/engine/math/trigonometry-h.gc index c59eb9c933..366c0e44ba 100644 --- a/goal_src/engine/math/trigonometry-h.gc +++ b/goal_src/engine/math/trigonometry-h.gc @@ -11,3 +11,12 @@ (defun-extern cos float float) (defun-extern vector-sincos! vector vector vector int) (defun-extern atan float float float) +(defun-extern acos float float) +(defun-extern acos-rad float float) +(defun-extern atan2-rad float float float) +(defun-extern sincos-rad! (pointer float) float int) +(defun-extern atan-series-rad float float) +(defun-extern vector-sin-rad! vector vector vector) +(defun-extern vector-rad<-vector-deg/2! vector vector int) +(defun-extern vector-sincos-rad! vector vector vector int) +(defun-extern deg-diff float float float) diff --git a/goal_src/engine/math/vector-h.gc b/goal_src/engine/math/vector-h.gc index c43a659704..87757af772 100644 --- a/goal_src/engine/math/vector-h.gc +++ b/goal_src/engine/math/vector-h.gc @@ -682,3 +682,7 @@ ) (define *zero-vector* (new 'static 'vector :x 0. :y 0. :z 0. :w 0.)) +(define-extern vector-identity! (function vector vector)) +(define-extern vector-length (function vector float)) +(define-extern vector-xz-normalize! (function vector float vector)) +(define-extern vector-xz-length (function vector float)) diff --git a/goalc/compiler/Compiler.h b/goalc/compiler/Compiler.h index 293d8dea62..56068da0a6 100644 --- a/goalc/compiler/Compiler.h +++ b/goalc/compiler/Compiler.h @@ -63,6 +63,9 @@ class Compiler { private: bool get_true_or_false(const goos::Object& form, const goos::Object& boolean); bool try_getting_macro_from_goos(const goos::Object& macro_name, goos::Object* dest); + bool expand_macro_once(const goos::Object& src, goos::Object* out, Env* env); + goos::Object expand_macro_completely(const goos::Object& src, Env* env); + void set_bitfield(const goos::Object& form, BitFieldVal* dst, RegVal* src, Env* env); Val* do_set(const goos::Object& form, Val* dst, RegVal* src_in_reg, Val* src, Env* env); Val* compile_goos_macro(const goos::Object& o, diff --git a/goalc/compiler/compilation/Asm.cpp b/goalc/compiler/compilation/Asm.cpp index 432bdd59c6..682723d93e 100644 --- a/goalc/compiler/compilation/Asm.cpp +++ b/goalc/compiler/compilation/Asm.cpp @@ -1210,18 +1210,19 @@ Val* Compiler::compile_asm_outer_product_vf(const goos::Object& form, // Init two temp registers auto temp1 = env->make_vfr(dest->type()); auto temp2 = env->make_vfr(dest->type()); + auto temp_dst = env->make_vfr(dest->type()); // First Portion // - Swizzle src1 appropriately env->emit_ir(color, temp1, src1, 0b00001001); // - Move it into 'dest' safely (avoid mutating `w`) - env->emit_ir(color, dest, dest, temp1, 0b0111); + env->emit_ir(color, temp_dst, temp_dst, temp1, 0b0111); // - Swizzle src2 appropriately env->emit_ir(color, temp1, src2, 0b00010010); // - Multiply - Result in `dest` - env->emit_ir(color, temp1, dest, temp1, IR_VFMath3Asm::Kind::MUL); + env->emit_ir(color, temp1, temp_dst, temp1, IR_VFMath3Asm::Kind::MUL); // - Move it into 'dest' safely (avoid mutating `w`) - env->emit_ir(color, dest, dest, temp1, 0b0111); + env->emit_ir(color, temp_dst, temp_dst, temp1, 0b0111); // Second Portion // - Swizzle src2 appropriately @@ -1233,7 +1234,7 @@ Val* Compiler::compile_asm_outer_product_vf(const goos::Object& form, // Finalize // - Subtract - env->emit_ir(color, temp2, dest, temp1, IR_VFMath3Asm::Kind::SUB); + env->emit_ir(color, temp2, temp_dst, temp1, IR_VFMath3Asm::Kind::SUB); // - Blend result, as to avoid not modifying dest's `w` component env->emit_ir(color, dest, dest, temp2, 0b0111); return get_none(); diff --git a/goalc/compiler/compilation/Macro.cpp b/goalc/compiler/compilation/Macro.cpp index 6223312206..bf68d38101 100644 --- a/goalc/compiler/compilation/Macro.cpp +++ b/goalc/compiler/compilation/Macro.cpp @@ -193,4 +193,42 @@ Val* Compiler::compile_mlet(const goos::Object& form, const goos::Object& rest, } }); return result; +} + +bool Compiler::expand_macro_once(const goos::Object& src, goos::Object* out, Env*) { + if (!src.is_pair()) { + return false; + } + + auto first = src.as_pair()->car; + auto rest = src.as_pair()->cdr; + if (!first.is_symbol()) { + return false; + } + + goos::Object macro_obj; + if (!try_getting_macro_from_goos(first, ¯o_obj)) { + return false; + } + + auto macro = macro_obj.as_macro(); + Arguments args = m_goos.get_args(src, rest, macro->args); + auto mac_env_obj = EnvironmentObject::make_new(); + auto mac_env = mac_env_obj.as_env(); + mac_env->parent_env = m_goos.global_environment.as_env(); + m_goos.set_args_in_env(src, args, macro->args, mac_env); + + auto goos_result = m_goos.eval_list_return_last(macro->body, macro->body, mac_env); + // make the macro expanded form point to the source where the macro was used for error messages. + m_goos.reader.db.inherit_info(src, goos_result); + + *out = goos_result; + return true; +} + +goos::Object Compiler::expand_macro_completely(const goos::Object& src, Env* env) { + goos::Object result = src; + while (expand_macro_once(result, &result, env)) { + } + return result; } \ No newline at end of file diff --git a/goalc/compiler/compilation/Static.cpp b/goalc/compiler/compilation/Static.cpp index a732ad8b43..d04127bc96 100644 --- a/goalc/compiler/compilation/Static.cpp +++ b/goalc/compiler/compilation/Static.cpp @@ -434,7 +434,8 @@ StaticResult Compiler::compile_static_no_eval_for_pairs(const goos::Object& form * - a constant * - #t or #f */ -StaticResult Compiler::compile_static(const goos::Object& form, Env* env) { +StaticResult Compiler::compile_static(const goos::Object& form_before_macro, Env* env) { + auto form = expand_macro_completely(form_before_macro, env); auto fie = get_parent_env_of_type(env); auto fe = get_parent_env_of_type(env); auto segment = fe->segment; diff --git a/test/decompiler/reference/all_forward_declarations.gc b/test/decompiler/reference/all_forward_declarations.gc index ce715bbfed..ef93df312c 100644 --- a/test/decompiler/reference/all_forward_declarations.gc +++ b/test/decompiler/reference/all_forward_declarations.gc @@ -97,4 +97,23 @@ (define-extern cos (function float float)) (define-extern vector-sincos! (function vector vector vector int)) (define-extern matrix-axis-sin-cos! (function matrix vector float float none)) -(define-extern atan (function float float float)) \ No newline at end of file +(define-extern atan (function float float float)) + +;; transform +(define-extern vector-identity! (function vector vector)) + +;; quaternion +(define-extern acos (function float float)) +(define-extern acos-rad (function float float)) +(define-extern atan2-rad (function float float float)) +(define-extern vector-length (function vector float)) +(define-extern sincos-rad! (function (pointer float) float int)) +(define-extern atan-series-rad (function float float)) +(define-extern vector-sin-rad! (function vector vector vector)) +(define-extern vector-rad<-vector-deg/2! (function vector vector int)) +(define-extern vector-sincos-rad! (function vector vector vector int)) +(define-extern deg-diff (function float float float)) +(define-extern vector-xz-normalize! (function vector float vector)) +(declare-type quaternion structure) +(define-extern quaternion-from-two-vectors-max-angle! (function quaternion vector vector float quaternion)) +(define-extern vector-xz-length (function vector float)) \ No newline at end of file diff --git a/test/decompiler/reference/gkernel-h_REF.gc b/test/decompiler/reference/gkernel-h_REF.gc index 177779129a..11b2ac03c4 100644 --- a/test/decompiler/reference/gkernel-h_REF.gc +++ b/test/decompiler/reference/gkernel-h_REF.gc @@ -288,38 +288,25 @@ ;; WARN: Unsupported inline assembly instruction kind - [subu a2, v1, s7] ;; WARN: Unsupported inline assembly instruction kind - [sllv a2, v1, r0] (defmethod print handle ((obj handle)) - (local-vars - (r0-0 none) - (a2-0 int) - (a2-1 process) - (a2-2 (pointer process)) - (s7-0 none) - ) + (local-vars (r0-0 none) (a2-0 int) (a2-2 (pointer process)) (s7-0 none)) (if (nonzero? obj) (let ((t9-0 format) (a0-1 #t) (a1-0 "#") + (v1-0 obj) ) - (let ((v1-0 obj)) - (.subu a2-0 (the-as handle v1-0) s7-0) - (set! a2-1 (and (nonzero? a2-0) (begin - (.sllv a2-2 (the-as handle v1-0) r0-0) - (let ((a3-0 (-> a2-2 0))) - (set! - a2-1 - (if (= (sar v1-0 32) (-> a3-0 pid)) - a3-0 - ) - ) - ) - (let ((v1-2 a2-1)) - ) - a2-1 - ) - ) - ) + (.subu a2-0 (the-as handle v1-0) s7-0) + (t9-0 a0-1 a1-0 (and (nonzero? a2-0) (begin + (.sllv a2-2 (the-as handle v1-0) r0-0) + (let ((a3-0 (-> a2-2 0))) + (if (= (sar v1-0 32) (-> a3-0 pid)) + a3-0 + ) + ) + ) + ) + (sar (the-as int obj) 32) ) - (t9-0 a0-1 a1-0 a2-1 (sar (the-as int obj) 32)) ) (format #t "#") ) diff --git a/test/decompiler/reference/gkernel_REF.gc b/test/decompiler/reference/gkernel_REF.gc index 32c8c74228..7ceb4052da 100644 --- a/test/decompiler/reference/gkernel_REF.gc +++ b/test/decompiler/reference/gkernel_REF.gc @@ -582,7 +582,6 @@ ) ;; definition for method 14 of type dead-pool -;; INFO: Return type mismatch process-tree vs process. (defmethod get-process dead-pool ((obj dead-pool) (arg0 type) (arg1 int)) (let ((s4-0 (the-as object (-> obj child)))) (when @@ -602,7 +601,7 @@ (v1-6 (the-as process s4-0)) ) (t9-1 a0-2 a1-2 a2-1 (if (the-as process v1-6) - (-> (the-as (pointer process-tree) v1-6) 0 self) + (-> (the-as (pointer process) v1-6) 0 self) ) (-> obj name) ) @@ -611,19 +610,16 @@ ) (the-as process (cond (s4-0 - (set! - (-> (the-as (pointer process-tree) s4-0) 0 type) - arg0 - ) - (-> (the-as (pointer process-tree) s4-0) 0) + (set! (-> (the-as (pointer process) s4-0) 0 type) arg0) + (-> (the-as (pointer process) s4-0) 0) ) (else (format 0 "WARNING: ~A ~A could not be allocated, because ~A was empty.~%" arg0 - (if (the-as (pointer process-tree) s4-0) - (-> (the-as (pointer process-tree) s4-0) 0 self) + (if (the-as (pointer process) s4-0) + (-> (the-as (pointer process) s4-0) 0 self) ) (-> obj name) ) @@ -886,17 +882,13 @@ (let ((v1-5 (-> s1-0 next))) (set! (-> s1-0 next) s4-0) (set! (-> s4-0 next) v1-5) - (when v1-5 + (if v1-5 (set! (-> v1-5 prev) s4-0) - (let ((v1-6 s4-0)) - ) ) ) (set! (-> s4-0 prev) s1-0) - (when (= s1-0 (-> obj alive-list prev)) + (if (= s1-0 (-> obj alive-list prev)) (set! (-> obj alive-list prev) s4-0) - (let ((v1-9 s4-0)) - ) ) (let ((a0-4 (gap-location obj s1-0))) (set! @@ -914,14 +906,12 @@ (if (= (-> obj first-gap) s1-0) (set! (-> obj first-gap) (find-gap obj s4-0)) ) - (when + (if (or (not (-> obj first-shrink)) (< (the-as int s3-0) (the-as int (-> obj first-shrink process))) ) (set! (-> obj first-shrink) s4-0) - (let ((v1-22 s4-0)) - ) ) (set! (-> s3-0 parent) (-> obj ppointer)) (set! (-> s3-0 pool) obj) @@ -1048,13 +1038,9 @@ ) ((< f0-2 0.2) (set! arg0 (shl arg0 2)) - (let ((v1-10 arg0)) - ) ) ((< f0-2 0.3) (set! arg0 (shl arg0 1)) - (let ((v1-12 arg0)) - ) ) ) ) @@ -1066,8 +1052,6 @@ (when (not v1-13) (set! v1-13 (-> obj alive-list next)) (set! (-> obj first-shrink) v1-13) - (let ((a0-5 v1-13)) - ) ) (if v1-13 (shrink-heap obj (-> v1-13 process)) @@ -1130,10 +1114,8 @@ (let ((v1-19 (-> a1-3 next))) (set! (-> a1-3 next) s4-0) (set! (-> s4-0 next) v1-19) - (when v1-19 + (if v1-19 (set! (-> v1-19 prev) s4-0) - (let ((v1-20 s4-0)) - ) ) ) (set! (-> s4-0 prev) a1-3) @@ -1285,8 +1267,6 @@ (iterate-process-tree (-> v1-4 0) arg1 arg2) (set! v1-4 s3-1) ) - (let ((a0-4 v1-4)) - ) ) ) ) @@ -1323,8 +1303,6 @@ (execute-process-tree (-> v1-8 0) arg1 arg2) (set! v1-8 s4-1) ) - (let ((a0-6 v1-8)) - ) ) ) ) @@ -1353,8 +1331,6 @@ ) (set! v1-5 s5-1) ) - (let ((a0-5 v1-5)) - ) ) ) (the-as process #f) @@ -1395,7 +1371,7 @@ ) ) (when (-> a0-0 trans-hook) - (let* + (let ((s4-0 (new 'process @@ -1406,13 +1382,14 @@ (-> a0-0 main-thread stack-top) ) ) - (v0-1 - (reset-and-call s4-0 (-> a0-0 trans-hook)) + ) + (let + ((v0-1 + (reset-and-call s4-0 (-> a0-0 trans-hook)) + ) ) ) (delete s4-0) - (let ((v1-12 v0-1)) - ) ) (if (= (-> a0-0 status) 'dead) (return (begin @@ -1617,52 +1594,44 @@ (v1-4 (the-as (pointer process-tree) #f)) ) (let ((t1-0 t0-0)) - (when (= (if t1-0 - (-> t1-0 0 self) - ) - arg0 - ) + (if (= (if t1-0 + (-> t1-0 0 self) + ) + arg0 + ) (set! a3-1 a2-1) - (let ((t1-3 a3-1)) - ) ) ) (let ((t1-4 t0-0)) - (when (= (if t1-4 - (-> t1-4 0 self) - ) - arg1 - ) + (if (= (if t1-4 + (-> t1-4 0 self) + ) + arg1 + ) (set! v1-4 a2-1) - (let ((t1-7 v1-4)) - ) ) ) (while (and (-> t0-0 0 brother) (or (not a3-1) (not v1-4))) (let ((t1-8 t0-0)) - (when (= (-> (if t1-8 - (-> t1-8 0 self) - ) - brother - ) - arg1 - ) + (if (= (-> (if t1-8 + (-> t1-8 0 self) + ) + brother + ) + arg1 + ) (set! v1-4 t0-0) - (let ((t1-12 v1-4)) - ) ) ) (let ((t1-13 t0-0)) - (when (= (-> (if t1-13 - (-> t1-13 0 self) - ) - brother - ) - arg0 - ) + (if (= (-> (if t1-13 + (-> t1-13 0 self) + ) + brother + ) + arg0 + ) (set! a3-1 t0-0) - (let ((t1-17 a3-1)) - ) ) ) (set! t0-0 (-> t0-0 0 brother)) @@ -1842,32 +1811,30 @@ (entity-deactivate-handler obj (-> obj entity)) ) (let ((s5-0 pp)) - ) - (let ((s4-0 (-> obj stack-frame-top))) - (while (the-as protect-frame s4-0) - (let ((v1-5 (-> s4-0 type))) - (if (or (= v1-5 protect-frame) (= v1-5 state)) - ((-> (the-as protect-frame s4-0) exit)) + (let ((s4-0 (-> obj stack-frame-top))) + (while (the-as protect-frame s4-0) + (let ((v1-5 (-> s4-0 type))) + (if (or (= v1-5 protect-frame) (= v1-5 state)) + ((-> (the-as protect-frame s4-0) exit)) + ) + ) + (set! + (the-as protect-frame s4-0) + (-> (the-as protect-frame s4-0) next) ) ) - (set! - (the-as protect-frame s4-0) - (-> (the-as protect-frame s4-0) next) - ) + ) + (let ((s6-2 s5-0)) ) ) - (let ((v0-2 (process-disconnect obj)) - (v1-11 (-> obj child)) - ) + (let ((v0-2 (process-disconnect obj))) + ) + (let ((v1-11 (-> obj child))) (while v1-11 (let ((s5-1 (-> v1-11 0 brother))) (deactivate (-> v1-11 0)) - (let ((v1-13 v0-2)) - ) (set! v1-11 s5-1) ) - (let ((a0-8 v1-11)) - ) ) ) (return-process (-> obj pool) obj) diff --git a/test/decompiler/reference/gstate_REF.gc b/test/decompiler/reference/gstate_REF.gc index 73785a6d8e..f159827565 100644 --- a/test/decompiler/reference/gstate_REF.gc +++ b/test/decompiler/reference/gstate_REF.gc @@ -99,8 +99,6 @@ (cond ((-> s0-2 exit) (set! (-> pp stack-frame-top) s0-2) - (let ((v1-20 s0-2)) - ) ) (else (set! (-> pp stack-frame-top) #f) @@ -143,14 +141,24 @@ ;; definition for function send-event-function (defun send-event-function ((arg0 process) (arg1 event-message-block)) - (when (and arg0 (!= (-> arg0 type) process-tree) (-> arg0 event-hook)) - (let ((s6-1 arg0)) - ) - ((-> arg0 event-hook) - (-> arg1 from) - (-> arg1 num-params) - (-> arg1 message) - arg1 + (if (and arg0 (!= (-> arg0 type) process-tree) (-> arg0 event-hook)) + (let ((gp-0 pp)) + (let ((s6-1 arg0)) + ) + (let + ((v0-0 + ((-> arg0 event-hook) + (-> arg1 from) + (-> arg1 num-params) + (-> arg1 message) + arg1 + ) + ) + ) + (let ((s6-2 gp-0)) + ) + v0-0 + ) ) ) ) diff --git a/test/decompiler/reference/gstring_REF.gc b/test/decompiler/reference/gstring_REF.gc index ed6accfa46..283910e74d 100644 --- a/test/decompiler/reference/gstring_REF.gc +++ b/test/decompiler/reference/gstring_REF.gc @@ -489,10 +489,8 @@ (&- arg-end (the-as uint arg-start)) ) ) - (when (= (-> arg-end 0) 34) + (if (= (-> arg-end 0) 34) (set! arg-end (&-> arg-end 1)) - (let ((v1-6 arg-end)) - ) ) (let ((a1-3 (string-skip-whitespace arg-end))) (string-suck-up! arg a1-3) @@ -548,8 +546,6 @@ (when (= (-> next-char-2 1) 45) (set! v1-0 #t) (set! next-char-2 (&-> next-char-2 1)) - (let ((a1-8 next-char-2)) - ) ) (while (or @@ -566,47 +562,23 @@ (>= (the-as uint 102) (-> next-char-2 0)) ) ) - (cond - ((and + (set! + result + (if + (and (>= (-> next-char-2 0) (the-as uint 65)) (>= (the-as uint 70) (-> next-char-2 0)) ) - (set! - result - (the-as - int - (+ (+ (-> next-char-2 0) -55) (the-as uint (shl result 4))) - ) - ) - (let ((a1-14 (the-as uint result))) - ) - ) - (else - (cond - ((and + (+ (+ (-> next-char-2 0) -55) (the-as uint (shl result 4))) + (the-as + int + (if + (and (>= (-> next-char-2 0) (the-as uint 97)) (>= (the-as uint 102) (-> next-char-2 0)) ) - (set! - result - (the-as - int - (+ (+ (-> next-char-2 0) -87) (the-as uint (shl result 4))) - ) - ) - (let ((a1-20 (the-as uint result))) - ) - ) - (else - (set! - result - (the-as - int - (+ (+ (-> next-char-2 0) -48) (the-as uint (shl result 4))) - ) - ) - (let ((a1-23 (the-as uint result))) - ) + (+ (+ (-> next-char-2 0) -87) (the-as uint (shl result 4))) + (+ (+ (-> next-char-2 0) -48) (the-as uint (shl result 4))) ) ) ) @@ -637,8 +609,6 @@ (when (= (-> str-ptr 1) 45) (set! v1-0 #t) (set! str-ptr (&-> str-ptr 1)) - (let ((a1-47 str-ptr)) - ) ) (while (and diff --git a/test/decompiler/reference/math_REF.gc b/test/decompiler/reference/math_REF.gc index 128e6b77ba..bb6dfe0261 100644 --- a/test/decompiler/reference/math_REF.gc +++ b/test/decompiler/reference/math_REF.gc @@ -131,12 +131,11 @@ (rand-vu-init 1.418091) ;; definition for function rand-vu -;; INFO: Return type mismatch int vs float. ;; WARN: Inline assembly instruction marked with TODO - [TODO.VRGET] ;; WARN: Inline assembly instruction marked with TODO - [TODO.VRXOR] ;; WARN: Inline assembly instruction marked with TODO - [TODO.VRNEXT] (defun rand-vu () - (local-vars (v0-0 int)) + (local-vars (v0-0 float)) (rlet ((Q :class vf) (vf0 :class vf) (vf1 :class vf) @@ -150,15 +149,14 @@ (TODO.VRNEXT vf1) (.sub.w.vf vf1 vf1 vf0) (.mov v0-0 vf1) - (the-as float v0-0) + v0-0 ) ) ;; definition for function rand-vu-nostep -;; INFO: Return type mismatch int vs float. ;; WARN: Inline assembly instruction marked with TODO - [TODO.VRGET] (defun rand-vu-nostep () - (local-vars (v0-0 int)) + (local-vars (v0-0 float)) (rlet ((vf0 :class vf) (vf1 :class vf) ) @@ -166,7 +164,7 @@ (TODO.VRGET vf1) (.sub.w.vf vf1 vf1 vf0) (.mov v0-0 vf1) - (the-as float v0-0) + v0-0 ) ) @@ -182,24 +180,14 @@ ;; definition for function rand-vu-int-range (defun rand-vu-int-range ((first int) (second int)) - (cond - ((< first second) - (set! second (+ second 1)) - (let ((v1-1 second)) - ) - ) - (else - (set! first (+ first 1)) - (let ((v1-3 first)) - ) - ) + (if (< first second) + (set! second (+ second 1)) + (set! first (+ first 1)) ) (let ((float-in-range (rand-vu-float-range (the float first) (the float second)))) - (when (< float-in-range 0.0) + (if (< float-in-range 0.0) (set! float-in-range (+ -1.0 float-in-range)) - (let ((v1-5 float-in-range)) - ) ) (the int float-in-range) ) diff --git a/test/decompiler/reference/matrix_REF.gc b/test/decompiler/reference/matrix_REF.gc index f2e2a25652..b1efadf14b 100644 --- a/test/decompiler/reference/matrix_REF.gc +++ b/test/decompiler/reference/matrix_REF.gc @@ -238,8 +238,6 @@ (set! (-> dst data 1) (-> temp-vec3 data 1)) (set! (-> dst data 2) (-> temp-vec3 data 2)) ) - (let ((v1-1 dst)) - ) dst ) @@ -259,8 +257,6 @@ (set! (-> dst data 1) (-> temp-vec3 data 1)) (set! (-> dst data 2) (-> temp-vec3 data 2)) ) - (let ((v1-1 dst)) - ) dst ) @@ -815,8 +811,6 @@ (set! (-> dst data 14) 0.0) (let ((f0-12 1.0)) (set! (-> dst data 15) f0-12) - (let ((v1-1 f0-12)) - ) ) dst ) @@ -912,9 +906,8 @@ ) ;; definition for function matrix3-determinant -;; INFO: Return type mismatch int vs float. (defun matrix3-determinant ((arg0 matrix)) - (local-vars (v0-0 int)) + (local-vars (v0-0 float)) (rlet ((acc :class vf) (vf10 :class vf) (vf11 :class vf) @@ -929,7 +922,7 @@ (.add.y.vf vf13 vf13 vf13 :mask #b1) (.add.z.vf vf13 vf13 vf13 :mask #b1) (.mov v0-0 vf13) - (the-as float v0-0) + v0-0 ) ) diff --git a/test/decompiler/reference/quaternion-h_REF.gc b/test/decompiler/reference/quaternion-h_REF.gc index 8b53bf64e1..636779e7d5 100644 --- a/test/decompiler/reference/quaternion-h_REF.gc +++ b/test/decompiler/reference/quaternion-h_REF.gc @@ -3,11 +3,11 @@ ;; definition of type quaternion (deftype quaternion (structure) - ((data float 4 :offset-assert 0) - (x float :offset 0) - (y float :offset 4) - (z float :offset 8) - (w float :offset 12) + ((x float :offset-assert 0) + (y float :offset-assert 4) + (z float :offset-assert 8) + (w float :offset-assert 12) + (data float 4 :offset 0) (vec vector :inline :offset 0) (quad uint128 :offset 0) ) @@ -17,15 +17,16 @@ ) ;; definition for method 3 of type quaternion +;; INFO: this function exists in multiple non-identical object files ;; Used lq/sq (defmethod inspect quaternion ((obj quaternion)) (format #t "[~8x] ~A~%" obj 'quaternion) - (format #t "~Tdata[4] @ #x~X~%" (-> obj data)) - (format #t "~Tx: ~f~%" (-> obj data 0)) - (format #t "~Ty: ~f~%" (-> obj data 1)) - (format #t "~Tz: ~f~%" (-> obj data 2)) - (format #t "~Tw: ~f~%" (-> obj data 3)) - (format #t "~Tvec: #~%" (-> obj data)) + (format #t "~Tdata[4] @ #x~X~%" (&-> obj x)) + (format #t "~Tx: ~f~%" (-> obj x)) + (format #t "~Ty: ~f~%" (-> obj y)) + (format #t "~Tz: ~f~%" (-> obj z)) + (format #t "~Tw: ~f~%" (-> obj w)) + (format #t "~Tvec: #~%" (&-> obj x)) (format #t "~Tquad: ~D~%" (-> obj vec quad)) obj ) diff --git a/test/decompiler/reference/quaternion_REF.gc b/test/decompiler/reference/quaternion_REF.gc new file mode 100644 index 0000000000..bb9440e4b1 --- /dev/null +++ b/test/decompiler/reference/quaternion_REF.gc @@ -0,0 +1,1176 @@ +;;-*-Lisp-*- +(in-package goal) + +;; definition for method 3 of type quaternion +;; INFO: this function exists in multiple non-identical object files +(defmethod inspect quaternion ((obj quaternion)) + (format #t "[~8x] quaternion~%" obj) + (format + #t + "~T[~F] [~F] [~F] [~F]~%" + (-> obj x) + (-> obj y) + (-> obj z) + (-> obj w) + ) + (let + ((f0-5 + (/ + 1.0 + (sqrtf + (+ + (+ (* (-> obj x) (-> obj x)) (* (-> obj y) (-> obj y))) + (* (-> obj z) (-> obj z)) + ) + ) + ) + ) + ) + (format + #t + "~Taxis: ~F ~F ~F" + (* f0-5 (-> obj x)) + (* f0-5 (-> obj y)) + (* f0-5 (-> obj z)) + ) + ) + (let ((f0-9 (* 2.0 (acos (-> obj w))))) + (format #t "~T~Tangle: (deg ~R)~%" f0-9) + ) + obj + ) + +;; definition for function quaternion-axis-angle! +(defun + quaternion-axis-angle! + ((quat quaternion) (x float) (y float) (z float) (angle float)) + (let* ((f28-0 (* 0.5 angle)) + (f30-0 (sin f28-0)) + (f0-1 (cos f28-0)) + ) + (set! (-> quat x) (* x f30-0)) + (set! (-> quat y) (* y f30-0)) + (set! (-> quat z) (* z f30-0)) + (set! (-> quat w) f0-1) + ) + quat + ) + +;; definition for function quaternion-vector-angle! +(defun quaternion-vector-angle! ((quat quaternion) (axis vector) (angle float)) + (let* ((f28-0 (* 0.5 angle)) + (f30-0 (sin f28-0)) + (f0-1 (cos f28-0)) + ) + (set! (-> quat x) (* (-> axis data 0) f30-0)) + (set! (-> quat y) (* (-> axis data 1) f30-0)) + (set! (-> quat z) (* (-> axis data 2) f30-0)) + (set! (-> quat w) f0-1) + ) + quat + ) + +;; definition for function vector-angle<-quaternion! +(defun vector-angle<-quaternion! ((arg0 vector) (arg1 quaternion)) + (let* ((f0-0 1.0) + (f1-0 1.0) + (f2-0 (-> arg1 w)) + (f30-0 (/ f0-0 (sqrtf (- f1-0 (* f2-0 f2-0))))) + (f0-3 (* 2.0 (acos-rad (-> arg1 w)))) + ) + (set! (-> arg0 data 0) (* (-> arg1 x) f30-0)) + (set! (-> arg0 data 1) (* (-> arg1 y) f30-0)) + (set! (-> arg0 data 2) (* (-> arg1 z) f30-0)) + (set! (-> arg0 data 3) f0-3) + ) + arg0 + ) + +;; definition for function quaternion-zero! +;; Used lq/sq +(defun quaternion-zero! ((arg0 quaternion)) + (set! (-> arg0 vec quad) (the-as uint128 0)) + arg0 + ) + +;; definition for function quaternion-identity! +;; Used lq/sq +(defun quaternion-identity! ((arg0 quaternion)) + (set! (-> arg0 vec quad) (the-as uint128 0)) + (set! (-> arg0 w) 1.0) + arg0 + ) + +;; definition for function quaternion-i! +;; Used lq/sq +(defun quaternion-i! ((arg0 quaternion)) + (set! (-> arg0 vec quad) (the-as uint128 0)) + (set! (-> arg0 x) 1.0) + arg0 + ) + +;; definition for function quaternion-j! +;; Used lq/sq +(defun quaternion-j! ((arg0 quaternion)) + (set! (-> arg0 vec quad) (the-as uint128 0)) + (set! (-> arg0 y) 1.0) + arg0 + ) + +;; definition for function quaternion-k! +;; Used lq/sq +(defun quaternion-k! ((arg0 quaternion)) + (set! (-> arg0 vec quad) (the-as uint128 0)) + (set! (-> arg0 z) 1.0) + arg0 + ) + +;; definition for function quaternion-copy! +;; Used lq/sq +(defun quaternion-copy! ((arg0 quaternion) (arg1 quaternion)) + (set! (-> arg0 vec quad) (-> arg1 vec quad)) + arg0 + ) + +;; definition for function quaternion-set! +(defun + quaternion-set! + ((arg0 quaternion) (arg1 float) (arg2 float) (arg3 float) (arg4 float)) + (set! (-> arg0 x) arg1) + (set! (-> arg0 y) arg2) + (set! (-> arg0 z) arg3) + (set! (-> arg0 w) arg4) + arg0 + ) + +;; definition for function quaternion+! +(defun quaternion+! ((arg0 quaternion) (arg1 quaternion) (arg2 quaternion)) + (rlet ((vf1 :class vf) + (vf2 :class vf) + ) + (.lvf vf1 (&-> arg1 vec quad)) + (.lvf vf2 (&-> arg2 vec quad)) + (.add.vf vf1 vf1 vf2) + (.svf (&-> arg0 vec quad) vf1) + arg0 + ) + ) + +;; definition for function quaternion-! +(defun quaternion-! ((arg0 quaternion) (arg1 quaternion) (arg2 quaternion)) + (rlet ((vf1 :class vf) + (vf2 :class vf) + ) + (.lvf vf1 (&-> arg1 vec quad)) + (.lvf vf2 (&-> arg2 vec quad)) + (.sub.vf vf1 vf1 vf2) + (.svf (&-> arg0 vec quad) vf1) + arg0 + ) + ) + +;; definition for function quaternion-negate! +;; WARN: Bad vector register dependency: vf2 +(defun quaternion-negate! ((arg0 quaternion) (arg1 quaternion)) + (rlet ((vf1 :class vf) + (vf2 :class vf) + ) + (.lvf vf1 (&-> arg1 vec quad)) + (.sub.vf vf2 vf2 vf2) + (.sub.vf vf1 vf2 vf1) + (.svf (&-> arg0 vec quad) vf1) + arg0 + ) + ) + +;; definition for function quaternion-conjugate! +;; WARN: Bad vector register dependency: vf2 +(defun quaternion-conjugate! ((arg0 quaternion) (arg1 quaternion)) + (rlet ((vf1 :class vf) + (vf2 :class vf) + ) + (.lvf vf1 (&-> arg1 vec quad)) + (.sub.vf vf2 vf2 vf2) + (.sub.vf vf2 vf2 vf1 :mask #b111) + (.add.vf vf2 vf2 vf1 :mask #b1000) + (.svf (&-> arg0 vec quad) vf2) + arg0 + ) + ) + +;; definition for function quaternion-float*! +(defun quaternion-float*! ((arg0 quaternion) (arg1 quaternion) (arg2 float)) + (rlet ((vf1 :class vf) + (vf2 :class vf) + ) + (.lvf vf1 (&-> arg1 vec quad)) + (.mov vf2 arg2) + (.mul.x.vf vf1 vf1 vf2) + (.svf (&-> arg0 vec quad) vf1) + arg0 + ) + ) + +;; definition for function quaternion-float/! +(defun quaternion-float/! ((arg0 quaternion) (arg1 quaternion) (arg2 float)) + (let ((f0-1 (/ 1.0 arg2))) + (quaternion-float*! arg0 arg1 f0-1) + ) + arg0 + ) + +;; definition for function quaternion-norm2 +(defun quaternion-norm2 ((arg0 quaternion)) + (local-vars (v0-0 float)) + (rlet ((acc :class vf) + (vf0 :class vf) + (vf1 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg0 vec quad)) + (.mul.vf vf1 vf1 vf1) + (.add.z.vf acc vf1 vf1 :mask #b1000) + (.add.mul.y.vf acc vf0 vf1 acc :mask #b1000) + (.add.mul.x.vf vf1 vf0 vf1 acc :mask #b1000) + (.add.w.vf vf1 vf0 vf1) + (.mov v0-0 vf1) + v0-0 + ) + ) + +;; definition for function quaternion-norm +(defun quaternion-norm ((arg0 quaternion)) + (local-vars (v1-1 float)) + (rlet ((acc :class vf) + (vf0 :class vf) + (vf1 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg0 vec quad)) + (.mul.vf vf1 vf1 vf1) + (.add.z.vf acc vf1 vf1 :mask #b1000) + (.add.mul.y.vf acc vf0 vf1 acc :mask #b1000) + (.add.mul.x.vf vf1 vf0 vf1 acc :mask #b1000) + (.add.w.vf vf1 vf0 vf1) + (.mov v1-1 vf1) + (sqrtf v1-1) + ) + ) + +;; definition for function quaternion-normalize! +(defun quaternion-normalize! ((arg0 quaternion)) + (rlet ((acc :class vf) + (Q :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg0 vec quad)) + (.mul.vf vf2 vf1 vf1) + (.add.z.vf acc vf2 vf2 :mask #b1000) + (.add.mul.y.vf acc vf0 vf2 acc :mask #b1000) + (.add.mul.x.vf vf2 vf0 vf2 acc :mask #b1000) + (.isqrt.vf Q vf0 vf2 :fsf #b11 :ftf #b11) + (.wait.vf) + (.mul.vf vf2 vf1 Q) + (.nop.vf) + (.nop.vf) + (.svf (&-> arg0 vec quad) vf2) + arg0 + ) + ) + +;; definition for function quaternion-inverse! +;; WARN: Bad vector register dependency: vf3 +(defun quaternion-inverse! ((arg0 quaternion) (arg1 quaternion)) + (rlet ((acc :class vf) + (Q :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg1 vec quad)) + (.mul.vf vf2 vf1 vf1) + (.sub.vf vf3 vf3 vf3) + (.add.z.vf acc vf2 vf2 :mask #b1000) + (.add.mul.y.vf acc vf0 vf2 acc :mask #b1000) + (.add.mul.x.vf vf2 vf0 vf2 acc :mask #b1000) + (.sub.vf vf3 vf3 vf1 :mask #b111) + (.div.vf Q vf0 vf2 :fsf #b11 :ftf #b11) + (.add.vf vf3 vf3 vf1 :mask #b1000) + (.wait.vf) + (.mul.vf vf3 vf3 Q) + (.nop.vf) + (.nop.vf) + (.svf (&-> arg0 vec quad) vf3) + arg0 + ) + ) + +;; definition for function quaternion-dot +(defun quaternion-dot ((arg0 quaternion) (arg1 quaternion)) + (local-vars (v0-0 float)) + (rlet ((acc :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg0 vec quad)) + (.lvf vf2 (&-> arg1 vec quad)) + (.mul.vf vf1 vf1 vf2) + (.add.z.vf acc vf1 vf1 :mask #b1000) + (.add.mul.y.vf acc vf0 vf1 acc :mask #b1000) + (.add.mul.x.vf vf1 vf0 vf1 acc :mask #b1000) + (.add.w.vf vf1 vf0 vf1) + (.mov v0-0 vf1) + v0-0 + ) + ) + +;; definition for function quaternion*! +(defun quaternion*! ((arg0 quaternion) (arg1 quaternion) (arg2 quaternion)) + (rlet ((acc :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg1 vec quad)) + (.lvf vf2 (&-> arg2 vec quad)) + (.sub.vf vf4 vf0 vf0 :mask #b1000) + (.mul.vf vf3 vf1 vf2) + (.outer.product.vf vf4 vf1 vf2) + (.mul.w.vf acc vf1 vf2) + (.add.mul.w.vf acc vf2 vf1 acc) + (.sub.mul.w.vf acc vf0 vf3 acc :mask #b1000) + (.sub.mul.z.vf acc vf0 vf3 acc :mask #b1000) + (.sub.mul.y.vf acc vf0 vf3 acc :mask #b1000) + (.sub.mul.x.vf acc vf0 vf3 acc :mask #b1000) + (.add.mul.w.vf vf1 vf4 vf0 acc) + (.svf (&-> arg0 vec quad) vf1) + arg0 + ) + ) + +;; definition for function quaternion-right-mult-matrix! +(defun quaternion-right-mult-matrix! ((arg0 matrix) (arg1 quaternion)) + (let ((f3-0 (-> arg1 x)) + (f2-0 (-> arg1 y)) + (f1-0 (-> arg1 z)) + (f0-0 (-> arg1 w)) + ) + (set! (-> arg0 data 0) f0-0) + (set! (-> arg0 data 1) f1-0) + (set! (-> arg0 data 2) (- f2-0)) + (set! (-> arg0 data 3) f3-0) + (set! (-> arg0 data 4) (- f1-0)) + (set! (-> arg0 data 5) f0-0) + (set! (-> arg0 data 6) f3-0) + (set! (-> arg0 data 7) f2-0) + (set! (-> arg0 data 8) f2-0) + (set! (-> arg0 data 9) (- f3-0)) + (set! (-> arg0 data 10) f0-0) + (set! (-> arg0 data 11) f1-0) + (set! (-> arg0 data 12) (- f3-0)) + (set! (-> arg0 data 13) (- f2-0)) + (set! (-> arg0 data 14) (- f1-0)) + (set! (-> arg0 data 15) f0-0) + ) + arg0 + ) + +;; definition for function quaternion-left-mult-matrix! +(defun quaternion-left-mult-matrix! ((arg0 matrix) (arg1 quaternion)) + (let ((f2-0 (-> arg1 x)) + (f1-0 (-> arg1 y)) + (f0-0 (-> arg1 z)) + ) + (let ((f3-0 (-> arg1 w))) + (set! (-> arg0 data 0) f2-0) + (set! (-> arg0 data 1) f3-0) + (set! (-> arg0 data 2) (- f0-0)) + (set! (-> arg0 data 3) f1-0) + (set! (-> arg0 data 4) f1-0) + (set! (-> arg0 data 5) f0-0) + (set! (-> arg0 data 6) f3-0) + (set! (-> arg0 data 7) (- f3-0)) + (set! (-> arg0 data 8) f0-0) + (set! (-> arg0 data 9) (- f1-0)) + (set! (-> arg0 data 10) f2-0) + (set! (-> arg0 data 11) f3-0) + (set! (-> arg0 data 12) f3-0) + ) + (set! (-> arg0 data 13) (- f2-0)) + (set! (-> arg0 data 14) (- f1-0)) + (set! (-> arg0 data 15) (- f0-0)) + ) + arg0 + ) + +;; definition for function quaternion->matrix +(defun quaternion->matrix ((arg0 matrix) (arg1 quaternion)) + (rlet ((acc :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + (vf5 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg1 vec quad)) + (.add.vf vf5 vf1 vf1) + (.add.w.vf vf2 vf0 vf1 :mask #b1) + (.add.z.vf vf2 vf0 vf1 :mask #b10) + (.sub.y.vf vf2 vf0 vf1 :mask #b100) + (.sub.w.vf vf2 vf0 vf0 :mask #b1000) + (.sub.z.vf vf3 vf0 vf1 :mask #b1) + (.add.w.vf vf3 vf0 vf1 :mask #b10) + (.add.x.vf vf3 vf0 vf1 :mask #b100) + (.sub.w.vf vf3 vf0 vf0 :mask #b1000) + (.add.y.vf vf4 vf0 vf1 :mask #b1) + (.sub.x.vf vf4 vf0 vf1 :mask #b10) + (.add.w.vf vf4 vf0 vf1 :mask #b100) + (.sub.w.vf vf4 vf0 vf0 :mask #b1000) + (.outer.product.vf vf2 vf5 vf2) + (.outer.product.vf vf3 vf5 vf3) + (.outer.product.vf vf4 vf5 vf4) + (.add.w.vf vf2 vf2 vf0 :mask #b1) + (.add.w.vf vf3 vf3 vf0 :mask #b10) + (.add.w.vf vf4 vf4 vf0 :mask #b100) + (.svf (&-> arg0 vector 3 quad) vf0) + (.svf (&-> arg0 vector 0 quad) vf2) + (.svf (&-> arg0 vector 1 quad) vf3) + (.svf (&-> arg0 vector 2 quad) vf4) + arg0 + ) + ) + +;; definition for function matrix->quaternion +(defun matrix->quaternion ((arg0 quaternion) (arg1 matrix)) + (let ((f0-2 (+ (+ (-> arg1 data 0) (-> arg1 data 5)) (-> arg1 data 10)))) + (if (< 0.0 f0-2) + (let ((f0-4 (sqrtf (+ 1.0 f0-2)))) + (set! (-> arg0 w) (* 0.5 f0-4)) + (let ((f0-5 (/ 0.5 f0-4))) + (set! (-> arg0 x) (* f0-5 (- (-> arg1 data 6) (-> arg1 data 9)))) + (set! (-> arg0 y) (* f0-5 (- (-> arg1 data 8) (-> arg1 data 2)))) + (let ((f0-6 (* f0-5 (- (-> arg1 data 1) (-> arg1 data 4))))) + (set! (-> arg0 z) f0-6) + ) + ) + ) + (let ((a2-0 0) + (a3-0 1) + (v1-1 2) + ) + (when (< (-> arg1 data 0) (-> arg1 data 5)) + (set! a2-0 1) + (set! a3-0 2) + (set! v1-1 0) + ) + (when + (< + (-> + (the-as + (pointer float) + (+ (+ (shl a2-0 2) (shl a2-0 4)) (the-as int arg1)) + ) + ) + (-> arg1 data 10) + ) + (set! a2-0 2) + (set! a3-0 0) + (set! v1-1 1) + ) + (let + ((f0-12 + (sqrtf + (+ + (- + 1.0 + (+ + (-> + (the-as + (pointer float) + (+ (+ (shl a3-0 2) (shl a3-0 4)) (the-as int arg1)) + ) + ) + (-> + (the-as + (pointer float) + (+ (+ (shl v1-1 2) (shl v1-1 4)) (the-as int arg1)) + ) + ) + ) + ) + (-> + (the-as + (pointer float) + (+ (+ (shl a2-0 2) (shl a2-0 4)) (the-as int arg1)) + ) + ) + ) + ) + ) + ) + (set! (-> arg0 data a2-0) (* 0.5 f0-12)) + (if (!= f0-12 0.0) + (set! f0-12 (/ 0.5 f0-12)) + ) + (set! + (-> arg0 w) + (* + (- + (-> + (the-as + (pointer float) + (+ (+ (shl v1-1 2) (shl a3-0 4)) (the-as int arg1)) + ) + ) + (-> + (the-as + (pointer float) + (+ (+ (shl a3-0 2) (shl v1-1 4)) (the-as int arg1)) + ) + ) + ) + f0-12 + ) + ) + (set! + (-> arg0 data a3-0) + (* + (+ + (-> + (the-as + (pointer float) + (+ (+ (shl a3-0 2) (shl a2-0 4)) (the-as int arg1)) + ) + ) + (-> + (the-as + (pointer float) + (+ (+ (shl a2-0 2) (shl a3-0 4)) (the-as int arg1)) + ) + ) + ) + f0-12 + ) + ) + (let + ((f0-13 + (* + (+ + (-> + (the-as + (pointer float) + (+ (+ (shl v1-1 2) (shl a2-0 4)) (the-as int arg1)) + ) + ) + (-> + (the-as + (pointer float) + (+ (+ (shl a2-0 2) (shl v1-1 4)) (the-as int arg1)) + ) + ) + ) + f0-12 + ) + ) + ) + (set! (-> arg0 data v1-1) f0-13) + ) + ) + ) + ) + ) + arg0 + ) + +;; definition for function matrix-with-scale->quaternion +;; WARN: Unsupported inline assembly instruction kind - [mula.s f0, f3] +;; WARN: Unsupported inline assembly instruction kind - [madda.s f1, f4] +;; WARN: Unsupported inline assembly instruction kind - [madd.s f0, f2, f5] +;; WARN: Unsupported inline assembly instruction kind - [mula.s f1, f4] +;; WARN: Unsupported inline assembly instruction kind - [madda.s f2, f5] +;; WARN: Unsupported inline assembly instruction kind - [madd.s f1, f3, f6] +;; WARN: Unsupported inline assembly instruction kind - [mula.s f2, f5] +;; WARN: Unsupported inline assembly instruction kind - [madda.s f3, f6] +;; WARN: Unsupported inline assembly instruction kind - [madd.s f2, f4, f7] +;; Used lq/sq +(defun matrix-with-scale->quaternion ((arg0 quaternion) (arg1 matrix)) + (local-vars (a1-4 float) (f0-1 float) (f1-2 float) (f2-3 float)) + (rlet ((vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + (vf5 :class vf) + (vf6 :class vf) + (vf7 :class vf) + ) + (let ((v1-0 (new 'stack 'matrix))) + (set! (-> v1-0 vector 0 quad) (the-as uint128 0)) + (set! (-> v1-0 vector 1 quad) (the-as uint128 0)) + (set! (-> v1-0 vector 2 quad) (the-as uint128 0)) + (set! (-> v1-0 vector 3 quad) (the-as uint128 0)) + (let* ((a3-0 (-> arg1 data)) + (a2-0 (-> arg1 data)) + (f0-0 (-> a3-0 0)) + (f1-0 (-> a3-0 1)) + (f2-0 (-> a3-0 2)) + (f3-0 (-> a2-0 0)) + (f4-0 (-> a2-0 1)) + (f5-0 (-> a2-0 2)) + ) + (.mula.s f0-0 f3-0) + (.madda.s f1-0 f4-0) + (.madd.s f0-1 f2-0 f5-0) + ) + (let ((f0-2 f0-1)) + (let* ((a3-1 (&-> arg1 data 4)) + (a2-2 (&-> arg1 data 4)) + (f1-1 (-> a3-1 0)) + (f2-1 (-> a3-1 1)) + (f3-1 (-> a3-1 2)) + (f4-1 (-> a2-2 0)) + (f5-1 (-> a2-2 1)) + (f6-0 (-> a2-2 2)) + ) + (.mula.s f1-1 f4-1) + (.madda.s f2-1 f5-1) + (.madd.s f1-2 f3-1 f6-0) + ) + (let ((f1-3 f1-2)) + (let* ((a3-2 (&-> arg1 data 8)) + (a2-4 (&-> arg1 data 8)) + (f2-2 (-> a3-2 0)) + (f3-2 (-> a3-2 1)) + (f4-2 (-> a3-2 2)) + (f5-2 (-> a2-4 0)) + (f6-1 (-> a2-4 1)) + (f7-0 (-> a2-4 2)) + ) + (.mula.s f2-2 f5-2) + (.madda.s f3-2 f6-1) + (.madd.s f2-3 f4-2 f7-0) + ) + (let* ((f2-4 f2-3) + (f0-4 (/ 1.0 (sqrtf f0-2))) + (f1-5 (/ 1.0 (sqrtf f1-3))) + (f2-6 (/ 1.0 (sqrtf f2-4))) + ) + (.lvf vf1 (&-> arg1 vector 0 quad)) + (.lvf vf2 (&-> arg1 vector 1 quad)) + (.lvf vf3 (&-> arg1 vector 2 quad)) + (.lvf vf4 (&-> arg1 vector 3 quad)) + (let ((a1-1 f0-4)) + (.mov vf5 a1-1) + ) + (let ((a1-2 f1-5)) + (.mov vf6 a1-2) + ) + (let ((a1-3 f2-6)) + (.mov vf7 a1-3) + ) + ) + ) + ) + (.mul.x.vf vf1 vf1 vf5) + (.mul.x.vf vf2 vf2 vf6) + (.mul.x.vf vf3 vf3 vf7) + (.svf (&-> v1-0 vector 0 quad) vf1) + (.svf (&-> v1-0 vector 1 quad) vf2) + (.svf (&-> v1-0 vector 2 quad) vf3) + (.svf (&-> v1-0 vector 3 quad) vf4) + (.mov a1-4 vf4) + (matrix->quaternion arg0 v1-0) + ) + ) + ) + +;; definition for function quaternion-vector-len +(defun quaternion-vector-len ((arg0 quaternion)) + (let ((f0-0 1.0) + (f1-0 (-> arg0 w)) + ) + (sqrtf (- f0-0 (* f1-0 f1-0))) + ) + ) + +;; definition for function quaternion-log! +(defun quaternion-log! ((arg0 quaternion) (arg1 quaternion)) + (cond + ((= (-> arg1 w) 0.0) + (set! (-> arg0 x) (* 1.5707963 (-> arg1 x))) + (set! (-> arg0 y) (* 1.5707963 (-> arg1 y))) + (set! (-> arg0 z) (* 1.5707963 (-> arg1 z))) + ) + (else + (let* ((f30-0 (quaternion-vector-len arg1)) + (f0-9 (/ (atan2-rad (-> arg1 w) f30-0) f30-0)) + ) + (set! (-> arg0 x) (* (-> arg1 x) f0-9)) + (set! (-> arg0 y) (* (-> arg1 y) f0-9)) + (let ((f0-10 (* (-> arg1 z) f0-9))) + (set! (-> arg0 z) f0-10) + ) + ) + ) + ) + arg0 + ) + +;; definition for function quaternion-exp! +(defun quaternion-exp! ((arg0 quaternion) (arg1 quaternion)) + (let ((f30-0 (vector-length (the-as vector arg1)))) + (cond + ((= f30-0 0.0) + (set! (-> arg0 x) 0.0) + (set! (-> arg0 y) 0.0) + (set! (-> arg0 z) 0.0) + (let ((f0-4 1.0)) + (set! (-> arg0 w) f0-4) + ) + ) + (else + (let ((s5-0 (new 'stack 'vector))) + (sincos-rad! (the-as (pointer float) s5-0) f30-0) + (let ((f0-6 (/ (-> s5-0 data 0) f30-0))) + (set! (-> arg0 x) (* (-> arg1 x) f0-6)) + (set! (-> arg0 y) (* (-> arg1 y) f0-6)) + (set! (-> arg0 z) (* (-> arg1 z) f0-6)) + ) + (let ((f0-8 (-> s5-0 data 1))) + (set! (-> arg0 w) f0-8) + ) + ) + ) + ) + ) + arg0 + ) + +;; definition for function quaternion-slerp! +(defun + quaternion-slerp! + ((arg0 quaternion) (arg1 quaternion) (arg2 quaternion) (arg3 float)) + (local-vars (v1-7 float)) + (rlet ((acc :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + ) + (let ((f0-0 (quaternion-dot arg1 arg2)) + (f30-0 1.0) + ) + (when (< f0-0 0.0) + (set! f0-0 (- f0-0)) + (set! f30-0 -1.0) + ) + (cond + ((< (- 1.0 f0-0) 0.0001) + (let ((v1-2 (- 1.0 arg3))) + (.mov vf1 v1-2) + ) + (let ((v1-3 (* arg3 f30-0))) + (.mov vf2 v1-3) + ) + (.lvf vf3 (&-> arg1 vec quad)) + (.lvf vf4 (&-> arg2 vec quad)) + (.mul.x.vf acc vf3 vf1) + (.add.mul.x.vf vf3 vf4 vf2 acc) + (.svf (&-> arg0 vec quad) vf3) + (quaternion-normalize! arg0) + ) + (else + (let* ((f1-4 1.0) + (f2-1 f0-0) + (f1-6 (sqrtf (- f1-4 (* f2-1 f2-1)))) + (f0-6 (/ (- f1-6 f0-0) (+ f1-6 f0-0))) + (f28-0 (/ 1.0 f1-6)) + ) + (let ((f0-7 (atan-series-rad f0-6)) + (s2-0 (new 'stack 'vector)) + ) + (set! (-> s2-0 data 0) (* (- 1.0 arg3) f0-7)) + (set! (-> s2-0 data 1) (* (* arg3 f0-7) f30-0)) + (vector-sin-rad! s2-0 s2-0) + (.lvf vf1 (&-> s2-0 quad)) + ) + (let ((v1-6 f28-0)) + (.mov vf2 v1-6) + ) + ) + (.mul.x.vf vf1 vf1 vf2) + (.lvf vf3 (&-> arg1 vec quad)) + (.lvf vf4 (&-> arg2 vec quad)) + (.mul.x.vf acc vf3 vf1) + (.add.mul.y.vf vf3 vf4 vf1 acc) + (.svf (&-> arg0 vec quad) vf3) + (.mov v1-7 vf3) + ) + ) + ) + arg0 + ) + ) + +;; definition for function quaternion-pseudo-slerp! +(defun + quaternion-pseudo-slerp! + ((arg0 quaternion) (arg1 quaternion) (arg2 quaternion) (arg3 float)) + (rlet ((acc :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + ) + (let ((f1-0 (quaternion-dot arg1 arg2)) + (f0-0 1.0) + ) + (when (< f1-0 0.0) + (let ((f0-1 (- f1-0))) + ) + (set! f0-0 -1.0) + ) + (let ((v1-2 (- 1.0 arg3))) + (.mov vf1 v1-2) + ) + (let ((v1-3 (* arg3 f0-0))) + (.mov vf2 v1-3) + ) + ) + (.lvf vf3 (&-> arg1 vec quad)) + (.lvf vf4 (&-> arg2 vec quad)) + (.mul.x.vf acc vf3 vf1) + (.add.mul.x.vf vf3 vf4 vf2 acc) + (.svf (&-> arg0 vec quad) vf3) + (quaternion-normalize! arg0) + arg0 + ) + ) + +;; definition for function quaternion-zxy! +(defun quaternion-zxy! ((arg0 quaternion) (arg1 vector)) + (rlet ((acc :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + (vf5 :class vf) + (vf6 :class vf) + (vf7 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (let ((s4-0 (new 'stack 'vector)) + (gp-0 (new 'stack 'vector)) + (s5-0 (new 'stack 'vector)) + ) + (vector-rad<-vector-deg/2! s4-0 arg1) + (vector-sincos-rad! gp-0 s5-0 s4-0) + (.lvf vf1 (&-> gp-0 quad)) + (.lvf vf2 (&-> s5-0 quad)) + ) + (.mul.x.vf vf4 vf0 vf1 :mask #b1000) + (.add.vf vf4 vf0 vf2 :mask #b111) + (.sub.vf vf4 vf0 vf4 :mask #b110) + (.add.vf vf3 vf0 vf1 :mask #b111) + (.mul.x.vf vf3 vf0 vf2 :mask #b1000) + (.outer.product.vf vf6 vf0 vf0) + (.outer.product.vf vf5 vf0 vf0) + (.mul.x.vf vf6 vf0 vf6 :mask #b1000) + (.mul.x.vf vf5 vf0 vf5 :mask #b1000) + (.mul.vf acc vf6 vf4) + (.add.mul.vf vf7 vf5 vf3 acc) + (.svf (&-> arg0 vec quad) vf7) + arg0 + ) + ) + +;; definition for function vector-x-quaternion! +;; Used lq/sq +(defun vector-x-quaternion! ((arg0 vector) (arg1 quaternion)) + (let ((s5-0 (new 'stack 'matrix))) + (set! (-> s5-0 vector 0 quad) (the-as uint128 0)) + (set! (-> s5-0 vector 1 quad) (the-as uint128 0)) + (set! (-> s5-0 vector 2 quad) (the-as uint128 0)) + (set! (-> s5-0 vector 3 quad) (the-as uint128 0)) + (quaternion->matrix s5-0 arg1) + (set! (-> arg0 quad) (-> (the-as (pointer uint128) (-> s5-0 data)) 0)) + ) + arg0 + ) + +;; definition for function vector-y-quaternion! +;; Used lq/sq +(defun vector-y-quaternion! ((arg0 vector) (arg1 quaternion)) + (let ((s5-0 (new 'stack 'matrix))) + (set! (-> s5-0 vector 0 quad) (the-as uint128 0)) + (set! (-> s5-0 vector 1 quad) (the-as uint128 0)) + (set! (-> s5-0 vector 2 quad) (the-as uint128 0)) + (set! (-> s5-0 vector 3 quad) (the-as uint128 0)) + (quaternion->matrix s5-0 arg1) + (set! (-> arg0 quad) (-> (the-as (pointer uint128) (&-> s5-0 data 4)) 0)) + ) + arg0 + ) + +;; definition for function vector-z-quaternion! +;; Used lq/sq +(defun vector-z-quaternion! ((arg0 vector) (arg1 quaternion)) + (let ((s5-0 (new 'stack 'matrix))) + (set! (-> s5-0 vector 0 quad) (the-as uint128 0)) + (set! (-> s5-0 vector 1 quad) (the-as uint128 0)) + (set! (-> s5-0 vector 2 quad) (the-as uint128 0)) + (set! (-> s5-0 vector 3 quad) (the-as uint128 0)) + (quaternion->matrix s5-0 arg1) + (set! (-> arg0 quad) (-> (the-as (pointer uint128) (&-> s5-0 data 8)) 0)) + ) + arg0 + ) + +;; definition for function quaternion-y-angle +(defun quaternion-y-angle ((arg0 quaternion)) + (let ((v1-1 (vector-z-quaternion! (new 'stack 'vector) arg0))) + (atan (-> v1-1 data 0) (-> v1-1 data 2)) + ) + ) + +;; definition for function quaternion-vector-y-angle +(defun quaternion-vector-y-angle ((arg0 quaternion) (arg1 vector)) + (let ((f30-0 (quaternion-y-angle arg0)) + (f0-2 (atan (-> arg1 data 0) (-> arg1 data 2))) + ) + (deg-diff f30-0 f0-2) + ) + ) + +;; definition for function quaternion-rotate-local-x! +;; Used lq/sq +(defun + quaternion-rotate-local-x! + ((arg0 quaternion) (arg1 quaternion) (arg2 float)) + (let ((t9-0 quaternion-vector-angle!) + (a0-1 (new 'stack 'quaternion)) + ) + (set! (-> a0-1 vec quad) (the-as uint128 0)) + (let ((a2-1 (t9-0 a0-1 (new 'static 'vector :x 1.0 :w 1.0) arg2))) + (quaternion-normalize! (quaternion*! arg0 arg1 a2-1)) + ) + ) + ) + +;; definition for function quaternion-rotate-local-y! +;; Used lq/sq +(defun + quaternion-rotate-local-y! + ((arg0 quaternion) (arg1 quaternion) (arg2 float)) + (let ((t9-0 quaternion-vector-angle!) + (a0-1 (new 'stack 'quaternion)) + ) + (set! (-> a0-1 vec quad) (the-as uint128 0)) + (let ((a2-1 (t9-0 a0-1 (new 'static 'vector :y 1.0 :w 1.0) arg2))) + (quaternion-normalize! (quaternion*! arg0 arg1 a2-1)) + ) + ) + ) + +;; definition for function quaternion-rotate-local-z! +;; Used lq/sq +(defun + quaternion-rotate-local-z! + ((arg0 quaternion) (arg1 quaternion) (arg2 float)) + (let ((t9-0 quaternion-vector-angle!) + (a0-1 (new 'stack 'quaternion)) + ) + (set! (-> a0-1 vec quad) (the-as uint128 0)) + (let ((a2-1 (t9-0 a0-1 (new 'static 'vector :z 1.0 :w 1.0) arg2))) + (quaternion-normalize! (quaternion*! arg0 arg1 a2-1)) + ) + ) + ) + +;; definition for function quaternion-rotate-y! +;; Used lq/sq +(defun quaternion-rotate-y! ((arg0 quaternion) (arg1 quaternion) (arg2 float)) + (let ((t9-0 quaternion-vector-angle!) + (a0-1 (new 'stack 'quaternion)) + ) + (set! (-> a0-1 vec quad) (the-as uint128 0)) + (let ((a1-2 (t9-0 a0-1 (new 'static 'vector :y 1.0 :w 1.0) arg2))) + (quaternion-normalize! (quaternion*! arg0 a1-2 arg1)) + ) + ) + ) + +;; definition for function quaternion-rotate-x! +;; Used lq/sq +(defun quaternion-rotate-x! ((arg0 quaternion) (arg1 quaternion) (arg2 float)) + (let ((s4-0 quaternion-vector-angle!) + (s3-0 (new 'stack 'quaternion)) + ) + (set! (-> s3-0 vec quad) (the-as uint128 0)) + (let ((t9-0 vector-x-quaternion!) + (a0-1 (new 'stack 'vector)) + ) + (set! (-> a0-1 quad) (the-as uint128 0)) + (let ((a1-3 (s4-0 s3-0 (t9-0 a0-1 arg1) arg2))) + (quaternion-normalize! (quaternion*! arg0 a1-3 arg1)) + ) + ) + ) + ) + +;; definition for function quaternion-rotate-z! +;; Used lq/sq +(defun quaternion-rotate-z! ((arg0 quaternion) (arg1 quaternion) (arg2 float)) + (let ((s4-0 quaternion-vector-angle!) + (s3-0 (new 'stack 'quaternion)) + ) + (set! (-> s3-0 vec quad) (the-as uint128 0)) + (let ((t9-0 vector-z-quaternion!) + (a0-1 (new 'stack 'vector)) + ) + (set! (-> a0-1 quad) (the-as uint128 0)) + (let ((a1-3 (s4-0 s3-0 (t9-0 a0-1 arg1) arg2))) + (quaternion-normalize! (quaternion*! arg0 a1-3 arg1)) + ) + ) + ) + ) + +;; definition for function quaternion-delta-y +;; WARN: Unsupported inline assembly instruction kind - [mula.s f0, f3] +;; WARN: Unsupported inline assembly instruction kind - [madda.s f1, f4] +;; WARN: Unsupported inline assembly instruction kind - [madd.s f0, f2, f5] +(defun quaternion-delta-y ((arg0 quaternion) (arg1 quaternion)) + (local-vars (f0-1 float)) + (let ((gp-0 acos)) + (let* ((s5-0 (vector-z-quaternion! (new 'stack 'vector) arg0)) + (v1-1 (vector-z-quaternion! (new 'stack 'vector) arg1)) + (f0-0 (-> s5-0 data 0)) + (f1-0 (-> s5-0 data 1)) + (f2-0 (-> s5-0 data 2)) + (f3-0 (-> v1-1 data 0)) + (f4-0 (-> v1-1 data 1)) + (f5-0 (-> v1-1 data 2)) + ) + (.mula.s f0-0 f3-0) + (.madda.s f1-0 f4-0) + (.madd.s f0-1 f2-0 f5-0) + ) + (gp-0 f0-1) + ) + ) + +;; definition for function quaternion-rotate-y-to-vector! +(defun + quaternion-rotate-y-to-vector! + ((arg0 quaternion) (arg1 quaternion) (arg2 quaternion) (arg3 float)) + (let ((s5-0 (new 'stack 'quaternion))) + (let ((t9-0 vector-xz-normalize!) + (a0-1 (new 'stack 'vector)) + ) + (set! (-> a0-1 data 0) (-> arg2 x)) + (set! (-> a0-1 data 1) 0.0) + (set! (-> a0-1 data 2) (-> arg2 z)) + (set! (-> a0-1 data 3) 1.0) + (let ((s0-0 (t9-0 a0-1 1.0))) + (quaternion-from-two-vectors-max-angle! + s5-0 + (vector-z-quaternion! (the-as vector (new 'stack 'quaternion)) arg1) + s0-0 + arg3 + ) + ) + ) + (quaternion-normalize! (quaternion*! arg0 s5-0 arg1)) + ) + ) + +;; definition for function vector-rotate-y! +(defun vector-rotate-y! ((arg0 vector) (arg1 vector) (arg2 float)) + (let + ((a1-2 + (quaternion-vector-angle! + (new 'stack 'quaternion) + (new 'static 'vector :y 1.0 :w 1.0) + arg2 + ) + ) + (s4-0 (new 'stack 'matrix)) + ) + (quaternion->matrix s4-0 a1-2) + (vector-matrix*! arg0 arg1 s4-0) + ) + ) + +;; definition for function vector-y-angle +(defun vector-y-angle ((arg0 vector)) + (atan (-> arg0 data 0) (-> arg0 data 2)) + ) + +;; definition for function vector-x-angle +(defun vector-x-angle ((arg0 vector)) + (atan (-> arg0 data 1) (vector-xz-length arg0)) + ) + +;; definition for function quaterion<-rotate-y-vector +(defun quaterion<-rotate-y-vector ((arg0 quaternion) (arg1 vector)) + (quaternion-vector-angle! + arg0 + (new 'static 'vector :y 1.0 :w 1.0) + (vector-y-angle arg1) + ) + ) + +;; definition (debug) for function quaternion-validate +;; INFO: Return type mismatch int vs none. +(defun-debug quaternion-validate ((arg0 quaternion)) + (local-vars (pp process)) + (let ((f0-0 (quaternion-norm arg0))) + (when (or (< 1.01 f0-0) (< f0-0 0.99)) + (format #t "WARNING: bad quaternion (magnitude ~F) process is " f0-0) + (if (and pp (type-type? (-> pp type) process-tree)) + (format #t "~A~%" (-> pp name)) + (format #t "#f~%") + ) + ) + ) + (let ((v0-5 0)) + ) + (none) + ) + +;; definition for function quaternion-xz-angle +(defun quaternion-xz-angle ((arg0 quaternion)) + (let ((gp-0 (new 'stack 'matrix)) + (s5-0 (new 'stack 'vector)) + ) + (quaternion->matrix gp-0 arg0) + (let ((v1-1 s5-0)) + (set! (-> v1-1 data 0) 0.0) + (set! (-> v1-1 data 1) 0.0) + (set! (-> v1-1 data 2) 1.0) + (set! (-> v1-1 data 3) 1.0) + ) + (vector-matrix*! s5-0 s5-0 gp-0) + (vector-y-angle s5-0) + ) + ) + +;; failed to figure out what this is: +(none) + + + + diff --git a/test/decompiler/reference/transform-h_REF.gc b/test/decompiler/reference/transform-h_REF.gc index 40f2fe6c0f..fca6f31f2f 100644 --- a/test/decompiler/reference/transform-h_REF.gc +++ b/test/decompiler/reference/transform-h_REF.gc @@ -30,6 +30,9 @@ :method-count-assert 9 :size-assert #x40 :flag-assert #x900000040 + (:methods + (new (symbol type) _type_ 0) + ) ) ;; definition for method 3 of type trs diff --git a/test/decompiler/reference/transform_REF.gc b/test/decompiler/reference/transform_REF.gc new file mode 100644 index 0000000000..ec52bc2878 --- /dev/null +++ b/test/decompiler/reference/transform_REF.gc @@ -0,0 +1,116 @@ +;;-*-Lisp-*- +(in-package goal) + +;; definition for method 2 of type transform +(defmethod print transform ((obj transform)) + (format #t "# obj trans data 0) + (-> obj trans data 1) + (-> obj trans data 2) + (-> obj trans data 3) + ) + (format + #t + "~T~Trot: ~F ~F ~F ~F ~%" + (-> obj rot data 0) + (-> obj rot data 1) + (-> obj rot data 2) + (-> obj rot data 3) + ) + (format + #t + "~T~Tscale:~F ~F ~F ~F>" + (-> obj scale data 0) + (-> obj scale data 1) + (-> obj scale data 2) + (-> obj scale data 3) + ) + obj + ) + +;; definition for method 0 of type trs +(defmethod new trs ((allocation symbol) (type-to-make type)) + (let + ((obj + (object-new allocation type-to-make (the-as int (-> type-to-make size))) + ) + ) + (set! (-> obj trans data 3) 1.0) + (set! (-> obj rot data 3) 1.0) + (vector-identity! (-> obj scale)) + obj + ) + ) + +;; definition for function transform-matrix-calc! +;; Used lq/sq +(defun transform-matrix-calc! ((tf transform) (dst-mat matrix)) + (let ((s4-0 (new 'stack 'matrix))) + (set! (-> s4-0 vector 0 quad) (the-as uint128 0)) + (set! (-> s4-0 vector 1 quad) (the-as uint128 0)) + (set! (-> s4-0 vector 2 quad) (the-as uint128 0)) + (set! (-> s4-0 vector 3 quad) (the-as uint128 0)) + (let ((s3-0 (new 'stack 'matrix))) + (set! (-> s3-0 vector 0 quad) (the-as uint128 0)) + (set! (-> s3-0 vector 1 quad) (the-as uint128 0)) + (set! (-> s3-0 vector 2 quad) (the-as uint128 0)) + (set! (-> s3-0 vector 3 quad) (the-as uint128 0)) + (matrix-identity! dst-mat) + (matrix-translate! dst-mat (-> tf trans)) + (matrix-rotate-y! s4-0 (-> tf rot data 1)) + (matrix*! s3-0 s4-0 dst-mat) + (matrix-rotate-x! s4-0 (-> tf rot data 0)) + (matrix*! dst-mat s4-0 s3-0) + (matrix-rotate-z! s4-0 (-> tf rot data 2)) + (matrix*! s3-0 s4-0 dst-mat) + (matrix-scale! s4-0 (-> tf scale)) + (matrix*! dst-mat s4-0 s3-0) + ) + ) + ) + +;; definition for function transform-matrix-parent-calc! +;; Used lq/sq +(defun + transform-matrix-parent-calc! + ((tf transform) (dst-mat matrix) (inv-scale vector)) + (let ((s4-0 (new 'stack 'matrix))) + (set! (-> s4-0 vector 0 quad) (the-as uint128 0)) + (set! (-> s4-0 vector 1 quad) (the-as uint128 0)) + (set! (-> s4-0 vector 2 quad) (the-as uint128 0)) + (set! (-> s4-0 vector 3 quad) (the-as uint128 0)) + (let ((s3-0 (new 'stack 'matrix))) + (set! (-> s3-0 vector 0 quad) (the-as uint128 0)) + (set! (-> s3-0 vector 1 quad) (the-as uint128 0)) + (set! (-> s3-0 vector 2 quad) (the-as uint128 0)) + (set! (-> s3-0 vector 3 quad) (the-as uint128 0)) + (matrix-identity! s3-0) + (matrix-translate! s3-0 (-> tf trans)) + (matrix-inv-scale! s4-0 inv-scale) + (matrix*! dst-mat s4-0 s3-0) + (matrix-rotate-y! s4-0 (-> tf rot data 1)) + (matrix*! s3-0 s4-0 dst-mat) + (matrix-rotate-x! s4-0 (-> tf rot data 0)) + (matrix*! dst-mat s4-0 s3-0) + (matrix-rotate-z! s4-0 (-> tf rot data 2)) + (matrix*! s3-0 s4-0 dst-mat) + (matrix-scale! s4-0 (-> tf scale)) + (matrix*! dst-mat s4-0 s3-0) + ) + ) + ) + +;; definition for function trs-matrix-calc! +(defun trs-matrix-calc! ((tf trs) (dst-mat matrix)) + (transform-matrix-calc! (the-as transform (-> tf trans)) dst-mat) + ) + +;; failed to figure out what this is: +(none) + + + + diff --git a/test/decompiler/reference/vector-h_REF.gc b/test/decompiler/reference/vector-h_REF.gc index e348021333..e21dab5e95 100644 --- a/test/decompiler/reference/vector-h_REF.gc +++ b/test/decompiler/reference/vector-h_REF.gc @@ -842,9 +842,8 @@ ) ;; definition for function vector-dot-vu -;; INFO: Return type mismatch int vs float. (defun vector-dot-vu ((arg0 vector) (arg1 vector)) - (local-vars (v0-0 int)) + (local-vars (v0-0 float)) (rlet ((vf1 :class vf) (vf2 :class vf) ) @@ -854,7 +853,7 @@ (.add.y.vf vf1 vf1 vf1 :mask #b1) (.add.z.vf vf1 vf1 vf1 :mask #b1) (.mov v0-0 vf1) - (the-as float v0-0) + v0-0 ) ) @@ -883,9 +882,8 @@ ) ;; definition for function vector4-dot-vu -;; INFO: Return type mismatch int vs float. (defun vector4-dot-vu ((arg0 vector) (arg1 vector)) - (local-vars (v0-0 int)) + (local-vars (v0-0 float)) (rlet ((acc :class vf) (vf0 :class vf) (vf1 :class vf) @@ -902,7 +900,7 @@ (.add.mul.z.vf acc vf3 vf1 acc :mask #b1) (.add.mul.w.vf vf1 vf3 vf1 acc :mask #b1) (.mov v0-0 vf1) - (the-as float v0-0) + v0-0 ) ) diff --git a/test/decompiler/test_FormExpressionBuild.cpp b/test/decompiler/test_FormExpressionBuild.cpp index 65920bf9ae..b9ff6b6729 100644 --- a/test/decompiler/test_FormExpressionBuild.cpp +++ b/test/decompiler/test_FormExpressionBuild.cpp @@ -2550,7 +2550,7 @@ TEST_F(FormRegressionTest, ExprTerminal2) { std::string expected = "(let\n" - " ((f0-4 (sqrt (/ (- (* 0.0 arg0) arg1) arg2))))\n" + " ((f0-4 (sqrtf (/ (- (* 0.0 arg0) arg1) arg2))))\n" " (- f0-4 (+ arg1 (* arg2 (* f0-4 f0-4))))\n" " )"; test_with_expr(func, type, expected, false, "", {{"L17", "A ~A"}}); diff --git a/test/decompiler/test_FormExpressionBuild2.cpp b/test/decompiler/test_FormExpressionBuild2.cpp index 978803d28a..952cbc7eb2 100644 --- a/test/decompiler/test_FormExpressionBuild2.cpp +++ b/test/decompiler/test_FormExpressionBuild2.cpp @@ -3,6 +3,7 @@ using namespace decompiler; +// tests stack variables TEST_F(FormRegressionTest, MatrixPMult) { std::string func = "sll r0, r0, 0\n" @@ -56,4 +57,272 @@ TEST_F(FormRegressionTest, MatrixPMult) { "[\n" " [16, \"matrix\"]\n" " ]"); +} + +// TODO- this should also work without the cast, but be uglier. +TEST_F(FormRegressionTest, VectorXQuaternionWithCast) { + std::string func = + "sll r0, r0, 0\n" + + " daddiu sp, sp, -112\n" + " sd ra, 0(sp)\n" + " sq s5, 80(sp)\n" + " sq gp, 96(sp)\n" + + " or gp, a0, r0\n" + " daddiu s5, sp, 16\n" + " sq r0, 0(s5)\n" + " sq r0, 16(s5)\n" + " sq r0, 32(s5)\n" + " sq r0, 48(s5)\n" + " lw t9, quaternion->matrix(s7)\n" + " or a0, s5, r0\n" + " jalr ra, t9\n" + " sll v0, ra, 0\n" + + " daddu v1, r0, s5\n" + " lq v1, 0(v1)\n" + + " sq v1, 0(gp)\n" + " or v0, gp, r0\n" + " ld ra, 0(sp)\n" + " lq gp, 96(sp)\n" + " lq s5, 80(sp)\n" + " jr ra\n" + " daddiu sp, sp, 112"; + std::string type = "(function quaternion quaternion quaternion)"; + std::string expected = + "(begin\n" + " (let ((s5-0 (new (quote stack) (quote matrix))))\n" + " (set! (-> s5-0 vector 0 quad) (the-as uint128 0))\n" + " (set! (-> s5-0 vector 1 quad) (the-as uint128 0))\n" + " (set! (-> s5-0 vector 2 quad) (the-as uint128 0))\n" + " (set! (-> s5-0 vector 3 quad) (the-as uint128 0))\n" + " (quaternion->matrix s5-0 arg1)\n" + " (set! (-> arg0 vec quad) (-> (the-as (pointer uint128) (-> s5-0 data)) 0))\n" + " )\n" + " arg0\n" + " )"; + test_with_stack_vars(func, type, expected, + "[\n" + " [16, \"matrix\"]\n" + " ]", + "[[10, \"v1\", \"(pointer uint128)\"]]"); +} + +TEST_F(FormRegressionTest, EliminateFloatDeadSet) { + std::string func = + "sll r0, r0, 0\n" + "L32:\n" + " daddiu sp, sp, -16\n" + " sd fp, 8(sp)\n" + " or fp, t9, r0\n" + + " lwu v1, 4(a0)\n" + " mtc1 f0, v1\n" + " cvt.s.w f1, f0\n" + //" lwc1 f0, L83(fp)\n" + " mtc1 f0, r0\n" + " lw a1, *display*(s7)\n" + " ld a1, 780(a1)\n" + " divu a1, v1\n" + " mfhi v1\n" + " mtc1 f2, v1\n" + " cvt.s.w f2, f2\n" + " lwc1 f3, 0(a0)\n" + " add.s f2, f2, f3\n" + " div.s f3, f2, f1\n" + " cvt.w.s f3, f3\n" + " cvt.s.w f3, f3\n" + " mul.s f3, f3, f1\n" + " sub.s f2, f2, f3\n" + " div.s f1, f2, f1\n" + " mul.s f0, f0, f1\n" + //" lwc1 f1, L84(fp)\n" + " mtc1 f1, r0\n" + //" lwc1 f2, L83(fp)\n" + " mtc1 f2, r0\n" + " lwc1 f3, 12(a0)\n" + " mul.s f2, f2, f3\n" + " sub.s f1, f1, f2\n" + //" lwc1 f2, L84(fp)\n" + " mtc1 f2, r0\n" + //" lwc1 f3, L83(fp)\n" + " mtc1 f3, r0\n" + " lwc1 f4, 8(a0)\n" + " mul.s f3, f3, f4\n" + " sub.s f2, f2, f3\n" + //" lwc1 f3, L84(fp)\n" + " mtc1 f3, r0\n" + " add.s f3, f3, f1\n" + " c.lt.s f0, f3\n" + " bc1t L33\n" + " sll r0, r0, 0\n" + + " mtc1 f0, r0\n" + " mfc1 v1, f0\n" + " beq r0, r0, L36\n" + " sll r0, r0, 0\n" + + "L33:\n" + //" lwc1 f3, L84(fp)\n"e + " mtc1 f3, r0\n" + " c.lt.s f3, f0\n" + " bc1f L34\n" + " sll r0, r0, 0\n" + + //" lwc1 f2, L84(fp)\n" + " mtc1 f2, r0\n" + //" lwc1 f3, L82(fp)\n" + " mtc1 f3, r0\n" + " add.s f0, f3, f0\n" + " div.s f0, f0, f1\n" + " sub.s f0, f2, f0\n" + " mfc1 v1, f0\n" + " beq r0, r0, L36\n" + " sll r0, r0, 0\n" + + "L34:\n" + " c.lt.s f0, f2\n" + " bc1t L35\n" + " sll r0, r0, 0\n" + + //" lwc1 f0, L84(fp)\n" + " mtc1 f0, r0\n" + " mfc1 v1, f0\n" + " beq r0, r0, L36\n" + " sll r0, r0, 0\n" + + "L35:\n" + " div.s f0, f0, f2\n" + " mfc1 v1, f0\n" + + "L36:\n" + " mfc1 v0, f0\n" + " ld fp, 8(sp)\n" + " jr ra\n" + " daddiu sp, sp, 16"; + std::string type = "(function sync-info-paused float)"; + std::string expected = + "(let* ((v1-0 (-> arg0 period))\n" + " (f1-0 (the float v1-0))\n" + " (f0-1 0.0)\n" + " (f2-2\n" + " (+\n" + " (the float (mod (-> *display* base-frame-counter) v1-0))\n" + " (-> arg0 offset)\n" + " )\n" + " )\n" + " (f0-2\n" + " (* f0-1 (/ (- f2-2 (* (the float (the int (/ f2-2 f1-0))) f1-0)) f1-0))\n" + " )\n" + " (f1-3 (- 0.0 (* 0.0 (-> arg0 pause-after-in))))\n" + " (f2-7 (- 0.0 (* 0.0 (-> arg0 pause-after-out))))\n" + " )\n" + " (cond\n" + " ((>= f0-2 (+ 0.0 f1-3))\n" + " 0.0\n" + " )\n" + " ((< 0.0 f0-2)\n" + " (- 0.0 (/ (+ 0.0 f0-2) f1-3))\n" + " )\n" + " ((>= f0-2 f2-7)\n" + " 0.0\n" + " )\n" + " (else\n" + " (/ f0-2 f2-7)\n" + " )\n" + " )\n" + " )"; + test_with_stack_vars(func, type, expected, "[]"); +} + +TEST_F(FormRegressionTest, IterateProcessTree) { + std::string func = + "sll r0, r0, 0\n" + + " daddiu sp, sp, -80\n" + " sd ra, 0(sp)\n" + " sq s3, 16(sp)\n" + " sq s4, 32(sp)\n" + " sq s5, 48(sp)\n" + " sq gp, 64(sp)\n" + + " or s3, a0, r0\n" + " or gp, a1, r0\n" + " or s5, a2, r0\n" + " lwu v1, 4(s3)\n" + " andi v1, v1, 256\n" + " bnel v1, r0, L113\n" + + " daddiu s4, s7, 8\n" + + " or t9, gp, r0\n" + " or a0, s3, r0\n" + " jalr ra, t9\n" + " sll v0, ra, 0\n" + " or s4, v0, r0\n" + + "L113:\n" + " daddiu v1, s7, dead\n" + " bne s4, v1, L114\n" + " sll r0, r0, 0\n" + + " or v1, s7, r0\n" + " beq r0, r0, L117\n" + " sll r0, r0, 0\n" + + "L114:\n" + " lwu v1, 16(s3)\n" + " beq r0, r0, L116\n" + " sll r0, r0, 0\n" + + "L115:\n" + " lwu a0, 0(v1)\n" + " lwu s3, 12(a0)\n" + " lw t9, iterate-process-tree(s7)\n" + " lwu a0, 0(v1)\n" + " or a1, gp, r0\n" + " or a2, s5, r0\n" + " jalr ra, t9\n" + " sll v0, ra, 0\n" + + " or v1, s3, r0\n" + " or a0, v1, r0\n" + + "L116:\n" + " bne s7, v1, L115\n" + " sll r0, r0, 0\n" + + " or v1, s7, r0\n" + + "L117:\n" + " or v0, s4, r0\n" + " ld ra, 0(sp)\n" + " lq gp, 64(sp)\n" + " lq s5, 48(sp)\n" + " lq s4, 32(sp)\n" + " lq s3, 16(sp)\n" + " jr ra\n" + " daddiu sp, sp, 80"; + std::string type = "(function process-tree (function object object) kernel-context object)"; + std::string expected = + "(let ((s4-0 (or (nonzero? (logand (-> arg0 mask) 256)) (arg1 arg0))))\n" + " (cond\n" + " ((= s4-0 (quote dead))\n" + " )\n" + " (else\n" + " (let ((v1-4 (-> arg0 child)))\n" + " (while v1-4\n" + " (let ((s3-1 (-> v1-4 0 brother)))\n" + " (iterate-process-tree (-> v1-4 0) arg1 arg2)\n" + " (set! v1-4 s3-1)\n" + " )\n" + " )\n" + " )\n" + " )\n" + " )\n" + " s4-0\n" + " )"; + test_with_stack_vars(func, type, expected, "[]"); } \ No newline at end of file diff --git a/test/decompiler/test_FormExpressionBuildLong.cpp b/test/decompiler/test_FormExpressionBuildLong.cpp index 84b7e765a8..366a67ecdb 100644 --- a/test/decompiler/test_FormExpressionBuildLong.cpp +++ b/test/decompiler/test_FormExpressionBuildLong.cpp @@ -2357,8 +2357,6 @@ TEST_F(FormRegressionTest, ExprStringToInt) { " (when (= (-> a0-3 1) 45)\n" " (set! v1-0 #t)\n" " (set! a0-3 (&-> a0-3 1))\n" - " (let ((a1-8 a0-3))\n" - " )\n" " )\n" " (while\n" " (or\n" @@ -2375,38 +2373,23 @@ TEST_F(FormRegressionTest, ExprStringToInt) { " (>= (the-as uint 102) (-> a0-3 0))\n" " )\n" " )\n" - " (cond\n" - " ((and\n" + " (set!\n" + " v0-0\n" + " (if\n" + " (and\n" " (>= (-> a0-3 0) (the-as uint 65))\n" " (>= (the-as uint 70) (-> a0-3 0))\n" " )\n" - " (set!\n" - " v0-0\n" - " (the-as int (+ (+ (-> a0-3 0) -55) (the-as uint (shl v0-0 4))))\n" - " )\n" - " (let ((a1-14 (the-as uint v0-0)))\n" - " )\n" - " )\n" - " (else\n" - " (cond\n" - " ((and\n" + " (+ (+ (-> a0-3 0) -55) (the-as uint (shl v0-0 4)))\n" + " (the-as\n" + " int\n" + " (if\n" + " (and\n" " (>= (-> a0-3 0) (the-as uint 97))\n" " (>= (the-as uint 102) (-> a0-3 0))\n" " )\n" - " (set!\n" - " v0-0\n" - " (the-as int (+ (+ (-> a0-3 0) -87) (the-as uint (shl v0-0 4))))\n" - " )\n" - " (let ((a1-20 (the-as uint v0-0)))\n" - " )\n" - " )\n" - " (else\n" - " (set!\n" - " v0-0\n" - " (the-as int (+ (+ (-> a0-3 0) -48) (the-as uint (shl v0-0 4))))\n" - " )\n" - " (let ((a1-23 (the-as uint v0-0)))\n" - " )\n" + " (+ (+ (-> a0-3 0) -87) (the-as uint (shl v0-0 4)))\n" + " (+ (+ (-> a0-3 0) -48) (the-as uint (shl v0-0 4)))\n" " )\n" " )\n" " )\n" @@ -2437,8 +2420,6 @@ TEST_F(FormRegressionTest, ExprStringToInt) { " (when (= (-> a0-1 1) 45)\n" " (set! v1-0 #t)\n" " (set! a0-1 (&-> a0-1 1))\n" - " (let ((a1-47 a0-1))\n" - " )\n" " )\n" " (while\n" " (and (>= (-> a0-1 0) (the-as uint 48)) (>= (the-as uint 57) (-> a0-1 0)))\n" diff --git a/test/decompiler/test_gkernel_decomp.cpp b/test/decompiler/test_gkernel_decomp.cpp index 5662654853..a48052e3ce 100644 --- a/test/decompiler/test_gkernel_decomp.cpp +++ b/test/decompiler/test_gkernel_decomp.cpp @@ -1090,7 +1090,7 @@ TEST_F(FormRegressionTest, ExprMethod14DeadPool) { " (v1-6 (the-as process s4-0))\n" " )\n" " (t9-1 a0-2 a1-2 a2-1 (if (the-as process v1-6)\n" - " (-> (the-as (pointer process-tree) v1-6) 0 self)\n" + " (-> (the-as (pointer process) v1-6) 0 self)\n" " )\n" " (-> arg0 name)\n" " )\n" @@ -1099,16 +1099,16 @@ TEST_F(FormRegressionTest, ExprMethod14DeadPool) { " )\n" " (the-as process (cond\n" " (s4-0\n" - " (set! (-> (the-as (pointer process-tree) s4-0) 0 type) arg1)\n" - " (-> (the-as (pointer process-tree) s4-0) 0)\n" + " (set! (-> (the-as (pointer process) s4-0) 0 type) arg1)\n" + " (-> (the-as (pointer process) s4-0) 0)\n" " )\n" " (else\n" " (format\n" " 0\n" " \"WARNING: ~A ~A could not be allocated, because ~A was empty.~%\"\n" " arg1\n" - " (if (the-as (pointer process-tree) s4-0)\n" - " (-> (the-as (pointer process-tree) s4-0) 0 self)\n" + " (if (the-as (pointer process) s4-0)\n" + " (-> (the-as (pointer process) s4-0) 0 self)\n" " )\n" " (-> arg0 name)\n" " )\n" @@ -1123,8 +1123,8 @@ TEST_F(FormRegressionTest, ExprMethod14DeadPool) { func, type, expected, false, "dead-pool", {{"L315", "WARNING: ~A ~A had to be allocated from the debug pool, because ~A was empty.~%"}, {"L314", "WARNING: ~A ~A could not be allocated, because ~A was empty.~%"}}, - "[\t\t[24, \"v1\", \"(pointer process-tree)\"],\n" - "\t\t[[30,39], \"s4\", \"(pointer process-tree)\"]]"); + "[\t\t[24, \"v1\", \"(pointer process)\"],\n" + "\t\t[[30,39], \"s4\", \"(pointer process)\"]]"); } TEST_F(FormRegressionTest, ExprMethod15DeadPool) { @@ -2016,13 +2016,12 @@ TEST_F(FormRegressionTest, ExprMethod14DeadPoolHeap) { " ((v1-5 (-> s1-0 next)))\n" " (set! (-> s1-0 next) s4-0)\n" " (set! (-> s4-0 next) v1-5)\n" - " (when v1-5 (set! (-> v1-5 prev) s4-0) (let ((v1-6 s4-0))))\n" + " (if v1-5 (set! (-> v1-5 prev) s4-0))\n" " )\n" " (set! (-> s4-0 prev) s1-0)\n" - " (when\n" + " (if\n" " (= s1-0 (-> arg0 alive-list prev))\n" " (set! (-> arg0 alive-list prev) s4-0)\n" - " (let ((v1-9 s4-0)))\n" " )\n" " (let\n" " ((a0-4 (gap-location arg0 s1-0)))\n" @@ -2042,13 +2041,12 @@ TEST_F(FormRegressionTest, ExprMethod14DeadPoolHeap) { " (= (-> arg0 first-gap) s1-0)\n" " (set! (-> arg0 first-gap) (find-gap arg0 s4-0))\n" " )\n" - " (when\n" + " (if\n" " (or\n" " (not (-> arg0 first-shrink))\n" " (< (the-as int s3-0) (the-as int (-> arg0 first-shrink process)))\n" " )\n" " (set! (-> arg0 first-shrink) s4-0)\n" - " (let ((v1-22 s4-0)))\n" " )\n" " (set! (-> s3-0 parent) (-> arg0 ppointer))\n" " (set! (-> s3-0 pool) arg0)\n" @@ -2593,8 +2591,8 @@ TEST_F(FormRegressionTest, ExprMethod16DeadPoolHeap) { " (format *stdcon* \"~3LLow Actor Memory~%~0L\" a2-0)\n" " )\n" " )\n" - " ((< f0-2 (l.f L347)) (set! arg1 (shl arg1 2)) (let ((v1-10 arg1))))\n" - " ((< f0-2 (l.f L348)) (set! arg1 (shl arg1 1)) (let ((v1-12 arg1))))\n" + " ((< f0-2 (l.f L347)) (set! arg1 (shl arg1 2)))\n" + " ((< f0-2 (l.f L348)) (set! arg1 (shl arg1 1)))\n" " )\n" " )\n" " (set! (-> arg0 compact-count-targ) (the-as uint arg1))\n" @@ -2608,7 +2606,6 @@ TEST_F(FormRegressionTest, ExprMethod16DeadPoolHeap) { " (not v1-13)\n" " (set! v1-13 (-> arg0 alive-list next))\n" " (set! (-> arg0 first-shrink) v1-13)\n" - " (let ((a0-5 v1-13)))\n" " )\n" " (if v1-13 (shrink-heap arg0 (-> v1-13 process)))\n" " )\n" @@ -2818,7 +2815,7 @@ TEST_F(FormRegressionTest, ExprMethod18DeadPoolHeap) { " ((v1-19 (-> a1-3 next)))\n" " (set! (-> a1-3 next) s4-0)\n" " (set! (-> s4-0 next) v1-19)\n" - " (when v1-19 (set! (-> v1-19 prev) s4-0) (let ((v1-20 s4-0))))\n" + " (if v1-19 (set! (-> v1-19 prev) s4-0))\n" " )\n" " (set! (-> s4-0 prev) a1-3)\n" " (set! (-> arg0 alive-list prev) s4-0)\n" diff --git a/test/offline/offline_test_main.cpp b/test/offline/offline_test_main.cpp index 51012b976e..0504b06a6f 100644 --- a/test/offline/offline_test_main.cpp +++ b/test/offline/offline_test_main.cpp @@ -14,7 +14,7 @@ const std::unordered_set g_object_files_to_decompile = { "gcommon", "gstring-h", "gkernel-h", "gkernel", /*"pskernel",*/ "gstring", "dgo-h", "gstate", "types-h", "vu1-macros", "math", "vector-h", "bounding-box-h", "matrix-h", "quaternion-h", "euler-h", "transform-h", "geometry-h", - "trigonometry-h", /* transformq-h */ "matrix", + "trigonometry-h", /* transformq-h */ "matrix", "transform", "quaternion", /* gap */ "bounding-box"}; @@ -25,7 +25,7 @@ const std::vector g_object_files_to_check_against_reference = { "math", "vector-h", "bounding-box-h", "matrix-h", "quaternion-h", "euler-h", "transform-h", "geometry-h", "trigonometry-h", /* transformq-h, */ - "matrix", + "matrix", "transform", "quaternion", /* gap */ "bounding-box"}; // the functions we expect the decompiler to skip @@ -82,7 +82,8 @@ const std::unordered_set skip_in_compiling = { "(method 10 process)", /// GSTATE - "enter-state", // stack pointer asm + "enter-state", // stack pointer asm + "send-event-function", // pp asm (eventually we should make this work) /// MATH "rand-vu-init", "rand-vu", "rand-vu-nostep", // random hardware @@ -92,6 +93,11 @@ const std::unordered_set skip_in_compiling = { "(method 3 vector)", // this function appears twice, which confuses the compiler. "vector-dot", // fpu acc "vector4-dot", // fpu acc + + // QUATERNION + "matrix-with-scale->quaternion", // fpu acc + "quaternion-delta-y", // fpu acc + }; // default location for the data. It can be changed with a command line argument.