mirror of
https://github.com/open-goal/jak-project.git
synced 2024-10-20 11:26:18 -04:00
recognize vector, matrix, quaternion constructors in a better way (#630)
* recognize vector, matrix, quaternion constructors in a better way * fix bad bug
This commit is contained in:
parent
ae2666a7c5
commit
69e24ae577
|
@ -1721,10 +1721,140 @@ Form* make_optional_cast(const std::optional<TypeSpec>& cast_type,
|
|||
return in;
|
||||
}
|
||||
}
|
||||
|
||||
bool try_to_rewrite_vector_inline_ctor(const Env& env,
|
||||
FormPool& pool,
|
||||
FormStack& stack,
|
||||
const std::string& type_name) {
|
||||
// now, let's check for a matrix initialization.
|
||||
auto matrix_entries = stack.try_getting_active_stack_entries({true, false});
|
||||
if (matrix_entries) {
|
||||
// the (set! var (new 'stack-no-clear 'matrix))
|
||||
if (matrix_entries->at(0).destination->reg() == Register(Reg::GPR, Reg::R0)) {
|
||||
return false;
|
||||
}
|
||||
auto var_name = env.get_variable_name(*matrix_entries->at(0).destination);
|
||||
auto src = matrix_entries->at(0).source->try_as_element<StackStructureDefElement>();
|
||||
if (!src) {
|
||||
return false;
|
||||
}
|
||||
if (src->type() != TypeSpec(type_name)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// zeroing the rows:
|
||||
std::vector<RegisterAccess> write_vars;
|
||||
|
||||
auto elt = matrix_entries->at(1).elt;
|
||||
|
||||
std::vector<DerefTokenMatcher> token_matchers = {DerefTokenMatcher::string("vec"),
|
||||
DerefTokenMatcher::string("quad")};
|
||||
if (type_name == "vector") {
|
||||
token_matchers = {DerefTokenMatcher::string("quad")};
|
||||
}
|
||||
|
||||
auto matcher = Matcher::set(Matcher::deref(Matcher::any_reg(0), false, token_matchers),
|
||||
Matcher::cast("uint128", Matcher::integer(0)));
|
||||
|
||||
Form hack;
|
||||
hack.elts().push_back(elt);
|
||||
auto mr = match(matcher, &hack);
|
||||
|
||||
if (mr.matched) {
|
||||
if (var_name != env.get_variable_name(*mr.maps.regs.at(0))) {
|
||||
return false;
|
||||
}
|
||||
write_vars.push_back(*mr.maps.regs.at(0));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
// success!
|
||||
for (auto& wv : write_vars) {
|
||||
env.get_use_def_info(wv);
|
||||
Env* menv = const_cast<Env*>(&env);
|
||||
menv->disable_use(wv);
|
||||
}
|
||||
stack.pop(2);
|
||||
|
||||
stack.push_value_to_reg(
|
||||
*matrix_entries->at(0).destination,
|
||||
pool.alloc_single_element_form<GenericElement>(
|
||||
nullptr,
|
||||
GenericOperator::make_function(pool.alloc_single_element_form<ConstantTokenElement>(
|
||||
nullptr, fmt::format("new-stack-{}0", type_name)))),
|
||||
true, TypeSpec(type_name));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool try_to_rewrite_matrix_inline_ctor(const Env& env, FormPool& pool, FormStack& stack) {
|
||||
// now, let's check for a matrix initialization.
|
||||
auto matrix_entries = stack.try_getting_active_stack_entries({true, false, false, false, false});
|
||||
if (matrix_entries) {
|
||||
// the (set! var (new 'stack-no-clear 'matrix))
|
||||
if (matrix_entries->at(0).destination->reg() == Register(Reg::GPR, Reg::R0)) {
|
||||
return false;
|
||||
}
|
||||
auto var_name = env.get_variable_name(*matrix_entries->at(0).destination);
|
||||
auto src = matrix_entries->at(0).source->try_as_element<StackStructureDefElement>();
|
||||
if (!src) {
|
||||
return false;
|
||||
}
|
||||
if (src->type() != TypeSpec("matrix")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// zeroing the rows:
|
||||
std::vector<RegisterAccess> write_vars;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
auto elt = matrix_entries->at(i + 1).elt;
|
||||
|
||||
auto matcher = Matcher::set(
|
||||
Matcher::deref(Matcher::any_reg(0), false,
|
||||
{DerefTokenMatcher::string("vector"), DerefTokenMatcher::integer(i),
|
||||
DerefTokenMatcher::string("quad")}),
|
||||
Matcher::cast("uint128", Matcher::integer(0)));
|
||||
|
||||
Form hack;
|
||||
hack.elts().push_back(elt);
|
||||
auto mr = match(matcher, &hack);
|
||||
|
||||
if (mr.matched) {
|
||||
if (var_name != env.get_variable_name(*mr.maps.regs.at(0))) {
|
||||
return false;
|
||||
}
|
||||
write_vars.push_back(*mr.maps.regs.at(0));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// success!
|
||||
for (auto& wv : write_vars) {
|
||||
env.get_use_def_info(wv);
|
||||
Env* menv = const_cast<Env*>(&env);
|
||||
menv->disable_use(wv);
|
||||
}
|
||||
stack.pop(5);
|
||||
|
||||
stack.push_value_to_reg(*matrix_entries->at(0).destination,
|
||||
pool.alloc_single_element_form<GenericElement>(
|
||||
nullptr, GenericOperator::make_function(
|
||||
pool.alloc_single_element_form<ConstantTokenElement>(
|
||||
nullptr, "new-stack-matrix0"))),
|
||||
true, TypeSpec("matrix"));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void StorePlainDeref::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
||||
mark_popped();
|
||||
|
||||
if (m_expr.is_var()) {
|
||||
// this matches the order in Compiler::compile_set
|
||||
auto vars = std::vector<RegisterAccess>({m_expr.var(), m_base_var});
|
||||
|
@ -1759,6 +1889,12 @@ void StorePlainDeref::push_to_stack(const Env& env, FormPool& pool, FormStack& s
|
|||
fr->mark_popped();
|
||||
stack.push_form_element(fr, true);
|
||||
}
|
||||
|
||||
if (!try_to_rewrite_matrix_inline_ctor(env, pool, stack)) {
|
||||
if (!try_to_rewrite_vector_inline_ctor(env, pool, stack, "vector")) {
|
||||
try_to_rewrite_vector_inline_ctor(env, pool, stack, "quaternion");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StoreArrayAccess::push_to_stack(const Env& env, FormPool& pool, FormStack& stack) {
|
||||
|
|
|
@ -46,7 +46,6 @@ class FormStack {
|
|||
std::string print(const Env& env);
|
||||
bool is_root() const { return m_is_root_stack; }
|
||||
|
||||
private:
|
||||
struct StackEntry {
|
||||
bool active = true; // should this appear in the output?
|
||||
std::optional<RegisterAccess>
|
||||
|
@ -64,6 +63,45 @@ class FormStack {
|
|||
|
||||
std::string print(const Env& env) const;
|
||||
};
|
||||
|
||||
std::optional<std::vector<StackEntry>> try_getting_active_stack_entries(
|
||||
const std::vector<bool>& is_set) const {
|
||||
if (is_set.size() > m_stack.size()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<StackEntry> entries;
|
||||
size_t offset = m_stack.size() - is_set.size();
|
||||
for (size_t i = 0; i < is_set.size(); i++) {
|
||||
auto& my_entry = m_stack.at(i + offset);
|
||||
if (my_entry.active) {
|
||||
if (is_set.at(i)) {
|
||||
if (!my_entry.destination) {
|
||||
return {};
|
||||
}
|
||||
assert(my_entry.source && !my_entry.elt);
|
||||
} else {
|
||||
if (my_entry.destination) {
|
||||
return {};
|
||||
}
|
||||
assert(my_entry.elt && !my_entry.source);
|
||||
}
|
||||
entries.push_back(my_entry);
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
void pop(int count) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
assert(!m_stack.empty());
|
||||
m_stack.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<StackEntry> m_stack;
|
||||
bool m_is_root_stack = false;
|
||||
};
|
||||
|
|
|
@ -336,100 +336,6 @@ FormElement* fix_up_abs_2(LetElement* in, const Env& env, FormPool& pool) {
|
|||
return in;
|
||||
}
|
||||
|
||||
FormElement* fix_up_vector_inline_zero(LetElement* in, const Env& env, FormPool& pool) {
|
||||
/*
|
||||
* (let ((local-trans (new 'stack-no-clear 'vector)))
|
||||
* (set! (-> local-trans quad) (the-as uint128 0))
|
||||
*/
|
||||
|
||||
if (in->entries().size() != 1) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (in->body()->elts().empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Form* src = in->entries().at(0).src;
|
||||
auto src_as_stackvar = src->try_as_element<StackStructureDefElement>();
|
||||
if (!src_as_stackvar) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool is_vector = src_as_stackvar->type() == TypeSpec("vector");
|
||||
bool is_matrix = src_as_stackvar->type() == TypeSpec("matrix");
|
||||
|
||||
if (is_vector) {
|
||||
auto first_elt = in->body()->elts().at(0);
|
||||
|
||||
auto matcher = Matcher::set(
|
||||
Matcher::deref(Matcher::any_reg(0), false, {DerefTokenMatcher::string("quad")}),
|
||||
Matcher::cast("uint128", Matcher::integer(0)));
|
||||
|
||||
Form hack;
|
||||
hack.elts().push_back(first_elt);
|
||||
auto mr = match(matcher, &hack);
|
||||
|
||||
if (mr.matched) {
|
||||
auto var = in->entries().at(0).dest;
|
||||
auto var_name = env.get_variable_name(var);
|
||||
|
||||
if (var_name != env.get_variable_name(*mr.maps.regs.at(0))) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto new_op = pool.alloc_single_element_form<GenericElement>(
|
||||
nullptr,
|
||||
GenericOperator::make_function(
|
||||
pool.alloc_single_element_form<ConstantTokenElement>(nullptr, "new-stack-vector0")));
|
||||
src->parent_element = in;
|
||||
in->entries().at(0).src = new_op;
|
||||
in->body()->elts().erase(in->body()->elts().begin());
|
||||
return in;
|
||||
}
|
||||
} else if (is_matrix) {
|
||||
if (in->body()->elts().size() < 4) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto var = in->entries().at(0).dest;
|
||||
auto var_name = env.get_variable_name(var);
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
auto elt = in->body()->elts().at(i);
|
||||
|
||||
auto matcher = Matcher::set(
|
||||
Matcher::deref(Matcher::any_reg(0), false,
|
||||
{DerefTokenMatcher::string("vector"), DerefTokenMatcher::integer(i),
|
||||
DerefTokenMatcher::string("quad")}),
|
||||
Matcher::cast("uint128", Matcher::integer(0)));
|
||||
|
||||
Form hack;
|
||||
hack.elts().push_back(elt);
|
||||
auto mr = match(matcher, &hack);
|
||||
|
||||
if (mr.matched) {
|
||||
if (var_name != env.get_variable_name(*mr.maps.regs.at(0))) {
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
auto new_op = pool.alloc_single_element_form<GenericElement>(
|
||||
nullptr,
|
||||
GenericOperator::make_function(
|
||||
pool.alloc_single_element_form<ConstantTokenElement>(nullptr, "new-stack-matrix0")));
|
||||
src->parent_element = in;
|
||||
in->entries().at(0).src = new_op;
|
||||
in->body()->elts().erase(in->body()->elts().begin(), in->body()->elts().begin() + 4);
|
||||
return in;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Attempt to rewrite a let as another form. If it cannot be rewritten, this will return nullptr.
|
||||
*/
|
||||
|
@ -454,11 +360,6 @@ FormElement* rewrite_let(LetElement* in, const Env& env, FormPool& pool) {
|
|||
return as_abs_2;
|
||||
}
|
||||
|
||||
auto as_vector = fix_up_vector_inline_zero(in, env, pool);
|
||||
if (as_vector) {
|
||||
return as_vector;
|
||||
}
|
||||
|
||||
// nothing matched.
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -23,3 +23,13 @@
|
|||
|
||||
(define-extern matrix->quaternion (function quaternion matrix quaternion))
|
||||
(define-extern vector-y-angle (function vector float))
|
||||
|
||||
(defmacro new-stack-quaternion0 ()
|
||||
"Get a stack quaternion that's set to 0.
|
||||
This is more efficient than (new 'stack 'quaternion) because
|
||||
this doesn't call the constructor."
|
||||
`(let ((q (new 'stack-no-clear 'quaternion)))
|
||||
(set! (-> q quad) (the-as uint128 0))
|
||||
q
|
||||
)
|
||||
)
|
||||
|
|
|
@ -892,84 +892,80 @@
|
|||
|
||||
(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-no-clear 'quaternion))
|
||||
(let ((a2-1 (quaternion-vector-angle!
|
||||
(new-stack-quaternion0)
|
||||
(new 'static 'vector :x 1.0 :w 1.0)
|
||||
arg2
|
||||
)
|
||||
)
|
||||
)
|
||||
(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))
|
||||
)
|
||||
(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-no-clear 'quaternion))
|
||||
(let ((a2-1 (quaternion-vector-angle!
|
||||
(new-stack-quaternion0)
|
||||
(new 'static 'vector :y 1.0 :w 1.0)
|
||||
arg2
|
||||
)
|
||||
)
|
||||
)
|
||||
(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))
|
||||
)
|
||||
(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-no-clear 'quaternion))
|
||||
(let ((a2-1 (quaternion-vector-angle!
|
||||
(new-stack-quaternion0)
|
||||
(new 'static 'vector :z 1.0 :w 1.0)
|
||||
arg2
|
||||
)
|
||||
)
|
||||
)
|
||||
(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))
|
||||
)
|
||||
(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-no-clear 'quaternion))
|
||||
(let ((a1-2 (quaternion-vector-angle!
|
||||
(new-stack-quaternion0)
|
||||
(new 'static 'vector :y 1.0 :w 1.0)
|
||||
arg2
|
||||
)
|
||||
)
|
||||
)
|
||||
(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))
|
||||
)
|
||||
(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-no-clear 'quaternion))
|
||||
)
|
||||
(set! (-> s3-0 vec quad) (the-as uint128 0))
|
||||
(let ((t9-0 vector-x-quaternion!)
|
||||
(a0-1 (new 'stack-no-clear 'vector))
|
||||
(let ((a1-3 (quaternion-vector-angle!
|
||||
(new-stack-quaternion0)
|
||||
(vector-x-quaternion! (new-stack-vector0) arg1)
|
||||
arg2
|
||||
)
|
||||
)
|
||||
(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))
|
||||
)
|
||||
)
|
||||
(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-no-clear 'quaternion))
|
||||
)
|
||||
(set! (-> s3-0 vec quad) (the-as uint128 0))
|
||||
(let ((t9-0 vector-z-quaternion!)
|
||||
(a0-1 (new 'stack-no-clear 'vector))
|
||||
(let ((a1-3 (quaternion-vector-angle!
|
||||
(new-stack-quaternion0)
|
||||
(vector-z-quaternion! (new-stack-vector0) arg1)
|
||||
arg2
|
||||
)
|
||||
)
|
||||
(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))
|
||||
)
|
||||
)
|
||||
(quaternion-normalize! (quaternion*! arg0 a1-3 arg1))
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
@ -66,6 +66,17 @@
|
|||
)
|
||||
)
|
||||
|
||||
(defmacro new-stack-quaternion0 ()
|
||||
"Get a stack quaternion that's set to 0.
|
||||
This is more efficient than (new 'stack 'quaternion) because
|
||||
this doesn't call the constructor."
|
||||
`(let ((q (new 'stack-no-clear 'quaternion)))
|
||||
(set! (-> q quad) (the-as uint128 0))
|
||||
q
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
(defmacro with-pp (&rest body)
|
||||
`(rlet ((pp :reg r13 :reset-here #t :type process))
|
||||
,@body)
|
||||
|
|
|
@ -772,10 +772,7 @@
|
|||
;; Used lq/sq
|
||||
(defun matrix-rotate-yx! ((dst matrix) (rot-y-deg float) (rot-x-deg float))
|
||||
(matrix-rotate-y! dst rot-y-deg)
|
||||
(let* ((t9-1 matrix-rotate-x!)
|
||||
(a0-2 (new-stack-matrix0))
|
||||
(a1-2 (t9-1 a0-2 rot-x-deg))
|
||||
)
|
||||
(let ((a1-2 (matrix-rotate-x! (new-stack-matrix0) rot-x-deg)))
|
||||
(matrix*! dst a1-2 dst)
|
||||
)
|
||||
dst
|
||||
|
|
|
@ -924,13 +924,16 @@
|
|||
(defun
|
||||
quaternion-rotate-local-x!
|
||||
((arg0 quaternion) (arg1 quaternion) (arg2 float))
|
||||
(let ((t9-0 quaternion-vector-angle!)
|
||||
(a0-1 (new 'stack-no-clear '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))
|
||||
(let
|
||||
((a2-1
|
||||
(quaternion-vector-angle!
|
||||
(new-stack-quaternion0)
|
||||
(new 'static 'vector :x 1.0 :w 1.0)
|
||||
arg2
|
||||
)
|
||||
)
|
||||
)
|
||||
(quaternion-normalize! (quaternion*! arg0 arg1 a2-1))
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -939,13 +942,16 @@
|
|||
(defun
|
||||
quaternion-rotate-local-y!
|
||||
((arg0 quaternion) (arg1 quaternion) (arg2 float))
|
||||
(let ((t9-0 quaternion-vector-angle!)
|
||||
(a0-1 (new 'stack-no-clear '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))
|
||||
(let
|
||||
((a2-1
|
||||
(quaternion-vector-angle!
|
||||
(new-stack-quaternion0)
|
||||
(new 'static 'vector :y 1.0 :w 1.0)
|
||||
arg2
|
||||
)
|
||||
)
|
||||
)
|
||||
(quaternion-normalize! (quaternion*! arg0 arg1 a2-1))
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -954,58 +960,64 @@
|
|||
(defun
|
||||
quaternion-rotate-local-z!
|
||||
((arg0 quaternion) (arg1 quaternion) (arg2 float))
|
||||
(let ((t9-0 quaternion-vector-angle!)
|
||||
(a0-1 (new 'stack-no-clear '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))
|
||||
(let
|
||||
((a2-1
|
||||
(quaternion-vector-angle!
|
||||
(new-stack-quaternion0)
|
||||
(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-no-clear '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))
|
||||
(let
|
||||
((a1-2
|
||||
(quaternion-vector-angle!
|
||||
(new-stack-quaternion0)
|
||||
(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-no-clear 'quaternion))
|
||||
)
|
||||
(set! (-> s3-0 vec quad) (the-as uint128 0))
|
||||
(let* ((t9-0 vector-x-quaternion!)
|
||||
(a0-1 (new-stack-vector0))
|
||||
(a1-3 (s4-0 s3-0 (t9-0 a0-1 arg1) arg2))
|
||||
)
|
||||
(quaternion-normalize! (quaternion*! arg0 a1-3 arg1))
|
||||
(let
|
||||
((a1-3
|
||||
(quaternion-vector-angle!
|
||||
(new-stack-quaternion0)
|
||||
(vector-x-quaternion! (new-stack-vector0) 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-no-clear 'quaternion))
|
||||
)
|
||||
(set! (-> s3-0 vec quad) (the-as uint128 0))
|
||||
(let* ((t9-0 vector-z-quaternion!)
|
||||
(a0-1 (new-stack-vector0))
|
||||
(a1-3 (s4-0 s3-0 (t9-0 a0-1 arg1) arg2))
|
||||
)
|
||||
(quaternion-normalize! (quaternion*! arg0 a1-3 arg1))
|
||||
(let
|
||||
((a1-3
|
||||
(quaternion-vector-angle!
|
||||
(new-stack-quaternion0)
|
||||
(vector-z-quaternion! (new-stack-vector0) arg1)
|
||||
arg2
|
||||
)
|
||||
)
|
||||
)
|
||||
(quaternion-normalize! (quaternion*! arg0 a1-3 arg1))
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
@ -415,9 +415,7 @@
|
|||
(set! sv-56 (t9-3 a0-5 1.0))
|
||||
)
|
||||
(let* ((f30-0 (vector-y-angle sv-52))
|
||||
(t9-5 vector-flatten!)
|
||||
(a0-7 (new-stack-vector0))
|
||||
(a0-8 (t9-5 a0-7 sv-56 sv-48))
|
||||
(a0-8 (vector-flatten! (new-stack-vector0) sv-56 sv-48))
|
||||
(f0-0 (vector-y-angle a0-8))
|
||||
(f0-1 (deg-diff f30-0 f0-0))
|
||||
)
|
||||
|
@ -482,9 +480,7 @@
|
|||
)
|
||||
)
|
||||
(f30-2 (vector-x-angle sv-52))
|
||||
(t9-16 vector-flatten!)
|
||||
(a0-19 (new-stack-vector0))
|
||||
(s3-2 (t9-16 a0-19 sv-56 s3-1))
|
||||
(s3-2 (vector-flatten! (new-stack-vector0) sv-56 s3-1))
|
||||
(f0-15 (vector-x-angle s3-2))
|
||||
(f0-21
|
||||
(fmax
|
||||
|
@ -595,9 +591,7 @@
|
|||
(set! sv-56 (t9-3 a0-3 1.0))
|
||||
)
|
||||
(let* ((f30-0 (vector-y-angle sv-52))
|
||||
(t9-5 vector-flatten!)
|
||||
(a0-5 (new-stack-vector0))
|
||||
(a0-6 (t9-5 a0-5 sv-56 sv-48))
|
||||
(a0-6 (vector-flatten! (new-stack-vector0) sv-56 sv-48))
|
||||
(f0-0 (vector-y-angle a0-6))
|
||||
(f0-1 (deg-diff f30-0 f0-0))
|
||||
)
|
||||
|
@ -645,9 +639,7 @@
|
|||
)
|
||||
)
|
||||
(f30-2 (vector-x-angle sv-52))
|
||||
(t9-14 vector-flatten!)
|
||||
(a0-14 (new-stack-vector0))
|
||||
(s4-4 (t9-14 a0-14 sv-56 s4-3))
|
||||
(s4-4 (vector-flatten! (new-stack-vector0) sv-56 s4-3))
|
||||
(f0-14 (vector-x-angle s4-4))
|
||||
(f0-20
|
||||
(fmax
|
||||
|
|
|
@ -1382,4 +1382,124 @@ TEST_F(FormRegressionTest, DebugMenuFuncDecode) {
|
|||
" )\n"
|
||||
" )";
|
||||
test_with_expr(func, type, expected, false, "", {}, "[[13, \"a0\", \"symbol\"]]");
|
||||
}
|
||||
|
||||
TEST_F(FormRegressionTest, MatrixNewInlineProp) {
|
||||
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"
|
||||
" or s5, a2, r0\n"
|
||||
" lw t9, matrix-rotate-y!(s7)\n"
|
||||
" or a0, gp, r0\n"
|
||||
" jalr ra, t9\n"
|
||||
" sll v0, ra, 0\n"
|
||||
|
||||
" lw t9, matrix-rotate-x!(s7)\n"
|
||||
" daddiu a0, sp, 16\n"
|
||||
" sq r0, 0(a0)\n"
|
||||
" sq r0, 16(a0)\n"
|
||||
" sq r0, 32(a0)\n"
|
||||
" sq r0, 48(a0)\n"
|
||||
" or a1, s5, r0\n"
|
||||
" jalr ra, t9\n"
|
||||
" sll v0, ra, 0\n"
|
||||
|
||||
" or a1, v0, r0\n"
|
||||
" lw t9, matrix*!(s7)\n"
|
||||
" or a0, gp, r0\n"
|
||||
" or a2, gp, r0\n"
|
||||
" jalr ra, t9\n"
|
||||
" sll v0, ra, 0\n"
|
||||
|
||||
" or v1, v0, r0\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\n"
|
||||
|
||||
" sll r0, r0, 0\n"
|
||||
" sll r0, r0, 0\n"
|
||||
" sll r0, r0, 0\n";
|
||||
std::string type = "(function matrix float float matrix)";
|
||||
std::string expected =
|
||||
"(begin\n"
|
||||
" (matrix-rotate-y! arg0 arg1)\n"
|
||||
" (let ((a1-2 (matrix-rotate-x! (new-stack-matrix0) arg2)))\n"
|
||||
" (matrix*! arg0 a1-2 arg0)\n"
|
||||
" )\n"
|
||||
" arg0\n"
|
||||
" )";
|
||||
test_with_stack_structures(func, type, expected, R"([[16, "matrix"]])");
|
||||
}
|
||||
|
||||
TEST_F(FormRegressionTest, VectorNewInlineProp) {
|
||||
std::string func =
|
||||
"sll r0, r0, 0\n"
|
||||
" daddiu sp, sp, -64\n"
|
||||
" sd ra, 0(sp)\n"
|
||||
" sd fp, 8(sp)\n"
|
||||
" or fp, t9, r0\n"
|
||||
" sq s5, 32(sp)\n"
|
||||
" sq gp, 48(sp)\n"
|
||||
" or gp, a0, r0\n"
|
||||
" daddiu s5, sp, 16\n"
|
||||
" sq r0, 0(s5)\n"
|
||||
" or v1, s5, r0\n"
|
||||
" lwc1 f0, 0(a1)\n"
|
||||
" swc1 f0, 0(v1)\n"
|
||||
" lwc1 f0, 4(a1)\n"
|
||||
" swc1 f0, 4(v1)\n"
|
||||
" lwc1 f0, 8(a1)\n"
|
||||
" swc1 f0, 8(v1)\n"
|
||||
" mtc1 f0, r0\n"
|
||||
" swc1 f0, 12(v1)\n"
|
||||
" lw t9, vector-matrix*!(s7)\n"
|
||||
" or a0, s5, r0\n"
|
||||
" or a1, s5, r0\n"
|
||||
" jalr ra, t9\n"
|
||||
" sll v0, ra, 0\n"
|
||||
|
||||
" lwc1 f0, 0(s5)\n"
|
||||
" swc1 f0, 0(gp)\n"
|
||||
" lwc1 f0, 4(s5)\n"
|
||||
" swc1 f0, 4(gp)\n"
|
||||
" lwc1 f0, 8(s5)\n"
|
||||
" swc1 f0, 8(gp)\n"
|
||||
" or v1, gp, r0\n"
|
||||
" or v0, gp, r0\n"
|
||||
" ld ra, 0(sp)\n"
|
||||
" ld fp, 8(sp)\n"
|
||||
" lq gp, 48(sp)\n"
|
||||
" lq s5, 32(sp)\n"
|
||||
" jr ra\n"
|
||||
" daddiu sp, sp, 64\n"
|
||||
|
||||
" sll r0, r0, 0\n"
|
||||
" sll r0, r0, 0\n"
|
||||
" sll r0, r0, 0\n";
|
||||
std::string type = "(function vector3s vector3s matrix vector3s)";
|
||||
std::string expected =
|
||||
"(begin\n"
|
||||
" (let ((s5-0 (new-stack-vector0)))\n"
|
||||
" (let ((v1-0 s5-0))\n"
|
||||
" (set! (-> v1-0 x) (-> arg1 x))\n"
|
||||
" (set! (-> v1-0 y) (-> arg1 y))\n"
|
||||
" (set! (-> v1-0 z) (-> arg1 z))\n"
|
||||
" (set! (-> v1-0 w) 0.0)\n"
|
||||
" )\n"
|
||||
" (vector-matrix*! s5-0 s5-0 arg2)\n"
|
||||
" (set! (-> arg0 x) (-> s5-0 x))\n"
|
||||
" (set! (-> arg0 y) (-> s5-0 y))\n"
|
||||
" (set! (-> arg0 z) (-> s5-0 z))\n"
|
||||
" )\n"
|
||||
" arg0\n"
|
||||
" )";
|
||||
test_with_stack_structures(func, type, expected, R"([[16, "vector"]])");
|
||||
}
|
Loading…
Reference in a new issue