[Decomp] Math library: transform and quaternion (#344)

* decompile transform

* types for quaternion

* part of quaternion

* finish quaternion

* fix offline test reference

* wip fix to let issue

* fix
This commit is contained in:
water111
2021-04-02 11:35:14 -04:00
committed by GitHub
parent 7867de8fd7
commit 9969445cf7
44 changed files with 3485 additions and 459 deletions
+7
View File
@@ -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
+1
View File
@@ -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;
+40 -15
View File
@@ -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*>(&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*>(&env);
if (ri.consumes.find(src_var.reg()) == ri.consumes.end()) {
menv->disable_use(src_var);
}
}
}
}
+9
View File
@@ -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) {
+14 -1
View File
@@ -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<SimpleAtom> form_as_atom(const Form* f) {
return {};
}
FormElement* make_cast_using_existing(FormElement* elt, const TypeSpec& type, FormPool& pool) {
auto as_cast = dynamic_cast<CastElement*>(elt);
if (as_cast) {
if (as_cast->type() != type) {
as_cast->set_type(type);
}
return as_cast;
} else {
return pool.alloc_element<CastElement>(type, pool.alloc_single_form(nullptr, elt));
}
}
} // namespace decompiler
+3
View File
@@ -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<SimpleAtom> 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
+50 -3
View File
@@ -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<CastElement*>(in->try_as_single_element());
if (in_as_cast && in_as_cast->type() == out_type) {
return in;
}
return pool.alloc_single_element_form<CastElement>(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<FormElement*> 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<TypeSpec>& cast_type, Form* in, FormPool& pool) {
if (cast_type) {
auto in_as_cast = dynamic_cast<CastElement*>(in->try_as_single_element());
if (in_as_cast && in_as_cast->type() == cast_type) {
return in;
}
return pool.alloc_single_element_form<CastElement>(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<SetVarElement*> dest_sets;
std::vector<TypeSpec> source_types; // only explicit accesses that aren't move-eliminated
for (auto form : write_output_forms) {
auto last_in_body = dynamic_cast<SetVarElement*>(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<CastElement>(nullptr, expected_type, result_value);
}
stack.push_value_to_reg(*last_var, result_value, true,
env.get_variable_type(*last_var, false));
}
} else {
+4
View File
@@ -344,6 +344,10 @@ std::vector<FormElement*> FormStack::rewrite(FormPool& pool, const Env& env) {
result.push_back(e.elt);
}
}
if (result.empty()) {
result.push_back(pool.alloc_element<EmptyElement>());
}
return result;
}
+27 -22
View File
@@ -1354,6 +1354,7 @@ void convert_and_inline(FormPool& pool, Function& f, const BlockVtx* as_block, T
auto op_as_set = dynamic_cast<SetVarElement*>(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<SimpleExpressionElement*>(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;
}
}
}
}
+16 -1
View File
@@ -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<CastElement*>(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<CastElement>(nullptr, dst_type, src);
}
+1
View File
@@ -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);
}
}
+135 -112
View File
@@ -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)
@@ -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],
@@ -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"]]
}
@@ -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"]
]
}
@@ -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": {
+3 -1
View File
@@ -33,4 +33,6 @@
(dummy-9 () none 9)
(dummy-10 () none 10)
)
)
)
(defun-extern quaternion-from-two-vectors-max-angle! quaternion vector vector float quaternion)
+5 -5
View File
@@ -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)
)
File diff suppressed because it is too large Load Diff
+4 -1
View File
@@ -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
)
)
+98
View File
@@ -5,3 +5,101 @@
;; name in dgo: transform
;; dgos: GAME, ENGINE
(defmethod print transform ((obj transform))
(format #t "#<transform @ #x~X~%" obj)
(format #t "~T~Ttrans:~F ~F ~F ~F ~%"
(-> 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)
)
+9
View File
@@ -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)
+4
View File
@@ -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))
+3
View File
@@ -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,
+5 -4
View File
@@ -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<IR_SwizzleVF>(color, temp1, src1, 0b00001001);
// - Move it into 'dest' safely (avoid mutating `w`)
env->emit_ir<IR_BlendVF>(color, dest, dest, temp1, 0b0111);
env->emit_ir<IR_BlendVF>(color, temp_dst, temp_dst, temp1, 0b0111);
// - Swizzle src2 appropriately
env->emit_ir<IR_SwizzleVF>(color, temp1, src2, 0b00010010);
// - Multiply - Result in `dest`
env->emit_ir<IR_VFMath3Asm>(color, temp1, dest, temp1, IR_VFMath3Asm::Kind::MUL);
env->emit_ir<IR_VFMath3Asm>(color, temp1, temp_dst, temp1, IR_VFMath3Asm::Kind::MUL);
// - Move it into 'dest' safely (avoid mutating `w`)
env->emit_ir<IR_BlendVF>(color, dest, dest, temp1, 0b0111);
env->emit_ir<IR_BlendVF>(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<IR_VFMath3Asm>(color, temp2, dest, temp1, IR_VFMath3Asm::Kind::SUB);
env->emit_ir<IR_VFMath3Asm>(color, temp2, temp_dst, temp1, IR_VFMath3Asm::Kind::SUB);
// - Blend result, as to avoid not modifying dest's `w` component
env->emit_ir<IR_BlendVF>(color, dest, dest, temp2, 0b0111);
return get_none();
+38
View File
@@ -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, &macro_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;
}
+2 -1
View File
@@ -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<FileEnv>(env);
auto fe = get_parent_env_of_type<FunctionEnv>(env);
auto segment = fe->segment;
@@ -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))
(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))
+13 -26
View File
@@ -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 "#<handle :process ~A :pid ~D>")
(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 "#<handle :process 0 :pid 0>")
)
+54 -87
View File
@@ -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)
+18 -10
View File
@@ -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
)
)
)
)
+12 -42
View File
@@ -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
+8 -20
View File
@@ -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)
)
+2 -9
View File
@@ -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
)
)
+12 -11
View File
@@ -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: #<vector @ #x~X>~%" (-> 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: #<vector @ #x~X>~%" (&-> obj x))
(format #t "~Tquad: ~D~%" (-> obj vec quad))
obj
)
File diff suppressed because it is too large Load Diff
@@ -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
+116
View File
@@ -0,0 +1,116 @@
;;-*-Lisp-*-
(in-package goal)
;; definition for method 2 of type transform
(defmethod print transform ((obj transform))
(format #t "#<transform @ #x~X~%" obj)
(format
#t
"~T~Ttrans:~F ~F ~F ~F ~%"
(-> 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)
+4 -6
View File
@@ -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
)
)
+1 -1
View File
@@ -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"}});
@@ -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, "[]");
}
@@ -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"
+13 -16
View File
@@ -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"
+9 -3
View File
@@ -14,7 +14,7 @@ const std::unordered_set<std::string> 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<std::string> 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<std::string> 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<std::string> 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.