From 0a76e6e1575da24f9e2540086f4fc8749dfa239a Mon Sep 17 00:00:00 2001 From: water111 <48171810+water111@users.noreply.github.com> Date: Sun, 28 Mar 2021 20:26:30 -0400 Subject: [PATCH] [Decompiler] Make matrix decompile (#341) * small fixes * update * add instructions * finish matrix * add matrix test cases --- decompiler/IR2/AtomicOpTypeAnalysis.cpp | 15 +- decompiler/IR2/OpenGoalMapping.cpp | 23 +- decompiler/analysis/inline_asm_rewrite.cpp | 3 +- decompiler/config/all-types.gc | 4 +- .../jak1_ntsc_black_label/var_names.jsonc | 1518 +++++---- doc/changelog.md | 6 + doc/goal_doc.md | 20 + goal_src/engine/math/matrix-h.gc | 31 +- goal_src/engine/math/matrix.gc | 2900 ++++++++++------- goalc/compiler/CodeGenerator.cpp | 10 + goalc/compiler/Compiler.h | 12 + goalc/compiler/IR.cpp | 121 +- goalc/compiler/IR.h | 23 +- goalc/compiler/compilation/Asm.cpp | 83 + goalc/compiler/compilation/Atoms.cpp | 7 + goalc/compiler/compilation/Function.cpp | 6 +- goalc/emitter/IGen.h | 136 + goalc/emitter/Register.cpp | 4 +- goalc/regalloc/Allocator.cpp | 24 +- test/decompiler/reference/gcommon_REF.gc | 76 +- test/decompiler/reference/gkernel-h_REF.gc | 4 +- test/decompiler/reference/gkernel_REF.gc | 4 +- test/decompiler/reference/gstate_REF.gc | 8 +- test/decompiler/reference/math_REF.gc | 4 +- test/decompiler/reference/matrix-h_REF.gc | 2 +- test/decompiler/reference/matrix_REF.gc | 1271 ++++---- test/decompiler/reference/vector-h_REF.gc | 24 +- .../source_templates/with_game/test-matrix.gc | 164 + .../source_templates/with_game/test-pextlw.gc | 54 + test/goalc/test_with_game.cpp | 81 + test/offline/offline_test_main.cpp | 4 - test/test_emitter_avx.cpp | 135 + 32 files changed, 4182 insertions(+), 2595 deletions(-) create mode 100644 test/goalc/source_templates/with_game/test-matrix.gc create mode 100644 test/goalc/source_templates/with_game/test-pextlw.gc diff --git a/decompiler/IR2/AtomicOpTypeAnalysis.cpp b/decompiler/IR2/AtomicOpTypeAnalysis.cpp index e94ab8c16b..a0892d20e0 100644 --- a/decompiler/IR2/AtomicOpTypeAnalysis.cpp +++ b/decompiler/IR2/AtomicOpTypeAnalysis.cpp @@ -543,8 +543,19 @@ TypeState AsmOp::propagate_types_internal(const TypeState& input, TypeState result = input; if (m_dst.has_value()) { auto kind = m_dst->reg().get_kind(); - if (kind == Reg::GPR || kind == Reg::FPR) { - result.get(m_dst->reg()) = TP_Type::make_from_ts("int"); + if (kind == Reg::FPR) { + result.get(m_dst->reg()) = TP_Type::make_from_ts("float"); + } else if (kind == Reg::GPR) { + for (auto& x : m_src) { + if (x && x->reg().get_kind() == Reg::GPR) { + auto src_type = result.get(x->reg()).typespec(); + if (dts.ts.tc(TypeSpec("int128"), src_type) || dts.ts.tc(TypeSpec("uint128"), src_type)) { + result.get(m_dst->reg()) = TP_Type::make_from_ts("uint128"); + return result; + } + } + result.get(m_dst->reg()) = TP_Type::make_from_ts("int"); + } } } return result; diff --git a/decompiler/IR2/OpenGoalMapping.cpp b/decompiler/IR2/OpenGoalMapping.cpp index 63844aefed..d7b1a69823 100644 --- a/decompiler/IR2/OpenGoalMapping.cpp +++ b/decompiler/IR2/OpenGoalMapping.cpp @@ -13,6 +13,11 @@ const std::map MIPS_ASM_TO_OPEN_GOAL_FUN {InstructionKind::PSRAW, {"TODO.PSRAW", {}}}, {InstructionKind::PSUBW, {"TODO.PSUBW", {}}}, + {InstructionKind::PEXTUW, {".pextuw", {}}}, + {InstructionKind::PEXTLW, {".pextlw", {}}}, + {InstructionKind::PCPYLD, {".pcpyld", {}}}, + {InstructionKind::PCPYUD, {".pcpyud", {}}}, + // NOTE - depending on how this is used, this may case issues! Be Warned! // lots of implicit logic in OpenGOAL depending on argument types! {InstructionKind::MFC1, {".mov", {}}}, @@ -163,6 +168,7 @@ std::vector OpenGOALAsm::get_args(const std::vector args; std::vector named_args; + bool got_fsf = false; for (int i = 0; i < instr.n_src; i++) { auto v = m_src.at(i); InstructionAtom atom = instr.get_src(i); @@ -172,12 +178,23 @@ std::vector OpenGOALAsm::get_args(const std::vectorlabels)); new_entries.push_back(entry); continue; } else if (elem->op()->instruction().kind == InstructionKind::VOPMULA) { diff --git a/decompiler/config/all-types.gc b/decompiler/config/all-types.gc index 748dae067d..99cdc2c053 100644 --- a/decompiler/config/all-types.gc +++ b/decompiler/config/all-types.gc @@ -1205,7 +1205,7 @@ :size-assert #x40 :flag-assert #xa00000040 (:methods - (dummy-9 () none 9) + (transform-vectors! (_type_ (inline-array vector) (inline-array vector) int) none 9) ) ) @@ -1446,7 +1446,7 @@ (define-extern matrix-axis-angle! (function matrix vector float none)) -(define-extern matrix-axis-sin-cos-vu! function) +(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) diff --git a/decompiler/config/jak1_ntsc_black_label/var_names.jsonc b/decompiler/config/jak1_ntsc_black_label/var_names.jsonc index 248779a05a..9015a3fa2e 100644 --- a/decompiler/config/jak1_ntsc_black_label/var_names.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/var_names.jsonc @@ -1,634 +1,886 @@ { - "identity":{ - "args":["obj"] - }, - - "1/":{ - "args":["x"] - }, - - "+":{ - "args":["x", "y"] - }, - - "-":{ - "args":["x", "y"] - }, - - "*":{ - "args":["x", "y"] - }, - - "/":{ - "args":["x", "y"] - }, - - "ash":{ - "args":["value", "shift-amount"] - }, - - "mod":{ - "args":["x", "y"] - }, - - "rem":{ - "args":["x", "y"] - }, - - "abs":{ - "args":["x"] - }, - - "min":{ - "args":["x", "y"] - }, - - "max":{ - "args":["x", "y"] - }, - - "logior":{ - "args":["x", "y"] - }, - - "logand":{ - "args":["x", "y"] - }, - - "lognor":{ - "args":["x", "y"] - }, - - "logxor":{ - "args":["x", "y"] - }, - - "lognot":{ - "args":["x"] - }, - - "basic-type?":{ - "args":["obj", "parent-type"], - "vars":{"v1-0":"obj-type", "a0-1":"end-type"} - }, - - "type-type?":{ - "args":["child-type", "parent-type"], - "vars":{"v1-0":"end-type"} - }, - - "find-parent-method":{ - "args":["child-type", "method-id"], - "vars":{"v0-0":"current-method", "v1-2":"original-method", "v1-5":"unused1"} - }, - - "ref":{ - "args":["lst", "index"], - "vars":{"v1-0":"count"} - }, - - "(method 4 pair)": { - "vars":{"v0-0":"result", "v1-1":"iter"} - }, - - "last":{ - "args":["lst"], - "vars":{"v0-0":"iter"} - }, - "member":{ - "args":["obj", "lst"], - "vars":{"v1-0":"iter"} - }, - "nmember":{ - "args":["obj", "lst"] - }, - "assoc":{ - "args":["item", "alist"], - "vars":{"v1-0":"iter"} - }, - "assoce":{ - "args":["item", "alist"], - "vars":{"v1-0":"iter"} - }, - "nassoc":{ - "args":["item-name", "alist"], - "vars":{"a1-1":"key"} - }, - "nassoce":{ - "args":["item-name", "alist"], - "vars":{"s4-0":"key"} - }, - "append!":{ - "args":["front", "back"], - "vars":{"v1-1":"iter"} - }, - "delete!":{ - "args":["item", "lst"], - "vars":{"a2-0":"iter", "v1-1":"iter-prev"} - }, - "delete-car!":{ - "args":["item", "lst"], - "vars":{"a2-0":"iter", "v1-2":"iter-prev"} - }, - "insert-cons!":{ - "args":["kv", "alist"], - "vars":{"a3-0":"updated-list"} - }, - "sort":{ - "args":["lst", "compare-func"], - "vars":{"s4-0":"unsorted-count", "s3-0":"iter", "s2-0":"first-elt", "s1-0":"seoncd-elt", "v1-1":"compare-result"} - }, - "(method 0 inline-array-class)":{ - "args":["allocation", "type-to-make", "size"], - "vars":{"v0-0":"obj"} - }, - "(method 0 array)":{ - "args":["allocation", "type-to-make", "content-type", "len"], - "vars":{"v0-1":"obj"} - }, - - "(method 2 array)":{ - "vars":{"v1-1":"content-type-sym"} - }, - - "(method 3 array)":{ - "vars":{"v1-1":"content-type-sym"} - }, - - "mem-copy!":{ - "args":["dst", "src", "size"], - "vars":{"v0-0":"result", "v1-0":"i"} - }, - "qmem-copy<-!":{ - "args":["dst", "src", "size"], - "vars":{"v0-0":"result", "v1-1":"qwc", "a2-1":"value"} - }, - "qmem-copy->!":{ - "args":["dst", "src", "size"], - "vars":{"v0-0":"result", "v1-1":"qwc", "a1-1":"src-ptr", "a0-1":"dst-ptr", "a2-3":"value"} - }, - "mem-set32!":{ - "args":["dst", "size", "value"], - "vars":{"v0-0":"result", "v1-0":"i"} - }, - "mem-or!":{ - "args":["dst", "src", "size"], - "vars":{"v0-0":"result", "v1-0":"i"} - }, - "fact":{ - "args":["x"] - }, - "mem-print":{ - "args":["data", "word-count"], - "vars":{"s4-0":"current-qword"} - }, - "print-tree-bitmask":{ - "args":["bits", "count"], - "vars":{"s4-0":"i"} - }, - "valid?":{ - "args":["obj", "expected-type", "name", "allow-false", "print-dest"], - "vars":{"v1-1":"in-goal-mem"} - }, - - // GKERNEL - - "(method 0 cpu-thread)":{ - "vars":{"v0-0":["obj", "cpu-thread"]} - }, - - "inspect-process-heap":{ - "vars":{"s5-0":["obj", "pointer"]} - }, - - "(method 23 dead-pool-heap)":{ - "args":["this", "rec"] - }, - - - "(method 0 dead-pool-heap)":{ - "vars":{"v0-0":["obj", "dead-pool-heap"]} - }, - - "seek":{ - "args":["x", "target", "diff"], - "vars":{"f2-0":"err"} - }, - - "lerp":{ - "args":["minimum", "maximum", "amount"] - }, - - "lerp-scale":{ - "args":["min-out", "max-out", "in", "min-in", "max-in"], - "vars":{"f0-1":"scale"} - }, - - "lerp-clamp":{ - "args":["minimum", "maximum", "amount"] - }, - - "rand-vu-int-range":{ - "args":["first", "second"], - "vars":{"f0-4":"float-in-range"} - }, - - "(method 0 bit-array)":{ - "args":["allocation", "type-to-make", "length"], - "vars":{"v0-0":"obj"} - }, - - "(method 12 bit-array)":{ - "vars":{"v1-2":"idx"} - }, - - "box-vector-enside?":{ - "args":["box", "pt"] - }, - - "box-vector-inside?":{ - "args":["box", "pt"] - }, - - "string=":{ - "args":["str-a", "str-b"], - "vars":{"a2-0":"a-ptr", "v1-0":"b-ptr"} - }, - - "string-charp=":{ - "args":["str", "charp"], - "vars":{"v1-0":"str-ptr"} - }, - - "copyn-string<-charp":{ - "args":["str", "charp", "len"], - "vars":{"a3-0":"i", "v1-0":"str-ptr"} - }, - - "string<-charp":{ - "args":["str", "charp"], - "vars":{"v1-0":"str-ptr"} - }, - - "charp<-string":{ - "args":["charp", "str"], - "vars":{"v1-0":"str-ptr"} - }, - - "copy-charp<-charp":{ - "args":["dst", "src"] - }, - - "cat-string<-string":{ - "args":["a", "b"], - "vars":{"v1-0":"a-ptr", "a1-1":"b-ptr"} - }, - - "catn-string<-charp":{ - "args":["a", "b", "len"], - "vars":{"v1-0":"a-ptr", "a3-2":"i"} - }, - - "cat-string<-string_to_charp":{ - "args":["a", "b", "end-ptr"], - "vars":{"v1-0":"b-ptr", "v0-0":"a-ptr"} - }, - - "append-character-to-string":{ - "args":["str", "char"], - "vars":{"v1-0":"str-ptr"} - }, - - "charp-basename":{ - "args":["charp"], - "vars":{"v1-0":"ptr"} - }, - - "string?":{ - "args":["a", "b"], - "vars":{"s4-1":"len", "v1-4":"i"} - }, - "string<=?":{ - "args":["a", "b"], - "vars":{"s4-1":"len", "v1-4":"i"} - }, - "string>=?":{ - "args":["a", "b"], - "vars":{"s4-1":"len", "v1-4":"i"} - }, - "string-cat-to-last-char":{ - "args":["base-str", "append-str", "char"], - "vars":{"s4-0":"end-of-append", "v1-0":"location-of-char"} - }, - "string-suck-up!":{ - "args":["str", "location"], - "vars":{"v1-2":"str-ptr"} - }, - "string-strip-trailing-whitespace!":{ - "args":["str"], - "vars":{"v1-6":"ptr"} - }, - - "string-get-arg!!":{ - "args":["a-str", "arg"], - "vars":{"s4-0":"arg-word-start", "s4-1":"arg-end", "v1-3":"arg-start"} - }, - - "string->int":{ - "args":["str"], - "vars":{"a0-1":"str-ptr", "v0-0":"result", - "a0-2":"next-char-1","a0-3":"next-char-2"} - }, - - "string-get-flag!!":{ - "args":["result", "in", "first-flag", "second-flag"] - }, - - "(method 0 state)":{ - "args":["allocation", "type-to-make", "name", "code", "trans", "enter", "exit", "event"], - "vars":{"v0-0":"obj"} - }, - - "previous-brother":{ - "args":["proc"], - "vars":{"v1-0":"parent", "v1-2":"child"} - }, - - "deg-seek":{ - "args":["in", "target", "max-diff"], - "vars":{"v1-1":"in-int", "a0-2":"target-int", "a1-2":"max-diff-int", "a2-1":"diff", "a3-0":"abs-diff"} - }, - - "deg-seek-smooth":{ - "args":["in", "target", "max-diff", "amount"], - "vars":{"f0-1":"step"} - }, - - "deg-lerp-clamp":{ - "args":["min-val", "max-val", "in"] - }, - - "sinerp-clamp":{ - "args":["minimum", "maximum", "amount"] - }, - - "coserp-clamp":{ - "args":["minimum", "maximum", "amount"] - }, - "coserp":{ - "args":["minimum", "maximum", "amount"] - }, - - "coserp180-clamp":{ - "args":["minimum", "maximum", "amount"] - }, - "coserp180":{ - "args":["minimum", "maximum", "amount"] - }, - "ease-in-out":{ - "args":["total", "progress"] - }, - "dma-send-to-spr":{ - "args":["sadr", "madr", "qwc", "sync"] - }, - "dma-send-to-spr-no-flush":{ - "args":["sadr", "madr", "qwc", "sync"] - }, - "dma-send-from-spr":{ - "args":["madr", "sadr", "qwc", "sync"] - }, - "dma-send-from-spr-no-flush":{ - "args":["madr", "sadr", "qwc", "sync"] - }, - "dump-vu1-range":{ - "args":["start", "total-count"] - }, - "ultimate-memcpy":{ - "args":["dst", "src", "size-bytes"], - "vars":{"s2-0":"qwc-remaining", - "s1-0":"qwc-transferred-now", - "s4-0":"spr-to-bank", - "s3-0":"spr-from-bank"} - }, - - "dma-buffer-add-vu-function":{ - "args":["dma-buf", "vu-func"], - "vars":{"t1-1":"dma-buf-2", "v1-0":"func-ptr", "a3-0":"qlen", "a1-1":"origin", "t0-1":"qwc-now", - "t2-0":"buf-ptr"} - }, - - "dma-buffer-add-buckets":{ - "args":["dma-buf", "count"], - "vars":{"a2-0":"i", "v1-0":"current-bucket"} - }, - - "dma-buffer-patch-buckets":{ - "args":["bucket", "count"], - "vars":{"v1-1":"i"} - }, - - "dma-bucket-insert-tag":{ - "args":["base", "idx", "tag-start", "tag-end"] - }, - - "disasm-vif-details":{ - "args":["stream", "data", "kind", "count"], - "vars":{"s4-0":"count2", "s3-0":"data-ptr", "s2-0":"i"} - }, - - "cpad-invalid!":{ - "args":["pad"] - }, - - "(method 0 cpad-info)":{ - "args":["alloction", "type-to-make", "idx"], - "vars":{"s5-0":"obj"} - }, - - "analog-input":{ - "args":["in", "offset", "center-val", "max-val", "out-range"], - "vars":{"f1-1":"offset-in", "f0-3":"magnitude", "v1-0":"max-magnitude"} - }, - - "cpad-set-buzz!":{ - "args":["pad", "buzz-idx", "buzz-amount", "duration"] - }, - - "service-cpads":{ - "vars":{"gp-0":"pad-list", "s5-0":"pad-idx", "s4-0":"pad", "s3-0":"buzz-idx", "v1-29":"current-button0"} - }, - - "buzz-stop!":{ - "args":["idx"] - }, - - "default-buffer-init":{ - "args":["buff"], - "vars":{"v1-0":"buff", "v1-1":"buff", "v1-3":"buff", "v1-4":"buff", "a1-4":"tag", "a1-6":"tag2", "a1-8":"data", "a0-1":"tag3", "v1-2":"buff"} - }, - - "add-reg-gif-packet":{ - "args":["packet", "reg-idx", "reg-val"], - "vars":{"v1-0":"tag"} - }, - - "(method 0 draw-context)":{ - "args":["allocation", "type-to-make", "org-x", "org-y", "width", "height", "color-0"] - }, - - "(method 0 display)":{ - "args":["allocation", "type-to-make", "psm", "w", "h", "ztest", "zpsm"], - "vars":{"gp-0":"obj"} - }, - - "(method 9 __assert-info-private-struct)":{ - "args":["obj", "filename", "line-num", "column-num"] - }, - - "__assert":{ - "args":["exp", "msg"] - }, - - "__assert-min-max-range-float":{ - "args":["exp", "minimum", "maximum", "msg-exp", "msg-min", "msg-max"] - }, - - "__assert-min-max-range-int":{ - "args":["exp", "minimum", "maximum", "msg-exp", "msg-min", "msg-max"] - }, - - "__assert-zero-lim-range-int":{ - "args":["exp", "maximum", "msg-exp", "msg-max"] - }, - - "update-math-camera":{ - "args":["math-cam", "ignored", "aspect"], - "vars":{"f0-4":"temp1", "v1-1":"elim1", - "f0-6":"temp2", "v1-2":"elim2", - "f1-3":"x-rat", "f0-7":"y-rat", - "v1-3":"cull-info", - "f2-2":"unused-x-thing", - "f2-5":"y-thing", - "f3-11":"one-plus-2x-squared", - "f3-14":"one-plus-2y-squared", - "f2-9":"temp3", - "a0-2":"elim3", - "f2-11":"dx-rat", - "f1-5":"dy-rat", - "f0-10":"drat-sqr-len", - "f2-8":"unused-thing-2", - "f1-8":"d-temp", - "f0-12":"temp4", - "a0-6":"elim4", - "f1-12":"dx-rat-2", - "f0-14":"d-temp-2", - "f2-13":"dx-rat-times-4", - "f3-21":"d-temp-3", - "f4-21":"inverse-x-len", - "f5-11":"inverse-x-len-2", - "f0-16":"temp5", - "a0-7":"elim5", - "f1-15":"dy-rat", - "f0-18":"d-temp-4", - "f2-15":"dy-rat-times-4", - "f3-22":"d-temp-5", - "f4-26":"inverse-y-len", - "f5-16":"inverse-y-len-2", - "f0-20":"temp6", - "v1-4":"elim6", - "v0-2":"cam-mat", - "f2-16":"fog-constant-1", - "f3-23":"fog-constant-2", - "f0-12":"fog-contsant-3", - "f0-24":"fog-factor-1", - "f1-22":"fog-factor-2", - "f4-35":"cam-fov-mult", - "f5-19":"corrected-fog", - "f5-23":"hvdf-x", - "f6-29":"hvdf-y", - "f2-18":"hvdf-z", - "f4-40":"hvdf-w", - "f2-19":"persp-xx", - "f3-36":"persp-yy", - "f1-32":"persp-x", - "v1-11":"sprite-row-0", - "v1-12":"sprite-row-1", - "v1-13":"sprite-row-2", - "v1-14":"sprite-row-3", - "f1-37":"temp7", - "v1-16":"elim7", - "v1-24":"pfog", - "a0-12":"vis-gif-0", - "a0-13":"vis-gif-1", - "a0-14":"vis-gif-1-again", - "a0-15":"vis-gif-1-again-again" - - - - - } - }, - - "(method 0 engine)":{ - "args":["allocation", "type-to-make", "name", "length"], - "vars":{"v0-0":"obj", "v1-11":"idx-to-link", "a0-1":"end-idx"} - }, - - "connection-process-apply":{ - "args":["proc", "func"], - "vars":{"s5-0":"iter"} - }, - - "(method 15 engine)":{ - "args":["obj", "proc", "func", "p1", "p2", "p3"], - "vars":{"v1-0":"con"} - }, - - "surface-interp!":{ - "args":["dst", "src0", "src1", "amount"] - }, - - "surface-mult!":{ - "args":["dst", "src0", "src1"] - - }, - - "(method 0 collide-shape-prim)":{ - "args":["allocation", "type-to-make", "cshape", "prim-id", "size-bytes"] - }, - - "(method 0 collide-shape-prim-sphere)":{ - "args":["allocation", "type-to-make", "cshape", "prim-id"] - }, - "(method 0 collide-shape-prim-mesh)":{ - "args":["allocation", "type-to-make", "cshape", "mesh-id", "prim-id"] - }, - "(method 0 collide-shape-prim-group)":{ - "args":["allocation", "type-to-make", "cshape", "elt-count", "prim-id"] - }, - "(method 0 collide-shape)":{ - "args":["allocation", "type-to-make", "proc", "collide-list-kind", "prim-id"], - "vars":{"s5-0":"obj"} - }, - "(method 11 touching-prims-entry-pool)":{ - "vars":{"a1-0":"current", "v1-0":"prev", "a2-0":"next"} - }, - - // LEVEL - "lookup-level-info":{ - "args":["name"], - "vars":{"a1-1":["info", "level-load-info"], "v1-0":"rest", "a1-0":"current-sym"} - }, - - "(method 21 level-group)":{ - "args":["obj", "name", "cmd-idx"], - "vars":{"v1-1":"cmd-lst"} - } - - -} \ No newline at end of file + "identity": { + "args": ["obj"] + }, + + "1/": { + "args": ["x"] + }, + + "+": { + "args": ["x", "y"] + }, + + "-": { + "args": ["x", "y"] + }, + + "*": { + "args": ["x", "y"] + }, + + "/": { + "args": ["x", "y"] + }, + + "ash": { + "args": ["value", "shift-amount"] + }, + + "mod": { + "args": ["x", "y"] + }, + + "rem": { + "args": ["x", "y"] + }, + + "abs": { + "args": ["x"] + }, + + "min": { + "args": ["x", "y"] + }, + + "max": { + "args": ["x", "y"] + }, + + "logior": { + "args": ["x", "y"] + }, + + "logand": { + "args": ["x", "y"] + }, + + "lognor": { + "args": ["x", "y"] + }, + + "logxor": { + "args": ["x", "y"] + }, + + "lognot": { + "args": ["x"] + }, + + "basic-type?": { + "args": ["obj", "parent-type"], + "vars": { "v1-0": "obj-type", "a0-1": "end-type" } + }, + + "type-type?": { + "args": ["child-type", "parent-type"], + "vars": { "v1-0": "end-type" } + }, + + "find-parent-method": { + "args": ["child-type", "method-id"], + "vars": { + "v0-0": "current-method", + "v1-2": "original-method", + "v1-5": "unused1" + } + }, + + "ref": { + "args": ["lst", "index"], + "vars": { "v1-0": "count" } + }, + + "(method 4 pair)": { + "vars": { "v0-0": "result", "v1-1": "iter" } + }, + + "last": { + "args": ["lst"], + "vars": { "v0-0": "iter" } + }, + "member": { + "args": ["obj", "lst"], + "vars": { "v1-0": "iter" } + }, + "nmember": { + "args": ["obj", "lst"] + }, + "assoc": { + "args": ["item", "alist"], + "vars": { "v1-0": "iter" } + }, + "assoce": { + "args": ["item", "alist"], + "vars": { "v1-0": "iter" } + }, + "nassoc": { + "args": ["item-name", "alist"], + "vars": { "a1-1": "key" } + }, + "nassoce": { + "args": ["item-name", "alist"], + "vars": { "s4-0": "key" } + }, + "append!": { + "args": ["front", "back"], + "vars": { "v1-1": "iter" } + }, + "delete!": { + "args": ["item", "lst"], + "vars": { "a2-0": "iter", "v1-1": "iter-prev" } + }, + "delete-car!": { + "args": ["item", "lst"], + "vars": { "a2-0": "iter", "v1-2": "iter-prev" } + }, + "insert-cons!": { + "args": ["kv", "alist"], + "vars": { "a3-0": "updated-list" } + }, + "sort": { + "args": ["lst", "compare-func"], + "vars": { + "s4-0": "unsorted-count", + "s3-0": "iter", + "s2-0": "first-elt", + "s1-0": "seoncd-elt", + "v1-1": "compare-result" + } + }, + "(method 0 inline-array-class)": { + "args": ["allocation", "type-to-make", "size"], + "vars": { "v0-0": "obj" } + }, + "(method 0 array)": { + "args": ["allocation", "type-to-make", "content-type", "len"], + "vars": { "v0-1": "obj" } + }, + + "(method 2 array)": { + "vars": { "v1-1": "content-type-sym" } + }, + + "(method 3 array)": { + "vars": { "v1-1": "content-type-sym" } + }, + + "mem-copy!": { + "args": ["dst", "src", "size"], + "vars": { "v0-0": "result", "v1-0": "i" } + }, + "qmem-copy<-!": { + "args": ["dst", "src", "size"], + "vars": { "v0-0": "result", "v1-1": "qwc", "a2-1": "value" } + }, + "qmem-copy->!": { + "args": ["dst", "src", "size"], + "vars": { + "v0-0": "result", + "v1-1": "qwc", + "a1-1": "src-ptr", + "a0-1": "dst-ptr", + "a2-3": "value" + } + }, + "mem-set32!": { + "args": ["dst", "size", "value"], + "vars": { "v0-0": "result", "v1-0": "i" } + }, + "mem-or!": { + "args": ["dst", "src", "size"], + "vars": { "v0-0": "result", "v1-0": "i" } + }, + "fact": { + "args": ["x"] + }, + "mem-print": { + "args": ["data", "word-count"], + "vars": { "s4-0": "current-qword" } + }, + "print-tree-bitmask": { + "args": ["bits", "count"], + "vars": { "s4-0": "i" } + }, + "valid?": { + "args": ["obj", "expected-type", "name", "allow-false", "print-dest"], + "vars": { "v1-1": "in-goal-mem" } + }, + + // GKERNEL + + "(method 0 cpu-thread)": { + "vars": { "v0-0": ["obj", "cpu-thread"] } + }, + + "inspect-process-heap": { + "vars": { "s5-0": ["obj", "pointer"] } + }, + + "(method 23 dead-pool-heap)": { + "args": ["this", "rec"] + }, + + "(method 0 dead-pool-heap)": { + "vars": { "v0-0": ["obj", "dead-pool-heap"] } + }, + + "seek": { + "args": ["x", "target", "diff"], + "vars": { "f2-0": "err" } + }, + + "lerp": { + "args": ["minimum", "maximum", "amount"] + }, + + "lerp-scale": { + "args": ["min-out", "max-out", "in", "min-in", "max-in"], + "vars": { "f0-1": "scale" } + }, + + "lerp-clamp": { + "args": ["minimum", "maximum", "amount"] + }, + + "rand-vu-int-range": { + "args": ["first", "second"], + "vars": { "f0-4": "float-in-range" } + }, + + "(method 0 bit-array)": { + "args": ["allocation", "type-to-make", "length"], + "vars": { "v0-0": "obj" } + }, + + "(method 12 bit-array)": { + "vars": { "v1-2": "idx" } + }, + + "box-vector-enside?": { + "args": ["box", "pt"] + }, + + "box-vector-inside?": { + "args": ["box", "pt"] + }, + + "string=": { + "args": ["str-a", "str-b"], + "vars": { "a2-0": "a-ptr", "v1-0": "b-ptr" } + }, + + "string-charp=": { + "args": ["str", "charp"], + "vars": { "v1-0": "str-ptr" } + }, + + "copyn-string<-charp": { + "args": ["str", "charp", "len"], + "vars": { "a3-0": "i", "v1-0": "str-ptr" } + }, + + "string<-charp": { + "args": ["str", "charp"], + "vars": { "v1-0": "str-ptr" } + }, + + "charp<-string": { + "args": ["charp", "str"], + "vars": { "v1-0": "str-ptr" } + }, + + "copy-charp<-charp": { + "args": ["dst", "src"] + }, + + "cat-string<-string": { + "args": ["a", "b"], + "vars": { "v1-0": "a-ptr", "a1-1": "b-ptr" } + }, + + "catn-string<-charp": { + "args": ["a", "b", "len"], + "vars": { "v1-0": "a-ptr", "a3-2": "i" } + }, + + "cat-string<-string_to_charp": { + "args": ["a", "b", "end-ptr"], + "vars": { "v1-0": "b-ptr", "v0-0": "a-ptr" } + }, + + "append-character-to-string": { + "args": ["str", "char"], + "vars": { "v1-0": "str-ptr" } + }, + + "charp-basename": { + "args": ["charp"], + "vars": { "v1-0": "ptr" } + }, + + "string?": { + "args": ["a", "b"], + "vars": { "s4-1": "len", "v1-4": "i" } + }, + "string<=?": { + "args": ["a", "b"], + "vars": { "s4-1": "len", "v1-4": "i" } + }, + "string>=?": { + "args": ["a", "b"], + "vars": { "s4-1": "len", "v1-4": "i" } + }, + "string-cat-to-last-char": { + "args": ["base-str", "append-str", "char"], + "vars": { "s4-0": "end-of-append", "v1-0": "location-of-char" } + }, + "string-suck-up!": { + "args": ["str", "location"], + "vars": { "v1-2": "str-ptr" } + }, + "string-strip-trailing-whitespace!": { + "args": ["str"], + "vars": { "v1-6": "ptr" } + }, + + "string-get-arg!!": { + "args": ["a-str", "arg"], + "vars": { "s4-0": "arg-word-start", "s4-1": "arg-end", "v1-3": "arg-start" } + }, + + "string->int": { + "args": ["str"], + "vars": { + "a0-1": "str-ptr", + "v0-0": "result", + "a0-2": "next-char-1", + "a0-3": "next-char-2" + } + }, + + "string-get-flag!!": { + "args": ["result", "in", "first-flag", "second-flag"] + }, + + "(method 0 state)": { + "args": [ + "allocation", + "type-to-make", + "name", + "code", + "trans", + "enter", + "exit", + "event" + ], + "vars": { "v0-0": "obj" } + }, + + "previous-brother": { + "args": ["proc"], + "vars": { "v1-0": "parent", "v1-2": "child" } + }, + + // Matrix + "matrix-identity": { + "args": ["mat"], + "vars": { "f0-0": "one" } + }, + + "matrix+!": { + "args": ["dst", "src1", "src2"], + "vars": { "v1-0": "i" } + }, + + "matrix-!": { + "args": ["dst", "src1", "src2"], + "vars": { "v1-0": "i" } + }, + + "matrix*!": { + "args": ["dst", "src1", "src2"] + }, + + "matrixp*!": { + "args": ["dst", "src1", "src2"], + "vars": { "s5-0": "temp-mat" } + }, + + "vector-matrix*!": { + "args": ["dst", "vec", "mat"] + }, + + "vector-rotate*!": { + "args": ["dst", "vec", "mat"] + }, + + "vector3s-matrix*!": { + "args": ["dst", "vec", "mat"], + "vars": { "s5-0": "temp-vec3" } + }, + + "vector3s-rotate*!": { + "args": ["dst", "vec", "mat"], + "vars": { "s5-0": "temp-vec3" } + }, + + "matrix-transpose!": { + "args": ["dst", "src"] + }, + + "matrix-inverse-of-rot-trans!": { + "args": ["dst", "src"] + }, + + "matrix-4x4-inverse!": { + "args": ["dst", "src"] + }, + + "matrix-translate!": { + "args": ["dst", "trans"] + }, + + "matrix-translate+!": { + "args": ["dst", "src", "trans"] + }, + + "matrix-scale!": { + "args": ["dst", "scale"] + }, + + "scale-matrix!": { + "args": ["dst", "scale", "src"] + }, + + "matrix-inv-scale!": { + "args": ["dst", "scale"] + }, + + "column-scale-matrix!": { + "args": ["dst", "scale", "src"] + }, + + "matrix-rotate-x!": { + "args": ["dst", "rot-deg"], + "vars": { "f30-0": "rot-sin", "f0-0": "rot-cos" } + }, + + "matrix-rotate-y!": { + "args": ["dst", "rot-deg"], + "vars": { "f30-0": "rot-sin", "f0-0": "rot-cos" } + }, + + "matrix-rotate-z!": { + "args": ["dst", "rot-deg"], + "vars": { "f30-0": "rot-sin", "f0-0": "rot-cos" } + }, + + "matrix-rotate-zyx!": { + "args": ["dst", "rot-xyz-deg"], + "vars": { "gp-0": "temp-mat", "s5-0": "rot-mat" } + }, + + "matrix-rotate-xyz!": { + "args": ["dst", "rot-xyz-deg"], + "vars": { "gp-0": "temp-mat", "s5-0": "rot-mat" } + }, + + "matrix-rotate-zxy!": { + "args": ["dst", "rot-xyz-deg"], + "vars": { "gp-0": "temp-mat", "s5-0": "rot-mat" } + }, + + "matrix-rotate-yxz!": { + "args": ["dst", "rot-xyz-deg"], + "vars": { "gp-0": "temp-mat", "s5-0": "rot-mat" } + }, + + "matrix-rotate-yzx!": { + "args": ["dst", "rot-xyz-deg"], + "vars": { "gp-0": "temp-mat", "s5-0": "rot-mat" } + }, + + "matrix-rotate-yxy!": { + "args": ["dst", "rots-deg"], + "vars": { + "a2-0": "sincos-input", + "s5-0": "sin-vec", + "s4-0": "cos-vec", + "f1-1": "cos-y", + "f0-5": "sin-y", + "f2-0": "cos-x", + "f5-0": "sin-x", + "f3-0": "cos-z", + "f4-0": "sin-z" + } + }, + + "matrix-rotate-yx!": { + "args": ["dst", "rot-y-deg", "rot-x-deg"] + }, + + "matrix-axis-angle!": { + "args": ["dst", "axis", "angle-deg"] + }, + + "matrix-lerp!": { + "args": ["dst", "src1", "src2", "alpha"] + }, + + "matrix-3x3-determinant": { + "args": ["mat"] + }, + + "matrix-3x3-inverse!": { + "args": ["dst", "src"] + }, + + "matrix-3x3-inverse-transpose!": { + "args": ["dst", "src"] + }, + + "matrix3-inverse-transpose!": { + "args": ["dst", "src"] + }, + + "matrix-4x4-determinant": { + "args": ["dst", "src"] + }, + + "matrix-4x4-inverse-transpose!": { + "args": ["dst", "src"] + }, + + "matrix-y-angle": { + "args": ["mat"], + "vars": { "v1-0": "z-row" } + }, + + "deg-seek": { + "args": ["in", "target", "max-diff"], + "vars": { + "v1-1": "in-int", + "a0-2": "target-int", + "a1-2": "max-diff-int", + "a2-1": "diff", + "a3-0": "abs-diff" + } + }, + + "deg-seek-smooth": { + "args": ["in", "target", "max-diff", "amount"], + "vars": { "f0-1": "step" } + }, + + "deg-lerp-clamp": { + "args": ["min-val", "max-val", "in"] + }, + + "sinerp-clamp": { + "args": ["minimum", "maximum", "amount"] + }, + + "coserp-clamp": { + "args": ["minimum", "maximum", "amount"] + }, + "coserp": { + "args": ["minimum", "maximum", "amount"] + }, + + "coserp180-clamp": { + "args": ["minimum", "maximum", "amount"] + }, + "coserp180": { + "args": ["minimum", "maximum", "amount"] + }, + "ease-in-out": { + "args": ["total", "progress"] + }, + "dma-send-to-spr": { + "args": ["sadr", "madr", "qwc", "sync"] + }, + "dma-send-to-spr-no-flush": { + "args": ["sadr", "madr", "qwc", "sync"] + }, + "dma-send-from-spr": { + "args": ["madr", "sadr", "qwc", "sync"] + }, + "dma-send-from-spr-no-flush": { + "args": ["madr", "sadr", "qwc", "sync"] + }, + "dump-vu1-range": { + "args": ["start", "total-count"] + }, + "ultimate-memcpy": { + "args": ["dst", "src", "size-bytes"], + "vars": { + "s2-0": "qwc-remaining", + "s1-0": "qwc-transferred-now", + "s4-0": "spr-to-bank", + "s3-0": "spr-from-bank" + } + }, + + "dma-buffer-add-vu-function": { + "args": ["dma-buf", "vu-func"], + "vars": { + "t1-1": "dma-buf-2", + "v1-0": "func-ptr", + "a3-0": "qlen", + "a1-1": "origin", + "t0-1": "qwc-now", + "t2-0": "buf-ptr" + } + }, + + "dma-buffer-add-buckets": { + "args": ["dma-buf", "count"], + "vars": { "a2-0": "i", "v1-0": "current-bucket" } + }, + + "dma-buffer-patch-buckets": { + "args": ["bucket", "count"], + "vars": { "v1-1": "i" } + }, + + "dma-bucket-insert-tag": { + "args": ["base", "idx", "tag-start", "tag-end"] + }, + + "disasm-vif-details": { + "args": ["stream", "data", "kind", "count"], + "vars": { "s4-0": "count2", "s3-0": "data-ptr", "s2-0": "i" } + }, + + "cpad-invalid!": { + "args": ["pad"] + }, + + "(method 0 cpad-info)": { + "args": ["alloction", "type-to-make", "idx"], + "vars": { "s5-0": "obj" } + }, + + "analog-input": { + "args": ["in", "offset", "center-val", "max-val", "out-range"], + "vars": { + "f1-1": "offset-in", + "f0-3": "magnitude", + "v1-0": "max-magnitude" + } + }, + + "cpad-set-buzz!": { + "args": ["pad", "buzz-idx", "buzz-amount", "duration"] + }, + + "service-cpads": { + "vars": { + "gp-0": "pad-list", + "s5-0": "pad-idx", + "s4-0": "pad", + "s3-0": "buzz-idx", + "v1-29": "current-button0" + } + }, + + "buzz-stop!": { + "args": ["idx"] + }, + + "default-buffer-init": { + "args": ["buff"], + "vars": { + "v1-0": "buff", + "v1-1": "buff", + "v1-3": "buff", + "v1-4": "buff", + "a1-4": "tag", + "a1-6": "tag2", + "a1-8": "data", + "a0-1": "tag3", + "v1-2": "buff" + } + }, + + "add-reg-gif-packet": { + "args": ["packet", "reg-idx", "reg-val"], + "vars": { "v1-0": "tag" } + }, + + "(method 0 draw-context)": { + "args": [ + "allocation", + "type-to-make", + "org-x", + "org-y", + "width", + "height", + "color-0" + ] + }, + + "(method 0 display)": { + "args": ["allocation", "type-to-make", "psm", "w", "h", "ztest", "zpsm"], + "vars": { "gp-0": "obj" } + }, + + "(method 9 __assert-info-private-struct)": { + "args": ["obj", "filename", "line-num", "column-num"] + }, + + "__assert": { + "args": ["exp", "msg"] + }, + + "__assert-min-max-range-float": { + "args": ["exp", "minimum", "maximum", "msg-exp", "msg-min", "msg-max"] + }, + + "__assert-min-max-range-int": { + "args": ["exp", "minimum", "maximum", "msg-exp", "msg-min", "msg-max"] + }, + + "__assert-zero-lim-range-int": { + "args": ["exp", "maximum", "msg-exp", "msg-max"] + }, + + "update-math-camera": { + "args": ["math-cam", "ignored", "aspect"], + "vars": { + "f0-4": "temp1", + "v1-1": "elim1", + "f0-6": "temp2", + "v1-2": "elim2", + "f1-3": "x-rat", + "f0-7": "y-rat", + "v1-3": "cull-info", + "f2-2": "unused-x-thing", + "f2-5": "y-thing", + "f3-11": "one-plus-2x-squared", + "f3-14": "one-plus-2y-squared", + "f2-9": "temp3", + "a0-2": "elim3", + "f2-11": "dx-rat", + "f1-5": "dy-rat", + "f0-10": "drat-sqr-len", + "f2-8": "unused-thing-2", + "f1-8": "d-temp", + "f0-12": "temp4", + "a0-6": "elim4", + "f1-12": "dx-rat-2", + "f0-14": "d-temp-2", + "f2-13": "dx-rat-times-4", + "f3-21": "d-temp-3", + "f4-21": "inverse-x-len", + "f5-11": "inverse-x-len-2", + "f0-16": "temp5", + "a0-7": "elim5", + "f1-15": "dy-rat", + "f0-18": "d-temp-4", + "f2-15": "dy-rat-times-4", + "f3-22": "d-temp-5", + "f4-26": "inverse-y-len", + "f5-16": "inverse-y-len-2", + "f0-20": "temp6", + "v1-4": "elim6", + "v0-2": "cam-mat", + "f2-16": "fog-constant-1", + "f3-23": "fog-constant-2", + "f0-12": "fog-contsant-3", + "f0-24": "fog-factor-1", + "f1-22": "fog-factor-2", + "f4-35": "cam-fov-mult", + "f5-19": "corrected-fog", + "f5-23": "hvdf-x", + "f6-29": "hvdf-y", + "f2-18": "hvdf-z", + "f4-40": "hvdf-w", + "f2-19": "persp-xx", + "f3-36": "persp-yy", + "f1-32": "persp-x", + "v1-11": "sprite-row-0", + "v1-12": "sprite-row-1", + "v1-13": "sprite-row-2", + "v1-14": "sprite-row-3", + "f1-37": "temp7", + "v1-16": "elim7", + "v1-24": "pfog", + "a0-12": "vis-gif-0", + "a0-13": "vis-gif-1", + "a0-14": "vis-gif-1-again", + "a0-15": "vis-gif-1-again-again" + } + }, + + "(method 0 engine)": { + "args": ["allocation", "type-to-make", "name", "length"], + "vars": { "v0-0": "obj", "v1-11": "idx-to-link", "a0-1": "end-idx" } + }, + + "connection-process-apply": { + "args": ["proc", "func"], + "vars": { "s5-0": "iter" } + }, + + "(method 15 engine)": { + "args": ["obj", "proc", "func", "p1", "p2", "p3"], + "vars": { "v1-0": "con" } + }, + + "surface-interp!": { + "args": ["dst", "src0", "src1", "amount"] + }, + + "surface-mult!": { + "args": ["dst", "src0", "src1"] + }, + + "(method 0 collide-shape-prim)": { + "args": ["allocation", "type-to-make", "cshape", "prim-id", "size-bytes"] + }, + + "(method 0 collide-shape-prim-sphere)": { + "args": ["allocation", "type-to-make", "cshape", "prim-id"] + }, + "(method 0 collide-shape-prim-mesh)": { + "args": ["allocation", "type-to-make", "cshape", "mesh-id", "prim-id"] + }, + "(method 0 collide-shape-prim-group)": { + "args": ["allocation", "type-to-make", "cshape", "elt-count", "prim-id"] + }, + "(method 0 collide-shape)": { + "args": [ + "allocation", + "type-to-make", + "proc", + "collide-list-kind", + "prim-id" + ], + "vars": { "s5-0": "obj" } + }, + "(method 11 touching-prims-entry-pool)": { + "vars": { "a1-0": "current", "v1-0": "prev", "a2-0": "next" } + }, + + // LEVEL + "lookup-level-info": { + "args": ["name"], + "vars": { + "a1-1": ["info", "level-load-info"], + "v1-0": "rest", + "a1-0": "current-sym" + } + }, + + "(method 21 level-group)": { + "args": ["obj", "name", "cmd-idx"], + "vars": { "v1-1": "cmd-lst" } + } +} diff --git a/doc/changelog.md b/doc/changelog.md index cc84cb333f..3b4da4202d 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -125,3 +125,9 @@ - There is now an option for `allow-misaligned` which allows the alignment of an struct type to be less than 16-bytes when inlined, without enabling array packing. This seems like a stupid option, but GOAL has this in some places, so we support it too. - In method declarations in a `deftype`, you can no longer provide argument names. There was ambiguity when parsing a compound typespec vs named argument. The names were not used for anything. - 128-bit integer register variables (`i128`) are now supported. These work with assembly forms, `set!`s between registers, and `set!`s of memory locations with type `(pointer uint128)` or `(pointer int128)`. +- Fixed a bug where the compiler would abort if had to spill an `xmm` register containing an `i128` value. +- Added `.pextlw`, `.pextuw`, `.pcpyld`, and `.pcpyud` assembly forms +- Fixed a bug where `uint128` or children defined with `local-vars` would end up using a 64-bit GPR instead of a 128-bit XMM. +- Fixed a bug where 128-bit variable spills could be misaligned, causing a segfault at `vmovaps`. +- Added `.ppach` and `.pceqw` +- Fixed a bug where setting 128-bit / 64-bit variables from each other only did a 32-bit set \ No newline at end of file diff --git a/doc/goal_doc.md b/doc/goal_doc.md index f2c62083e8..73f5283fca 100644 --- a/doc/goal_doc.md +++ b/doc/goal_doc.md @@ -1520,6 +1520,26 @@ Wrapper around `vcvtdq2ps` and `vcvtps2dq` to convert packed 32-bit signed integ Wrapper around `vpsrld`, `vpsrad`, and `vpslld`. Does shifts on each of the 4 32-bit integers in the register. +## `.pextlw`, `.pextuw`, `.pcpyud`, `.pcpyld`, `.pceqw`, `.ppach` +``` +(.pextlw dst src0 src1 [:color #t|#f]) +(.pextuw dst src0 src1 [:color #t|#f]) +(.pcpyud dst src0 src1 [:color #t|#f]) +(.pcpyld dst src0 src1 [:color #t|#f]) +(.pceqw dst src0 src1 [:color #t|#f]) +(.ppach dest src0 src1) +``` + +Equivalents of the EE's MMI instructions with the same name. These can only be used on 128-bit variables. Most map to single x86 instructions: +- `pextlw` is `VPUNPCKLDQ` (sources swapped) +- `pextuw` is `VPUNPCKHDQ` (sources swapped) +- `pcpyld` is `VPUNPCKLQDQ` (sources swapped) +- `pcpyud` is `VPUNPCKHQDQ` (sources _not_ swapped) +- `pceqw` is `VPCMPEQD` + +Some map to multiple instructions. These must use the coloring system. +- `ppach` is a sequence of 7 instructions (`VPSHUFLW`, `VPSHUFHW`, `VPSRLDQ`, `VPUNPCKLQDQ`). + # Compiler Forms - Unsorted ## `let` diff --git a/goal_src/engine/math/matrix-h.gc b/goal_src/engine/math/matrix-h.gc index c897e08702..ca655adc68 100644 --- a/goal_src/engine/math/matrix-h.gc +++ b/goal_src/engine/math/matrix-h.gc @@ -5,7 +5,7 @@ ;; name in dgo: matrix-h ;; dgos: GAME, ENGINE -;; matrix-h +;; A 4x4 matrix, stored in row-major order (deftype matrix (structure) ((data float 16 :offset-assert 0) (vector vector 4 :inline :offset 0) @@ -15,10 +15,13 @@ :size-assert #x40 :flag-assert #xa00000040 (:methods - (dummy-9 () none 9) - ) + (transform-vectors! (_type_ (inline-array vector) (inline-array vector) int) none 9) + ) ) +;; A 3x3 matrix, stored in row-major order. +;; NOTE: the rows each have an extra 4-bytes of padding +;; so this is really a 3x4 matrix. (deftype matrix3 (structure) ((data float 12 :offset-assert 0) (vector vector 3 :inline :offset 0) @@ -40,16 +43,16 @@ :flag-assert #x900000020 ) -(defun matrix-copy! ((arg0 matrix) (arg1 matrix)) - (let ((v1-0 (-> arg1 vector 0 quad)) - (a2-0 (-> arg1 vector 1 quad)) - (a3-0 (-> arg1 vector 2 quad)) - (a1-1 (-> arg1 vector 3 quad)) +(defun matrix-copy! ((dst matrix) (src matrix)) + (let ((v1-0 (-> src vector 0 quad)) + (a2-0 (-> src vector 1 quad)) + (a3-0 (-> src vector 2 quad)) + (a1-1 (-> src vector 3 quad)) ) - (set! (-> arg0 vector 0 quad) v1-0) - (set! (-> arg0 vector 1 quad) a2-0) - (set! (-> arg0 vector 2 quad) a3-0) - (set! (-> arg0 vector 3 quad) a1-1) - ) - arg0 + (set! (-> dst vector 0 quad) v1-0) + (set! (-> dst vector 1 quad) a2-0) + (set! (-> dst vector 2 quad) a3-0) + (set! (-> dst vector 3 quad) a1-1) + ) + dst ) diff --git a/goal_src/engine/math/matrix.gc b/goal_src/engine/math/matrix.gc index 533ad2e6ae..3cfb737a9c 100644 --- a/goal_src/engine/math/matrix.gc +++ b/goal_src/engine/math/matrix.gc @@ -5,30 +5,32 @@ ;; name in dgo: matrix ;; dgos: GAME, ENGINE -;; NOTE: basically everything here is transposed from what normal people do. -;; They treat their vectors as column vectors and do v*M as their normal matrix multiply. -;; w = v*M -;; w^T = (v*M)^T -;; w^T = M^T*v^T -;; So to swap between ND convention and normal convention: -;; - treat ND row vectors as column vectors -;; - transpose all matrices +;; This file implements the GOAL matrix library. -;; Matrices are stored in row major order. -;; One nice result of row-major + everything transposed is that a translation + rotation stores -;; the translation vector (bottom row!) contiguously in memory so it is fast to load/store. -;; Also, the order of transformations is left-to-right instead of right-to-left when writing things out. +;; In general, a vector is always treated as a row vector. +;; Chaining transformation is done like v_row * T1_goal * T2_goal, which means do T1 before T2. +;; This is the opposite of the usual convention: +;; T2_normal * T1_normal * v_col +;; However, there is good news: +;; T1_normal = T1_goal ^ T +;; T2_normal = T2_goal ^ T +;; This is due to the property +;; (A * B)^T = B^T * A^T -;; TODO: -;; - matrix-transpose! -;; - matrix-4x4-inverse! -;; - matrix-axis-sin-cos-vu! -;; - matrix-axis-sin-cos! -;; - matrix-axis-angle! -;; - (method 9 matrix) +;; So a homogeneous transformation is: +;; R_xx R_xy R_xz 0 +;; R_yx R_yy R_yz 0 +;; R_zx R_zy R_zz 0 +;; T_x T_y T_z 1 + +;; which is probably the transpose of what you're used to. + +;; In general, be careful with using these functions as they often have strange +;; requirements for the form of the input matrix or if the input/output matrix are +;; allowed to be the same memory. (defmethod inspect matrix ((obj matrix)) - "Print out a matrix" + "Print out all the values in a matrix." (format #t "[~8x] matrix~%" obj) (format #t "~T[~F] [~F] [~F] [~F]~%" (-> obj data 0) @@ -36,29 +38,29 @@ (-> obj data 2) (-> obj data 3) ) - (format #t "~T[~F] [~F] [~F] [~F]~%" + (format #t "~T[~F] [~F] [~F] [~F]~%" (-> obj data 4) (-> obj data 5) (-> obj data 6) (-> obj data 7) ) - (format #t "~T[~F] [~F] [~F] [~F]~%" - (-> obj data 8) - (-> obj data 9) - (-> obj data 10) - (-> obj data 11) - ) - (format #t "~T[~F] [~F] [~F] [~F]~%" - (-> obj data 12) - (-> obj data 13) - (-> obj data 14) - (-> obj data 15) - ) + (format #t "~T[~F] [~F] [~F] [~F]~%" + (-> obj data 8) + (-> obj data 9) + (-> obj data 10) + (-> obj data 11) + ) + (format #t "~T[~F] [~F] [~F] [~F]~%" + (-> obj data 12) + (-> obj data 13) + (-> obj data 14) + (-> obj data 15) + ) obj ) (defmethod inspect matrix3 ((obj matrix3)) - "Print out a matrix3" + "Print out the values in a 3x3 matrix." (format #t "[~8x] matrix3~%" obj) (format #t "~T[~F] [~F] [~F]~%" (-> obj data 0) @@ -78,46 +80,51 @@ obj ) -(defun matrix-identity! ((m matrix)) - "Set m to the identity matrix." - (rlet ((vf1 :class vf)) - ;; zero - (.xor.vf vf1 vf1 vf1) - (.svf (-> m vector 0) vf1) - (.svf (-> m vector 1) vf1) - (.svf (-> m vector 2) vf1) - (.svf (-> m vector 2) vf1) - ) +(defun matrix-identity! ((dst matrix)) + "Set dst to the identity matrix." + ;; zero matrix + (set! (-> dst vector 0 quad) (the-as uint128 0)) + (set! (-> dst vector 1 quad) (the-as uint128 0)) + (set! (-> dst vector 2 quad) (the-as uint128 0)) + (set! (-> dst vector 3 quad) (the-as uint128 0)) + ;; set diagonal to 1.0 + ;; doing it like this is a slight optimization and avoids + ;; reloading the 1.0 constant from memory each time. (let ((one 1.0)) - (set! (-> m data 15) one) - (set! (-> m data 10) one) - (set! (-> m data 5) one) - (set! (-> m data 0) one) + (set! (-> dst data 15) one) + (set! (-> dst data 10) one) + (set! (-> dst data 5) one) + (set! (-> dst data 0) one) ) - m + dst ) +;; A 4x4 identity matrix (define *identity-matrix* (the-as matrix (new 'global 'matrix))) (matrix-identity! *identity-matrix*) -(defun matrix+! ((arg0 matrix) (arg1 matrix) (arg2 matrix)) - "Set arg0 = arg1 + arg2. Not particularly efficient." - (dotimes (v1-0 16) - (set! (-> arg0 data v1-0) (+ (-> arg1 data v1-0) (-> arg2 data v1-0))) +(defun matrix+! ((dst matrix) (src1 matrix) (src2 matrix)) + "Set dst = src1 + src2. It is okay for any arguments to be the same data. + This is not an efficient implementation." + (dotimes (i 16) + (set! (-> dst data i) (+ (-> src1 data i) (-> src2 data i))) ) - arg0 + dst ) -(defun matrix-! ((arg0 matrix) (arg1 matrix) (arg2 matrix)) - "Set arg0 = arg1 - arg2. Not particularly efficient." - (dotimes (v1-0 16) - (set! (-> arg0 data v1-0) (- (-> arg1 data v1-0) (-> arg2 data v1-0))) +(defun matrix-! ((dst matrix) (src1 matrix) (src2 matrix)) + "Set dst = src1 - src1. It is okay for any arugments to be the same data. + This is not an efficient implementation." + (dotimes (i 16) + (set! (-> dst data i) (- (-> src1 data i) (-> src2 data i))) ) - arg0 + dst ) -(defun matrix*! ((arg0 matrix) (arg1 matrix) (arg2 matrix)) - "4x4 matrix multiplication. Set arg0 = arg1 * arg2." +;; definition for function matrix*! +(defun matrix*! ((dst matrix) (src1 matrix) (src2 matrix)) + "Set dst = src1 * src2. It is okay for any arguments to be the same data. + This is a moderately efficient implementation." (rlet ((acc :class vf) (vf10 :class vf) (vf11 :class vf) @@ -132,14 +139,16 @@ (vf20 :class vf) (vf21 :class vf) ) - (.lvf vf10 arg1) - (.lvf vf14 arg2) - (.lvf vf15 arg2 :offset 16) - (.lvf vf16 arg2 :offset 32) - (.lvf vf17 arg2 :offset 48) - (.lvf vf11 arg1 :offset 16) - (.lvf vf12 arg1 :offset 32) - (.lvf vf13 arg1 :offset 48) + ;; This could likely be faster on PS2 with some clever reordering. + ;; These loads will stall. + (.lvf vf10 (&-> src1 vector 0 quad)) + (.lvf vf14 (&-> src2 vector 0 quad)) + (.lvf vf15 (&-> src2 vector 1 quad)) + (.lvf vf16 (&-> src2 vector 2 quad)) + (.lvf vf17 (&-> src2 vector 3 quad)) + (.lvf vf11 (&-> src1 vector 1 quad)) + (.lvf vf12 (&-> src1 vector 2 quad)) + (.lvf vf13 (&-> src1 vector 3 quad)) (.mul.x.vf acc vf14 vf10) (.add.mul.y.vf acc vf15 vf10 acc) (.add.mul.z.vf acc vf16 vf10 acc) @@ -156,37 +165,35 @@ (.add.mul.y.vf acc vf15 vf13 acc) (.add.mul.z.vf acc vf16 vf13 acc) (.add.mul.w.vf vf21 vf17 vf13 acc) - (.svf arg0 vf18) - (.svf arg0 vf19 :offset 16) - (.svf arg0 vf20 :offset 32) - (.svf arg0 vf21 :offset 48) - arg0 + (.svf (&-> dst vector 0 quad) vf18) + (.svf (&-> dst vector 1 quad) vf19) + (.svf (&-> dst vector 2 quad) vf20) + (.svf (&-> dst vector 3 quad) vf21) + dst ) ) -(defun matrixp*! ((arg0 matrix) (arg1 matrix) (arg2 matrix)) - "Also 4x4 matrix multiplication, but first stores the result in a temporary. - So this appears to be a strictly worse version of matrix*!. - This function is never used" - (let ((s5-0 (new 'stack 'matrix))) - (set! (-> s5-0 vector 0 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 1 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 2 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 3 quad) (the-as uint128 0)) - (matrix*! s5-0 arg1 arg2) - (set! (-> arg0 vector 0 quad) (-> s5-0 vector 0 quad)) - (set! (-> arg0 vector 1 quad) (-> s5-0 vector 1 quad)) - (set! (-> arg0 vector 2 quad) (-> s5-0 vector 2 quad)) - (set! (-> arg0 vector 3 quad) (-> s5-0 vector 3 quad)) +(defun matrixp*! ((dst matrix) (src1 matrix) (src2 matrix)) + "Set dst = src1 * src2. NOTE: this function is a wrapper around matrix*! + that adds no additional functionality. It seems to be a leftover from + a time when matrix*! wasn't safe to use in place. This is unused." + (let ((temp-mat (new 'stack 'matrix))) + (set! (-> temp-mat vector 0 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 1 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 2 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 3 quad) (the-as uint128 0)) + ;; if matrix*! was unsafe to use in place, this would make sense. + (matrix*! temp-mat src1 src2) + (set! (-> dst vector 0 quad) (-> temp-mat vector 0 quad)) + (set! (-> dst vector 1 quad) (-> temp-mat vector 1 quad)) + (set! (-> dst vector 2 quad) (-> temp-mat vector 2 quad)) + (set! (-> dst vector 3 quad) (-> temp-mat vector 3 quad)) ) - arg0 + dst ) -(defun vector-matrix*! ((arg0 vector) (arg1 vector) (arg2 matrix)) - "Multiply vector by matrix. This is probably the opposite of what you expect and treats - arg1 as a 1x4 row vector. - arg0 = arg1 * arg2 - 1x4 1x4 4x4" +(defun vector-matrix*! ((dst vector) (vec vector) (mat matrix)) + "Set dst = vec * mat. dst may be equal to src." (rlet ((acc :class vf) (vf1 :class vf) (vf2 :class vf) @@ -194,23 +201,24 @@ (vf4 :class vf) (vf5 :class vf) ) - (.lvf vf1 (&-> arg2 vector 0 quad)) - (.lvf vf2 (&-> arg2 vector 1 quad)) - (.lvf vf3 (&-> arg2 vector 2 quad)) - (.lvf vf4 (&-> arg2 vector 3 quad)) - (.lvf vf5 (&-> arg1 quad)) + (.lvf vf1 (&-> mat vector 0 quad)) + (.lvf vf2 (&-> mat vector 1 quad)) + (.lvf vf3 (&-> mat vector 2 quad)) + (.lvf vf4 (&-> mat vector 3 quad)) + (.lvf vf5 (&-> vec quad)) (.mul.x.vf acc vf1 vf5) (.add.mul.y.vf acc vf2 vf5 acc) (.add.mul.z.vf acc vf3 vf5 acc) (.add.mul.w.vf vf5 vf4 vf5 acc) - (.svf (&-> arg0 quad) vf5) - arg0 + (.svf (&-> dst quad) vf5) + dst ) ) - -(defun vector-rotate*! ((arg0 vector) (arg1 vector) (arg2 matrix)) - "Special case of matrix-vector multiplication for just rotating." +(defun vector-rotate*! ((dst vector) (vec vector) (mat matrix)) + "Set dst to be the input vector rotated by the rotation part of mat. + The input matrix should be a homogeneous transform with a rotation matrix as its upper-left 3x3. + dst may be equal to src." (rlet ((acc :class vf) (vf1 :class vf) (vf2 :class vf) @@ -218,64 +226,116 @@ (vf4 :class vf) (vf5 :class vf) ) - (.lvf vf5 (&-> arg1 quad)) - (.lvf vf1 (&-> arg2 vector 0 quad)) - (.lvf vf2 (&-> arg2 vector 1 quad)) + ;; this implementation is better than vector-matrix*! + ;; (nop!) + ;; (nop!) + (.lvf vf5 (&-> vec quad)) + ;; (nop!) + (.lvf vf1 (&-> mat vector 0 quad)) + ;; (nop!) + (.lvf vf2 (&-> mat vector 1 quad)) + ;; the mul's assume the right-most column of the input matrix are 0,0,0,X (.mul.x.vf acc vf1 vf5) - (.lvf vf3 (&-> arg2 vector 2 quad)) + (.lvf vf3 (&-> mat vector 2 quad)) (.add.mul.y.vf acc vf2 vf5 acc) - (.lvf vf4 (&-> arg2 vector 3 quad)) ;; this doesn't need to be here... + ;; this load doesn't need to be here! + (.lvf vf4 (&-> mat vector 3 quad)) (.add.mul.z.vf vf5 vf3 vf5 acc) - (.svf (&-> arg0 quad) vf5) - arg0 + ;; (nop!) + ;; (nop!) + (.svf (&-> dst quad) vf5) + dst ) ) -(defun vector3s-matrix*! ((arg0 vector3s) (arg1 vector3s) (arg2 matrix)) - "Multiply a vector3s by a matrix. The w component is treated as 1.0. - The w component of the output is not written." - (let ((s5-0 (new 'stack 'vector))) - (set! (-> s5-0 quad) (the-as uint128 0)) - (let ((v1-0 s5-0)) - (set! (-> v1-0 data 0) (-> arg1 data 0)) - (set! (-> v1-0 data 1) (-> arg1 data 1)) - (set! (-> v1-0 data 2) (-> arg1 data 2)) +(defun vector3s-matrix*! ((dst vector3s) (vec vector3s) (mat matrix)) + "Set dst to be ([src 1.0] * mat).xyz. Doesn't touch the w of dst. + dst and vec can be the same memory" + (let ((temp-vec3 (new 'stack 'vector))) + ;; create a temporary vec with [x, y, z, 1.0] + (set! (-> temp-vec3 quad) (the-as uint128 0)) + (let ((v1-0 temp-vec3)) + (set! (-> v1-0 data 0) (-> vec data 0)) + (set! (-> v1-0 data 1) (-> vec data 1)) + (set! (-> v1-0 data 2) (-> vec data 2)) (set! (-> v1-0 data 3) 1.0) ) - (vector-matrix*! s5-0 s5-0 arg2) - (set! (-> arg0 data 0) (-> s5-0 data 0)) - (set! (-> arg0 data 1) (-> s5-0 data 1)) - (set! (-> arg0 data 2) (-> s5-0 data 2)) + (vector-matrix*! temp-vec3 temp-vec3 mat) + ;; only write back x,y,z + (set! (-> dst data 0) (-> temp-vec3 data 0)) + (set! (-> dst data 1) (-> temp-vec3 data 1)) + (set! (-> dst data 2) (-> temp-vec3 data 2)) ) - arg0 + dst ) -(defun vector3s-rotate*! ((arg0 vector3s) (arg1 vector3s) (arg2 matrix)) - "Do a vector-rotate*!, treating the input's w as 1.0. Does not write output's w." - (let ((s5-0 (new 'stack 'vector))) - (set! (-> s5-0 quad) (the-as uint128 0)) - (let ((v1-0 s5-0)) - (set! (-> v1-0 data 0) (-> arg1 data 0)) - (set! (-> v1-0 data 1) (-> arg1 data 1)) - (set! (-> v1-0 data 2) (-> arg1 data 2)) +(defun vector3s-rotate*! ((dst vector3s) (vec vector3s) (mat matrix)) + "Set dst to vec rotated by the rotation in the homogeneous transform mat. + mat should not have a scale/shear (the upper 3x3 should be a pure rotation)." + (let ((temp-vec3 (new 'stack 'vector))) + (set! (-> temp-vec3 quad) (the-as uint128 0)) + (let ((v1-0 temp-vec3)) + (set! (-> v1-0 data 0) (-> vec data 0)) + (set! (-> v1-0 data 1) (-> vec data 1)) + (set! (-> v1-0 data 2) (-> vec data 2)) (set! (-> v1-0 data 3) 1.0) ) - (vector-rotate*! s5-0 s5-0 arg2) - (set! (-> arg0 data 0) (-> s5-0 data 0)) - (set! (-> arg0 data 1) (-> s5-0 data 1)) - (set! (-> arg0 data 2) (-> s5-0 data 2)) + (vector-rotate*! temp-vec3 temp-vec3 mat) + (set! (-> dst data 0) (-> temp-vec3 data 0)) + (set! (-> dst data 1) (-> temp-vec3 data 1)) + (set! (-> dst data 2) (-> temp-vec3 data 2)) ) - (let ((v1-1 arg0)) - ) - arg0 + dst ) -;; todo: matrix-transpose! -(define-extern matrix-transpose! (function matrix matrix matrix)) +(defun matrix-transpose! ((dst matrix) (src matrix)) + "Set dst = src^T. src and dst can be the same." + (local-vars + (v1-0 uint128) + (v1-1 uint128) + (v1-2 uint128) + (a1-1 uint128) + (a2-1 uint128) + (a3-1 uint128) + (a3-2 uint128) + (t0-1 uint128) + ) + ;; (nop!) + ;; (nop!) + (let ((t0-0 (-> src vector 0 quad))) + ;; (nop!) + (let ((t1-0 (-> src vector 1 quad))) + ;; (nop!) + (let ((a2-0 (-> src vector 2 quad))) + (.pextlw v1-0 t1-0 t0-0) + (let ((a3-0 (-> src vector 3 quad))) + (.pextuw a1-1 t1-0 t0-0) + ;; (.mov r0-0 f31-0) not sure what this weird thing is. + ;; it has no effect, but they use it instead of nop sometimes? + (.pextlw t0-1 a3-0 a2-0) + ;; (.mov r0-1 f31-0) + (.pextuw a2-1 a3-0 a2-0) + ) + ) + ) + ) + ;; (.mov r0-2 f31-0) + (.pcpyld a3-1 t0-1 v1-0) + ;; (.mov r0-3 f31-0) + (.pcpyud v1-1 v1-0 t0-1) + (set! (-> dst vector 0 quad) a3-1) + (.pcpyld a3-2 a2-1 a1-1) + (set! (-> dst vector 1 quad) v1-1) + (.pcpyud v1-2 a1-1 a2-1) + (set! (-> dst vector 2 quad) a3-2) + ;; (nop!) + (set! (-> dst vector 3 quad) v1-2) + dst + ) -(defun matrix-inverse-of-rot-trans! ((arg0 matrix) (arg1 matrix)) - "Invert arg1 and store in arg0. This only works if arg1 is a rotation and translation. - It is not safe to call this in place (arg0 and arg1 are the same matrix)" +(defun matrix-inverse-of-rot-trans! ((dst matrix) (src matrix)) + "Set dst = src^-1, assuming src is a homogeneous tranform with only rotation/translation. + NOTE: THIS FUNCTION REQUIRES dst != src" (rlet ((acc :class vf) (vf0 :class vf) (vf1 :class vf) @@ -285,484 +345,735 @@ (vf8 :class vf) ) (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - ;; transpose the whole matrix. This takes care of the upper 3x3 - ;; because R^T = R^-1 for any orthonormal matrix, and rotations are - ;; always orthonormal. The rest of the function is cleaning up the - ;; stuff that's not in this 3x3. - (matrix-transpose! arg0 arg1) + ;; this makes the upper 3x3 correct because R^-1 = R^T for any rotation. + ;; but now the transform is in the wrong spot, and needs to be rotated + ;; and inverted. + (matrix-transpose! dst src) - ;; load the transposed matrix. - (.lvf vf1 (&-> arg0 vector 0 quad)) - (.lvf vf2 (&-> arg0 vector 1 quad)) - (.lvf vf3 (&-> arg0 vector 2 quad)) + ;; load the inverted rotation + (.lvf vf1 (&-> dst vector 0 quad)) + (.lvf vf2 (&-> dst vector 1 quad)) + (.lvf vf3 (&-> dst vector 2 quad)) - ;; zero out the upper 3x1 right column of the matrix. - ;; their transformation matrices are transposed. + ;; set the right most column to [0, 0, 0] (.sub.vf vf1 vf1 vf1 :mask #b1000) (.sub.vf vf2 vf2 vf2 :mask #b1000) (.sub.vf vf3 vf3 vf3 :mask #b1000) - ;; this is the original translation. - (.lvf vf8 (&-> arg1 vector 3 quad)) - ;; which is now multiplied by the rotation. + ;; load the original [translation, 1] + (.lvf vf8 (&-> src vector 3 quad)) + ;; rotate the translation (.mul.x.vf acc vf1 vf8) (.add.mul.y.vf acc vf2 vf8 acc) (.add.mul.z.vf vf4 vf3 vf8 acc) - ;; and inverted. + ;; negate translation (.sub.vf vf4 vf0 vf4) - ;; and w is set to 1. + ;; set the w to 1.0 (.mov.vf vf4 vf0 :mask #b1000) - - ;; store the rotation rows - (.svf (&-> arg0 vector 0 quad) vf1) - (.svf (&-> arg0 vector 1 quad) vf2) - (.svf (&-> arg0 vector 2 quad) vf3) - ;; store the translation. - (.svf (&-> arg0 vector 3 quad) vf4) - arg0 + ;; write back the rotation with fixed right column + (.svf (&-> dst vector 0 quad) vf1) + (.svf (&-> dst vector 1 quad) vf2) + (.svf (&-> dst vector 2 quad) vf3) + ;; write back the negated and rotated translation. + (.svf (&-> dst vector 3 quad) vf4) + dst ) ) -(define-extern matrix-4x4-inverse! (function matrix matrix matrix)) -#| -(defun matrix-4x4-inverse! ((arg0 matrix) (arg1 matrix)) -(rlet ((acc :class vf) -(Q :class vf) -(vf0 :class vf) -(vf1 :class vf) -(vf10 :class vf) -(vf11 :class vf) -(vf12 :class vf) -(vf13 :class vf) -(vf14 :class vf) -(vf15 :class vf) -(vf16 :class vf) -(vf17 :class vf) -(vf18 :class vf) -(vf19 :class vf) -(vf2 :class vf) -(vf20 :class vf) -(vf23 :class vf) -(vf24 :class vf) -(vf25 :class vf) -(vf26 :class vf) -(vf27 :class vf) -(vf28 :class vf) -(vf29 :class vf) -(vf3 :class vf) -(vf30 :class vf) -(vf31 :class vf) -(vf4 :class vf) -(vf5 :class vf) -(vf6 :class vf) -(vf7 :class vf) -(vf8 :class vf) -(vf9 :class vf) -) -(.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) -(.lvf vf23 (&-> arg1 vector 0 quad)) -(.lvf vf24 (&-> arg1 vector 1 quad)) -(.lvf vf25 (&-> arg1 vector 2 quad)) -(.lvf vf1 (&-> arg1 vector 3 quad)) -(.mul.x.vf vf7 vf24 vf23) -(.mul.y.vf vf8 vf24 vf23) -(.mul.z.vf vf9 vf24 vf23) -(.mul.x.vf vf10 vf25 vf23) -(.mul.y.vf vf11 vf25 vf23) -(.mul.z.vf vf12 vf25 vf23) -(.mul.x.vf vf13 vf25 vf24) -(.mul.y.vf vf14 vf25 vf24) -(.mul.z.vf vf15 vf25 vf24) -(.mul.z.vf vf26 vf7 vf25 :mask #b10) -(.mul.z.vf vf27 vf11 vf24 :mask #b1) -(.mul.y.vf vf28 vf9 vf25 :mask #b1) -(.mul.z.vf vf29 vf14 vf23 :mask #b1) -(.mul.z.vf vf30 vf8 vf25 :mask #b1) -(.mul.y.vf vf31 vf7 vf25 :mask #b100) -(.add.y.vf vf16 vf27 vf26 :mask #b1) -(.sub.vf vf1 vf0 vf1) -(.add.x.vf vf17 vf29 vf30 :mask #b1) -(.sub.z.vf vf18 vf28 vf31 :mask #b1) -(.sub.y.vf vf23 vf14 vf15 :mask #b100) -(.sub.z.vf vf26 vf15 vf13 :mask #b1) -(.sub.x.vf vf29 vf13 vf14 :mask #b10) -(.sub.vf vf19 vf16 vf17 :mask #b1) -(.sub.z.vf vf24 vf12 vf11 :mask #b10) -(.sub.x.vf vf27 vf10 vf12 :mask #b100) -(.sub.y.vf vf30 vf11 vf10 :mask #b1) -(.add.vf vf20 vf19 vf18 :mask #b1) -(.sub.y.vf vf25 vf8 vf9 :mask #b100) -(.sub.z.vf vf28 vf9 vf7 :mask #b1) -(.sub.x.vf vf31 vf7 vf8 :mask #b10) -(.div.vf Q vf0 vf20 :ftf #b11 :fsf #b0) -;; Added for PC port: zero out these vectors entirely -(.xor.vf vf3 vf3 vf3) -(.xor.vf vf4 vf4 vf4) -(.xor.vf vf5 vf5 vf5) -;; This has no effect on the result, but prevents use from doing -;; math on uninitialized values, which can be slow if they happen to -;; be NaN's -;; ================== -;;(.sub.w.vf vf3 vf3 vf3 :mask #b1000) -;;(.sub.w.vf vf4 vf4 vf4 :mask #b1000) -;;(.sub.w.vf vf5 vf5 vf5 :mask #b1000) -(.mov.vf vf6 vf0 :mask #b1000) -;;(.wait.vf) -(.add.vf vf2 vf0 Q :mask #b1) -(.add.x.vf vf2 vf0 vf2 :mask #b111) -(.mul.z.vf vf3 vf2 vf23 :mask #b1) -(.mul.x.vf vf4 vf2 vf26 :mask #b1) -(.mul.y.vf vf5 vf2 vf29 :mask #b1) -(.mul.y.vf vf3 vf2 vf24 :mask #b10) -(.mul.z.vf vf4 vf2 vf27 :mask #b10) -(.mul.x.vf vf5 vf2 vf30 :mask #b10) -(.mul.z.vf vf3 vf2 vf25 :mask #b100) -(.mul.x.vf vf4 vf2 vf28 :mask #b100) -(.mul.y.vf vf5 vf2 vf31 :mask #b100) -(.mul.x.vf acc vf3 vf1) -(.svf (&-> arg0 vector 0 quad) vf3) -(.add.mul.y.vf acc vf4 vf1 acc) -(.svf (&-> arg0 vector 1 quad) vf4) -(.add.mul.z.vf vf6 vf5 vf1 acc :mask #b111) -(.svf (&-> arg0 vector 2 quad) vf5) -(nop!) -(.svf (&-> arg0 vector 3 quad) vf6) -arg0 -) -) -|# +(defun matrix-4x4-inverse! ((dst matrix) (src matrix)) + "Invert a 4x4 matrix. This assumes that the input is a homogeneous transform. + Src and dst can be the same." + (rlet ((acc :class vf) + (Q :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf10 :class vf) + (vf11 :class vf) + (vf12 :class vf) + (vf13 :class vf) + (vf14 :class vf) + (vf15 :class vf) + (vf16 :class vf) + (vf17 :class vf) + (vf18 :class vf) + (vf19 :class vf) + (vf2 :class vf) + (vf20 :class vf) + (vf23 :class vf) + (vf24 :class vf) + (vf25 :class vf) + (vf26 :class vf) + (vf27 :class vf) + (vf28 :class vf) + (vf29 :class vf) + (vf3 :class vf) + (vf30 :class vf) + (vf31 :class vf) + (vf4 :class vf) + (vf5 :class vf) + (vf6 :class vf) + (vf7 :class vf) + (vf8 :class vf) + (vf9 :class vf) + ) -(defun matrix-translate! ((arg0 matrix) (arg1 vector)) - "Create a translation matrix." - (matrix-identity! arg0) - (set! (-> arg0 data 12) (-> arg1 data 0)) - (set! (-> arg0 data 13) (-> arg1 data 1)) - (set! (-> arg0 data 14) (-> arg1 data 2)) - arg0 - ) - -(defun matrix-translate+! ((arg0 matrix) (arg1 matrix) (arg2 vector)) - "Set arg0 = arg1 with added translation of arg2. - It's okay to call this with arg0 == arg1 or not." - (set! (-> arg0 data 12) (+ (-> arg1 data 12) (-> arg2 data 0))) - (set! (-> arg0 data 13) (+ (-> arg1 data 13) (-> arg2 data 1))) - (set! (-> arg0 data 14) (+ (-> arg1 data 14) (-> arg2 data 2))) - (when (!= arg0 arg1) - ;; only copy matrix if we actually need to. - (set! (-> arg0 vector 0 quad) (-> arg1 vector 0 quad)) - (set! (-> arg0 vector 1 quad) (-> arg1 vector 1 quad)) - (set! (-> arg0 vector 2 quad) (-> arg1 vector 2 quad)) + ;; ADDED: the original implementation does math on vectors where some values are + ;; uninitialized. It doesn't use the result, so there's no problem, but this + ;; may cause strange slowdowns on x86 where doing math on NaNs can be extremely slow. + ;; ideally we should find a better solution. + (.xor.vf vf26 vf26 vf26) + (.xor.vf vf27 vf27 vf27) + (.xor.vf vf28 vf28 vf28) + (.xor.vf vf29 vf29 vf29) + (.xor.vf vf30 vf30 vf30) + (.xor.vf vf31 vf31 vf31) + (.xor.vf vf16 vf16 vf16) + (.xor.vf vf17 vf17 vf17) + (.xor.vf vf18 vf18 vf18) + (.xor.vf vf23 vf23 vf23) + (.xor.vf vf19 vf19 vf19) + + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + ;; (nop!) + ;; (nop!) + (.lvf vf23 (&-> src vector 0 quad)) + ;; (nop!) + (.lvf vf24 (&-> src vector 1 quad)) + ;; (nop!) + (.lvf vf25 (&-> src vector 2 quad)) + ;; (nop!) + (.lvf vf1 (&-> src vector 3 quad)) + (.mul.x.vf vf7 vf24 vf23) + ;; (nop!) + (.mul.y.vf vf8 vf24 vf23) + ;; (nop!) + (.mul.z.vf vf9 vf24 vf23) + ;; (nop!) + (.mul.x.vf vf10 vf25 vf23) + ;; (nop!) + (.mul.y.vf vf11 vf25 vf23) + ;; (nop!) + (.mul.z.vf vf12 vf25 vf23) + ;; (nop!) + (.mul.x.vf vf13 vf25 vf24) + ;; (nop!) + (.mul.y.vf vf14 vf25 vf24) + ;; (nop!) + (.mul.z.vf vf15 vf25 vf24) + ;; (nop!) + (.mul.z.vf vf26 vf7 vf25 :mask #b10) + ;; (nop!) + (.mul.z.vf vf27 vf11 vf24 :mask #b1) + ;; (nop!) + (.mul.y.vf vf28 vf9 vf25 :mask #b1) + ;; (nop!) + (.mul.z.vf vf29 vf14 vf23 :mask #b1) + ;; (nop!) + (.mul.z.vf vf30 vf8 vf25 :mask #b1) + ;; (nop!) + (.mul.y.vf vf31 vf7 vf25 :mask #b100) + ;; (nop!) + (.add.y.vf vf16 vf27 vf26 :mask #b1) + ;; (nop!) + (.sub.vf vf1 vf0 vf1) + ;; (nop!) + (.add.x.vf vf17 vf29 vf30 :mask #b1) + ;; (nop!) + (.sub.z.vf vf18 vf28 vf31 :mask #b1) + ;; (nop!) + (.sub.y.vf vf23 vf14 vf15 :mask #b100) + ;; (nop!) + (.sub.z.vf vf26 vf15 vf13 :mask #b1) + ;; (nop!) + (.sub.x.vf vf29 vf13 vf14 :mask #b10) + ;; (nop!) + (.sub.vf vf19 vf16 vf17 :mask #b1) + ;; (nop!) + (.sub.z.vf vf24 vf12 vf11 :mask #b10) + ;; (nop!) + (.sub.x.vf vf27 vf10 vf12 :mask #b100) + ;; (nop!) + (.sub.y.vf vf30 vf11 vf10 :mask #b1) + ;; (nop!) + (.add.vf vf20 vf19 vf18 :mask #b1) + ;; (nop!) + (.sub.y.vf vf25 vf8 vf9 :mask #b100) + ;; (nop!) + (.sub.z.vf vf28 vf9 vf7 :mask #b1) + ;; (nop!) + (.sub.x.vf vf31 vf7 vf8 :mask #b10) + ;; (nop!) + (.div.vf Q vf0 vf20 :fsf #b11 :ftf #b0) + ;; (nop!) + ;;(.sub.w.vf vf3 vf3 vf3 :mask #b1000) + (.xor.vf vf3 vf3 vf3) + ;; (nop!) + ;;(.sub.w.vf vf4 vf4 vf4 :mask #b1000) + (.xor.vf vf4 vf4 vf4) + ;; (nop!) + ;;(.sub.w.vf vf5 vf5 vf5 :mask #b1000) + (.xor.vf vf5 vf5 vf5) + ;; (nop!) + (.mov.vf vf6 vf0 :mask #b1000) + ;; (nop!) + (.wait.vf) + ;; (nop!) + (.add.vf vf2 vf0 Q :mask #b1) + ;; (nop!) + (.add.x.vf vf2 vf0 vf2 :mask #b111) + ;; (nop!) + (.mul.z.vf vf3 vf2 vf23 :mask #b1) + ;; (nop!) + (.mul.x.vf vf4 vf2 vf26 :mask #b1) + ;; (nop!) + (.mul.y.vf vf5 vf2 vf29 :mask #b1) + ;; (nop!) + (.mul.y.vf vf3 vf2 vf24 :mask #b10) + ;; (nop!) + (.mul.z.vf vf4 vf2 vf27 :mask #b10) + ;; (nop!) + (.mul.x.vf vf5 vf2 vf30 :mask #b10) + ;; (nop!) + (.mul.z.vf vf3 vf2 vf25 :mask #b100) + ;; (nop!) + (.mul.x.vf vf4 vf2 vf28 :mask #b100) + ;; (nop!) + (.mul.y.vf vf5 vf2 vf31 :mask #b100) + ;; (nop!) + (.mul.x.vf acc vf3 vf1) + (.svf (&-> dst vector 0 quad) vf3) + (.add.mul.y.vf acc vf4 vf1 acc) + (.svf (&-> dst vector 1 quad) vf4) + (.add.mul.z.vf vf6 vf5 vf1 acc :mask #b111) + (.svf (&-> dst vector 2 quad) vf5) + ;; (nop!) + (.svf (&-> dst vector 3 quad) vf6) + dst ) - arg0 ) -(defun matrix-scale! ((arg0 matrix) (arg1 vector)) - "Make arg0 a scaling matrix." - (set! (-> arg0 vector 0 quad) (the-as uint128 0)) - (set! (-> arg0 vector 1 quad) (the-as uint128 0)) - (set! (-> arg0 vector 2 quad) (the-as uint128 0)) - (set! (-> arg0 vector 3 quad) (the-as uint128 0)) - (set! (-> arg0 data 0) (-> arg1 data 0)) - (set! (-> arg0 data 5) (-> arg1 data 1)) - (set! (-> arg0 data 10) (-> arg1 data 2)) - (set! (-> arg0 data 15) 1.0) - arg0 +(defun matrix-translate! ((dst matrix) (trans vector)) + "Set dst to a homogeneous transform with only a translation of trans" + (matrix-identity! dst) + (set! (-> dst data 12) (-> trans data 0)) + (set! (-> dst data 13) (-> trans data 1)) + (set! (-> dst data 14) (-> trans data 2)) + dst ) -(defun scale-matrix! ((arg0 matrix) (arg1 vector) (arg2 matrix)) - "Apply a scale to an existing matrix" + +(defun matrix-translate+! ((dst matrix) (src matrix) (trans vector)) + "Add the given translation to the translation of homogenous transform mat src + and store in dst. It is okay for dst = src." + (set! (-> dst data 12) (+ (-> src data 12) (-> trans data 0))) + (set! (-> dst data 13) (+ (-> src data 13) (-> trans data 1))) + (set! (-> dst data 14) (+ (-> src data 14) (-> trans data 2))) + (when (!= dst src) + ;; only copy the untouched rows if we are storing in somewhere that's not the source + (set! (-> dst vector 0 quad) (-> src vector 0 quad)) + (set! (-> dst vector 1 quad) (-> src vector 1 quad)) + (set! (-> dst vector 2 quad) (-> src vector 2 quad)) + ) + dst + ) + +(defun matrix-scale! ((dst matrix) (scale vector)) + "Set dst to a homogenous transform with only a scale. The x,y,z components + of scale become the x,y,z scaling factors" + (set! (-> dst vector 0 quad) (the-as uint128 0)) + (set! (-> dst vector 1 quad) (the-as uint128 0)) + (set! (-> dst vector 2 quad) (the-as uint128 0)) + (set! (-> dst vector 3 quad) (the-as uint128 0)) + (set! (-> dst data 0) (-> scale data 0)) + (set! (-> dst data 5) (-> scale data 1)) + (set! (-> dst data 10) (-> scale data 2)) + (set! (-> dst data 15) 1.0) + dst + ) + +(defun scale-matrix! ((dst matrix) (scale vector) (src matrix)) + "Scale an existing matrix. Okay for dst = src. The scaling is applied per row. + This means the x component of scale is used to scale the first row of src. + The w component of scale is used." (rlet ((vf4 :class vf) (vf5 :class vf) (vf6 :class vf) (vf7 :class vf) (vf8 :class vf) ) - (.lvf vf4 (&-> arg1 quad)) - (.lvf vf5 (&-> arg2 vector 0 quad)) - (.lvf vf6 (&-> arg2 vector 1 quad)) - (.lvf vf7 (&-> arg2 vector 2 quad)) - (.lvf vf8 (&-> arg2 vector 3 quad)) - (.mul.x.vf vf5 vf5 vf4) - (.mul.y.vf vf6 vf6 vf4) - (.mul.z.vf vf7 vf7 vf4) - (.mul.w.vf vf8 vf8 vf4) - (.svf (&-> arg0 vector 0 quad) vf5) - (.svf (&-> arg0 vector 1 quad) vf6) - (.svf (&-> arg0 vector 2 quad) vf7) - (.svf (&-> arg0 vector 3 quad) vf8) - arg0 - ) + (.lvf vf4 (&-> scale quad)) + (.lvf vf5 (&-> src vector 0 quad)) + (.lvf vf6 (&-> src vector 1 quad)) + (.lvf vf7 (&-> src vector 2 quad)) + (.lvf vf8 (&-> src vector 3 quad)) + (.mul.x.vf vf5 vf5 vf4) + (.mul.y.vf vf6 vf6 vf4) + (.mul.z.vf vf7 vf7 vf4) + (.mul.w.vf vf8 vf8 vf4) + (.svf (&-> dst vector 0 quad) vf5) + (.svf (&-> dst vector 1 quad) vf6) + (.svf (&-> dst vector 2 quad) vf7) + (.svf (&-> dst vector 3 quad) vf8) + dst + ) ) -(defun matrix-inv-scale! ((arg0 matrix) (arg1 vector)) - "Create a scaling matrix which uses the inverse of the coefficients in arg1" - (set! (-> arg0 vector 0 quad) (the-as uint128 0)) - (set! (-> arg0 vector 1 quad) (the-as uint128 0)) - (set! (-> arg0 vector 2 quad) (the-as uint128 0)) - (set! (-> arg0 vector 3 quad) (the-as uint128 0)) - (set! (-> arg0 data 0) (/ 1.0 (-> arg1 data 0))) - (set! (-> arg0 data 5) (/ 1.0 (-> arg1 data 1))) - (set! (-> arg0 data 10) (/ 1.0 (-> arg1 data 2))) - (set! (-> arg0 data 15) 1.0) - arg0 +(defun matrix-inv-scale! ((dst matrix) (scale vector)) + "Set dst to a homogeneous transform with only a scale. + The x,y,z components of scale are inverted and used as the x,y,z scaling factors" + (set! (-> dst vector 0 quad) (the-as uint128 0)) + (set! (-> dst vector 1 quad) (the-as uint128 0)) + (set! (-> dst vector 2 quad) (the-as uint128 0)) + (set! (-> dst vector 3 quad) (the-as uint128 0)) + (set! (-> dst data 0) (/ 1.0 (-> scale data 0))) + (set! (-> dst data 5) (/ 1.0 (-> scale data 1))) + (set! (-> dst data 10) (/ 1.0 (-> scale data 2))) + (set! (-> dst data 15) 1.0) + dst ) -(defun column-scale-matrix! ((arg0 matrix) (arg1 vector) (arg2 matrix)) - "Scale an existing matrix, but treat the scale factors in the opposite direction." +(defun column-scale-matrix! ((dst matrix) (scale vector) (src matrix)) + "Scale an existing matrix. Okay for dst = src. The scaling is applied column-wise. + Meaning the x component of scale will scale the first column of src." (rlet ((vf4 :class vf) (vf5 :class vf) (vf6 :class vf) (vf7 :class vf) (vf8 :class vf) ) - (.lvf vf4 (&-> arg1 quad)) - (.lvf vf5 (&-> arg2 vector 0 quad)) - (.lvf vf6 (&-> arg2 vector 1 quad)) - (.lvf vf7 (&-> arg2 vector 2 quad)) - (.lvf vf8 (&-> arg2 vector 3 quad)) - (.mul.vf vf5 vf5 vf4) - (.mul.vf vf6 vf6 vf4) - (.mul.vf vf7 vf7 vf4) - (.mul.vf vf8 vf8 vf4) - (.svf (&-> arg0 vector 0 quad) vf5) - (.svf (&-> arg0 vector 1 quad) vf6) - (.svf (&-> arg0 vector 2 quad) vf7) - (.svf (&-> arg0 vector 3 quad) vf8) - arg0 - ) + (.lvf vf4 (&-> scale quad)) + (.lvf vf5 (&-> src vector 0 quad)) + (.lvf vf6 (&-> src vector 1 quad)) + (.lvf vf7 (&-> src vector 2 quad)) + (.lvf vf8 (&-> src vector 3 quad)) + (.mul.vf vf5 vf5 vf4) + (.mul.vf vf6 vf6 vf4) + (.mul.vf vf7 vf7 vf4) + (.mul.vf vf8 vf8 vf4) + (.svf (&-> dst vector 0 quad) vf5) + (.svf (&-> dst vector 1 quad) vf6) + (.svf (&-> dst vector 2 quad) vf7) + (.svf (&-> dst vector 3 quad) vf8) + dst + ) ) -(defun matrix-rotate-x! ((arg0 matrix) (arg1 float)) - "Create a matrix which represents a rotation around the x axis" - (let ((f30-0 (sin arg1)) - (f0-0 (cos arg1)) +(defun matrix-rotate-x! ((dst matrix) (rot-deg float)) + "Set dst to a homogeneous transform matrix for a rotation around the x-axis (degrees)" + (let ((rot-sin (sin rot-deg)) + (rot-cos (cos rot-deg)) ) - (set! (-> arg0 vector 0 quad) (the-as uint128 0)) - (set! (-> arg0 vector 1 quad) (the-as uint128 0)) - (set! (-> arg0 vector 2 quad) (the-as uint128 0)) - (set! (-> arg0 vector 3 quad) (the-as uint128 0)) - (set! (-> arg0 data 0) 1.0) - (set! (-> arg0 data 5) f0-0) - (set! (-> arg0 data 6) f30-0) - (set! (-> arg0 data 9) (- f30-0)) - (set! (-> arg0 data 10) f0-0) + (set! (-> dst vector 0 quad) (the-as uint128 0)) + (set! (-> dst vector 1 quad) (the-as uint128 0)) + (set! (-> dst vector 2 quad) (the-as uint128 0)) + (set! (-> dst vector 3 quad) (the-as uint128 0)) + (set! (-> dst data 0) 1.0) + (set! (-> dst data 5) rot-cos) + (set! (-> dst data 6) rot-sin) + (set! (-> dst data 9) (- rot-sin)) + (set! (-> dst data 10) rot-cos) ) - (set! (-> arg0 data 15) 1.0) - arg0 + (set! (-> dst data 15) 1.0) + dst ) -(defun matrix-rotate-y! ((arg0 matrix) (arg1 float)) - "Create a matrix for rotating around the y axis" - (let ((f30-0 (sin arg1)) - (f0-0 (cos arg1)) +(defun matrix-rotate-y! ((dst matrix) (rot-deg float)) + "Set dst to a homoegeneous transform matrix for a rotation around the y axis (degrees)" + (let ((rot-sin (sin rot-deg)) + (rot-cos (cos rot-deg)) ) - (set! (-> arg0 vector 0 quad) (the-as uint128 0)) - (set! (-> arg0 vector 1 quad) (the-as uint128 0)) - (set! (-> arg0 vector 2 quad) (the-as uint128 0)) - (set! (-> arg0 vector 3 quad) (the-as uint128 0)) - (set! (-> arg0 data 0) f0-0) - (set! (-> arg0 data 2) (- f30-0)) - (set! (-> arg0 data 5) 1.0) - (set! (-> arg0 data 8) f30-0) - (set! (-> arg0 data 10) f0-0) + (set! (-> dst vector 0 quad) (the-as uint128 0)) + (set! (-> dst vector 1 quad) (the-as uint128 0)) + (set! (-> dst vector 2 quad) (the-as uint128 0)) + (set! (-> dst vector 3 quad) (the-as uint128 0)) + (set! (-> dst data 0) rot-cos) + (set! (-> dst data 2) (- rot-sin)) + (set! (-> dst data 5) 1.0) + (set! (-> dst data 8) rot-sin) + (set! (-> dst data 10) rot-cos) ) - (set! (-> arg0 data 15) 1.0) - arg0 + (set! (-> dst data 15) 1.0) + dst ) -(defun matrix-rotate-z! ((arg0 matrix) (arg1 float)) - "Create a matrix for rotating around the z axis" - (let ((f30-0 (sin arg1)) - (f0-0 (cos arg1)) +(defun matrix-rotate-z! ((dst matrix) (rot-deg float)) + "Set dst to a homogeneous transform matrix for a rotation around the z-axis (degrees)" + (let ((rot-sin (sin rot-deg)) + (rot-cos (cos rot-deg)) ) - (set! (-> arg0 vector 0 quad) (the-as uint128 0)) - (set! (-> arg0 vector 1 quad) (the-as uint128 0)) - (set! (-> arg0 vector 2 quad) (the-as uint128 0)) - (set! (-> arg0 vector 3 quad) (the-as uint128 0)) - (set! (-> arg0 data 0) f0-0) - (set! (-> arg0 data 1) f30-0) - (set! (-> arg0 data 4) (- f30-0)) - (set! (-> arg0 data 5) f0-0) + (set! (-> dst vector 0 quad) (the-as uint128 0)) + (set! (-> dst vector 1 quad) (the-as uint128 0)) + (set! (-> dst vector 2 quad) (the-as uint128 0)) + (set! (-> dst vector 3 quad) (the-as uint128 0)) + (set! (-> dst data 0) rot-cos) + (set! (-> dst data 1) rot-sin) + (set! (-> dst data 4) (- rot-sin)) + (set! (-> dst data 5) rot-cos) ) - (set! (-> arg0 data 10) 1.0) - (set! (-> arg0 data 15) 1.0) - arg0 + (set! (-> dst data 10) 1.0) + (set! (-> dst data 15) 1.0) + dst ) -(defun matrix-rotate-zyx! ((arg0 matrix) (arg1 vector)) - "Create a matrix for a series of rotations" - (let ((gp-0 (new 'stack 'matrix))) - (set! (-> gp-0 vector 0 quad) (the-as uint128 0)) - (set! (-> gp-0 vector 1 quad) (the-as uint128 0)) - (set! (-> gp-0 vector 2 quad) (the-as uint128 0)) - (set! (-> gp-0 vector 3 quad) (the-as uint128 0)) - (let ((s5-0 (new 'stack 'matrix))) - (set! (-> s5-0 vector 0 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 1 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 2 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 3 quad) (the-as uint128 0)) - (matrix-rotate-x! arg0 (-> arg1 data 0)) - (matrix-rotate-y! gp-0 (-> arg1 data 1)) - (matrix*! s5-0 gp-0 arg0) - (matrix-rotate-z! gp-0 (-> arg1 data 2)) - (matrix*! arg0 gp-0 s5-0) +(defun matrix-rotate-zyx! ((dst matrix) (rot-xyz-deg vector)) + "Rotate in z,y,x order." + (let ((temp-mat (new 'stack 'matrix))) + (set! (-> temp-mat vector 0 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 1 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 2 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 3 quad) (the-as uint128 0)) + (let ((rot-mat (new 'stack 'matrix))) + (set! (-> rot-mat vector 0 quad) (the-as uint128 0)) + (set! (-> rot-mat vector 1 quad) (the-as uint128 0)) + (set! (-> rot-mat vector 2 quad) (the-as uint128 0)) + (set! (-> rot-mat vector 3 quad) (the-as uint128 0)) + ;; x-rot + (matrix-rotate-x! dst (-> rot-xyz-deg data 0)) + ;; y-rot + (matrix-rotate-y! temp-mat (-> rot-xyz-deg data 1)) + ;; rot-mat = yx + (matrix*! rot-mat temp-mat dst) + (matrix-rotate-z! temp-mat (-> rot-xyz-deg data 2)) + ;; dst = z*yz + (matrix*! dst temp-mat rot-mat) ) ) - arg0 + dst ) -(defun matrix-rotate-xyz! ((arg0 matrix) (arg1 vector)) - "Create a matrix for a series of rotations" - (let ((gp-0 (new 'stack 'matrix))) - (set! (-> gp-0 vector 0 quad) (the-as uint128 0)) - (set! (-> gp-0 vector 1 quad) (the-as uint128 0)) - (set! (-> gp-0 vector 2 quad) (the-as uint128 0)) - (set! (-> gp-0 vector 3 quad) (the-as uint128 0)) - (let ((s5-0 (new 'stack 'matrix))) - (set! (-> s5-0 vector 0 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 1 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 2 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 3 quad) (the-as uint128 0)) - (matrix-rotate-z! arg0 (-> arg1 data 2)) - (matrix-rotate-y! gp-0 (-> arg1 data 1)) - (matrix*! s5-0 gp-0 arg0) - (matrix-rotate-x! gp-0 (-> arg1 data 0)) - (matrix*! arg0 gp-0 s5-0) +(defun matrix-rotate-xyz! ((dst matrix) (rot-xyz-deg vector)) + "Rotate in x,y,z order" + (let ((temp-mat (new 'stack 'matrix))) + (set! (-> temp-mat vector 0 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 1 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 2 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 3 quad) (the-as uint128 0)) + (let ((rot-mat (new 'stack 'matrix))) + (set! (-> rot-mat vector 0 quad) (the-as uint128 0)) + (set! (-> rot-mat vector 1 quad) (the-as uint128 0)) + (set! (-> rot-mat vector 2 quad) (the-as uint128 0)) + (set! (-> rot-mat vector 3 quad) (the-as uint128 0)) + (matrix-rotate-z! dst (-> rot-xyz-deg data 2)) + (matrix-rotate-y! temp-mat (-> rot-xyz-deg data 1)) + (matrix*! rot-mat temp-mat dst) + (matrix-rotate-x! temp-mat (-> rot-xyz-deg data 0)) + (matrix*! dst temp-mat rot-mat) ) ) - arg0 + dst ) -(defun matrix-rotate-zxy! ((arg0 matrix) (arg1 vector)) - "Create a matrix for a series of rotations" - (let ((gp-0 (new 'stack 'matrix))) - (set! (-> gp-0 vector 0 quad) (the-as uint128 0)) - (set! (-> gp-0 vector 1 quad) (the-as uint128 0)) - (set! (-> gp-0 vector 2 quad) (the-as uint128 0)) - (set! (-> gp-0 vector 3 quad) (the-as uint128 0)) - (let ((s5-0 (new 'stack 'matrix))) - (set! (-> s5-0 vector 0 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 1 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 2 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 3 quad) (the-as uint128 0)) - (matrix-rotate-y! arg0 (-> arg1 data 1)) - (matrix-rotate-x! gp-0 (-> arg1 data 0)) - (matrix*! s5-0 gp-0 arg0) - (matrix-rotate-z! gp-0 (-> arg1 data 2)) - (matrix*! arg0 gp-0 s5-0) +(defun matrix-rotate-zxy! ((dst matrix) (rot-xyz-deg vector)) + "Rotate in z,x,y order" + (let ((temp-mat (new 'stack 'matrix))) + (set! (-> temp-mat vector 0 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 1 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 2 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 3 quad) (the-as uint128 0)) + (let ((rot-mat (new 'stack 'matrix))) + (set! (-> rot-mat vector 0 quad) (the-as uint128 0)) + (set! (-> rot-mat vector 1 quad) (the-as uint128 0)) + (set! (-> rot-mat vector 2 quad) (the-as uint128 0)) + (set! (-> rot-mat vector 3 quad) (the-as uint128 0)) + (matrix-rotate-y! dst (-> rot-xyz-deg data 1)) + (matrix-rotate-x! temp-mat (-> rot-xyz-deg data 0)) + (matrix*! rot-mat temp-mat dst) + (matrix-rotate-z! temp-mat (-> rot-xyz-deg data 2)) + (matrix*! dst temp-mat rot-mat) ) ) - arg0 + dst ) -(defun matrix-rotate-yxz! ((arg0 matrix) (arg1 vector)) - "Create a matrix for a series of rotations" - (let ((gp-0 (new 'stack 'matrix))) - (set! (-> gp-0 vector 0 quad) (the-as uint128 0)) - (set! (-> gp-0 vector 1 quad) (the-as uint128 0)) - (set! (-> gp-0 vector 2 quad) (the-as uint128 0)) - (set! (-> gp-0 vector 3 quad) (the-as uint128 0)) - (let ((s5-0 (new 'stack 'matrix))) - (set! (-> s5-0 vector 0 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 1 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 2 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 3 quad) (the-as uint128 0)) - (matrix-rotate-z! arg0 (-> arg1 data 2)) - (matrix-rotate-x! gp-0 (-> arg1 data 0)) - (matrix*! s5-0 gp-0 arg0) - (matrix-rotate-y! gp-0 (-> arg1 data 1)) - (matrix*! arg0 gp-0 s5-0) +(defun matrix-rotate-yxz! ((dst matrix) (rot-xyz-deg vector)) + "Rotate in y,x,z order." + (let ((temp-mat (new 'stack 'matrix))) + (set! (-> temp-mat vector 0 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 1 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 2 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 3 quad) (the-as uint128 0)) + (let ((rot-mat (new 'stack 'matrix))) + (set! (-> rot-mat vector 0 quad) (the-as uint128 0)) + (set! (-> rot-mat vector 1 quad) (the-as uint128 0)) + (set! (-> rot-mat vector 2 quad) (the-as uint128 0)) + (set! (-> rot-mat vector 3 quad) (the-as uint128 0)) + (matrix-rotate-z! dst (-> rot-xyz-deg data 2)) + (matrix-rotate-x! temp-mat (-> rot-xyz-deg data 0)) + (matrix*! rot-mat temp-mat dst) + (matrix-rotate-y! temp-mat (-> rot-xyz-deg data 1)) + (matrix*! dst temp-mat rot-mat) ) ) - arg0 + dst ) - -(defun matrix-rotate-yzx! ((arg0 matrix) (arg1 vector)) - "Create a matrix for a series of rotations" - (let ((gp-0 (new 'stack 'matrix))) - (set! (-> gp-0 vector 0 quad) (the-as uint128 0)) - (set! (-> gp-0 vector 1 quad) (the-as uint128 0)) - (set! (-> gp-0 vector 2 quad) (the-as uint128 0)) - (set! (-> gp-0 vector 3 quad) (the-as uint128 0)) - (let ((s5-0 (new 'stack 'matrix))) - (set! (-> s5-0 vector 0 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 1 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 2 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 3 quad) (the-as uint128 0)) - (matrix-rotate-z! arg0 (-> arg1 data 0)) - (matrix-rotate-x! gp-0 (-> arg1 data 2)) - (matrix*! s5-0 gp-0 arg0) - (matrix-rotate-y! gp-0 (-> arg1 data 1)) - (matrix*! arg0 gp-0 s5-0) +(defun matrix-rotate-yzx! ((dst matrix) (rot-xyz-deg vector)) + "Rotate in y,z,x order" + (let ((temp-mat (new 'stack 'matrix))) + (set! (-> temp-mat vector 0 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 1 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 2 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 3 quad) (the-as uint128 0)) + (let ((rot-mat (new 'stack 'matrix))) + (set! (-> rot-mat vector 0 quad) (the-as uint128 0)) + (set! (-> rot-mat vector 1 quad) (the-as uint128 0)) + (set! (-> rot-mat vector 2 quad) (the-as uint128 0)) + (set! (-> rot-mat vector 3 quad) (the-as uint128 0)) + (matrix-rotate-z! dst (-> rot-xyz-deg data 0)) + (matrix-rotate-x! temp-mat (-> rot-xyz-deg data 2)) + (matrix*! rot-mat temp-mat dst) + (matrix-rotate-y! temp-mat (-> rot-xyz-deg data 1)) + (matrix*! dst temp-mat rot-mat) ) ) - arg0 + dst ) -(defun matrix-rotate-yxy! ((arg0 matrix) (arg1 vector)) - "Create a matrix for a series of rotations" - (let ((a2-0 (new 'stack 'vector)) - (s5-0 (new 'stack 'vector)) - (s4-0 (new 'stack 'vector)) +(defun matrix-rotate-yxy! ((dst matrix) (rots-deg vector)) + "Rotate. I believe in yxy order? Compared to the other rotations, this one + is quite a bit more optimized and avoid repeated trig operations." + (let ((sincos-input (new 'stack 'vector)) + (sin-vec (new 'stack 'vector)) + (cos-vec (new 'stack 'vector)) ) - (let ((v1-0 a2-0)) - (set! (-> v1-0 data 0) (-> arg1 data 0)) - (set! (-> v1-0 data 1) (- (-> arg1 data 1) (-> arg1 data 2))) - (set! (-> v1-0 data 2) (-> arg1 data 2)) + + ;; the vector-sincos! lets us take the sine and cosine of 4 floats at a time. + ;; it uses vector operations and reuses the taylor series coefficients to do this quickly + (let ((v1-0 sincos-input)) + (set! (-> v1-0 data 0) (-> rots-deg data 0)) + (set! (-> v1-0 data 1) (- (-> rots-deg data 1) (-> rots-deg data 2))) + (set! (-> v1-0 data 2) (-> rots-deg data 2)) (set! (-> v1-0 data 3) 1.0) ) - (vector-sincos! s5-0 s4-0 a2-0) - (let ((f1-1 (-> s4-0 data 1)) - (f0-5 (-> s5-0 data 1)) - (f2-0 (-> s4-0 data 0)) - (f5-0 (-> s5-0 data 0)) - (f3-0 (-> s4-0 data 2)) - (f4-0 (-> s5-0 data 2)) + (vector-sincos! sin-vec cos-vec sincos-input) + (let ((cos-y (-> cos-vec data 1)) + (sin-y (-> sin-vec data 1)) + (cos-x (-> cos-vec data 0)) + (sin-x (-> sin-vec data 0)) + (cos-z (-> cos-vec data 2)) + (sin-z (-> sin-vec data 2)) ) - (set! (-> arg0 data 0) (- (* f1-1 f3-0) (* (* f0-5 f2-0) f4-0))) - (set! (-> arg0 data 1) (* f0-5 f5-0)) - (set! (-> arg0 data 2) (- (+ (* f1-1 f4-0) (* (* f0-5 f2-0) f3-0)))) - (set! (-> arg0 data 3) 0.0) - (set! (-> arg0 data 4) (* f5-0 f4-0)) - (set! (-> arg0 data 5) f2-0) - (set! (-> arg0 data 6) (* f5-0 f3-0)) - (set! (-> arg0 data 7) 0.0) - (set! (-> arg0 data 8) (+ (* f0-5 f3-0) (* (* f1-1 f2-0) f4-0))) - (set! (-> arg0 data 9) (- (* f1-1 f5-0))) - (set! (-> arg0 data 10) (- (* (* f1-1 f2-0) f3-0) (* f0-5 f4-0))) + ;; just directly set the coefficients instead of doing wasteful multiplies. + (set! (-> dst data 0) (- (* cos-y cos-z) (* (* sin-y cos-x) sin-z))) + (set! (-> dst data 1) (* sin-y sin-x)) + (set! (-> dst data 2) (- (+ (* cos-y sin-z) (* (* sin-y cos-x) cos-z)))) + (set! (-> dst data 3) 0.0) + (set! (-> dst data 4) (* sin-x sin-z)) + (set! (-> dst data 5) cos-x) + (set! (-> dst data 6) (* sin-x cos-z)) + (set! (-> dst data 7) 0.0) + (set! (-> dst data 8) (+ (* sin-y cos-z) (* (* cos-y cos-x) sin-z))) + (set! (-> dst data 9) (- (* cos-y sin-x))) + (set! (-> dst data 10) (- (* (* cos-y cos-x) cos-z) (* sin-y sin-z))) ) ) - (set! (-> arg0 data 11) 0.0) - (set! (-> arg0 data 12) 0.0) - (set! (-> arg0 data 13) 0.0) - (set! (-> arg0 data 14) 0.0) - (set! (-> arg0 data 16) 1.0) - arg0 + (set! (-> dst data 11) 0.0) + (set! (-> dst data 12) 0.0) + (set! (-> dst data 13) 0.0) + (set! (-> dst data 14) 0.0) + (set! (-> dst data 15) 1.0) + dst ) -(defun matrix-rotate-yx! ((arg0 matrix) (arg1 float) (arg2 float)) - (matrix-rotate-y! arg0 arg1) - ;; this is ugly because of the inline ctor. +(defun matrix-rotate-yx! ((dst matrix) (rot-y-deg float) (rot-x-deg float)) + "Rotate by y then x." + (matrix-rotate-y! dst rot-y-deg) + ;; this is weird. probably there is an inlined ctor in a new 'stack expression, used directly + ;; in an argument. like (matrix-rotate-x! (new 'stack-with-ctor 'matrix) ...) (let ((t9-1 matrix-rotate-x!) (a0-2 (new 'stack 'matrix)) ) - (set! (-> a0-2 vector 0 quad) (the-as uint128 0)) - (set! (-> a0-2 vector 1 quad) (the-as uint128 0)) - (set! (-> a0-2 vector 2 quad) (the-as uint128 0)) - (set! (-> a0-2 vector 3 quad) (the-as uint128 0)) - (let ((a1-2 (t9-1 a0-2 arg2))) - (matrix*! arg0 a1-2 arg0) - ) + (set! (-> a0-2 vector 0 quad) (the-as uint128 0)) + (set! (-> a0-2 vector 1 quad) (the-as uint128 0)) + (set! (-> a0-2 vector 2 quad) (the-as uint128 0)) + (set! (-> a0-2 vector 3 quad) (the-as uint128 0)) + (let ((a1-2 (t9-1 a0-2 rot-x-deg))) + (matrix*! dst a1-2 dst) ) - arg0 + ) + dst ) -;; todo: matrix-axis-sin-cos-vu! -;; todo: matrix-axis-sin-cos! -;; todo: matrix-axis-angle! +(defun matrix-axis-sin-cos-vu! ((dst matrix) (axis vector) (s float) (c float)) + "Create an axis-angle rotation matrix. But given the sin/cos of the angle." + ;; this is unused and basically identital to the non-VU version, so I'm leaving this out. + (/ 0 0) + (none) + ) -(defun matrix-lerp! ((arg0 matrix) (arg1 matrix) (arg2 matrix) (arg3 float)) +(defun matrix-axis-sin-cos! ((dst matrix) (axis vector) (s float) (c float)) + "Create an axis-angle rotation matrix. But given the sin/cos of the angle." + ;;or v0, a0, r0 + ;;or v1, a1, r0 + ;;mtc1 f0, a2 + ;;mtc1 f1, a3 + ;;sll r0, r0, 0 + + ;; input scramble: + ;; - v0 = dst + ;; - v1 = axis + ;; - f0 = sine + ;; - f1 = cosine + (rlet ((vf5 :class vf) ;; vf5.x will be sine, vf5.w will be -cosine + (vf6 :class vf) ;; vf6.x will be cosine + (vf1 :class vf) ;; vector. + (vf0 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + (vf11 :class vf) + (vf7 :class vf) + (vf8 :class vf) + (vf9 :class vf) + (vf10 :class vf) + (a1 :class i128 :type uint128) + (r0 :class i128 :type uint128)) ;; will be used for zero check. + ;; initialize constant vectors + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.xor.p r0 r0 r0) + + ;; this is an overly complicated check to see if xyz = 0. + + (let ((a0 65535) ;; ori a0, r0, 65535 + (v1 (-> axis quad))) ;; lq v1, 0(v1) + + ;; this a0 constant has ffff in the upper 16 bits to mask out w, later on. + ;; dsll32 a0, a0, 16 + (set! a0 (shl a0 48)) ;; a0 = ffff'0000'0000'0000 + + ;;mfc1 a1, f1 + ;;qmtc2.i vf6, a1 + (.mov vf6 c) ;; will set vf6.x to cosine. + + ;;pceqw a1, v1, r0 + ;; compare for equality with zero. + ;; this will set 32-bits for each component. + (.pceqw a1 v1 r0) + + ;; so we pack: [upper64, w0?16, z0?16, y0?16, x0?16] + (.ppach a1 r0 a1) + + ;;qmtc2.i vf1, v1 + (.mov vf1 v1) ;; should be quad move! + + ;;or v1, a1, a0 + ;; make it seem like w is zero. If x,y,z = 0, but w != 0, we want + ;; it to act like zero. + (let ((xyz-zero (logior a0 (the uint a1)))) + ;;mfc1 a0, f0 + ;;qmtc2.i vf5, a0 + (.mov vf5 s) + + ;;daddiu v1, v1, 1 + ;; if all is zero, this will overflow and give us 0. + (+! xyz-zero 1) + + ;;vsubx.w vf5, vf0, vf6 + (.sub.x.vf vf5 vf0 vf6 :mask #b1000) + + ;;beq v1, r0, L15 + ;;vaddx.y vf5, vf0, vf6 + (.add.x.vf vf5 vf0 vf6 :mask #b0010) + (when-goto (zero? xyz-zero) zero-case) + ) + ) + + ;; Nonzero case: + ;; vsubw.w vf2, vf0, vf0 + ;; vsubw.w vf3, vf0, vf0 + ;; vsubw.w vf4, vf0, vf0 + (.xor.vf vf2 vf2 vf2) + (.xor.vf vf3 vf3 vf3) + (.xor.vf vf4 vf4 vf4) + + ;;vmulx.xyz vf11, vf1, vf5 + (.mul.x.vf vf11 vf1 vf5 :mask #b0111) + + ;;vaddy.x vf7, vf0, vf5 + (.add.y.vf vf7 vf0 vf5 :mask #b0001) + + ;;vaddy.y vf8, vf0, vf5 + (.add.y.vf vf8 vf0 vf5 :mask #b0010) + + ;;vaddy.z vf9, vf0, vf5 + (.add.y.vf vf9 vf0 vf5 :mask #b0100) + + ;;vmulw.xyz vf10, vf1, vf5 + (.mul.w.vf vf10 vf1 vf5 :mask #b0111) + + ;;vsubz.y vf7, vf0, vf11 + (.sub.z.vf vf7 vf0 vf11 :mask #b0010) + + ;;vaddy.z vf7, vf0, vf11 + (.add.y.vf vf7 vf0 vf11 :mask #b0100) + + ;;vaddz.x vf8, vf0, vf11 + (.add.z.vf vf8 vf0 vf11 :mask #b0001) + + ;;vsubx.z vf8, vf0, vf11 + (.sub.x.vf vf8 vf0 vf11 :mask #b0100) + + ;;vmulx.xyz vf2, vf10, vf1 + (.mul.x.vf vf2 vf10 vf1 :mask #b0111) + + ;;vmuly.xyz vf3, vf10, vf1 + (.mul.y.vf vf3 vf10 vf1 :mask #b0111) + + ;;vmulz.xyz vf4, vf10, vf1 + (.mul.z.vf vf4 vf10 vf1 :mask #b0111) + + ;;vsuby.x vf9, vf0, vf11 + (.sub.y.vf vf9 vf0 vf11 :mask #b0001) + + ;;vaddx.y vf9, vf0, vf11 + (.add.x.vf vf9 vf0 vf11 :mask #b0010) + + ;;vadd.xyz vf2, vf2, vf7 + (.add.vf vf2 vf2 vf7 :mask #b0111) + + ;;vadd.xyz vf3, vf3, vf8 + (.add.vf vf3 vf3 vf8 :mask #b0111) + + ;;vadd.xyz vf4, vf4, vf9 + (.add.vf vf4 vf4 vf9 :mask #b0111) + + ;;sqc2 vf2, 0(v0) + ;;sqc2 vf3, 16(v0) + ;;sqc2 vf0, 48(v0) + ;;sqc2 vf4, 32(v0) + (.svf (-> dst vector 0) vf2) + (.svf (-> dst vector 1) vf3) + (.svf (-> dst vector 3) vf0) + (.svf (-> dst vector 2) vf4) + (goto end) + (label zero-case) + ;; overly clever way to set identity matrix + ;;lui v1, 16256 + ;;sqc2 vf0, 48(v0) + ;;pcpyld v1, r0, v1 + ;;mfc1 r0, f31 + ;;prot3w a0, v1 + ;;mfc1 r0, f31 + ;;prot3w a1, a0 + ;;sq v1, 0(v0) + ;;sll r0, r0, 0 + ;;sq a0, 32(v0) + ;;sll r0, r0, 0 + ;;sq a1, 16(v0) + (matrix-identity! dst) + (label end) + ) + (none) + ) + +(defun matrix-axis-angle! ((dst matrix) (axis vector) (angle-deg float)) + "Create an axis-angle rotation matrix." + (matrix-axis-sin-cos! dst axis (sin angle-deg) (cos angle-deg)) + (none) + ) + +(defun matrix-lerp! ((dst matrix) (src1 matrix) (src2 matrix) (alpha float)) + "Lerp an entire matrix, coefficient-wise." (rlet ((vf1 :class vf) (vf2 :class vf) (vf3 :class vf) @@ -773,15 +1084,17 @@ arg0 (vf8 :class vf) (vf9 :class vf) ) - (.mov vf9 arg3) - (.lvf vf1 (&-> arg1 vector 0 quad)) - (.lvf vf2 (&-> arg1 vector 1 quad)) - (.lvf vf3 (&-> arg1 vector 2 quad)) - (.lvf vf4 (&-> arg1 vector 3 quad)) - (.lvf vf5 (&-> arg2 vector 0 quad)) - (.lvf vf6 (&-> arg2 vector 1 quad)) - (.lvf vf7 (&-> arg2 vector 2 quad)) - (.lvf vf8 (&-> arg2 vector 3 quad)) + ;; this uses src1 + alpha * (src2 - src1) + ;; it seems like src1 * (1 - alpha) + src2 * alpha might have been faster? + (.mov vf9 alpha) + (.lvf vf1 (&-> src1 vector 0 quad)) + (.lvf vf2 (&-> src1 vector 1 quad)) + (.lvf vf3 (&-> src1 vector 2 quad)) + (.lvf vf4 (&-> src1 vector 3 quad)) + (.lvf vf5 (&-> src2 vector 0 quad)) + (.lvf vf6 (&-> src2 vector 1 quad)) + (.lvf vf7 (&-> src2 vector 2 quad)) + (.lvf vf8 (&-> src2 vector 3 quad)) (.sub.vf vf5 vf5 vf1) (.sub.vf vf6 vf6 vf2) (.sub.vf vf7 vf7 vf3) @@ -794,32 +1107,35 @@ arg0 (.add.vf vf2 vf2 vf6) (.add.vf vf3 vf3 vf7) (.add.vf vf4 vf4 vf8) - (.svf (&-> arg0 vector 0 quad) vf1) - (.svf (&-> arg0 vector 1 quad) vf2) - (.svf (&-> arg0 vector 2 quad) vf3) - (.svf (&-> arg0 vector 3 quad) vf4) - arg0 + (.svf (&-> dst vector 0 quad) vf1) + (.svf (&-> dst vector 1 quad) vf2) + (.svf (&-> dst vector 2 quad) vf3) + (.svf (&-> dst vector 3 quad) vf4) + dst ) ) -(defun matrix-3x3-determinant ((arg0 matrix)) - (let ((f8-0 (-> arg0 data 0)) - (f1-0 (-> arg0 data 1)) - (f4-0 (-> arg0 data 2)) - (f2-0 (-> arg0 data 4)) - (f5-0 (-> arg0 data 5)) - (f9-0 (-> arg0 data 6)) - (f3-0 (-> arg0 data 8)) - (f6-0 (-> arg0 data 9)) - (f0-0 (-> arg0 data 10)) +(defun matrix-3x3-determinant ((mat matrix)) + "Compute the determinant of a 3x3 matrix" + (let ((f8-0 (-> mat data 0)) + (f1-0 (-> mat data 1)) + (f4-0 (-> mat data 2)) + (f2-0 (-> mat data 4)) + (f5-0 (-> mat data 5)) + (f9-0 (-> mat data 6)) + (f3-0 (-> mat data 8)) + (f6-0 (-> mat data 9)) + (f0-0 (-> mat data 10)) ) - (- (+ (+ (* (* f8-0 f5-0) f0-0) (* (* f1-0 f9-0) f3-0)) (* (* f4-0 f2-0) f6-0)) - (+ (+ (* (* f8-0 f9-0) f6-0) (* (* f4-0 f5-0) f3-0)) (* (* f1-0 f2-0) f0-0)) - ) + (- + (+ (+ (* (* f8-0 f5-0) f0-0) (* (* f1-0 f9-0) f3-0)) (* (* f4-0 f2-0) f6-0)) + (+ (+ (* (* f8-0 f9-0) f6-0) (* (* f4-0 f5-0) f3-0)) (* (* f1-0 f2-0) f0-0)) + ) ) ) (defun matrix3-determinant ((arg0 matrix)) + "Unused. Not sure if this has limitations compared to the above version." (local-vars (v0-0 int)) (rlet ((acc :class vf) (vf10 :class vf) @@ -839,172 +1155,174 @@ arg0 ) ) -(defun matrix-3x3-inverse! ((arg0 matrix) (arg1 matrix)) - (let ((f0-0 (matrix-3x3-determinant arg1))) - (set! (-> arg0 data 0) - (/ (- (* (-> arg1 data 5) (-> arg1 data 10)) - (* (-> arg1 data 6) (-> arg1 data 9)) - ) - f0-0 - ) - ) - (set! (-> arg0 data 4) - (/ (- (* (-> arg1 data 6) (-> arg1 data 8)) - (* (-> arg1 data 4) (-> arg1 data 10)) - ) - f0-0 - ) - ) - (set! (-> arg0 data 8) - (/ (- (* (-> arg1 data 4) (-> arg1 data 9)) - (* (-> arg1 data 5) (-> arg1 data 8)) - ) - f0-0 - ) - ) - (set! (-> arg0 data 1) - (/ (- (* (-> arg1 data 9) (-> arg1 data 2)) - (* (-> arg1 data 10) (-> arg1 data 1)) - ) - f0-0 - ) - ) - (set! (-> arg0 data 5) - (/ (- (* (-> arg1 data 10) (-> arg1 data 0)) - (* (-> arg1 data 8) (-> arg1 data 2)) - ) - f0-0 - ) - ) - (set! (-> arg0 data 9) - (/ (- (* (-> arg1 data 8) (-> arg1 data 1)) - (* (-> arg1 data 9) (-> arg1 data 0)) - ) - f0-0 - ) - ) - (set! (-> arg0 data 2) - (/ (- (* (-> arg1 data 1) (-> arg1 data 6)) - (* (-> arg1 data 2) (-> arg1 data 5)) - ) - f0-0 - ) - ) - (set! (-> arg0 data 6) - (/ (- (* (-> arg1 data 2) (-> arg1 data 4)) - (* (-> arg1 data 0) (-> arg1 data 6)) - ) - f0-0 - ) - ) - (set! (-> arg0 data 10) - (/ (- (* (-> arg1 data 0) (-> arg1 data 5)) - (* (-> arg1 data 1) (-> arg1 data 4)) - ) - f0-0 - ) - ) - ) - arg0 - ) - -(defun matrix-3x3-inverse-transpose! ((arg0 matrix) (arg1 matrix)) - (let ((f0-0 (matrix-3x3-determinant arg1))) +(defun matrix-3x3-inverse! ((dst matrix) (src matrix)) + "Compute the inverse of a 3x3 matrix. Not very efficient. + Requires src != dst." + (let ((f0-0 (matrix-3x3-determinant src))) (set! - (-> arg0 data 0) + (-> dst data 0) (/ (- - (* (-> arg1 data 5) (-> arg1 data 10)) - (* (-> arg1 data 6) (-> arg1 data 9)) + (* (-> src data 5) (-> src data 10)) + (* (-> src data 6) (-> src data 9)) ) f0-0 ) ) (set! - (-> arg0 data 1) + (-> dst data 4) (/ (- - (* (-> arg1 data 6) (-> arg1 data 8)) - (* (-> arg1 data 4) (-> arg1 data 10)) + (* (-> src data 6) (-> src data 8)) + (* (-> src data 4) (-> src data 10)) ) f0-0 ) ) (set! - (-> arg0 data 2) + (-> dst data 8) + (/ + (- (* (-> src data 4) (-> src data 9)) (* (-> src data 5) (-> src data 8))) + f0-0 + ) + ) + (set! + (-> dst data 1) (/ (- - (* (-> arg1 data 4) (-> arg1 data 9)) - (* (-> arg1 data 5) (-> arg1 data 8)) + (* (-> src data 9) (-> src data 2)) + (* (-> src data 10) (-> src data 1)) ) f0-0 ) ) (set! - (-> arg0 data 4) + (-> dst data 5) (/ (- - (* (-> arg1 data 9) (-> arg1 data 2)) - (* (-> arg1 data 10) (-> arg1 data 1)) + (* (-> src data 10) (-> src data 0)) + (* (-> src data 8) (-> src data 2)) ) f0-0 ) ) (set! - (-> arg0 data 5) + (-> dst data 9) (/ - (- - (* (-> arg1 data 10) (-> arg1 data 0)) - (* (-> arg1 data 8) (-> arg1 data 2)) - ) + (- (* (-> src data 8) (-> src data 1)) (* (-> src data 9) (-> src data 0))) f0-0 ) ) (set! - (-> arg0 data 6) + (-> dst data 2) (/ - (- - (* (-> arg1 data 8) (-> arg1 data 1)) - (* (-> arg1 data 9) (-> arg1 data 0)) - ) + (- (* (-> src data 1) (-> src data 6)) (* (-> src data 2) (-> src data 5))) f0-0 ) ) (set! - (-> arg0 data 8) + (-> dst data 6) (/ - (- - (* (-> arg1 data 1) (-> arg1 data 6)) - (* (-> arg1 data 2) (-> arg1 data 5)) - ) + (- (* (-> src data 2) (-> src data 4)) (* (-> src data 0) (-> src data 6))) f0-0 ) ) (set! - (-> arg0 data 9) + (-> dst data 10) (/ - (- - (* (-> arg1 data 2) (-> arg1 data 4)) - (* (-> arg1 data 0) (-> arg1 data 6)) - ) - f0-0 - ) - ) - (set! - (-> arg0 data 10) - (/ - (- - (* (-> arg1 data 0) (-> arg1 data 5)) - (* (-> arg1 data 1) (-> arg1 data 4)) - ) + (- (* (-> src data 0) (-> src data 5)) (* (-> src data 1) (-> src data 4))) f0-0 ) ) ) - arg0 + dst ) -(defun matrix3-inverse-transpose! ((arg0 matrix) (arg1 matrix)) +(defun matrix-3x3-inverse-transpose! ((dst matrix) (src matrix)) + "Invert and transpose. + Requires dst != src." + (let ((f0-0 (matrix-3x3-determinant src))) + (set! + (-> dst data 0) + (/ + (- + (* (-> src data 5) (-> src data 10)) + (* (-> src data 6) (-> src data 9)) + ) + f0-0 + ) + ) + (set! + (-> dst data 1) + (/ + (- + (* (-> src data 6) (-> src data 8)) + (* (-> src data 4) (-> src data 10)) + ) + f0-0 + ) + ) + (set! + (-> dst data 2) + (/ + (- (* (-> src data 4) (-> src data 9)) (* (-> src data 5) (-> src data 8))) + f0-0 + ) + ) + (set! + (-> dst data 4) + (/ + (- + (* (-> src data 9) (-> src data 2)) + (* (-> src data 10) (-> src data 1)) + ) + f0-0 + ) + ) + (set! + (-> dst data 5) + (/ + (- + (* (-> src data 10) (-> src data 0)) + (* (-> src data 8) (-> src data 2)) + ) + f0-0 + ) + ) + (set! + (-> dst data 6) + (/ + (- (* (-> src data 8) (-> src data 1)) (* (-> src data 9) (-> src data 0))) + f0-0 + ) + ) + (set! + (-> dst data 8) + (/ + (- (* (-> src data 1) (-> src data 6)) (* (-> src data 2) (-> src data 5))) + f0-0 + ) + ) + (set! + (-> dst data 9) + (/ + (- (* (-> src data 2) (-> src data 4)) (* (-> src data 0) (-> src data 6))) + f0-0 + ) + ) + (set! + (-> dst data 10) + (/ + (- (* (-> src data 0) (-> src data 5)) (* (-> src data 1) (-> src data 4))) + f0-0 + ) + ) + ) + dst + ) + +(defun matrix3-inverse-transpose! ((dst matrix) (src matrix)) + "Unused. Not sure if this has limitations compared to other version." (rlet ((acc :class vf) (Q :class vf) (vf0 :class vf) @@ -1017,565 +1335,727 @@ arg0 (vf15 :class vf) ) (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (.lvf vf10 (&-> arg1 vector 0 quad)) - (.lvf vf11 (&-> arg1 vector 1 quad)) - (.lvf vf12 (&-> arg1 vector 2 quad)) + (.lvf vf10 (&-> src vector 0 quad)) + (.lvf vf11 (&-> src vector 1 quad)) + (.lvf vf12 (&-> src vector 2 quad)) (.outer.product.vf vf13 vf11 vf12) (.outer.product.vf vf14 vf12 vf10) (.mul.vf vf1 vf10 vf13 :mask #b111) (.outer.product.vf vf15 vf10 vf11) + (.nop.vf) (.add.y.vf vf1 vf1 vf1 :mask #b1) + (.nop.vf) + (.nop.vf) + (.nop.vf) (.add.z.vf vf1 vf1 vf1 :mask #b1) - (.div.vf Q vf0 vf1 :ftf #b11 :fsf #b0) - ;;(.wait.vf) + (.nop.vf) + (.nop.vf) + (.nop.vf) + (.div.vf Q vf0 vf1 :fsf #b11 :ftf #b0) + (.wait.vf) (.mul.vf vf13 vf13 Q) (.mul.vf vf14 vf14 Q) (.mul.vf vf15 vf15 Q) - (.svf (&-> arg0 vector 0 quad) vf13) - (.svf (&-> arg0 vector 1 quad) vf14) - (.svf (&-> arg0 vector 2 quad) vf15) - arg0 + (.nop.vf) + (.nop.vf) + (.svf (&-> dst vector 0 quad) vf13) + (.svf (&-> dst vector 1 quad) vf14) + (.svf (&-> dst vector 2 quad) vf15) + dst ) ) -(defun matrix-4x4-determinant ((arg0 matrix)) - (let ((f15-0 (-> arg0 data 0)) - (f14-0 (-> arg0 data 1)) - (f10-0 (-> arg0 data 2)) - (f2-0 (-> arg0 data 3)) - (f9-0 (-> arg0 data 4)) - (f6-0 (-> arg0 data 5)) - (f3-0 (-> arg0 data 6)) - (f11-0 (-> arg0 data 7)) - (f5-0 (-> arg0 data 8)) - (f1-0 (-> arg0 data 9)) - (f8-0 (-> arg0 data 10)) - (f13-0 (-> arg0 data 11)) - (f0-0 (-> arg0 data 12)) - (f7-0 (-> arg0 data 13)) - (f4-0 (-> arg0 data 14)) - (f12-0 (-> arg0 data 15)) +(defun matrix-4x4-determinant ((dst matrix)) + "Take the determinant of a 4x4 matrix. The answer is wrong." + (let ((f15-0 (-> dst data 0)) + (f14-0 (-> dst data 1)) + (f10-0 (-> dst data 2)) + (f2-0 (-> dst data 3)) + (f9-0 (-> dst data 4)) + (f6-0 (-> dst data 5)) + (f3-0 (-> dst data 6)) + (f11-0 (-> dst data 7)) + (f5-0 (-> dst data 8)) + (f1-0 (-> dst data 9)) + (f8-0 (-> dst data 10)) + (f13-0 (-> dst data 11)) + (f0-0 (-> dst data 12)) + (f7-0 (-> dst data 13)) + (f4-0 (-> dst data 14)) + (f12-0 (-> dst data 15)) ) - (- (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (+ (* (* (* f15-0 f6-0) f8-0) f12-0) - (* (* (* f15-0 f3-0) f13-0) f7-0) - ) - (* (* (* f15-0 f11-0) f1-0) f4-0) - ) - (* (* (* f14-0 f9-0) f13-0) f4-0) - ) - (* (* (* f14-0 f3-0) f5-0) f4-0) - ) - (* (* (* f14-0 f11-0) f8-0) f0-0) + (let ((result (- + (+ + (+ + (+ + (+ + (+ + (+ + (+ + (+ + (+ + (+ + (+ + (* (* (* f15-0 f6-0) f8-0) f12-0) + (* (* (* f15-0 f3-0) f13-0) f7-0) + ) + (* (* (* f15-0 f11-0) f1-0) f4-0) + ) + (* (* (* f14-0 f9-0) f13-0) f4-0) ) + (* (* (* f14-0 f3-0) f5-0) f4-0) + ) + (* (* (* f14-0 f11-0) f8-0) f0-0) + ) (* (* (* f10-0 f9-0) f1-0) f12-0) ) - (* (* (* f10-0 f6-0) f13-0) f0-0) + (* (* (* f10-0 f6-0) f13-0) f0-0) + ) + (* (* (* f10-0 f11-0) f5-0) f7-0) + ) + (* (* (* f2-0 f9-0) f1-0) f4-0) ) - (* (* (* f10-0 f11-0) f5-0) f7-0) + (* (* (* f2-0 f6-0) f8-0) f0-0) + ) + (* (* (* f2-0 f3-0) f5-0) f7-0) + ) + (+ + (+ + (+ + (+ + (+ + (+ + (+ + (+ + (+ + (+ + (+ + (* (* (* f15-0 f6-0) f13-0) f4-0) + (* (* (* f15-0 f3-0) f1-0) f12-0) + ) + (* (* (* f15-0 f11-0) f8-0) f7-0) + ) + (* (* (* f14-0 f9-0) f8-0) f12-0) + ) + (* (* (* f14-0 f3-0) f13-0) f0-0) + ) + (* (* (* f14-0 f11-0) f5-0) f4-0) + ) + (* (* (* f10-0 f9-0) f13-0) f7-0) + ) + (* (* (* f10-0 f6-0) f5-0) f12-0) + ) + (* (* (* f10-0 f11-0) f1-0) f0-0) + ) + (* (* (* f2-0 f9-0) f8-0) f7-0) + ) + (* (* (* f2-0 f6-0) f5-0) f4-0) + ) + (* (* (* f2-0 f3-0) f1-0) f0-0) + ) ) - (* (* (* f2-0 f9-0) f1-0) f4-0) - ) - (* (* (* f2-0 f6-0) f8-0) f0-0) - ) - (* (* (* f2-0 f3-0) f5-0) f7-0) - ) - (+ - (+ - (+ - (+ - (+ - (+ - (+ - (+ - (+ - (+ - (+ - (* (* (* f15-0 f6-0) f13-0) f4-0) - (* (* (* f15-0 f3-0) f1-0) f12-0) - ) - (* (* (* f15-0 f11-0) f8-0) f7-0) - ) - (* (* (* f14-0 f9-0) f8-0) f12-0) - ) - (* (* (* f14-0 f3-0) f13-0) f0-0) - ) - (* (* (* f14-0 f11-0) f5-0) f4-0) - ) - (* (* (* f10-0 f9-0) f13-0) f7-0) - ) - (* (* (* f10-0 f6-0) f5-0) f12-0) ) - (* (* (* f10-0 f11-0) f1-0) f0-0) - ) - (* (* (* f2-0 f9-0) f8-0) f7-0) ) - (* (* (* f2-0 f6-0) f5-0) f4-0) - ) - (* (* (* f2-0 f3-0) f1-0) f0-0) - ) - ) + result + ) ) ) - -(defun matrix-4x4-inverse-transpose! ((arg0 matrix) (arg1 matrix)) - (let ((f0-0 (matrix-4x4-determinant arg1))) - (let ((f9-0 (-> arg1 data 5)) - (f2-0 (-> arg1 data 6)) - (f5-0 (-> arg1 data 7)) - (f3-0 (-> arg1 data 9)) - (f6-0 (-> arg1 data 10)) - (f10-0 (-> arg1 data 11)) - (f4-0 (-> arg1 data 13)) - (f7-0 (-> arg1 data 14)) - (f1-0 (-> arg1 data 15)) - ) - (set! - (-> arg0 data 0) - (/ - (- - (+ - (+ (* (* f9-0 f6-0) f1-0) (* (* f2-0 f10-0) f4-0)) - (* (* f5-0 f3-0) f7-0) - ) - (+ - (+ (* (* f9-0 f10-0) f7-0) (* (* f5-0 f6-0) f4-0)) - (* (* f2-0 f3-0) f1-0) - ) +(defun matrix-4x4-inverse-transpose! ((dst matrix) (src matrix)) + "Invert and transpose an entire 4x4. I think has no restrictions, other than dst != src. Unused. + The answer is wrong. The determinant function is wrong." + (let ((f0-0 (matrix-4x4-determinant src))) + (let ((f9-0 (-> src data 5)) + (f2-0 (-> src data 6)) + (f5-0 (-> src data 7)) + (f3-0 (-> src data 9)) + (f6-0 (-> src data 10)) + (f10-0 (-> src data 11)) + (f4-0 (-> src data 13)) + (f7-0 (-> src data 14)) + (f1-0 (-> src data 15)) ) - f0-0 - ) - ) - ) - (let ((f9-2 (-> arg1 data 4)) - (f2-2 (-> arg1 data 6)) - (f5-2 (-> arg1 data 7)) - (f3-1 (-> arg1 data 8)) - (f6-1 (-> arg1 data 10)) - (f10-1 (-> arg1 data 11)) - (f4-3 (-> arg1 data 12)) - (f7-2 (-> arg1 data 14)) - (f1-6 (-> arg1 data 15)) - ) - (set! - (-> arg0 data 1) - (- - (/ - (- - (+ - (+ (* (* f9-2 f6-1) f1-6) (* (* f2-2 f10-1) f4-3)) - (* (* f5-2 f3-1) f7-2) - ) - (+ - (+ (* (* f9-2 f10-1) f7-2) (* (* f5-2 f6-1) f4-3)) - (* (* f2-2 f3-1) f1-6) - ) - ) - f0-0 - ) - ) - ) - ) - (let ((f9-4 (-> arg1 data 4)) - (f2-4 (-> arg1 data 5)) - (f5-4 (-> arg1 data 7)) - (f3-2 (-> arg1 data 8)) - (f6-2 (-> arg1 data 9)) - (f10-2 (-> arg1 data 11)) - (f4-6 (-> arg1 data 12)) - (f7-4 (-> arg1 data 13)) - (f1-13 (-> arg1 data 15)) - ) - (set! - (-> arg0 data 2) - (/ - (- - (+ - (+ (* (* f9-4 f6-2) f1-13) (* (* f2-4 f10-2) f4-6)) - (* (* f5-4 f3-2) f7-4) - ) - (+ - (+ (* (* f9-4 f10-2) f7-4) (* (* f5-4 f6-2) f4-6)) - (* (* f2-4 f3-2) f1-13) - ) - ) - f0-0 - ) - ) - ) - (let ((f9-6 (-> arg1 data 4)) - (f2-6 (-> arg1 data 5)) - (f5-6 (-> arg1 data 6)) - (f3-3 (-> arg1 data 8)) - (f6-3 (-> arg1 data 9)) - (f10-3 (-> arg1 data 10)) - (f4-9 (-> arg1 data 12)) - (f7-6 (-> arg1 data 13)) - (f1-19 (-> arg1 data 14)) - ) - (set! - (-> arg0 data 3) - (- - (/ - (- - (+ - (+ (* (* f9-6 f6-3) f1-19) (* (* f2-6 f10-3) f4-9)) - (* (* f5-6 f3-3) f7-6) - ) - (+ - (+ (* (* f9-6 f10-3) f7-6) (* (* f5-6 f6-3) f4-9)) - (* (* f2-6 f3-3) f1-19) - ) - ) - f0-0 - ) - ) - ) - ) - (let ((f9-8 (-> arg1 data 1)) - (f2-8 (-> arg1 data 2)) - (f5-8 (-> arg1 data 3)) - (f3-4 (-> arg1 data 9)) - (f6-4 (-> arg1 data 10)) - (f10-4 (-> arg1 data 11)) - (f4-12 (-> arg1 data 13)) - (f7-8 (-> arg1 data 14)) - (f1-26 (-> arg1 data 15)) - ) - (set! - (-> arg0 data 4) - (- - (/ - (- - (+ - (+ (* (* f9-8 f6-4) f1-26) (* (* f2-8 f10-4) f4-12)) - (* (* f5-8 f3-4) f7-8) - ) - (+ - (+ (* (* f9-8 f10-4) f7-8) (* (* f5-8 f6-4) f4-12)) - (* (* f2-8 f3-4) f1-26) - ) - ) - f0-0 - ) - ) - ) - ) - (let ((f9-10 (-> arg1 data 0)) - (f2-10 (-> arg1 data 2)) - (f5-10 (-> arg1 data 3)) - (f3-5 (-> arg1 data 8)) - (f6-5 (-> arg1 data 10)) - (f10-5 (-> arg1 data 11)) - (f4-15 (-> arg1 data 12)) - (f7-10 (-> arg1 data 14)) - (f1-33 (-> arg1 data 15)) - ) - (set! - (-> arg0 data 5) - (/ - (- - (+ - (+ (* (* f9-10 f6-5) f1-33) (* (* f2-10 f10-5) f4-15)) - (* (* f5-10 f3-5) f7-10) - ) - (+ - (+ (* (* f9-10 f10-5) f7-10) (* (* f5-10 f6-5) f4-15)) - (* (* f2-10 f3-5) f1-33) - ) - ) - f0-0 - ) - ) - ) - (let ((f9-12 (-> arg1 data 0)) - (f2-12 (-> arg1 data 1)) - (f5-12 (-> arg1 data 3)) - (f3-6 (-> arg1 data 8)) - (f6-6 (-> arg1 data 9)) - (f10-6 (-> arg1 data 11)) - (f4-18 (-> arg1 data 12)) - (f7-12 (-> arg1 data 13)) - (f1-39 (-> arg1 data 15)) - ) - (set! - (-> arg0 data 6) - (- - (/ - (- - (+ - (+ (* (* f9-12 f6-6) f1-39) (* (* f2-12 f10-6) f4-18)) - (* (* f5-12 f3-6) f7-12) - ) - (+ - (+ (* (* f9-12 f10-6) f7-12) (* (* f5-12 f6-6) f4-18)) - (* (* f2-12 f3-6) f1-39) - ) - ) - f0-0 - ) - ) - ) - ) - (let ((f9-14 (-> arg1 data 0)) - (f2-14 (-> arg1 data 1)) - (f5-14 (-> arg1 data 2)) - (f3-7 (-> arg1 data 8)) - (f6-7 (-> arg1 data 9)) - (f10-7 (-> arg1 data 10)) - (f4-21 (-> arg1 data 12)) - (f7-14 (-> arg1 data 13)) - (f1-46 (-> arg1 data 14)) - ) - (set! - (-> arg0 data 7) - (/ - (- - (+ - (+ (* (* f9-14 f6-7) f1-46) (* (* f2-14 f10-7) f4-21)) - (* (* f5-14 f3-7) f7-14) - ) - (+ - (+ (* (* f9-14 f10-7) f7-14) (* (* f5-14 f6-7) f4-21)) - (* (* f2-14 f3-7) f1-46) - ) - ) - f0-0 - ) - ) - ) - (let ((f9-16 (-> arg1 data 1)) - (f2-16 (-> arg1 data 2)) - (f5-16 (-> arg1 data 3)) - (f3-8 (-> arg1 data 5)) - (f6-8 (-> arg1 data 6)) - (f10-8 (-> arg1 data 7)) - (f4-24 (-> arg1 data 13)) - (f7-16 (-> arg1 data 14)) - (f1-52 (-> arg1 data 15)) - ) - (set! - (-> arg0 data 8) - (/ - (- - (+ - (+ (* (* f9-16 f6-8) f1-52) (* (* f2-16 f10-8) f4-24)) - (* (* f5-16 f3-8) f7-16) - ) - (+ - (+ (* (* f9-16 f10-8) f7-16) (* (* f5-16 f6-8) f4-24)) - (* (* f2-16 f3-8) f1-52) - ) - ) - f0-0 - ) - ) - ) - (let ((f9-18 (-> arg1 data 0)) - (f2-18 (-> arg1 data 2)) - (f5-18 (-> arg1 data 3)) - (f3-9 (-> arg1 data 4)) - (f6-9 (-> arg1 data 6)) - (f10-9 (-> arg1 data 7)) - (f4-27 (-> arg1 data 12)) - (f7-18 (-> arg1 data 14)) - (f1-58 (-> arg1 data 15)) - ) - (set! - (-> arg0 data 9) - (- - (/ - (- - (+ - (+ (* (* f9-18 f6-9) f1-58) (* (* f2-18 f10-9) f4-27)) - (* (* f5-18 f3-9) f7-18) - ) - (+ - (+ (* (* f9-18 f10-9) f7-18) (* (* f5-18 f6-9) f4-27)) - (* (* f2-18 f3-9) f1-58) - ) - ) - f0-0 - ) - ) - ) - ) - (let ((f9-20 (-> arg1 data 0)) - (f2-20 (-> arg1 data 1)) - (f5-20 (-> arg1 data 3)) - (f3-10 (-> arg1 data 4)) - (f6-10 (-> arg1 data 5)) - (f10-10 (-> arg1 data 7)) - (f4-30 (-> arg1 data 12)) - (f7-20 (-> arg1 data 13)) - (f1-65 (-> arg1 data 15)) - ) - (set! - (-> arg0 data 10) - (/ - (- - (+ - (+ (* (* f9-20 f6-10) f1-65) (* (* f2-20 f10-10) f4-30)) - (* (* f5-20 f3-10) f7-20) - ) - (+ - (+ (* (* f9-20 f10-10) f7-20) (* (* f5-20 f6-10) f4-30)) - (* (* f2-20 f3-10) f1-65) - ) - ) - f0-0 - ) - ) - ) - (let ((f9-22 (-> arg1 data 0)) - (f2-22 (-> arg1 data 1)) - (f5-22 (-> arg1 data 2)) - (f3-11 (-> arg1 data 4)) - (f6-11 (-> arg1 data 5)) - (f10-11 (-> arg1 data 6)) - (f4-33 (-> arg1 data 12)) - (f7-22 (-> arg1 data 13)) - (f1-71 (-> arg1 data 14)) - ) - (set! - (-> arg0 data 11) - (- - (/ - (- - (+ - (+ (* (* f9-22 f6-11) f1-71) (* (* f2-22 f10-11) f4-33)) - (* (* f5-22 f3-11) f7-22) - ) - (+ - (+ (* (* f9-22 f10-11) f7-22) (* (* f5-22 f6-11) f4-33)) - (* (* f2-22 f3-11) f1-71) - ) - ) - f0-0 - ) - ) - ) - ) - (let ((f9-24 (-> arg1 data 1)) - (f2-24 (-> arg1 data 2)) - (f5-24 (-> arg1 data 3)) - (f3-12 (-> arg1 data 5)) - (f6-12 (-> arg1 data 6)) - (f10-12 (-> arg1 data 7)) - (f4-36 (-> arg1 data 9)) - (f7-24 (-> arg1 data 10)) - (f1-78 (-> arg1 data 11)) - ) - (set! - (-> arg0 data 12) - (- - (/ - (- - (+ - (+ (* (* f9-24 f6-12) f1-78) (* (* f2-24 f10-12) f4-36)) - (* (* f5-24 f3-12) f7-24) - ) - (+ - (+ (* (* f9-24 f10-12) f7-24) (* (* f5-24 f6-12) f4-36)) - (* (* f2-24 f3-12) f1-78) - ) - ) - f0-0 - ) - ) - ) - ) - (let ((f9-26 (-> arg1 data 0)) - (f2-26 (-> arg1 data 2)) - (f5-26 (-> arg1 data 3)) - (f3-13 (-> arg1 data 4)) - (f6-13 (-> arg1 data 6)) - (f10-13 (-> arg1 data 7)) - (f4-39 (-> arg1 data 8)) - (f7-26 (-> arg1 data 10)) - (f1-85 (-> arg1 data 11)) - ) - (set! - (-> arg0 data 13) - (/ - (- - (+ - (+ (* (* f9-26 f6-13) f1-85) (* (* f2-26 f10-13) f4-39)) - (* (* f5-26 f3-13) f7-26) - ) - (+ - (+ (* (* f9-26 f10-13) f7-26) (* (* f5-26 f6-13) f4-39)) - (* (* f2-26 f3-13) f1-85) - ) - ) - f0-0 - ) - ) - ) - (let ((f9-28 (-> arg1 data 0)) - (f2-28 (-> arg1 data 1)) - (f5-28 (-> arg1 data 3)) - (f3-14 (-> arg1 data 4)) - (f6-14 (-> arg1 data 5)) - (f10-14 (-> arg1 data 7)) - (f4-42 (-> arg1 data 8)) - (f7-28 (-> arg1 data 9)) - (f1-91 (-> arg1 data 11)) - ) - (set! - (-> arg0 data 14) - (- - (/ - (- - (+ - (+ (* (* f9-28 f6-14) f1-91) (* (* f2-28 f10-14) f4-42)) - (* (* f5-28 f3-14) f7-28) - ) - (+ - (+ (* (* f9-28 f10-14) f7-28) (* (* f5-28 f6-14) f4-42)) - (* (* f2-28 f3-14) f1-91) - ) - ) - f0-0 - ) - ) - ) - ) - (let ((f8-60 (-> arg1 data 0)) - (f1-98 (-> arg1 data 1)) - (f5-30 (-> arg1 data 2)) - (f2-30 (-> arg1 data 4)) - (f6-15 (-> arg1 data 5)) - (f9-30 (-> arg1 data 6)) - (f4-45 (-> arg1 data 8)) - (f7-30 (-> arg1 data 9)) - (f3-15 (-> arg1 data 10)) - ) - (set! - (-> arg0 data 15) - (/ - (- - (+ - (+ (* (* f8-60 f6-15) f3-15) (* (* f1-98 f9-30) f4-45)) - (* (* f5-30 f2-30) f7-30) - ) - (+ - (+ (* (* f8-60 f9-30) f7-30) (* (* f5-30 f6-15) f4-45)) - (* (* f1-98 f2-30) f3-15) - ) - ) - f0-0 + (set! + (-> dst data 0) + (/ + (- + (+ + (+ (* (* f9-0 f6-0) f1-0) (* (* f2-0 f10-0) f4-0)) + (* (* f5-0 f3-0) f7-0) + ) + (+ + (+ (* (* f9-0 f10-0) f7-0) (* (* f5-0 f6-0) f4-0)) + (* (* f2-0 f3-0) f1-0) ) ) + f0-0 ) + ) ) - arg0 + (let ((f9-2 (-> src data 4)) + (f2-2 (-> src data 6)) + (f5-2 (-> src data 7)) + (f3-1 (-> src data 8)) + (f6-1 (-> src data 10)) + (f10-1 (-> src data 11)) + (f4-3 (-> src data 12)) + (f7-2 (-> src data 14)) + (f1-6 (-> src data 15)) + ) + (set! + (-> dst data 1) + (- + (/ + (- + (+ + (+ (* (* f9-2 f6-1) f1-6) (* (* f2-2 f10-1) f4-3)) + (* (* f5-2 f3-1) f7-2) + ) + (+ + (+ (* (* f9-2 f10-1) f7-2) (* (* f5-2 f6-1) f4-3)) + (* (* f2-2 f3-1) f1-6) + ) + ) + f0-0 + ) + ) + ) + ) + (let ((f9-4 (-> src data 4)) + (f2-4 (-> src data 5)) + (f5-4 (-> src data 7)) + (f3-2 (-> src data 8)) + (f6-2 (-> src data 9)) + (f10-2 (-> src data 11)) + (f4-6 (-> src data 12)) + (f7-4 (-> src data 13)) + (f1-13 (-> src data 15)) + ) + (set! + (-> dst data 2) + (/ + (- + (+ + (+ (* (* f9-4 f6-2) f1-13) (* (* f2-4 f10-2) f4-6)) + (* (* f5-4 f3-2) f7-4) + ) + (+ + (+ (* (* f9-4 f10-2) f7-4) (* (* f5-4 f6-2) f4-6)) + (* (* f2-4 f3-2) f1-13) + ) + ) + f0-0 + ) + ) + ) + (let ((f9-6 (-> src data 4)) + (f2-6 (-> src data 5)) + (f5-6 (-> src data 6)) + (f3-3 (-> src data 8)) + (f6-3 (-> src data 9)) + (f10-3 (-> src data 10)) + (f4-9 (-> src data 12)) + (f7-6 (-> src data 13)) + (f1-19 (-> src data 14)) + ) + (set! + (-> dst data 3) + (- + (/ + (- + (+ + (+ (* (* f9-6 f6-3) f1-19) (* (* f2-6 f10-3) f4-9)) + (* (* f5-6 f3-3) f7-6) + ) + (+ + (+ (* (* f9-6 f10-3) f7-6) (* (* f5-6 f6-3) f4-9)) + (* (* f2-6 f3-3) f1-19) + ) + ) + f0-0 + ) + ) + ) + ) + (let ((f9-8 (-> src data 1)) + (f2-8 (-> src data 2)) + (f5-8 (-> src data 3)) + (f3-4 (-> src data 9)) + (f6-4 (-> src data 10)) + (f10-4 (-> src data 11)) + (f4-12 (-> src data 13)) + (f7-8 (-> src data 14)) + (f1-26 (-> src data 15)) + ) + (set! + (-> dst data 4) + (- + (/ + (- + (+ + (+ (* (* f9-8 f6-4) f1-26) (* (* f2-8 f10-4) f4-12)) + (* (* f5-8 f3-4) f7-8) + ) + (+ + (+ (* (* f9-8 f10-4) f7-8) (* (* f5-8 f6-4) f4-12)) + (* (* f2-8 f3-4) f1-26) + ) + ) + f0-0 + ) + ) + ) + ) + (let ((f9-10 (-> src data 0)) + (f2-10 (-> src data 2)) + (f5-10 (-> src data 3)) + (f3-5 (-> src data 8)) + (f6-5 (-> src data 10)) + (f10-5 (-> src data 11)) + (f4-15 (-> src data 12)) + (f7-10 (-> src data 14)) + (f1-33 (-> src data 15)) + ) + (set! + (-> dst data 5) + (/ + (- + (+ + (+ (* (* f9-10 f6-5) f1-33) (* (* f2-10 f10-5) f4-15)) + (* (* f5-10 f3-5) f7-10) + ) + (+ + (+ (* (* f9-10 f10-5) f7-10) (* (* f5-10 f6-5) f4-15)) + (* (* f2-10 f3-5) f1-33) + ) + ) + f0-0 + ) + ) + ) + (let ((f9-12 (-> src data 0)) + (f2-12 (-> src data 1)) + (f5-12 (-> src data 3)) + (f3-6 (-> src data 8)) + (f6-6 (-> src data 9)) + (f10-6 (-> src data 11)) + (f4-18 (-> src data 12)) + (f7-12 (-> src data 13)) + (f1-39 (-> src data 15)) + ) + (set! + (-> dst data 6) + (- + (/ + (- + (+ + (+ (* (* f9-12 f6-6) f1-39) (* (* f2-12 f10-6) f4-18)) + (* (* f5-12 f3-6) f7-12) + ) + (+ + (+ (* (* f9-12 f10-6) f7-12) (* (* f5-12 f6-6) f4-18)) + (* (* f2-12 f3-6) f1-39) + ) + ) + f0-0 + ) + ) + ) + ) + (let ((f9-14 (-> src data 0)) + (f2-14 (-> src data 1)) + (f5-14 (-> src data 2)) + (f3-7 (-> src data 8)) + (f6-7 (-> src data 9)) + (f10-7 (-> src data 10)) + (f4-21 (-> src data 12)) + (f7-14 (-> src data 13)) + (f1-46 (-> src data 14)) + ) + (set! + (-> dst data 7) + (/ + (- + (+ + (+ (* (* f9-14 f6-7) f1-46) (* (* f2-14 f10-7) f4-21)) + (* (* f5-14 f3-7) f7-14) + ) + (+ + (+ (* (* f9-14 f10-7) f7-14) (* (* f5-14 f6-7) f4-21)) + (* (* f2-14 f3-7) f1-46) + ) + ) + f0-0 + ) + ) + ) + (let ((f9-16 (-> src data 1)) + (f2-16 (-> src data 2)) + (f5-16 (-> src data 3)) + (f3-8 (-> src data 5)) + (f6-8 (-> src data 6)) + (f10-8 (-> src data 7)) + (f4-24 (-> src data 13)) + (f7-16 (-> src data 14)) + (f1-52 (-> src data 15)) + ) + (set! + (-> dst data 8) + (/ + (- + (+ + (+ (* (* f9-16 f6-8) f1-52) (* (* f2-16 f10-8) f4-24)) + (* (* f5-16 f3-8) f7-16) + ) + (+ + (+ (* (* f9-16 f10-8) f7-16) (* (* f5-16 f6-8) f4-24)) + (* (* f2-16 f3-8) f1-52) + ) + ) + f0-0 + ) + ) + ) + (let ((f9-18 (-> src data 0)) + (f2-18 (-> src data 2)) + (f5-18 (-> src data 3)) + (f3-9 (-> src data 4)) + (f6-9 (-> src data 6)) + (f10-9 (-> src data 7)) + (f4-27 (-> src data 12)) + (f7-18 (-> src data 14)) + (f1-58 (-> src data 15)) + ) + (set! + (-> dst data 9) + (- + (/ + (- + (+ + (+ (* (* f9-18 f6-9) f1-58) (* (* f2-18 f10-9) f4-27)) + (* (* f5-18 f3-9) f7-18) + ) + (+ + (+ (* (* f9-18 f10-9) f7-18) (* (* f5-18 f6-9) f4-27)) + (* (* f2-18 f3-9) f1-58) + ) + ) + f0-0 + ) + ) + ) + ) + (let ((f9-20 (-> src data 0)) + (f2-20 (-> src data 1)) + (f5-20 (-> src data 3)) + (f3-10 (-> src data 4)) + (f6-10 (-> src data 5)) + (f10-10 (-> src data 7)) + (f4-30 (-> src data 12)) + (f7-20 (-> src data 13)) + (f1-65 (-> src data 15)) + ) + (set! + (-> dst data 10) + (/ + (- + (+ + (+ (* (* f9-20 f6-10) f1-65) (* (* f2-20 f10-10) f4-30)) + (* (* f5-20 f3-10) f7-20) + ) + (+ + (+ (* (* f9-20 f10-10) f7-20) (* (* f5-20 f6-10) f4-30)) + (* (* f2-20 f3-10) f1-65) + ) + ) + f0-0 + ) + ) + ) + (let ((f9-22 (-> src data 0)) + (f2-22 (-> src data 1)) + (f5-22 (-> src data 2)) + (f3-11 (-> src data 4)) + (f6-11 (-> src data 5)) + (f10-11 (-> src data 6)) + (f4-33 (-> src data 12)) + (f7-22 (-> src data 13)) + (f1-71 (-> src data 14)) + ) + (set! + (-> dst data 11) + (- + (/ + (- + (+ + (+ (* (* f9-22 f6-11) f1-71) (* (* f2-22 f10-11) f4-33)) + (* (* f5-22 f3-11) f7-22) + ) + (+ + (+ (* (* f9-22 f10-11) f7-22) (* (* f5-22 f6-11) f4-33)) + (* (* f2-22 f3-11) f1-71) + ) + ) + f0-0 + ) + ) + ) + ) + (let ((f9-24 (-> src data 1)) + (f2-24 (-> src data 2)) + (f5-24 (-> src data 3)) + (f3-12 (-> src data 5)) + (f6-12 (-> src data 6)) + (f10-12 (-> src data 7)) + (f4-36 (-> src data 9)) + (f7-24 (-> src data 10)) + (f1-78 (-> src data 11)) + ) + (set! + (-> dst data 12) + (- + (/ + (- + (+ + (+ (* (* f9-24 f6-12) f1-78) (* (* f2-24 f10-12) f4-36)) + (* (* f5-24 f3-12) f7-24) + ) + (+ + (+ (* (* f9-24 f10-12) f7-24) (* (* f5-24 f6-12) f4-36)) + (* (* f2-24 f3-12) f1-78) + ) + ) + f0-0 + ) + ) + ) + ) + (let ((f9-26 (-> src data 0)) + (f2-26 (-> src data 2)) + (f5-26 (-> src data 3)) + (f3-13 (-> src data 4)) + (f6-13 (-> src data 6)) + (f10-13 (-> src data 7)) + (f4-39 (-> src data 8)) + (f7-26 (-> src data 10)) + (f1-85 (-> src data 11)) + ) + (set! + (-> dst data 13) + (/ + (- + (+ + (+ (* (* f9-26 f6-13) f1-85) (* (* f2-26 f10-13) f4-39)) + (* (* f5-26 f3-13) f7-26) + ) + (+ + (+ (* (* f9-26 f10-13) f7-26) (* (* f5-26 f6-13) f4-39)) + (* (* f2-26 f3-13) f1-85) + ) + ) + f0-0 + ) + ) + ) + (let ((f9-28 (-> src data 0)) + (f2-28 (-> src data 1)) + (f5-28 (-> src data 3)) + (f3-14 (-> src data 4)) + (f6-14 (-> src data 5)) + (f10-14 (-> src data 7)) + (f4-42 (-> src data 8)) + (f7-28 (-> src data 9)) + (f1-91 (-> src data 11)) + ) + (set! + (-> dst data 14) + (- + (/ + (- + (+ + (+ (* (* f9-28 f6-14) f1-91) (* (* f2-28 f10-14) f4-42)) + (* (* f5-28 f3-14) f7-28) + ) + (+ + (+ (* (* f9-28 f10-14) f7-28) (* (* f5-28 f6-14) f4-42)) + (* (* f2-28 f3-14) f1-91) + ) + ) + f0-0 + ) + ) + ) + ) + (let ((f8-60 (-> src data 0)) + (f1-98 (-> src data 1)) + (f5-30 (-> src data 2)) + (f2-30 (-> src data 4)) + (f6-15 (-> src data 5)) + (f9-30 (-> src data 6)) + (f4-45 (-> src data 8)) + (f7-30 (-> src data 9)) + (f3-15 (-> src data 10)) + ) + (set! + (-> dst data 15) + (/ + (- + (+ + (+ (* (* f8-60 f6-15) f3-15) (* (* f1-98 f9-30) f4-45)) + (* (* f5-30 f2-30) f7-30) + ) + (+ + (+ (* (* f8-60 f9-30) f7-30) (* (* f5-30 f6-15) f4-45)) + (* (* f1-98 f2-30) f3-15) + ) + ) + f0-0 + ) + ) + ) + ) + dst ) -(defun matrix-y-angle ((arg0 matrix)) - (let ((v1-0 (&-> arg0 data 8))) - (atan (-> v1-0 0) (-> v1-0 2)) - ) +(defun matrix-y-angle ((mat matrix)) + "If mat has its upper 3x3 as a rotation, gets the y axis rotation." + (let ((z-row (&-> mat data 8))) + (atan (-> z-row 0) (-> z-row 2)) + ) ) -;; todo (method 9 matrix) + +(defmethod transform-vectors! matrix ((obj _type_) (dst (inline-array vector)) (src (inline-array vector)) (count int)) + "Transform many vectors. This acts like w = 1, even if it isn't. The value of w is copied." + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + (vf5 :class vf) + (vf6 :class vf) + (vf7 :class vf) + (vf8 :class vf) + (acc :class vf) + (v1 :type int) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + + ;; blez a3, L3 + (when-goto (<= count 0) end) + + ;; lqc2 vf1, 0(a0) + (.lvf vf1 (-> obj vector 0)) + + ;; lqc2 vf2, 16(a0) + (.lvf vf2 (-> obj vector 1)) + + ;; lqc2 vf3, 32(a0) + (.lvf vf3 (-> obj vector 2)) + + ;; lqc2 vf4, 48(a0) + (.lvf vf4 (-> obj vector 3)) + + ;; lqc2 vf5, 0(a2) + (.lvf vf5 (-> src 0)) + + ;; lqc2 vf6, 16(a2) + (.lvf vf6 (-> src 1)) + + (label loop-top) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;;vmulaw.xyzw acc, vf4, vf0 + (.mul.w.vf acc vf4 vf0) + + ;; lqc2 vf7, 32(a2) + (.lvf vf7 (-> src 2)) + + ;;vmaddax.xyzw acc, vf1, vf5 + (.add.mul.x.vf acc vf1 vf5 acc) + + ;;lqc2 vf8, 48(a2) + (.lvf vf8 (-> src 3)) + + ;;vmadday.xyzw acc, vf2, vf5 + (.add.mul.y.vf acc vf2 vf5 acc) + + ;;daddiu a2, a2, 64 + ;;(&+! src 64) + (set! src (the (inline-array vector) (+ 64 (the int src)))) + + ;;vmaddz.xyz vf5, vf3, vf5 + (.add.mul.z.vf vf5 vf3 vf5 acc :mask #b0111) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + ;;daddiu v1, a3, -1 + (set! v1 (- count 1)) + + ;;vmulaw.xyzw acc, vf4, vf0 + (.mul.w.vf acc vf4 vf0) + + ;;vmaddax.xyzw acc, vf1, vf6 + (.add.mul.x.vf acc vf1 vf6 acc) + + ;; vmadday.xyzw acc, vf2, vf6 + (.add.mul.y.vf acc vf2 vf6 acc) + + ;; vmaddz.xyz vf6, vf3, vf6 + (.add.mul.z.vf vf6 vf3 vf6 acc :mask #b0111) + + ;;sqc2 vf5, 0(a1) + (.svf (-> dst 0) vf5) + + ;;beq v1, r0, L3 + ;;vmulaw.xyzw acc, vf4, vf0 + (.mul.w.vf acc vf4 vf0) + (when-goto (zero? v1) end) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + ;;vmaddax.xyzw acc, vf1, vf7 + (.add.mul.x.vf acc vf1 vf7 acc) + ;;daddiu v1, v1, -1 + (+! v1 -1) + ;;vmadday.xyzw acc, vf2, vf7 + (.add.mul.y.vf acc vf2 vf7 acc) + ;;lqc2 vf5, 0(a2) + (.lvf vf5 (-> src 0)) + ;;vmaddz.xyz vf7, vf3, vf7 + (.add.mul.z.vf vf7 vf3 vf7 acc :mask #b0111) + ;;sqc2 vf6, 16(a1) + (.svf (-> dst 1) vf6) + + ;;beq v1, r0, L3 + ;;vmulaw.xyzw acc, vf4, vf0 + (.mul.w.vf acc vf4 vf0) + (when-goto (zero? v1) end) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;;vmaddax.xyzw acc, vf1, vf8 + (.add.mul.x.vf acc vf1 vf8 acc) + ;;daddiu v1, v1, -1 + (+! v1 -1) + ;;vmadday.xyzw acc, vf2, vf8 + (.add.mul.y.vf acc vf2 vf8 acc) + ;;lqc2 vf6, 16(a2) + (.lvf vf6 (-> src 1)) + ;;vmaddz.xyz vf8, vf3, vf8 + (.add.mul.z.vf vf8 vf3 vf8 acc :mask #b0111) + ;;sqc2 vf7, 32(a1) + (.svf (-> dst 2) vf7) + + ;;beq v1, r0, L3 + ;;daddiu a1, a1, 64 + ;;(&!+ dst 64) + (set! dst (the (inline-array vector) (+ 64 (the int dst)))) + (when-goto (zero? v1) end) + + ;;daddiu a3, v1, -1 + (set! count (- v1 1)) + ;;sqc2 vf8, -16(a1) + (.svf dst vf8 :offset -16) + (when-goto (not (zero? count)) loop-top) + (label end) + (none) + ) + ) diff --git a/goalc/compiler/CodeGenerator.cpp b/goalc/compiler/CodeGenerator.cpp index 78e2e71204..6cd4f6341a 100644 --- a/goalc/compiler/CodeGenerator.cpp +++ b/goalc/compiler/CodeGenerator.cpp @@ -175,6 +175,11 @@ void CodeGenerator::do_goal_function(FunctionEnv* env, int f_idx) { m_gen.add_instr(IGen::load_reg_offset_xmm32( op.reg, RSP, allocs.get_slot_for_spill(op.slot) * GPR_SIZE), i_rec); + } else if (op.reg.is_xmm() && + (op.reg_class == RegClass::VECTOR_FLOAT || op.reg_class == RegClass::INT_128)) { + m_gen.add_instr(IGen::load128_xmm128_reg_offset( + op.reg, RSP, allocs.get_slot_for_spill(op.slot) * GPR_SIZE), + i_rec); } else { assert(false); } @@ -197,6 +202,11 @@ void CodeGenerator::do_goal_function(FunctionEnv* env, int f_idx) { m_gen.add_instr(IGen::store_reg_offset_xmm32( RSP, op.reg, allocs.get_slot_for_spill(op.slot) * GPR_SIZE), i_rec); + } else if (op.reg.is_xmm() && + (op.reg_class == RegClass::VECTOR_FLOAT || op.reg_class == RegClass::INT_128)) { + m_gen.add_instr(IGen::store128_xmm128_reg_offset( + RSP, op.reg, allocs.get_slot_for_spill(op.slot) * GPR_SIZE), + i_rec); } else { assert(false); } diff --git a/goalc/compiler/Compiler.h b/goalc/compiler/Compiler.h index 124e7d3750..293d8dea62 100644 --- a/goalc/compiler/Compiler.h +++ b/goalc/compiler/Compiler.h @@ -87,6 +87,11 @@ class Compiler { emitter::Register::VF_ELEMENT broadcastElement, Env* env); + Val* compile_asm_int128_math3(const goos::Object& form, + const goos::Object& rest, + IR_Int128Math3Asm::Kind kind, + Env* env); + Val* compile_asm_vf_math2(const goos::Object& form, const goos::Object& rest, IR_VFMath2Asm::Kind kind, @@ -420,6 +425,13 @@ class Compiler { Val* compile_asm_pw_sll(const goos::Object& form, const goos::Object& rest, Env* env); Val* compile_asm_pw_srl(const goos::Object& form, const goos::Object& rest, Env* env); Val* compile_asm_pw_sra(const goos::Object& form, const goos::Object& rest, Env* env); + Val* compile_asm_pextlw(const goos::Object& form, const goos::Object& rest, Env* env); + Val* compile_asm_pextuw(const goos::Object& form, const goos::Object& rest, Env* env); + Val* compile_asm_pcpyud(const goos::Object& form, const goos::Object& rest, Env* env); + Val* compile_asm_pcpyld(const goos::Object& form, const goos::Object& rest, Env* env); + Val* compile_asm_pceqw(const goos::Object& form, const goos::Object& rest, Env* env); + Val* compile_asm_ppach(const goos::Object& form, const goos::Object& rest, Env* env); + Val* compile_asm_xorp(const goos::Object& form, const goos::Object& rest, Env* env); // Atoms diff --git a/goalc/compiler/IR.cpp b/goalc/compiler/IR.cpp index 3443b1ff2d..02a740fb3e 100644 --- a/goalc/compiler/IR.cpp +++ b/goalc/compiler/IR.cpp @@ -118,9 +118,9 @@ void regset_common(emitter::ObjectGenerator* gen, } else if (src_class == RegClass::FLOAT && dst_is_xmm128) { gen->add_instr(IGen::mov_xmm32_xmm32(dst_reg, src_reg), irec); } else if (src_class == RegClass::GPR_64 && dst_is_xmm128) { - gen->add_instr(IGen::movd_xmm32_gpr32(dst_reg, src_reg), irec); + gen->add_instr(IGen::movq_xmm64_gpr64(dst_reg, src_reg), irec); } else if (src_is_xmm128 && dst_class == RegClass::GPR_64) { - gen->add_instr(IGen::movd_gpr32_xmm32(dst_reg, src_reg), irec); + gen->add_instr(IGen::movq_gpr64_xmm64(dst_reg, src_reg), irec); } else { assert(false); // unhandled move. } @@ -1442,6 +1442,83 @@ void IR_VFMath3Asm::do_codegen(emitter::ObjectGenerator* gen, } } +/////////////////////// +// IR_Int128Math3Asm +/////////////////////// + +IR_Int128Math3Asm::IR_Int128Math3Asm(bool use_color, + const RegVal* dst, + const RegVal* src1, + const RegVal* src2, + Kind kind) + : IR_Asm(use_color), m_dst(dst), m_src1(src1), m_src2(src2), m_kind(kind) {} + +std::string IR_Int128Math3Asm::print() { + std::string function = ""; + switch (m_kind) { + case Kind::PEXTLW: + function = ".pextlw"; + break; + case Kind::PEXTUW: + function = ".pextuw"; + break; + case Kind::PCPYLD: + function = ".pcpyld"; + break; + case Kind::PCPYUD: + function = ".pcpyud"; + break; + case Kind::PCEQW: + function = ".pceqw"; + break; + default: + assert(false); + } + return fmt::format("{}{} {}, {}, {}", function, get_color_suffix_string(), m_dst->print(), + m_src1->print(), m_src2->print()); +} + +RegAllocInstr IR_Int128Math3Asm::to_rai() { + RegAllocInstr rai; + if (m_use_coloring) { + rai.write.push_back(m_dst->ireg()); + rai.read.push_back(m_src1->ireg()); + rai.read.push_back(m_src2->ireg()); + } + return rai; +} + +void IR_Int128Math3Asm::do_codegen(emitter::ObjectGenerator* gen, + const AllocationResult& allocs, + emitter::IR_Record irec) { + auto dst = get_reg_asm(m_dst, allocs, irec, m_use_coloring); + auto src1 = get_reg_asm(m_src1, allocs, irec, m_use_coloring); + auto src2 = get_reg_asm(m_src2, allocs, irec, m_use_coloring); + + switch (m_kind) { + case Kind::PEXTLW: + // NOTE: this is intentionally swapped because x86 and PS2 do this opposite ways. + gen->add_instr(IGen::pextlw_swapped(dst, src2, src1), irec); + break; + case Kind::PEXTUW: + // NOTE: this is intentionally swapped because x86 and PS2 do this opposite ways. + gen->add_instr(IGen::pextuw_swapped(dst, src2, src1), irec); + break; + case Kind::PCPYLD: + // NOTE: this is intentionally swapped because x86 and PS2 do this opposite ways. + gen->add_instr(IGen::pcpyld_swapped(dst, src2, src1), irec); + break; + case Kind::PCPYUD: + gen->add_instr(IGen::pcpyud(dst, src1, src2), irec); + break; + case Kind::PCEQW: + gen->add_instr(IGen::pceqw(dst, src1, src2), irec); + break; + default: + assert(false); + } +} + /////////////////////// // AsmVF2 /////////////////////// @@ -1475,6 +1552,22 @@ std::string IR_VFMath2Asm::print() { use_imm = true; function = ".pw.sra"; break; + case Kind::VPSRLDQ: + use_imm = true; + function = ".VPSRLDQ"; + break; + case Kind::VPSLLDQ: + use_imm = true; + function = ".VPSLLDQ"; + break; + case Kind::VPSHUFLW: + use_imm = true; + function = ".VPSHUFLW"; + break; + case Kind::VPSHUFHW: + use_imm = true; + function = ".VPSHUFHW"; + break; default: assert(false); } @@ -1530,6 +1623,30 @@ void IR_VFMath2Asm::do_codegen(emitter::ObjectGenerator* gen, assert(*m_imm <= 255); gen->add_instr(IGen::pw_sra(dst, src, *m_imm), irec); break; + case Kind::VPSRLDQ: + assert(m_imm.has_value()); + assert(*m_imm >= 0); + assert(*m_imm <= 255); + gen->add_instr(IGen::vpsrldq(dst, src, *m_imm), irec); + break; + case Kind::VPSLLDQ: + assert(m_imm.has_value()); + assert(*m_imm >= 0); + assert(*m_imm <= 255); + gen->add_instr(IGen::vpslldq(dst, src, *m_imm), irec); + break; + case Kind::VPSHUFLW: + assert(m_imm.has_value()); + assert(*m_imm >= 0); + assert(*m_imm <= 255); + gen->add_instr(IGen::vpshuflw(dst, src, *m_imm), irec); + break; + case Kind::VPSHUFHW: + assert(m_imm.has_value()); + assert(*m_imm >= 0); + assert(*m_imm <= 255); + gen->add_instr(IGen::vpshufhw(dst, src, *m_imm), irec); + break; default: assert(false); } diff --git a/goalc/compiler/IR.h b/goalc/compiler/IR.h index ba35e10083..8b0e986030 100644 --- a/goalc/compiler/IR.h +++ b/goalc/compiler/IR.h @@ -546,9 +546,30 @@ class IR_VFMath3Asm : public IR_Asm { Kind m_kind; }; +class IR_Int128Math3Asm : public IR_Asm { + public: + enum class Kind { PEXTLW, PEXTUW, PCPYUD, PCPYLD, PCEQW }; + IR_Int128Math3Asm(bool use_color, + const RegVal* dst, + const RegVal* src1, + const RegVal* src2, + Kind kind); + std::string print() override; + RegAllocInstr to_rai() override; + void do_codegen(emitter::ObjectGenerator* gen, + const AllocationResult& allocs, + emitter::IR_Record irec) override; + + protected: + const RegVal* m_dst = nullptr; + const RegVal* m_src1 = nullptr; + const RegVal* m_src2 = nullptr; + Kind m_kind; +}; + class IR_VFMath2Asm : public IR_Asm { public: - enum class Kind { ITOF, FTOI, PW_SLL, PW_SRL, PW_SRA }; + enum class Kind { ITOF, FTOI, PW_SLL, PW_SRL, PW_SRA, VPSRLDQ, VPSLLDQ, VPSHUFLW, VPSHUFHW }; IR_VFMath2Asm(bool use_color, const RegVal* dst, const RegVal* src, diff --git a/goalc/compiler/compilation/Asm.cpp b/goalc/compiler/compilation/Asm.cpp index a147512636..432bdd59c6 100644 --- a/goalc/compiler/compilation/Asm.cpp +++ b/goalc/compiler/compilation/Asm.cpp @@ -484,6 +484,28 @@ Val* Compiler::compile_asm_vf_math3(const goos::Object& form, return get_none(); } +Val* Compiler::compile_asm_int128_math3(const goos::Object& form, + const goos::Object& rest, + IR_Int128Math3Asm::Kind kind, + Env* env) { + auto args = get_va(form, rest); + va_check(form, args, {{}, {}, {}}, {{"color", {false, goos::ObjectType::SYMBOL}}}); + bool color = true; + if (args.has_named("color")) { + color = get_true_or_false(form, args.named.at("color")); + } + + auto dest = compile_error_guard(args.unnamed.at(0), env)->to_reg(env); + auto src1 = compile_error_guard(args.unnamed.at(1), env)->to_reg(env); + auto src2 = compile_error_guard(args.unnamed.at(2), env)->to_reg(env); + + if (!dest->settable()) { + throw_compiler_error(form, "Cannot set destination"); + } + env->emit_ir(color, dest, src1, src2, kind); + return get_none(); +} + Val* Compiler::compile_asm_vf_math2(const goos::Object& form, const goos::Object& rest, IR_VFMath2Asm::Kind kind, @@ -586,6 +608,67 @@ Val* Compiler::compile_asm_pw_sra(const goos::Object& form, const goos::Object& return compile_asm_vf_math2_imm_u8(form, rest, IR_VFMath2Asm::Kind::PW_SRA, env); } +Val* Compiler::compile_asm_pextlw(const goos::Object& form, const goos::Object& rest, Env* env) { + return compile_asm_int128_math3(form, rest, IR_Int128Math3Asm::Kind::PEXTLW, env); +} + +Val* Compiler::compile_asm_pextuw(const goos::Object& form, const goos::Object& rest, Env* env) { + return compile_asm_int128_math3(form, rest, IR_Int128Math3Asm::Kind::PEXTUW, env); +} + +Val* Compiler::compile_asm_pcpyud(const goos::Object& form, const goos::Object& rest, Env* env) { + return compile_asm_int128_math3(form, rest, IR_Int128Math3Asm::Kind::PCPYUD, env); +} + +Val* Compiler::compile_asm_pcpyld(const goos::Object& form, const goos::Object& rest, Env* env) { + return compile_asm_int128_math3(form, rest, IR_Int128Math3Asm::Kind::PCPYLD, env); +} + +Val* Compiler::compile_asm_pceqw(const goos::Object& form, const goos::Object& rest, Env* env) { + return compile_asm_int128_math3(form, rest, IR_Int128Math3Asm::Kind::PCEQW, env); +} + +Val* Compiler::compile_asm_ppach(const goos::Object& form, const goos::Object& rest, Env* env) { + auto args = get_va(form, rest); + va_check(form, args, {{}, {}, {}}, {}); + + auto dest = compile_error_guard(args.unnamed.at(0), env)->to_reg(env); + auto src1 = compile_error_guard(args.unnamed.at(1), env)->to_reg(env); // rs + auto src2 = compile_error_guard(args.unnamed.at(2), env)->to_reg(env); // rt + auto temp = env->make_ireg(TypeSpec("uint128"), RegClass::INT_128); + + if (!dest->settable()) { + throw_compiler_error(form, "Cannot set destination"); + } + + env->emit_ir(true, temp, src1, IR_VFMath2Asm::Kind::VPSHUFLW, 0x88); + env->emit_ir(true, dest, src2, IR_VFMath2Asm::Kind::VPSHUFLW, 0x88); + env->emit_ir(true, temp, temp, IR_VFMath2Asm::Kind::VPSHUFHW, 0x88); + env->emit_ir(true, dest, dest, IR_VFMath2Asm::Kind::VPSHUFHW, 0x88); + env->emit_ir(true, temp, temp, IR_VFMath2Asm::Kind::VPSRLDQ, 4); + env->emit_ir(true, dest, dest, IR_VFMath2Asm::Kind::VPSRLDQ, 4); + // is actually a VPUNPCKLQDQ with srcs swapped. + env->emit_ir(true, dest, temp, dest, IR_Int128Math3Asm::Kind::PCPYLD); + + return get_none(); +} + +Val* Compiler::compile_asm_xorp(const goos::Object& form, const goos::Object& rest, Env* env) { + auto args = get_va(form, rest); + va_check(form, args, {{}, {}, {}}, {}); + + auto dest = compile_error_guard(args.unnamed.at(0), env)->to_reg(env); + auto src1 = compile_error_guard(args.unnamed.at(1), env)->to_reg(env); // rs + auto src2 = compile_error_guard(args.unnamed.at(2), env)->to_reg(env); // rt + + if (!dest->settable()) { + throw_compiler_error(form, "Cannot set destination"); + } + + env->emit_ir(true, dest, src1, src2, IR_VFMath3Asm::Kind::XOR); + return get_none(); +} + Val* Compiler::compile_asm_itof_vf(const goos::Object& form, const goos::Object& rest, Env* env) { return compile_asm_vf_math2(form, rest, IR_VFMath2Asm::Kind::ITOF, env); } diff --git a/goalc/compiler/compilation/Atoms.cpp b/goalc/compiler/compilation/Atoms.cpp index c11bae48ce..f51b6fb83f 100644 --- a/goalc/compiler/compilation/Atoms.cpp +++ b/goalc/compiler/compilation/Atoms.cpp @@ -35,6 +35,7 @@ const std::unordered_map< {".wait.vf", &Compiler::compile_asm_wait_vf}, {".xor.vf", &Compiler::compile_asm_xor_vf}, + {".xor.p", &Compiler::compile_asm_xorp}, {".max.vf", &Compiler::compile_asm_max_vf}, {".max.x.vf", &Compiler::compile_asm_max_x_vf}, @@ -95,6 +96,12 @@ const std::unordered_map< {".pw.sll", &Compiler::compile_asm_pw_sll}, {".pw.srl", &Compiler::compile_asm_pw_srl}, {".pw.sra", &Compiler::compile_asm_pw_sra}, + {".pextlw", &Compiler::compile_asm_pextlw}, + {".pextuw", &Compiler::compile_asm_pextuw}, + {".pcpyld", &Compiler::compile_asm_pcpyld}, + {".pcpyud", &Compiler::compile_asm_pcpyud}, + {".pceqw", &Compiler::compile_asm_pceqw}, + {".ppach", &Compiler::compile_asm_ppach}, // BLOCK FORMS {"top-level", &Compiler::compile_top_level}, diff --git a/goalc/compiler/compilation/Function.cpp b/goalc/compiler/compilation/Function.cpp index c2db4c8ea4..cd5bea4291 100644 --- a/goalc/compiler/compilation/Function.cpp +++ b/goalc/compiler/compilation/Function.cpp @@ -87,10 +87,14 @@ Val* Compiler::compile_local_vars(const goos::Object& form, const goos::Object& throw_compiler_error(form, "Cannot declare a local named {}, this already exists.", name); } - if (type == TypeSpec("float")) { + if (m_ts.tc(TypeSpec("float"), type)) { auto ireg = fe->make_ireg(type, RegClass::FLOAT); ireg->mark_as_settable(); fe->params[name] = ireg; + } else if (m_ts.tc(TypeSpec("int128"), type) || m_ts.tc(TypeSpec("uint128"), type)) { + auto ireg = fe->make_ireg(type, RegClass::INT_128); + ireg->mark_as_settable(); + fe->params[name] = ireg; } else { auto ireg = fe->make_ireg(type, RegClass::GPR_64); ireg->mark_as_settable(); diff --git a/goalc/emitter/IGen.h b/goalc/emitter/IGen.h index fb63cda3d7..1bf67281ba 100644 --- a/goalc/emitter/IGen.h +++ b/goalc/emitter/IGen.h @@ -105,6 +105,34 @@ class IGen { return instr; } + /*! + * Move 64-bits of xmm to 64 bits of gpr (no sign extension). + */ + static Instruction movq_gpr64_xmm64(Register dst, Register src) { + assert(dst.is_gpr()); + assert(src.is_xmm()); + Instruction instr(0x66); + instr.set_op2(0x0f); + instr.set_op3(0x7e); + instr.set_modrm_and_rex(src.hw_id(), dst.hw_id(), 3, true); + instr.swap_op0_rex(); + return instr; + } + + /*! + * Move 64-bits of gpr to 64-bits of xmm (no sign extension) + */ + static Instruction movq_xmm64_gpr64(Register dst, Register src) { + assert(dst.is_xmm()); + assert(src.is_gpr()); + Instruction instr(0x66); + instr.set_op2(0x0f); + instr.set_op3(0x6e); + instr.set_modrm_and_rex(dst.hw_id(), src.hw_id(), 3, true); + instr.swap_op0_rex(); + return instr; + } + /*! * Move 32-bits between xmm's */ @@ -2401,6 +2429,114 @@ class IGen { instr.set(Imm(1, imm)); return instr; } + + static Instruction pextlw_swapped(Register dst, Register src0, Register src1) { + assert(dst.is_xmm()); + assert(src0.is_xmm()); + assert(src1.is_xmm()); + // VEX.128.66.0F.WIG 62/r VPUNPCKLDQ xmm1, xmm2, xmm3/m128 + // reg, vex, r/m + Instruction instr(0x62); + instr.set_vex_modrm_and_rex(dst.hw_id(), src1.hw_id(), VEX3::LeadingBytes::P_0F, src0.hw_id(), + false, VexPrefix::P_66); + return instr; + } + + static Instruction pextuw_swapped(Register dst, Register src0, Register src1) { + assert(dst.is_xmm()); + assert(src0.is_xmm()); + assert(src1.is_xmm()); + // VEX.128.66.0F.WIG 6A/r VPUNPCKHDQ xmm1, xmm2, xmm3/m128 + // reg, vex, r/m + Instruction instr(0x6a); + instr.set_vex_modrm_and_rex(dst.hw_id(), src1.hw_id(), VEX3::LeadingBytes::P_0F, src0.hw_id(), + false, VexPrefix::P_66); + return instr; + } + + static Instruction vpunpcklqdq(Register dst, Register src0, Register src1) { + assert(dst.is_xmm()); + assert(src0.is_xmm()); + assert(src1.is_xmm()); + // VEX.128.66.0F.WIG 6C/r VPUNPCKLQDQ xmm1, xmm2, xmm3/m128 + // reg, vex, r/m + Instruction instr(0x6c); + instr.set_vex_modrm_and_rex(dst.hw_id(), src1.hw_id(), VEX3::LeadingBytes::P_0F, src0.hw_id(), + false, VexPrefix::P_66); + return instr; + } + + static Instruction pcpyld_swapped(Register dst, Register src0, Register src1) { + return vpunpcklqdq(dst, src0, src1); + } + + static Instruction pcpyud(Register dst, Register src0, Register src1) { + assert(dst.is_xmm()); + assert(src0.is_xmm()); + assert(src1.is_xmm()); + // VEX.128.66.0F.WIG 6D/r VPUNPCKHQDQ xmm1, xmm2, xmm3/m128 + // reg, vex, r/m + Instruction instr(0x6d); + instr.set_vex_modrm_and_rex(dst.hw_id(), src1.hw_id(), VEX3::LeadingBytes::P_0F, src0.hw_id(), + false, VexPrefix::P_66); + return instr; + } + + static Instruction pceqw(Register dst, Register src0, Register src1) { + assert(dst.is_xmm()); + assert(src0.is_xmm()); + assert(src1.is_xmm()); + // VEX.128.66.0F.WIG 76 /r VPCMPEQD xmm1, xmm2, xmm3/m128 + // reg, vex, r/m + Instruction instr(0x76); + instr.set_vex_modrm_and_rex(dst.hw_id(), src1.hw_id(), VEX3::LeadingBytes::P_0F, src0.hw_id(), + false, VexPrefix::P_66); + return instr; + } + + static Instruction vpsrldq(Register dst, Register src, u8 imm) { + assert(dst.is_xmm()); + assert(src.is_xmm()); + // VEX.128.66.0F.WIG 73 /3 ib VPSRLDQ xmm1, xmm2, imm8 + Instruction instr(0x73); + instr.set_vex_modrm_and_rex(3, src.hw_id(), VEX3::LeadingBytes::P_0F, dst.hw_id(), false, + VexPrefix::P_66); + instr.set(Imm(1, imm)); + return instr; + } + + static Instruction vpslldq(Register dst, Register src, u8 imm) { + assert(dst.is_xmm()); + assert(src.is_xmm()); + // VEX.128.66.0F.WIG 73 /7 ib VPSLLDQ xmm1, xmm2, imm8 + Instruction instr(0x73); + instr.set_vex_modrm_and_rex(7, src.hw_id(), VEX3::LeadingBytes::P_0F, dst.hw_id(), false, + VexPrefix::P_66); + instr.set(Imm(1, imm)); + return instr; + } + + static Instruction vpshuflw(Register dst, Register src, u8 imm) { + assert(dst.is_xmm()); + assert(src.is_xmm()); + // VEX.128.F2.0F.WIG 70 /r ib VPSHUFLW xmm1, xmm2/m128, imm8 + Instruction instr(0x70); + instr.set_vex_modrm_and_rex(dst.hw_id(), src.hw_id(), VEX3::LeadingBytes::P_0F, 0, false, + VexPrefix::P_F2); + instr.set(Imm(1, imm)); + return instr; + } + + static Instruction vpshufhw(Register dst, Register src, u8 imm) { + assert(dst.is_xmm()); + assert(src.is_xmm()); + // VEX.128.F3.0F.WIG 70 /r ib VPSHUFHW xmm1, xmm2/m128, imm8 + Instruction instr(0x70); + instr.set_vex_modrm_and_rex(dst.hw_id(), src.hw_id(), VEX3::LeadingBytes::P_0F, 0, false, + VexPrefix::P_F3); + instr.set(Imm(1, imm)); + return instr; + } }; } // namespace emitter diff --git a/goalc/emitter/Register.cpp b/goalc/emitter/Register.cpp index e6a6760d1e..0368cf6c54 100644 --- a/goalc/emitter/Register.cpp +++ b/goalc/emitter/Register.cpp @@ -54,8 +54,8 @@ RegisterInfo RegisterInfo::make_register_info() { // todo - experiment with better orders for allocation. info.m_gpr_alloc_order = {RAX, RCX, RDX, RBX, RBP, RSI, RDI, R8, R9, R10, R11}; // arbitrary - info.m_xmm_alloc_order = {XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, - XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14}; + info.m_xmm_alloc_order = {XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, + XMM7, XMM8, XMM9, XMM10, XMM11, XMM12, XMM13}; // these should only be temp registers! info.m_gpr_temp_only_alloc_order = {RAX, RCX, RDX, RSI, RDI, R8, R9}; diff --git a/goalc/regalloc/Allocator.cpp b/goalc/regalloc/Allocator.cpp index 6f622268a9..4ab6101cbd 100644 --- a/goalc/regalloc/Allocator.cpp +++ b/goalc/regalloc/Allocator.cpp @@ -605,9 +605,31 @@ bool try_assignment_for_var(int var, } int get_stack_slot_for_var(int var, RegAllocCache* cache) { + int slot_size; + auto& info = cache->iregs.at(var); + switch (info.reg_class) { + case RegClass::INT_128: + slot_size = 2; + break; + case RegClass::VECTOR_FLOAT: + slot_size = 2; + break; + case RegClass::FLOAT: + slot_size = 1; // todo - this wastes some space + break; + case RegClass::GPR_64: + slot_size = 1; + break; + default: + assert(false); + } auto kv = cache->var_to_stack_slot.find(var); if (kv == cache->var_to_stack_slot.end()) { - auto slot = cache->current_stack_slot++; + if (slot_size == 2 && (cache->current_stack_slot & 1)) { + cache->current_stack_slot++; + } + auto slot = cache->current_stack_slot; + cache->current_stack_slot += slot_size; cache->var_to_stack_slot[var] = slot; return slot; } else { diff --git a/test/decompiler/reference/gcommon_REF.gc b/test/decompiler/reference/gcommon_REF.gc index 7b7ccbd5e9..63cc696230 100644 --- a/test/decompiler/reference/gcommon_REF.gc +++ b/test/decompiler/reference/gcommon_REF.gc @@ -112,24 +112,22 @@ ) ;; definition for method 3 of type vec4s -;; INFO: Return type mismatch int vs vec4s. -;; WARN: Unsupported inline assembly instruction kind - [131] -;; WARN: Unsupported inline assembly instruction kind - [131] -;; WARN: Unsupported inline assembly instruction kind - [73] -;; WARN: Unsupported inline assembly instruction kind - [132] -;; WARN: Unsupported inline assembly instruction kind - [73] -;; WARN: Unsupported inline assembly instruction kind - [132] -;; WARN: Unsupported inline assembly instruction kind - [131] +;; INFO: Return type mismatch uint128 vs vec4s. +;; WARN: Unsupported inline assembly instruction kind - [por gp, a0, r0] +;; WARN: Unsupported inline assembly instruction kind - [por a2, gp, r0] +;; WARN: Unsupported inline assembly instruction kind - [sllv a2, gp, r0] +;; WARN: Unsupported inline assembly instruction kind - [sllv a2, v1, r0] +;; WARN: Unsupported inline assembly instruction kind - [por v0, gp, r0] (defmethod inspect vec4s ((obj vec4s)) (local-vars (r0-0 none) - (v0-5 int) - (v1-0 int) - (v1-1 int) - (a2-0 int) - (a2-1 int) - (a2-3 int) - (gp-0 int) + (v0-5 uint128) + (v1-0 uint128) + (v1-1 uint128) + (a2-0 uint128) + (a2-1 uint128) + (a2-3 uint128) + (gp-0 uint128) ) (.por gp-0 obj r0-0) (let ((t9-0 format) @@ -146,7 +144,7 @@ (.sllv a2-1 gp-0 r0-0) (t9-1 a0-2 a1-1 a2-1) ) - (format #t "~Ty: ~f~%" (sar gp-0 32)) + (format #t "~Ty: ~f~%" (sar (the-as int gp-0) 32)) (let ((t9-3 format) (a0-4 #t) (a1-3 "~Tz: ~f~%") @@ -160,31 +158,29 @@ (a1-4 "~Tw: ~f~%") ) (.pcpyud v1-1 gp-0 r0-0) - (t9-4 a0-5 a1-4 (sar v1-1 32)) + (t9-4 a0-5 a1-4 (sar (the-as int v1-1) 32)) ) (.por v0-5 gp-0 r0-0) (the-as vec4s v0-5) ) ;; definition for method 2 of type vec4s -;; INFO: Return type mismatch int vs vec4s. -;; WARN: Unsupported inline assembly instruction kind - [131] -;; WARN: Unsupported inline assembly instruction kind - [73] -;; WARN: Unsupported inline assembly instruction kind - [132] -;; WARN: Unsupported inline assembly instruction kind - [73] -;; WARN: Unsupported inline assembly instruction kind - [132] -;; WARN: Unsupported inline assembly instruction kind - [131] -;; WARN: Unsupported inline assembly instruction kind - [131] +;; INFO: Return type mismatch uint128 vs vec4s. +;; WARN: Unsupported inline assembly instruction kind - [por gp, a0, r0] +;; WARN: Unsupported inline assembly instruction kind - [sllv a2, gp, r0] +;; WARN: Unsupported inline assembly instruction kind - [sllv t0, v1, r0] +;; WARN: Unsupported inline assembly instruction kind - [por t2, gp, r0] +;; WARN: Unsupported inline assembly instruction kind - [por v0, gp, r0] (defmethod print vec4s ((obj vec4s)) (local-vars (r0-0 none) - (v0-1 int) - (v1-0 int) - (v1-1 int) - (a2-0 int) - (t0-0 int) - (t2-0 int) - (gp-0 int) + (v0-1 uint128) + (v1-0 uint128) + (v1-1 uint128) + (a2-0 uint128) + (t0-0 uint128) + (t2-0 uint128) + (gp-0 uint128) ) (.por gp-0 obj r0-0) (let ((t9-0 format) @@ -192,11 +188,11 @@ (a1-0 "#") ) (.sllv a2-0 gp-0 r0-0) - (let ((a3-0 (sar gp-0 32))) + (let ((a3-0 (sar (the-as int gp-0) 32))) (.pcpyud v1-0 gp-0 r0-0) (.sllv t0-0 v1-0 r0-0) (.pcpyud v1-1 gp-0 r0-0) - (let ((t1-0 (sar v1-1 32))) + (let ((t1-0 (sar (the-as int v1-1) 32))) (.por t2-0 gp-0 r0-0) (t9-0 a0-1 a1-0 a2-0 a3-0 t0-0 t1-0 t2-0) ) @@ -1021,9 +1017,9 @@ ) ;; definition for function breakpoint-range-set! -;; WARN: Unsupported inline assembly instruction kind - [48] -;; WARN: Unsupported inline assembly instruction kind - [50] -;; WARN: Unsupported inline assembly instruction kind - [51] +;; WARN: Unsupported inline assembly instruction kind - [mtc0 Debug, a0] +;; WARN: Unsupported inline assembly instruction kind - [mtdab a1] +;; WARN: Unsupported inline assembly instruction kind - [mtdabm a2] (defun breakpoint-range-set! ((arg0 uint) (arg1 uint) (arg2 uint)) (.mtc0 Debug arg0) (.mtdab arg1) @@ -1032,9 +1028,9 @@ ) ;; definition for function valid? -;; WARN: Unsupported inline assembly instruction kind - [3] -;; WARN: Unsupported inline assembly instruction kind - [3] -;; WARN: Unsupported inline assembly instruction kind - [3] +;; WARN: Unsupported inline assembly instruction kind - [daddu v1, v1, s7] +;; WARN: Unsupported inline assembly instruction kind - [daddu v1, v1, s7] +;; WARN: Unsupported inline assembly instruction kind - [daddu v1, v1, s7] (defun valid? ((obj object) diff --git a/test/decompiler/reference/gkernel-h_REF.gc b/test/decompiler/reference/gkernel-h_REF.gc index d416dcaaab..177779129a 100644 --- a/test/decompiler/reference/gkernel-h_REF.gc +++ b/test/decompiler/reference/gkernel-h_REF.gc @@ -285,8 +285,8 @@ ) ;; definition for method 2 of type handle -;; WARN: Unsupported inline assembly instruction kind - [5] -;; WARN: Unsupported inline assembly instruction kind - [73] +;; 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) diff --git a/test/decompiler/reference/gkernel_REF.gc b/test/decompiler/reference/gkernel_REF.gc index ca44d814f7..32c8c74228 100644 --- a/test/decompiler/reference/gkernel_REF.gc +++ b/test/decompiler/reference/gkernel_REF.gc @@ -1833,8 +1833,8 @@ ;; definition for method 10 of type process ;; INFO: Return type mismatch int vs none. -;; WARN: Unsupported inline assembly instruction kind - [22] -;; WARN: Unsupported inline assembly instruction kind - [59] +;; WARN: Unsupported inline assembly instruction kind - [lw ra, return-from-thread(s7)] +;; WARN: Unsupported inline assembly instruction kind - [jr ra] (defmethod deactivate process ((obj process)) (let ((v0-0 (when (!= (-> obj status) 'dead) (set! (-> obj next-state) dead-state) diff --git a/test/decompiler/reference/gstate_REF.gc b/test/decompiler/reference/gstate_REF.gc index 707106fef6..73785a6d8e 100644 --- a/test/decompiler/reference/gstate_REF.gc +++ b/test/decompiler/reference/gstate_REF.gc @@ -49,10 +49,10 @@ ) ;; definition for function enter-state -;; WARN: Unsupported inline assembly instruction kind - [23] -;; WARN: Unsupported inline assembly instruction kind - [22] -;; WARN: Unsupported inline assembly instruction kind - [59] -;; WARN: Unsupported inline assembly instruction kind - [13] +;; WARN: Unsupported inline assembly instruction kind - [lwu sp, 28(v1)] +;; WARN: Unsupported inline assembly instruction kind - [lw ra, return-from-thread-dead(s7)] +;; WARN: Unsupported inline assembly instruction kind - [jr t9] +;; WARN: Unsupported inline assembly instruction kind - [sw v0, 0(sp)] (defun enter-state ((arg0 object) diff --git a/test/decompiler/reference/math_REF.gc b/test/decompiler/reference/math_REF.gc index 8a94712315..128e6b77ba 100644 --- a/test/decompiler/reference/math_REF.gc +++ b/test/decompiler/reference/math_REF.gc @@ -118,8 +118,8 @@ ;; definition for function rand-vu-init ;; INFO: Return type mismatch int vs float. -;; WARN: Unsupported inline assembly instruction kind - [56] -;; WARN: Unsupported inline assembly instruction kind - [57] +;; WARN: Unsupported inline assembly instruction kind - [ctc2.i vi_R, a0] +;; WARN: Unsupported inline assembly instruction kind - [cfc2.i v0, vi_R] (defun rand-vu-init ((arg0 float)) (local-vars (v0-0 int)) (.ctc2.i vi_R arg0) diff --git a/test/decompiler/reference/matrix-h_REF.gc b/test/decompiler/reference/matrix-h_REF.gc index 90289dd837..e60857a55d 100644 --- a/test/decompiler/reference/matrix-h_REF.gc +++ b/test/decompiler/reference/matrix-h_REF.gc @@ -11,7 +11,7 @@ :size-assert #x40 :flag-assert #xa00000040 (:methods - (dummy-9 () none 9) + (transform-vectors! (_type_ (inline-array vector) (inline-array vector) int) none 9) ) ) diff --git a/test/decompiler/reference/matrix_REF.gc b/test/decompiler/reference/matrix_REF.gc index 5cd93b6574..f2e2a25652 100644 --- a/test/decompiler/reference/matrix_REF.gc +++ b/test/decompiler/reference/matrix_REF.gc @@ -91,23 +91,23 @@ (matrix-identity! *identity-matrix*) ;; definition for function matrix+! -(defun matrix+! ((arg0 matrix) (arg1 matrix) (arg2 matrix)) - (dotimes (v1-0 16) - (set! (-> arg0 data v1-0) (+ (-> arg1 data v1-0) (-> arg2 data v1-0))) +(defun matrix+! ((dst matrix) (src1 matrix) (src2 matrix)) + (dotimes (i 16) + (set! (-> dst data i) (+ (-> src1 data i) (-> src2 data i))) ) - arg0 + dst ) ;; definition for function matrix-! -(defun matrix-! ((arg0 matrix) (arg1 matrix) (arg2 matrix)) - (dotimes (v1-0 16) - (set! (-> arg0 data v1-0) (- (-> arg1 data v1-0) (-> arg2 data v1-0))) +(defun matrix-! ((dst matrix) (src1 matrix) (src2 matrix)) + (dotimes (i 16) + (set! (-> dst data i) (- (-> src1 data i) (-> src2 data i))) ) - arg0 + dst ) ;; definition for function matrix*! -(defun matrix*! ((arg0 matrix) (arg1 matrix) (arg2 matrix)) +(defun matrix*! ((dst matrix) (src1 matrix) (src2 matrix)) (rlet ((acc :class vf) (vf10 :class vf) (vf11 :class vf) @@ -122,14 +122,14 @@ (vf20 :class vf) (vf21 :class vf) ) - (.lvf vf10 (&-> arg1 vector 0 quad)) - (.lvf vf14 (&-> arg2 vector 0 quad)) - (.lvf vf15 (&-> arg2 vector 1 quad)) - (.lvf vf16 (&-> arg2 vector 2 quad)) - (.lvf vf17 (&-> arg2 vector 3 quad)) - (.lvf vf11 (&-> arg1 vector 1 quad)) - (.lvf vf12 (&-> arg1 vector 2 quad)) - (.lvf vf13 (&-> arg1 vector 3 quad)) + (.lvf vf10 (&-> src1 vector 0 quad)) + (.lvf vf14 (&-> src2 vector 0 quad)) + (.lvf vf15 (&-> src2 vector 1 quad)) + (.lvf vf16 (&-> src2 vector 2 quad)) + (.lvf vf17 (&-> src2 vector 3 quad)) + (.lvf vf11 (&-> src1 vector 1 quad)) + (.lvf vf12 (&-> src1 vector 2 quad)) + (.lvf vf13 (&-> src1 vector 3 quad)) (.mul.x.vf acc vf14 vf10) (.add.mul.y.vf acc vf15 vf10 acc) (.add.mul.z.vf acc vf16 vf10 acc) @@ -146,33 +146,33 @@ (.add.mul.y.vf acc vf15 vf13 acc) (.add.mul.z.vf acc vf16 vf13 acc) (.add.mul.w.vf vf21 vf17 vf13 acc) - (.svf (&-> arg0 vector 0 quad) vf18) - (.svf (&-> arg0 vector 1 quad) vf19) - (.svf (&-> arg0 vector 2 quad) vf20) - (.svf (&-> arg0 vector 3 quad) vf21) - arg0 + (.svf (&-> dst vector 0 quad) vf18) + (.svf (&-> dst vector 1 quad) vf19) + (.svf (&-> dst vector 2 quad) vf20) + (.svf (&-> dst vector 3 quad) vf21) + dst ) ) ;; definition for function matrixp*! ;; Used lq/sq -(defun matrixp*! ((arg0 matrix) (arg1 matrix) (arg2 matrix)) - (let ((s5-0 (new 'stack 'matrix))) - (set! (-> s5-0 vector 0 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 1 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 2 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 3 quad) (the-as uint128 0)) - (matrix*! s5-0 arg1 arg2) - (set! (-> arg0 vector 0 quad) (-> s5-0 vector 0 quad)) - (set! (-> arg0 vector 1 quad) (-> s5-0 vector 1 quad)) - (set! (-> arg0 vector 2 quad) (-> s5-0 vector 2 quad)) - (set! (-> arg0 vector 3 quad) (-> s5-0 vector 3 quad)) +(defun matrixp*! ((dst matrix) (src1 matrix) (src2 matrix)) + (let ((temp-mat (new 'stack 'matrix))) + (set! (-> temp-mat vector 0 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 1 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 2 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 3 quad) (the-as uint128 0)) + (matrix*! temp-mat src1 src2) + (set! (-> dst vector 0 quad) (-> temp-mat vector 0 quad)) + (set! (-> dst vector 1 quad) (-> temp-mat vector 1 quad)) + (set! (-> dst vector 2 quad) (-> temp-mat vector 2 quad)) + (set! (-> dst vector 3 quad) (-> temp-mat vector 3 quad)) ) - arg0 + dst ) ;; definition for function vector-matrix*! -(defun vector-matrix*! ((arg0 vector) (arg1 vector) (arg2 matrix)) +(defun vector-matrix*! ((dst vector) (vec vector) (mat matrix)) (rlet ((acc :class vf) (vf1 :class vf) (vf2 :class vf) @@ -180,22 +180,22 @@ (vf4 :class vf) (vf5 :class vf) ) - (.lvf vf1 (&-> arg2 vector 0 quad)) - (.lvf vf2 (&-> arg2 vector 1 quad)) - (.lvf vf3 (&-> arg2 vector 2 quad)) - (.lvf vf4 (&-> arg2 vector 3 quad)) - (.lvf vf5 (&-> arg1 quad)) + (.lvf vf1 (&-> mat vector 0 quad)) + (.lvf vf2 (&-> mat vector 1 quad)) + (.lvf vf3 (&-> mat vector 2 quad)) + (.lvf vf4 (&-> mat vector 3 quad)) + (.lvf vf5 (&-> vec quad)) (.mul.x.vf acc vf1 vf5) (.add.mul.y.vf acc vf2 vf5 acc) (.add.mul.z.vf acc vf3 vf5 acc) (.add.mul.w.vf vf5 vf4 vf5 acc) - (.svf (&-> arg0 quad) vf5) - arg0 + (.svf (&-> dst quad) vf5) + dst ) ) ;; definition for function vector-rotate*! -(defun vector-rotate*! ((arg0 vector) (arg1 vector) (arg2 matrix)) +(defun vector-rotate*! ((dst vector) (vec vector) (mat matrix)) (rlet ((acc :class vf) (vf1 :class vf) (vf2 :class vf) @@ -205,100 +205,92 @@ ) (nop!) (nop!) - (.lvf vf5 (&-> arg1 quad)) + (.lvf vf5 (&-> vec quad)) (nop!) - (.lvf vf1 (&-> arg2 vector 0 quad)) + (.lvf vf1 (&-> mat vector 0 quad)) (nop!) - (.lvf vf2 (&-> arg2 vector 1 quad)) + (.lvf vf2 (&-> mat vector 1 quad)) (.mul.x.vf acc vf1 vf5) - (.lvf vf3 (&-> arg2 vector 2 quad)) + (.lvf vf3 (&-> mat vector 2 quad)) (.add.mul.y.vf acc vf2 vf5 acc) - (.lvf vf4 (&-> arg2 vector 3 quad)) + (.lvf vf4 (&-> mat vector 3 quad)) (.add.mul.z.vf vf5 vf3 vf5 acc) (nop!) (nop!) - (.svf (&-> arg0 quad) vf5) - arg0 + (.svf (&-> dst quad) vf5) + dst ) ) ;; definition for function vector3s-matrix*! ;; Used lq/sq -(defun vector3s-matrix*! ((arg0 vector3s) (arg1 vector3s) (arg2 matrix)) - (let ((s5-0 (new 'stack 'vector))) - (set! (-> s5-0 quad) (the-as uint128 0)) - (let ((v1-0 s5-0)) - (set! (-> v1-0 data 0) (-> arg1 data 0)) - (set! (-> v1-0 data 1) (-> arg1 data 1)) - (set! (-> v1-0 data 2) (-> arg1 data 2)) +(defun vector3s-matrix*! ((dst vector3s) (vec vector3s) (mat matrix)) + (let ((temp-vec3 (new 'stack 'vector))) + (set! (-> temp-vec3 quad) (the-as uint128 0)) + (let ((v1-0 temp-vec3)) + (set! (-> v1-0 data 0) (-> vec data 0)) + (set! (-> v1-0 data 1) (-> vec data 1)) + (set! (-> v1-0 data 2) (-> vec data 2)) (set! (-> v1-0 data 3) 1.0) ) - (vector-matrix*! s5-0 s5-0 arg2) - (set! (-> arg0 data 0) (-> s5-0 data 0)) - (set! (-> arg0 data 1) (-> s5-0 data 1)) - (set! (-> arg0 data 2) (-> s5-0 data 2)) + (vector-matrix*! temp-vec3 temp-vec3 mat) + (set! (-> dst data 0) (-> temp-vec3 data 0)) + (set! (-> dst data 1) (-> temp-vec3 data 1)) + (set! (-> dst data 2) (-> temp-vec3 data 2)) ) - (let ((v1-1 arg0)) + (let ((v1-1 dst)) ) - arg0 + dst ) ;; definition for function vector3s-rotate*! ;; Used lq/sq -(defun vector3s-rotate*! ((arg0 vector3s) (arg1 vector3s) (arg2 matrix)) - (let ((s5-0 (new 'stack 'vector))) - (set! (-> s5-0 quad) (the-as uint128 0)) - (let ((v1-0 s5-0)) - (set! (-> v1-0 data 0) (-> arg1 data 0)) - (set! (-> v1-0 data 1) (-> arg1 data 1)) - (set! (-> v1-0 data 2) (-> arg1 data 2)) +(defun vector3s-rotate*! ((dst vector3s) (vec vector3s) (mat matrix)) + (let ((temp-vec3 (new 'stack 'vector))) + (set! (-> temp-vec3 quad) (the-as uint128 0)) + (let ((v1-0 temp-vec3)) + (set! (-> v1-0 data 0) (-> vec data 0)) + (set! (-> v1-0 data 1) (-> vec data 1)) + (set! (-> v1-0 data 2) (-> vec data 2)) (set! (-> v1-0 data 3) 1.0) ) - (vector-rotate*! s5-0 s5-0 arg2) - (set! (-> arg0 data 0) (-> s5-0 data 0)) - (set! (-> arg0 data 1) (-> s5-0 data 1)) - (set! (-> arg0 data 2) (-> s5-0 data 2)) + (vector-rotate*! temp-vec3 temp-vec3 mat) + (set! (-> dst data 0) (-> temp-vec3 data 0)) + (set! (-> dst data 1) (-> temp-vec3 data 1)) + (set! (-> dst data 2) (-> temp-vec3 data 2)) ) - (let ((v1-1 arg0)) + (let ((v1-1 dst)) ) - arg0 + dst ) ;; definition for function matrix-transpose! -;; WARN: Unsupported inline assembly instruction kind - [105] -;; WARN: Unsupported inline assembly instruction kind - [118] -;; WARN: Unsupported inline assembly instruction kind - [105] -;; WARN: Unsupported inline assembly instruction kind - [118] -;; WARN: Unsupported inline assembly instruction kind - [125] -;; WARN: Unsupported inline assembly instruction kind - [132] -;; WARN: Unsupported inline assembly instruction kind - [125] -;; WARN: Unsupported inline assembly instruction kind - [132] ;; Used lq/sq -(defun matrix-transpose! ((arg0 matrix) (arg1 matrix)) +(defun matrix-transpose! ((dst matrix) (src matrix)) (local-vars (r0-0 int) (r0-1 int) (r0-2 int) (r0-3 int) - (v1-0 int) - (v1-1 int) - (v1-2 int) - (a1-1 int) - (a2-1 int) - (a3-1 int) - (a3-2 int) - (t0-1 int) + (v1-0 uint128) + (v1-1 uint128) + (v1-2 uint128) + (a1-1 uint128) + (a2-1 uint128) + (a3-1 uint128) + (a3-2 uint128) + (t0-1 uint128) (f31-0 none) ) (nop!) (nop!) - (let ((t0-0 (-> arg1 vector 0 quad))) + (let ((t0-0 (-> src vector 0 quad))) (nop!) - (let ((t1-0 (-> arg1 vector 1 quad))) + (let ((t1-0 (-> src vector 1 quad))) (nop!) - (let ((a2-0 (-> arg1 vector 2 quad))) + (let ((a2-0 (-> src vector 2 quad))) (.pextlw v1-0 t1-0 t0-0) - (let ((a3-0 (-> arg1 vector 3 quad))) + (let ((a3-0 (-> src vector 3 quad))) (.pextuw a1-1 t1-0 t0-0) (.mov r0-0 f31-0) (.pextlw t0-1 a3-0 a2-0) @@ -312,18 +304,18 @@ (.pcpyld a3-1 t0-1 v1-0) (.mov r0-3 f31-0) (.pcpyud v1-1 v1-0 t0-1) - (set! (-> arg0 vector 0 quad) (the-as uint128 a3-1)) + (set! (-> dst vector 0 quad) a3-1) (.pcpyld a3-2 a2-1 a1-1) - (set! (-> arg0 vector 1 quad) (the-as uint128 v1-1)) + (set! (-> dst vector 1 quad) v1-1) (.pcpyud v1-2 a1-1 a2-1) - (set! (-> arg0 vector 2 quad) (the-as uint128 a3-2)) + (set! (-> dst vector 2 quad) a3-2) (nop!) - (set! (-> arg0 vector 3 quad) (the-as uint128 v1-2)) - arg0 + (set! (-> dst vector 3 quad) v1-2) + dst ) ;; definition for function matrix-inverse-of-rot-trans! -(defun matrix-inverse-of-rot-trans! ((arg0 matrix) (arg1 matrix)) +(defun matrix-inverse-of-rot-trans! ((dst matrix) (src matrix)) (rlet ((acc :class vf) (vf0 :class vf) (vf1 :class vf) @@ -333,24 +325,24 @@ (vf8 :class vf) ) (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (matrix-transpose! arg0 arg1) - (.lvf vf1 (&-> arg0 vector 0 quad)) - (.lvf vf2 (&-> arg0 vector 1 quad)) - (.lvf vf3 (&-> arg0 vector 2 quad)) + (matrix-transpose! dst src) + (.lvf vf1 (&-> dst vector 0 quad)) + (.lvf vf2 (&-> dst vector 1 quad)) + (.lvf vf3 (&-> dst vector 2 quad)) (.sub.vf vf1 vf1 vf1 :mask #b1000) (.sub.vf vf2 vf2 vf2 :mask #b1000) (.sub.vf vf3 vf3 vf3 :mask #b1000) - (.lvf vf8 (&-> arg1 vector 3 quad)) + (.lvf vf8 (&-> src vector 3 quad)) (.mul.x.vf acc vf1 vf8) (.add.mul.y.vf acc vf2 vf8 acc) (.add.mul.z.vf vf4 vf3 vf8 acc) (.sub.vf vf4 vf0 vf4) (.mov.vf vf4 vf0 :mask #b1000) - (.svf (&-> arg0 vector 0 quad) vf1) - (.svf (&-> arg0 vector 1 quad) vf2) - (.svf (&-> arg0 vector 2 quad) vf3) - (.svf (&-> arg0 vector 3 quad) vf4) - arg0 + (.svf (&-> dst vector 0 quad) vf1) + (.svf (&-> dst vector 1 quad) vf2) + (.svf (&-> dst vector 2 quad) vf3) + (.svf (&-> dst vector 3 quad) vf4) + dst ) ) @@ -358,7 +350,7 @@ ;; WARN: Bad vector register dependency: vf3 ;; WARN: Bad vector register dependency: vf4 ;; WARN: Bad vector register dependency: vf5 -(defun matrix-4x4-inverse! ((arg0 matrix) (arg1 matrix)) +(defun matrix-4x4-inverse! ((dst matrix) (src matrix)) (rlet ((acc :class vf) (Q :class vf) (vf0 :class vf) @@ -395,13 +387,13 @@ (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) (nop!) (nop!) - (.lvf vf23 (&-> arg1 vector 0 quad)) + (.lvf vf23 (&-> src vector 0 quad)) (nop!) - (.lvf vf24 (&-> arg1 vector 1 quad)) + (.lvf vf24 (&-> src vector 1 quad)) (nop!) - (.lvf vf25 (&-> arg1 vector 2 quad)) + (.lvf vf25 (&-> src vector 2 quad)) (nop!) - (.lvf vf1 (&-> arg1 vector 3 quad)) + (.lvf vf1 (&-> src vector 3 quad)) (.mul.x.vf vf7 vf24 vf23) (nop!) (.mul.y.vf vf8 vf24 vf23) @@ -462,7 +454,7 @@ (nop!) (.sub.x.vf vf31 vf7 vf8 :mask #b10) (nop!) - (.div.vf Q vf0 vf20 :ftf #b11 :fsf #b0) + (.div.vf Q vf0 vf20 :fsf #b11 :ftf #b0) (nop!) (.sub.w.vf vf3 vf3 vf3 :mask #b1000) (nop!) @@ -497,342 +489,342 @@ (.mul.y.vf vf5 vf2 vf31 :mask #b100) (nop!) (.mul.x.vf acc vf3 vf1) - (.svf (&-> arg0 vector 0 quad) vf3) + (.svf (&-> dst vector 0 quad) vf3) (.add.mul.y.vf acc vf4 vf1 acc) - (.svf (&-> arg0 vector 1 quad) vf4) + (.svf (&-> dst vector 1 quad) vf4) (.add.mul.z.vf vf6 vf5 vf1 acc :mask #b111) - (.svf (&-> arg0 vector 2 quad) vf5) + (.svf (&-> dst vector 2 quad) vf5) (nop!) - (.svf (&-> arg0 vector 3 quad) vf6) - arg0 + (.svf (&-> dst vector 3 quad) vf6) + dst ) ) ;; definition for function matrix-translate! -(defun matrix-translate! ((arg0 matrix) (arg1 vector)) - (matrix-identity! arg0) - (set! (-> arg0 data 12) (-> arg1 data 0)) - (set! (-> arg0 data 13) (-> arg1 data 1)) - (set! (-> arg0 data 14) (-> arg1 data 2)) - arg0 +(defun matrix-translate! ((dst matrix) (trans vector)) + (matrix-identity! dst) + (set! (-> dst data 12) (-> trans data 0)) + (set! (-> dst data 13) (-> trans data 1)) + (set! (-> dst data 14) (-> trans data 2)) + dst ) ;; definition for function matrix-translate+! ;; Used lq/sq -(defun matrix-translate+! ((arg0 matrix) (arg1 matrix) (arg2 vector)) - (set! (-> arg0 data 12) (+ (-> arg1 data 12) (-> arg2 data 0))) - (set! (-> arg0 data 13) (+ (-> arg1 data 13) (-> arg2 data 1))) - (set! (-> arg0 data 14) (+ (-> arg1 data 14) (-> arg2 data 2))) - (when (!= arg0 arg1) - (set! (-> arg0 vector 0 quad) (-> arg1 vector 0 quad)) - (set! (-> arg0 vector 1 quad) (-> arg1 vector 1 quad)) - (set! (-> arg0 vector 2 quad) (-> arg1 vector 2 quad)) +(defun matrix-translate+! ((dst matrix) (src matrix) (trans vector)) + (set! (-> dst data 12) (+ (-> src data 12) (-> trans data 0))) + (set! (-> dst data 13) (+ (-> src data 13) (-> trans data 1))) + (set! (-> dst data 14) (+ (-> src data 14) (-> trans data 2))) + (when (!= dst src) + (set! (-> dst vector 0 quad) (-> src vector 0 quad)) + (set! (-> dst vector 1 quad) (-> src vector 1 quad)) + (set! (-> dst vector 2 quad) (-> src vector 2 quad)) ) - arg0 + dst ) ;; definition for function matrix-scale! ;; Used lq/sq -(defun matrix-scale! ((arg0 matrix) (arg1 vector)) - (set! (-> arg0 vector 0 quad) (the-as uint128 0)) - (set! (-> arg0 vector 1 quad) (the-as uint128 0)) - (set! (-> arg0 vector 2 quad) (the-as uint128 0)) - (set! (-> arg0 vector 3 quad) (the-as uint128 0)) - (set! (-> arg0 data 0) (-> arg1 data 0)) - (set! (-> arg0 data 5) (-> arg1 data 1)) - (set! (-> arg0 data 10) (-> arg1 data 2)) - (set! (-> arg0 data 15) 1.0) - arg0 +(defun matrix-scale! ((dst matrix) (scale vector)) + (set! (-> dst vector 0 quad) (the-as uint128 0)) + (set! (-> dst vector 1 quad) (the-as uint128 0)) + (set! (-> dst vector 2 quad) (the-as uint128 0)) + (set! (-> dst vector 3 quad) (the-as uint128 0)) + (set! (-> dst data 0) (-> scale data 0)) + (set! (-> dst data 5) (-> scale data 1)) + (set! (-> dst data 10) (-> scale data 2)) + (set! (-> dst data 15) 1.0) + dst ) ;; definition for function scale-matrix! -(defun scale-matrix! ((arg0 matrix) (arg1 vector) (arg2 matrix)) +(defun scale-matrix! ((dst matrix) (scale vector) (src matrix)) (rlet ((vf4 :class vf) (vf5 :class vf) (vf6 :class vf) (vf7 :class vf) (vf8 :class vf) ) - (.lvf vf4 (&-> arg1 quad)) - (.lvf vf5 (&-> arg2 vector 0 quad)) - (.lvf vf6 (&-> arg2 vector 1 quad)) - (.lvf vf7 (&-> arg2 vector 2 quad)) - (.lvf vf8 (&-> arg2 vector 3 quad)) + (.lvf vf4 (&-> scale quad)) + (.lvf vf5 (&-> src vector 0 quad)) + (.lvf vf6 (&-> src vector 1 quad)) + (.lvf vf7 (&-> src vector 2 quad)) + (.lvf vf8 (&-> src vector 3 quad)) (.mul.x.vf vf5 vf5 vf4) (.mul.y.vf vf6 vf6 vf4) (.mul.z.vf vf7 vf7 vf4) (.mul.w.vf vf8 vf8 vf4) - (.svf (&-> arg0 vector 0 quad) vf5) - (.svf (&-> arg0 vector 1 quad) vf6) - (.svf (&-> arg0 vector 2 quad) vf7) - (.svf (&-> arg0 vector 3 quad) vf8) - arg0 + (.svf (&-> dst vector 0 quad) vf5) + (.svf (&-> dst vector 1 quad) vf6) + (.svf (&-> dst vector 2 quad) vf7) + (.svf (&-> dst vector 3 quad) vf8) + dst ) ) ;; definition for function matrix-inv-scale! ;; Used lq/sq -(defun matrix-inv-scale! ((arg0 matrix) (arg1 vector)) - (set! (-> arg0 vector 0 quad) (the-as uint128 0)) - (set! (-> arg0 vector 1 quad) (the-as uint128 0)) - (set! (-> arg0 vector 2 quad) (the-as uint128 0)) - (set! (-> arg0 vector 3 quad) (the-as uint128 0)) - (set! (-> arg0 data 0) (/ 1.0 (-> arg1 data 0))) - (set! (-> arg0 data 5) (/ 1.0 (-> arg1 data 1))) - (set! (-> arg0 data 10) (/ 1.0 (-> arg1 data 2))) - (set! (-> arg0 data 15) 1.0) - arg0 +(defun matrix-inv-scale! ((dst matrix) (scale vector)) + (set! (-> dst vector 0 quad) (the-as uint128 0)) + (set! (-> dst vector 1 quad) (the-as uint128 0)) + (set! (-> dst vector 2 quad) (the-as uint128 0)) + (set! (-> dst vector 3 quad) (the-as uint128 0)) + (set! (-> dst data 0) (/ 1.0 (-> scale data 0))) + (set! (-> dst data 5) (/ 1.0 (-> scale data 1))) + (set! (-> dst data 10) (/ 1.0 (-> scale data 2))) + (set! (-> dst data 15) 1.0) + dst ) ;; definition for function column-scale-matrix! -(defun column-scale-matrix! ((arg0 matrix) (arg1 vector) (arg2 matrix)) +(defun column-scale-matrix! ((dst matrix) (scale vector) (src matrix)) (rlet ((vf4 :class vf) (vf5 :class vf) (vf6 :class vf) (vf7 :class vf) (vf8 :class vf) ) - (.lvf vf4 (&-> arg1 quad)) - (.lvf vf5 (&-> arg2 vector 0 quad)) - (.lvf vf6 (&-> arg2 vector 1 quad)) - (.lvf vf7 (&-> arg2 vector 2 quad)) - (.lvf vf8 (&-> arg2 vector 3 quad)) + (.lvf vf4 (&-> scale quad)) + (.lvf vf5 (&-> src vector 0 quad)) + (.lvf vf6 (&-> src vector 1 quad)) + (.lvf vf7 (&-> src vector 2 quad)) + (.lvf vf8 (&-> src vector 3 quad)) (.mul.vf vf5 vf5 vf4) (.mul.vf vf6 vf6 vf4) (.mul.vf vf7 vf7 vf4) (.mul.vf vf8 vf8 vf4) - (.svf (&-> arg0 vector 0 quad) vf5) - (.svf (&-> arg0 vector 1 quad) vf6) - (.svf (&-> arg0 vector 2 quad) vf7) - (.svf (&-> arg0 vector 3 quad) vf8) - arg0 + (.svf (&-> dst vector 0 quad) vf5) + (.svf (&-> dst vector 1 quad) vf6) + (.svf (&-> dst vector 2 quad) vf7) + (.svf (&-> dst vector 3 quad) vf8) + dst ) ) ;; definition for function matrix-rotate-x! ;; Used lq/sq -(defun matrix-rotate-x! ((arg0 matrix) (arg1 float)) - (let ((f30-0 (sin arg1)) - (f0-0 (cos arg1)) +(defun matrix-rotate-x! ((dst matrix) (rot-deg float)) + (let ((rot-sin (sin rot-deg)) + (rot-cos (cos rot-deg)) ) - (set! (-> arg0 vector 0 quad) (the-as uint128 0)) - (set! (-> arg0 vector 1 quad) (the-as uint128 0)) - (set! (-> arg0 vector 2 quad) (the-as uint128 0)) - (set! (-> arg0 vector 3 quad) (the-as uint128 0)) - (set! (-> arg0 data 0) 1.0) - (set! (-> arg0 data 5) f0-0) - (set! (-> arg0 data 6) f30-0) - (set! (-> arg0 data 9) (- f30-0)) - (set! (-> arg0 data 10) f0-0) + (set! (-> dst vector 0 quad) (the-as uint128 0)) + (set! (-> dst vector 1 quad) (the-as uint128 0)) + (set! (-> dst vector 2 quad) (the-as uint128 0)) + (set! (-> dst vector 3 quad) (the-as uint128 0)) + (set! (-> dst data 0) 1.0) + (set! (-> dst data 5) rot-cos) + (set! (-> dst data 6) rot-sin) + (set! (-> dst data 9) (- rot-sin)) + (set! (-> dst data 10) rot-cos) ) - (set! (-> arg0 data 15) 1.0) - arg0 + (set! (-> dst data 15) 1.0) + dst ) ;; definition for function matrix-rotate-y! ;; Used lq/sq -(defun matrix-rotate-y! ((arg0 matrix) (arg1 float)) - (let ((f30-0 (sin arg1)) - (f0-0 (cos arg1)) +(defun matrix-rotate-y! ((dst matrix) (rot-deg float)) + (let ((rot-sin (sin rot-deg)) + (rot-cos (cos rot-deg)) ) - (set! (-> arg0 vector 0 quad) (the-as uint128 0)) - (set! (-> arg0 vector 1 quad) (the-as uint128 0)) - (set! (-> arg0 vector 2 quad) (the-as uint128 0)) - (set! (-> arg0 vector 3 quad) (the-as uint128 0)) - (set! (-> arg0 data 0) f0-0) - (set! (-> arg0 data 2) (- f30-0)) - (set! (-> arg0 data 5) 1.0) - (set! (-> arg0 data 8) f30-0) - (set! (-> arg0 data 10) f0-0) + (set! (-> dst vector 0 quad) (the-as uint128 0)) + (set! (-> dst vector 1 quad) (the-as uint128 0)) + (set! (-> dst vector 2 quad) (the-as uint128 0)) + (set! (-> dst vector 3 quad) (the-as uint128 0)) + (set! (-> dst data 0) rot-cos) + (set! (-> dst data 2) (- rot-sin)) + (set! (-> dst data 5) 1.0) + (set! (-> dst data 8) rot-sin) + (set! (-> dst data 10) rot-cos) ) - (set! (-> arg0 data 15) 1.0) - arg0 + (set! (-> dst data 15) 1.0) + dst ) ;; definition for function matrix-rotate-z! ;; Used lq/sq -(defun matrix-rotate-z! ((arg0 matrix) (arg1 float)) - (let ((f30-0 (sin arg1)) - (f0-0 (cos arg1)) +(defun matrix-rotate-z! ((dst matrix) (rot-deg float)) + (let ((rot-sin (sin rot-deg)) + (rot-cos (cos rot-deg)) ) - (set! (-> arg0 vector 0 quad) (the-as uint128 0)) - (set! (-> arg0 vector 1 quad) (the-as uint128 0)) - (set! (-> arg0 vector 2 quad) (the-as uint128 0)) - (set! (-> arg0 vector 3 quad) (the-as uint128 0)) - (set! (-> arg0 data 0) f0-0) - (set! (-> arg0 data 1) f30-0) - (set! (-> arg0 data 4) (- f30-0)) - (set! (-> arg0 data 5) f0-0) + (set! (-> dst vector 0 quad) (the-as uint128 0)) + (set! (-> dst vector 1 quad) (the-as uint128 0)) + (set! (-> dst vector 2 quad) (the-as uint128 0)) + (set! (-> dst vector 3 quad) (the-as uint128 0)) + (set! (-> dst data 0) rot-cos) + (set! (-> dst data 1) rot-sin) + (set! (-> dst data 4) (- rot-sin)) + (set! (-> dst data 5) rot-cos) ) - (set! (-> arg0 data 10) 1.0) - (set! (-> arg0 data 15) 1.0) - arg0 + (set! (-> dst data 10) 1.0) + (set! (-> dst data 15) 1.0) + dst ) ;; definition for function matrix-rotate-zyx! ;; Used lq/sq -(defun matrix-rotate-zyx! ((arg0 matrix) (arg1 vector)) - (let ((gp-0 (new 'stack 'matrix))) - (set! (-> gp-0 vector 0 quad) (the-as uint128 0)) - (set! (-> gp-0 vector 1 quad) (the-as uint128 0)) - (set! (-> gp-0 vector 2 quad) (the-as uint128 0)) - (set! (-> gp-0 vector 3 quad) (the-as uint128 0)) - (let ((s5-0 (new 'stack 'matrix))) - (set! (-> s5-0 vector 0 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 1 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 2 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 3 quad) (the-as uint128 0)) - (matrix-rotate-x! arg0 (-> arg1 data 0)) - (matrix-rotate-y! gp-0 (-> arg1 data 1)) - (matrix*! s5-0 gp-0 arg0) - (matrix-rotate-z! gp-0 (-> arg1 data 2)) - (matrix*! arg0 gp-0 s5-0) +(defun matrix-rotate-zyx! ((dst matrix) (rot-xyz-deg vector)) + (let ((temp-mat (new 'stack 'matrix))) + (set! (-> temp-mat vector 0 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 1 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 2 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 3 quad) (the-as uint128 0)) + (let ((rot-mat (new 'stack 'matrix))) + (set! (-> rot-mat vector 0 quad) (the-as uint128 0)) + (set! (-> rot-mat vector 1 quad) (the-as uint128 0)) + (set! (-> rot-mat vector 2 quad) (the-as uint128 0)) + (set! (-> rot-mat vector 3 quad) (the-as uint128 0)) + (matrix-rotate-x! dst (-> rot-xyz-deg data 0)) + (matrix-rotate-y! temp-mat (-> rot-xyz-deg data 1)) + (matrix*! rot-mat temp-mat dst) + (matrix-rotate-z! temp-mat (-> rot-xyz-deg data 2)) + (matrix*! dst temp-mat rot-mat) ) ) - arg0 + dst ) ;; definition for function matrix-rotate-xyz! ;; Used lq/sq -(defun matrix-rotate-xyz! ((arg0 matrix) (arg1 vector)) - (let ((gp-0 (new 'stack 'matrix))) - (set! (-> gp-0 vector 0 quad) (the-as uint128 0)) - (set! (-> gp-0 vector 1 quad) (the-as uint128 0)) - (set! (-> gp-0 vector 2 quad) (the-as uint128 0)) - (set! (-> gp-0 vector 3 quad) (the-as uint128 0)) - (let ((s5-0 (new 'stack 'matrix))) - (set! (-> s5-0 vector 0 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 1 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 2 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 3 quad) (the-as uint128 0)) - (matrix-rotate-z! arg0 (-> arg1 data 2)) - (matrix-rotate-y! gp-0 (-> arg1 data 1)) - (matrix*! s5-0 gp-0 arg0) - (matrix-rotate-x! gp-0 (-> arg1 data 0)) - (matrix*! arg0 gp-0 s5-0) +(defun matrix-rotate-xyz! ((dst matrix) (rot-xyz-deg vector)) + (let ((temp-mat (new 'stack 'matrix))) + (set! (-> temp-mat vector 0 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 1 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 2 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 3 quad) (the-as uint128 0)) + (let ((rot-mat (new 'stack 'matrix))) + (set! (-> rot-mat vector 0 quad) (the-as uint128 0)) + (set! (-> rot-mat vector 1 quad) (the-as uint128 0)) + (set! (-> rot-mat vector 2 quad) (the-as uint128 0)) + (set! (-> rot-mat vector 3 quad) (the-as uint128 0)) + (matrix-rotate-z! dst (-> rot-xyz-deg data 2)) + (matrix-rotate-y! temp-mat (-> rot-xyz-deg data 1)) + (matrix*! rot-mat temp-mat dst) + (matrix-rotate-x! temp-mat (-> rot-xyz-deg data 0)) + (matrix*! dst temp-mat rot-mat) ) ) - arg0 + dst ) ;; definition for function matrix-rotate-zxy! ;; Used lq/sq -(defun matrix-rotate-zxy! ((arg0 matrix) (arg1 vector)) - (let ((gp-0 (new 'stack 'matrix))) - (set! (-> gp-0 vector 0 quad) (the-as uint128 0)) - (set! (-> gp-0 vector 1 quad) (the-as uint128 0)) - (set! (-> gp-0 vector 2 quad) (the-as uint128 0)) - (set! (-> gp-0 vector 3 quad) (the-as uint128 0)) - (let ((s5-0 (new 'stack 'matrix))) - (set! (-> s5-0 vector 0 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 1 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 2 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 3 quad) (the-as uint128 0)) - (matrix-rotate-y! arg0 (-> arg1 data 1)) - (matrix-rotate-x! gp-0 (-> arg1 data 0)) - (matrix*! s5-0 gp-0 arg0) - (matrix-rotate-z! gp-0 (-> arg1 data 2)) - (matrix*! arg0 gp-0 s5-0) +(defun matrix-rotate-zxy! ((dst matrix) (rot-xyz-deg vector)) + (let ((temp-mat (new 'stack 'matrix))) + (set! (-> temp-mat vector 0 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 1 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 2 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 3 quad) (the-as uint128 0)) + (let ((rot-mat (new 'stack 'matrix))) + (set! (-> rot-mat vector 0 quad) (the-as uint128 0)) + (set! (-> rot-mat vector 1 quad) (the-as uint128 0)) + (set! (-> rot-mat vector 2 quad) (the-as uint128 0)) + (set! (-> rot-mat vector 3 quad) (the-as uint128 0)) + (matrix-rotate-y! dst (-> rot-xyz-deg data 1)) + (matrix-rotate-x! temp-mat (-> rot-xyz-deg data 0)) + (matrix*! rot-mat temp-mat dst) + (matrix-rotate-z! temp-mat (-> rot-xyz-deg data 2)) + (matrix*! dst temp-mat rot-mat) ) ) - arg0 + dst ) ;; definition for function matrix-rotate-yxz! ;; Used lq/sq -(defun matrix-rotate-yxz! ((arg0 matrix) (arg1 vector)) - (let ((gp-0 (new 'stack 'matrix))) - (set! (-> gp-0 vector 0 quad) (the-as uint128 0)) - (set! (-> gp-0 vector 1 quad) (the-as uint128 0)) - (set! (-> gp-0 vector 2 quad) (the-as uint128 0)) - (set! (-> gp-0 vector 3 quad) (the-as uint128 0)) - (let ((s5-0 (new 'stack 'matrix))) - (set! (-> s5-0 vector 0 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 1 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 2 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 3 quad) (the-as uint128 0)) - (matrix-rotate-z! arg0 (-> arg1 data 2)) - (matrix-rotate-x! gp-0 (-> arg1 data 0)) - (matrix*! s5-0 gp-0 arg0) - (matrix-rotate-y! gp-0 (-> arg1 data 1)) - (matrix*! arg0 gp-0 s5-0) +(defun matrix-rotate-yxz! ((dst matrix) (rot-xyz-deg vector)) + (let ((temp-mat (new 'stack 'matrix))) + (set! (-> temp-mat vector 0 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 1 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 2 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 3 quad) (the-as uint128 0)) + (let ((rot-mat (new 'stack 'matrix))) + (set! (-> rot-mat vector 0 quad) (the-as uint128 0)) + (set! (-> rot-mat vector 1 quad) (the-as uint128 0)) + (set! (-> rot-mat vector 2 quad) (the-as uint128 0)) + (set! (-> rot-mat vector 3 quad) (the-as uint128 0)) + (matrix-rotate-z! dst (-> rot-xyz-deg data 2)) + (matrix-rotate-x! temp-mat (-> rot-xyz-deg data 0)) + (matrix*! rot-mat temp-mat dst) + (matrix-rotate-y! temp-mat (-> rot-xyz-deg data 1)) + (matrix*! dst temp-mat rot-mat) ) ) - arg0 + dst ) ;; definition for function matrix-rotate-yzx! ;; Used lq/sq -(defun matrix-rotate-yzx! ((arg0 matrix) (arg1 vector)) - (let ((gp-0 (new 'stack 'matrix))) - (set! (-> gp-0 vector 0 quad) (the-as uint128 0)) - (set! (-> gp-0 vector 1 quad) (the-as uint128 0)) - (set! (-> gp-0 vector 2 quad) (the-as uint128 0)) - (set! (-> gp-0 vector 3 quad) (the-as uint128 0)) - (let ((s5-0 (new 'stack 'matrix))) - (set! (-> s5-0 vector 0 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 1 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 2 quad) (the-as uint128 0)) - (set! (-> s5-0 vector 3 quad) (the-as uint128 0)) - (matrix-rotate-z! arg0 (-> arg1 data 0)) - (matrix-rotate-x! gp-0 (-> arg1 data 2)) - (matrix*! s5-0 gp-0 arg0) - (matrix-rotate-y! gp-0 (-> arg1 data 1)) - (matrix*! arg0 gp-0 s5-0) +(defun matrix-rotate-yzx! ((dst matrix) (rot-xyz-deg vector)) + (let ((temp-mat (new 'stack 'matrix))) + (set! (-> temp-mat vector 0 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 1 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 2 quad) (the-as uint128 0)) + (set! (-> temp-mat vector 3 quad) (the-as uint128 0)) + (let ((rot-mat (new 'stack 'matrix))) + (set! (-> rot-mat vector 0 quad) (the-as uint128 0)) + (set! (-> rot-mat vector 1 quad) (the-as uint128 0)) + (set! (-> rot-mat vector 2 quad) (the-as uint128 0)) + (set! (-> rot-mat vector 3 quad) (the-as uint128 0)) + (matrix-rotate-z! dst (-> rot-xyz-deg data 0)) + (matrix-rotate-x! temp-mat (-> rot-xyz-deg data 2)) + (matrix*! rot-mat temp-mat dst) + (matrix-rotate-y! temp-mat (-> rot-xyz-deg data 1)) + (matrix*! dst temp-mat rot-mat) ) ) - arg0 + dst ) ;; definition for function matrix-rotate-yxy! -(defun matrix-rotate-yxy! ((arg0 matrix) (arg1 vector)) - (let ((a2-0 (new 'stack 'vector)) - (s5-0 (new 'stack 'vector)) - (s4-0 (new 'stack 'vector)) +(defun matrix-rotate-yxy! ((dst matrix) (rots-deg vector)) + (let ((sincos-input (new 'stack 'vector)) + (sin-vec (new 'stack 'vector)) + (cos-vec (new 'stack 'vector)) ) - (let ((v1-0 a2-0)) - (set! (-> v1-0 data 0) (-> arg1 data 0)) - (set! (-> v1-0 data 1) (- (-> arg1 data 1) (-> arg1 data 2))) - (set! (-> v1-0 data 2) (-> arg1 data 2)) + (let ((v1-0 sincos-input)) + (set! (-> v1-0 data 0) (-> rots-deg data 0)) + (set! (-> v1-0 data 1) (- (-> rots-deg data 1) (-> rots-deg data 2))) + (set! (-> v1-0 data 2) (-> rots-deg data 2)) (set! (-> v1-0 data 3) 1.0) ) - (vector-sincos! s5-0 s4-0 a2-0) - (let ((f1-1 (-> s4-0 data 1)) - (f0-5 (-> s5-0 data 1)) - (f2-0 (-> s4-0 data 0)) - (f5-0 (-> s5-0 data 0)) - (f3-0 (-> s4-0 data 2)) - (f4-0 (-> s5-0 data 2)) + (vector-sincos! sin-vec cos-vec sincos-input) + (let ((cos-y (-> cos-vec data 1)) + (sin-y (-> sin-vec data 1)) + (cos-x (-> cos-vec data 0)) + (sin-x (-> sin-vec data 0)) + (cos-z (-> cos-vec data 2)) + (sin-z (-> sin-vec data 2)) ) - (set! (-> arg0 data 0) (- (* f1-1 f3-0) (* (* f0-5 f2-0) f4-0))) - (set! (-> arg0 data 1) (* f0-5 f5-0)) - (set! (-> arg0 data 2) (- (+ (* f1-1 f4-0) (* (* f0-5 f2-0) f3-0)))) - (set! (-> arg0 data 3) 0.0) - (set! (-> arg0 data 4) (* f5-0 f4-0)) - (set! (-> arg0 data 5) f2-0) - (set! (-> arg0 data 6) (* f5-0 f3-0)) - (set! (-> arg0 data 7) 0.0) - (set! (-> arg0 data 8) (+ (* f0-5 f3-0) (* (* f1-1 f2-0) f4-0))) - (set! (-> arg0 data 9) (- (* f1-1 f5-0))) - (set! (-> arg0 data 10) (- (* (* f1-1 f2-0) f3-0) (* f0-5 f4-0))) + (set! (-> dst data 0) (- (* cos-y cos-z) (* (* sin-y cos-x) sin-z))) + (set! (-> dst data 1) (* sin-y sin-x)) + (set! (-> dst data 2) (- (+ (* cos-y sin-z) (* (* sin-y cos-x) cos-z)))) + (set! (-> dst data 3) 0.0) + (set! (-> dst data 4) (* sin-x sin-z)) + (set! (-> dst data 5) cos-x) + (set! (-> dst data 6) (* sin-x cos-z)) + (set! (-> dst data 7) 0.0) + (set! (-> dst data 8) (+ (* sin-y cos-z) (* (* cos-y cos-x) sin-z))) + (set! (-> dst data 9) (- (* cos-y sin-x))) + (set! (-> dst data 10) (- (* (* cos-y cos-x) cos-z) (* sin-y sin-z))) ) ) - (set! (-> arg0 data 11) 0.0) - (set! (-> arg0 data 12) 0.0) - (set! (-> arg0 data 13) 0.0) - (set! (-> arg0 data 14) 0.0) + (set! (-> dst data 11) 0.0) + (set! (-> dst data 12) 0.0) + (set! (-> dst data 13) 0.0) + (set! (-> dst data 14) 0.0) (let ((f0-12 1.0)) - (set! (-> arg0 data 15) f0-12) + (set! (-> dst data 15) f0-12) (let ((v1-1 f0-12)) ) ) - arg0 + dst ) ;; definition for function matrix-rotate-yx! ;; Used lq/sq -(defun matrix-rotate-yx! ((arg0 matrix) (arg1 float) (arg2 float)) - (matrix-rotate-y! arg0 arg1) +(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 'matrix)) ) @@ -840,11 +832,11 @@ (set! (-> a0-2 vector 1 quad) (the-as uint128 0)) (set! (-> a0-2 vector 2 quad) (the-as uint128 0)) (set! (-> a0-2 vector 3 quad) (the-as uint128 0)) - (let ((a1-2 (t9-1 a0-2 arg2))) - (matrix*! arg0 a1-2 arg0) + (let ((a1-2 (t9-1 a0-2 rot-x-deg))) + (matrix*! dst a1-2 dst) ) ) - arg0 + dst ) ;; definition for function matrix-axis-sin-cos-vu! @@ -854,13 +846,13 @@ ;; ERROR: function was not converted to expressions. Cannot decompile. ;; definition for function matrix-axis-angle! -(defun matrix-axis-angle! ((arg0 matrix) (arg1 vector) (arg2 float)) - (matrix-axis-sin-cos! arg0 arg1 (sin arg2) (cos arg2)) +(defun matrix-axis-angle! ((dst matrix) (axis vector) (angle-deg float)) + (matrix-axis-sin-cos! dst axis (sin angle-deg) (cos angle-deg)) (none) ) ;; definition for function matrix-lerp! -(defun matrix-lerp! ((arg0 matrix) (arg1 matrix) (arg2 matrix) (arg3 float)) +(defun matrix-lerp! ((dst matrix) (src1 matrix) (src2 matrix) (alpha float)) (rlet ((vf1 :class vf) (vf2 :class vf) (vf3 :class vf) @@ -871,15 +863,15 @@ (vf8 :class vf) (vf9 :class vf) ) - (.mov vf9 arg3) - (.lvf vf1 (&-> arg1 vector 0 quad)) - (.lvf vf2 (&-> arg1 vector 1 quad)) - (.lvf vf3 (&-> arg1 vector 2 quad)) - (.lvf vf4 (&-> arg1 vector 3 quad)) - (.lvf vf5 (&-> arg2 vector 0 quad)) - (.lvf vf6 (&-> arg2 vector 1 quad)) - (.lvf vf7 (&-> arg2 vector 2 quad)) - (.lvf vf8 (&-> arg2 vector 3 quad)) + (.mov vf9 alpha) + (.lvf vf1 (&-> src1 vector 0 quad)) + (.lvf vf2 (&-> src1 vector 1 quad)) + (.lvf vf3 (&-> src1 vector 2 quad)) + (.lvf vf4 (&-> src1 vector 3 quad)) + (.lvf vf5 (&-> src2 vector 0 quad)) + (.lvf vf6 (&-> src2 vector 1 quad)) + (.lvf vf7 (&-> src2 vector 2 quad)) + (.lvf vf8 (&-> src2 vector 3 quad)) (.sub.vf vf5 vf5 vf1) (.sub.vf vf6 vf6 vf2) (.sub.vf vf7 vf7 vf3) @@ -892,25 +884,25 @@ (.add.vf vf2 vf2 vf6) (.add.vf vf3 vf3 vf7) (.add.vf vf4 vf4 vf8) - (.svf (&-> arg0 vector 0 quad) vf1) - (.svf (&-> arg0 vector 1 quad) vf2) - (.svf (&-> arg0 vector 2 quad) vf3) - (.svf (&-> arg0 vector 3 quad) vf4) - arg0 + (.svf (&-> dst vector 0 quad) vf1) + (.svf (&-> dst vector 1 quad) vf2) + (.svf (&-> dst vector 2 quad) vf3) + (.svf (&-> dst vector 3 quad) vf4) + dst ) ) ;; definition for function matrix-3x3-determinant -(defun matrix-3x3-determinant ((arg0 matrix)) - (let ((f8-0 (-> arg0 data 0)) - (f1-0 (-> arg0 data 1)) - (f4-0 (-> arg0 data 2)) - (f2-0 (-> arg0 data 4)) - (f5-0 (-> arg0 data 5)) - (f9-0 (-> arg0 data 6)) - (f3-0 (-> arg0 data 8)) - (f6-0 (-> arg0 data 9)) - (f0-0 (-> arg0 data 10)) +(defun matrix-3x3-determinant ((mat matrix)) + (let ((f8-0 (-> mat data 0)) + (f1-0 (-> mat data 1)) + (f4-0 (-> mat data 2)) + (f2-0 (-> mat data 4)) + (f5-0 (-> mat data 5)) + (f9-0 (-> mat data 6)) + (f3-0 (-> mat data 8)) + (f6-0 (-> mat data 9)) + (f0-0 (-> mat data 10)) ) (- (+ (+ (* (* f8-0 f5-0) f0-0) (* (* f1-0 f9-0) f3-0)) (* (* f4-0 f2-0) f6-0)) @@ -942,201 +934,171 @@ ) ;; definition for function matrix-3x3-inverse! -(defun matrix-3x3-inverse! ((arg0 matrix) (arg1 matrix)) - (let ((f0-0 (matrix-3x3-determinant arg1))) +(defun matrix-3x3-inverse! ((dst matrix) (src matrix)) + (let ((f0-0 (matrix-3x3-determinant src))) (set! - (-> arg0 data 0) + (-> dst data 0) (/ (- - (* (-> arg1 data 5) (-> arg1 data 10)) - (* (-> arg1 data 6) (-> arg1 data 9)) + (* (-> src data 5) (-> src data 10)) + (* (-> src data 6) (-> src data 9)) ) f0-0 ) ) (set! - (-> arg0 data 4) + (-> dst data 4) (/ (- - (* (-> arg1 data 6) (-> arg1 data 8)) - (* (-> arg1 data 4) (-> arg1 data 10)) + (* (-> src data 6) (-> src data 8)) + (* (-> src data 4) (-> src data 10)) ) f0-0 ) ) (set! - (-> arg0 data 8) + (-> dst data 8) + (/ + (- (* (-> src data 4) (-> src data 9)) (* (-> src data 5) (-> src data 8))) + f0-0 + ) + ) + (set! + (-> dst data 1) (/ (- - (* (-> arg1 data 4) (-> arg1 data 9)) - (* (-> arg1 data 5) (-> arg1 data 8)) + (* (-> src data 9) (-> src data 2)) + (* (-> src data 10) (-> src data 1)) ) f0-0 ) ) (set! - (-> arg0 data 1) + (-> dst data 5) (/ (- - (* (-> arg1 data 9) (-> arg1 data 2)) - (* (-> arg1 data 10) (-> arg1 data 1)) + (* (-> src data 10) (-> src data 0)) + (* (-> src data 8) (-> src data 2)) ) f0-0 ) ) (set! - (-> arg0 data 5) + (-> dst data 9) (/ - (- - (* (-> arg1 data 10) (-> arg1 data 0)) - (* (-> arg1 data 8) (-> arg1 data 2)) - ) + (- (* (-> src data 8) (-> src data 1)) (* (-> src data 9) (-> src data 0))) f0-0 ) ) (set! - (-> arg0 data 9) + (-> dst data 2) (/ - (- - (* (-> arg1 data 8) (-> arg1 data 1)) - (* (-> arg1 data 9) (-> arg1 data 0)) - ) + (- (* (-> src data 1) (-> src data 6)) (* (-> src data 2) (-> src data 5))) f0-0 ) ) (set! - (-> arg0 data 2) + (-> dst data 6) (/ - (- - (* (-> arg1 data 1) (-> arg1 data 6)) - (* (-> arg1 data 2) (-> arg1 data 5)) - ) + (- (* (-> src data 2) (-> src data 4)) (* (-> src data 0) (-> src data 6))) f0-0 ) ) (set! - (-> arg0 data 6) + (-> dst data 10) (/ - (- - (* (-> arg1 data 2) (-> arg1 data 4)) - (* (-> arg1 data 0) (-> arg1 data 6)) - ) - f0-0 - ) - ) - (set! - (-> arg0 data 10) - (/ - (- - (* (-> arg1 data 0) (-> arg1 data 5)) - (* (-> arg1 data 1) (-> arg1 data 4)) - ) + (- (* (-> src data 0) (-> src data 5)) (* (-> src data 1) (-> src data 4))) f0-0 ) ) ) - arg0 + dst ) ;; definition for function matrix-3x3-inverse-transpose! -(defun matrix-3x3-inverse-transpose! ((arg0 matrix) (arg1 matrix)) - (let ((f0-0 (matrix-3x3-determinant arg1))) +(defun matrix-3x3-inverse-transpose! ((dst matrix) (src matrix)) + (let ((f0-0 (matrix-3x3-determinant src))) (set! - (-> arg0 data 0) + (-> dst data 0) (/ (- - (* (-> arg1 data 5) (-> arg1 data 10)) - (* (-> arg1 data 6) (-> arg1 data 9)) + (* (-> src data 5) (-> src data 10)) + (* (-> src data 6) (-> src data 9)) ) f0-0 ) ) (set! - (-> arg0 data 1) + (-> dst data 1) (/ (- - (* (-> arg1 data 6) (-> arg1 data 8)) - (* (-> arg1 data 4) (-> arg1 data 10)) + (* (-> src data 6) (-> src data 8)) + (* (-> src data 4) (-> src data 10)) ) f0-0 ) ) (set! - (-> arg0 data 2) + (-> dst data 2) + (/ + (- (* (-> src data 4) (-> src data 9)) (* (-> src data 5) (-> src data 8))) + f0-0 + ) + ) + (set! + (-> dst data 4) (/ (- - (* (-> arg1 data 4) (-> arg1 data 9)) - (* (-> arg1 data 5) (-> arg1 data 8)) + (* (-> src data 9) (-> src data 2)) + (* (-> src data 10) (-> src data 1)) ) f0-0 ) ) (set! - (-> arg0 data 4) + (-> dst data 5) (/ (- - (* (-> arg1 data 9) (-> arg1 data 2)) - (* (-> arg1 data 10) (-> arg1 data 1)) + (* (-> src data 10) (-> src data 0)) + (* (-> src data 8) (-> src data 2)) ) f0-0 ) ) (set! - (-> arg0 data 5) + (-> dst data 6) (/ - (- - (* (-> arg1 data 10) (-> arg1 data 0)) - (* (-> arg1 data 8) (-> arg1 data 2)) - ) + (- (* (-> src data 8) (-> src data 1)) (* (-> src data 9) (-> src data 0))) f0-0 ) ) (set! - (-> arg0 data 6) + (-> dst data 8) (/ - (- - (* (-> arg1 data 8) (-> arg1 data 1)) - (* (-> arg1 data 9) (-> arg1 data 0)) - ) + (- (* (-> src data 1) (-> src data 6)) (* (-> src data 2) (-> src data 5))) f0-0 ) ) (set! - (-> arg0 data 8) + (-> dst data 9) (/ - (- - (* (-> arg1 data 1) (-> arg1 data 6)) - (* (-> arg1 data 2) (-> arg1 data 5)) - ) + (- (* (-> src data 2) (-> src data 4)) (* (-> src data 0) (-> src data 6))) f0-0 ) ) (set! - (-> arg0 data 9) + (-> dst data 10) (/ - (- - (* (-> arg1 data 2) (-> arg1 data 4)) - (* (-> arg1 data 0) (-> arg1 data 6)) - ) - f0-0 - ) - ) - (set! - (-> arg0 data 10) - (/ - (- - (* (-> arg1 data 0) (-> arg1 data 5)) - (* (-> arg1 data 1) (-> arg1 data 4)) - ) + (- (* (-> src data 0) (-> src data 5)) (* (-> src data 1) (-> src data 4))) f0-0 ) ) ) - arg0 + dst ) ;; definition for function matrix3-inverse-transpose! -(defun matrix3-inverse-transpose! ((arg0 matrix) (arg1 matrix)) +(defun matrix3-inverse-transpose! ((dst matrix) (src matrix)) (rlet ((acc :class vf) (Q :class vf) (vf0 :class vf) @@ -1149,9 +1111,9 @@ (vf15 :class vf) ) (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (.lvf vf10 (&-> arg1 vector 0 quad)) - (.lvf vf11 (&-> arg1 vector 1 quad)) - (.lvf vf12 (&-> arg1 vector 2 quad)) + (.lvf vf10 (&-> src vector 0 quad)) + (.lvf vf11 (&-> src vector 1 quad)) + (.lvf vf12 (&-> src vector 2 quad)) (.outer.product.vf vf13 vf11 vf12) (.outer.product.vf vf14 vf12 vf10) (.mul.vf vf1 vf10 vf13 :mask #b111) @@ -1165,38 +1127,38 @@ (.nop.vf) (.nop.vf) (.nop.vf) - (.div.vf Q vf0 vf1 :ftf #b11 :fsf #b0) + (.div.vf Q vf0 vf1 :fsf #b11 :ftf #b0) (.wait.vf) (.mul.vf vf13 vf13 Q) (.mul.vf vf14 vf14 Q) (.mul.vf vf15 vf15 Q) (.nop.vf) (.nop.vf) - (.svf (&-> arg0 vector 0 quad) vf13) - (.svf (&-> arg0 vector 1 quad) vf14) - (.svf (&-> arg0 vector 2 quad) vf15) - arg0 + (.svf (&-> dst vector 0 quad) vf13) + (.svf (&-> dst vector 1 quad) vf14) + (.svf (&-> dst vector 2 quad) vf15) + dst ) ) ;; definition for function matrix-4x4-determinant -(defun matrix-4x4-determinant ((arg0 matrix)) - (let ((f15-0 (-> arg0 data 0)) - (f14-0 (-> arg0 data 1)) - (f10-0 (-> arg0 data 2)) - (f2-0 (-> arg0 data 3)) - (f9-0 (-> arg0 data 4)) - (f6-0 (-> arg0 data 5)) - (f3-0 (-> arg0 data 6)) - (f11-0 (-> arg0 data 7)) - (f5-0 (-> arg0 data 8)) - (f1-0 (-> arg0 data 9)) - (f8-0 (-> arg0 data 10)) - (f13-0 (-> arg0 data 11)) - (f0-0 (-> arg0 data 12)) - (f7-0 (-> arg0 data 13)) - (f4-0 (-> arg0 data 14)) - (f12-0 (-> arg0 data 15)) +(defun matrix-4x4-determinant ((dst matrix)) + (let ((f15-0 (-> dst data 0)) + (f14-0 (-> dst data 1)) + (f10-0 (-> dst data 2)) + (f2-0 (-> dst data 3)) + (f9-0 (-> dst data 4)) + (f6-0 (-> dst data 5)) + (f3-0 (-> dst data 6)) + (f11-0 (-> dst data 7)) + (f5-0 (-> dst data 8)) + (f1-0 (-> dst data 9)) + (f8-0 (-> dst data 10)) + (f13-0 (-> dst data 11)) + (f0-0 (-> dst data 12)) + (f7-0 (-> dst data 13)) + (f4-0 (-> dst data 14)) + (f12-0 (-> dst data 15)) ) (- (+ @@ -1272,20 +1234,20 @@ ) ;; definition for function matrix-4x4-inverse-transpose! -(defun matrix-4x4-inverse-transpose! ((arg0 matrix) (arg1 matrix)) - (let ((f0-0 (matrix-4x4-determinant arg1))) - (let ((f9-0 (-> arg1 data 5)) - (f2-0 (-> arg1 data 6)) - (f5-0 (-> arg1 data 7)) - (f3-0 (-> arg1 data 9)) - (f6-0 (-> arg1 data 10)) - (f10-0 (-> arg1 data 11)) - (f4-0 (-> arg1 data 13)) - (f7-0 (-> arg1 data 14)) - (f1-0 (-> arg1 data 15)) +(defun matrix-4x4-inverse-transpose! ((dst matrix) (src matrix)) + (let ((f0-0 (matrix-4x4-determinant src))) + (let ((f9-0 (-> src data 5)) + (f2-0 (-> src data 6)) + (f5-0 (-> src data 7)) + (f3-0 (-> src data 9)) + (f6-0 (-> src data 10)) + (f10-0 (-> src data 11)) + (f4-0 (-> src data 13)) + (f7-0 (-> src data 14)) + (f1-0 (-> src data 15)) ) (set! - (-> arg0 data 0) + (-> dst data 0) (/ (- (+ @@ -1301,18 +1263,18 @@ ) ) ) - (let ((f9-2 (-> arg1 data 4)) - (f2-2 (-> arg1 data 6)) - (f5-2 (-> arg1 data 7)) - (f3-1 (-> arg1 data 8)) - (f6-1 (-> arg1 data 10)) - (f10-1 (-> arg1 data 11)) - (f4-3 (-> arg1 data 12)) - (f7-2 (-> arg1 data 14)) - (f1-6 (-> arg1 data 15)) + (let ((f9-2 (-> src data 4)) + (f2-2 (-> src data 6)) + (f5-2 (-> src data 7)) + (f3-1 (-> src data 8)) + (f6-1 (-> src data 10)) + (f10-1 (-> src data 11)) + (f4-3 (-> src data 12)) + (f7-2 (-> src data 14)) + (f1-6 (-> src data 15)) ) (set! - (-> arg0 data 1) + (-> dst data 1) (- (/ (- @@ -1330,18 +1292,18 @@ ) ) ) - (let ((f9-4 (-> arg1 data 4)) - (f2-4 (-> arg1 data 5)) - (f5-4 (-> arg1 data 7)) - (f3-2 (-> arg1 data 8)) - (f6-2 (-> arg1 data 9)) - (f10-2 (-> arg1 data 11)) - (f4-6 (-> arg1 data 12)) - (f7-4 (-> arg1 data 13)) - (f1-13 (-> arg1 data 15)) + (let ((f9-4 (-> src data 4)) + (f2-4 (-> src data 5)) + (f5-4 (-> src data 7)) + (f3-2 (-> src data 8)) + (f6-2 (-> src data 9)) + (f10-2 (-> src data 11)) + (f4-6 (-> src data 12)) + (f7-4 (-> src data 13)) + (f1-13 (-> src data 15)) ) (set! - (-> arg0 data 2) + (-> dst data 2) (/ (- (+ @@ -1357,18 +1319,18 @@ ) ) ) - (let ((f9-6 (-> arg1 data 4)) - (f2-6 (-> arg1 data 5)) - (f5-6 (-> arg1 data 6)) - (f3-3 (-> arg1 data 8)) - (f6-3 (-> arg1 data 9)) - (f10-3 (-> arg1 data 10)) - (f4-9 (-> arg1 data 12)) - (f7-6 (-> arg1 data 13)) - (f1-19 (-> arg1 data 14)) + (let ((f9-6 (-> src data 4)) + (f2-6 (-> src data 5)) + (f5-6 (-> src data 6)) + (f3-3 (-> src data 8)) + (f6-3 (-> src data 9)) + (f10-3 (-> src data 10)) + (f4-9 (-> src data 12)) + (f7-6 (-> src data 13)) + (f1-19 (-> src data 14)) ) (set! - (-> arg0 data 3) + (-> dst data 3) (- (/ (- @@ -1386,18 +1348,18 @@ ) ) ) - (let ((f9-8 (-> arg1 data 1)) - (f2-8 (-> arg1 data 2)) - (f5-8 (-> arg1 data 3)) - (f3-4 (-> arg1 data 9)) - (f6-4 (-> arg1 data 10)) - (f10-4 (-> arg1 data 11)) - (f4-12 (-> arg1 data 13)) - (f7-8 (-> arg1 data 14)) - (f1-26 (-> arg1 data 15)) + (let ((f9-8 (-> src data 1)) + (f2-8 (-> src data 2)) + (f5-8 (-> src data 3)) + (f3-4 (-> src data 9)) + (f6-4 (-> src data 10)) + (f10-4 (-> src data 11)) + (f4-12 (-> src data 13)) + (f7-8 (-> src data 14)) + (f1-26 (-> src data 15)) ) (set! - (-> arg0 data 4) + (-> dst data 4) (- (/ (- @@ -1415,18 +1377,18 @@ ) ) ) - (let ((f9-10 (-> arg1 data 0)) - (f2-10 (-> arg1 data 2)) - (f5-10 (-> arg1 data 3)) - (f3-5 (-> arg1 data 8)) - (f6-5 (-> arg1 data 10)) - (f10-5 (-> arg1 data 11)) - (f4-15 (-> arg1 data 12)) - (f7-10 (-> arg1 data 14)) - (f1-33 (-> arg1 data 15)) + (let ((f9-10 (-> src data 0)) + (f2-10 (-> src data 2)) + (f5-10 (-> src data 3)) + (f3-5 (-> src data 8)) + (f6-5 (-> src data 10)) + (f10-5 (-> src data 11)) + (f4-15 (-> src data 12)) + (f7-10 (-> src data 14)) + (f1-33 (-> src data 15)) ) (set! - (-> arg0 data 5) + (-> dst data 5) (/ (- (+ @@ -1442,18 +1404,18 @@ ) ) ) - (let ((f9-12 (-> arg1 data 0)) - (f2-12 (-> arg1 data 1)) - (f5-12 (-> arg1 data 3)) - (f3-6 (-> arg1 data 8)) - (f6-6 (-> arg1 data 9)) - (f10-6 (-> arg1 data 11)) - (f4-18 (-> arg1 data 12)) - (f7-12 (-> arg1 data 13)) - (f1-39 (-> arg1 data 15)) + (let ((f9-12 (-> src data 0)) + (f2-12 (-> src data 1)) + (f5-12 (-> src data 3)) + (f3-6 (-> src data 8)) + (f6-6 (-> src data 9)) + (f10-6 (-> src data 11)) + (f4-18 (-> src data 12)) + (f7-12 (-> src data 13)) + (f1-39 (-> src data 15)) ) (set! - (-> arg0 data 6) + (-> dst data 6) (- (/ (- @@ -1471,18 +1433,18 @@ ) ) ) - (let ((f9-14 (-> arg1 data 0)) - (f2-14 (-> arg1 data 1)) - (f5-14 (-> arg1 data 2)) - (f3-7 (-> arg1 data 8)) - (f6-7 (-> arg1 data 9)) - (f10-7 (-> arg1 data 10)) - (f4-21 (-> arg1 data 12)) - (f7-14 (-> arg1 data 13)) - (f1-46 (-> arg1 data 14)) + (let ((f9-14 (-> src data 0)) + (f2-14 (-> src data 1)) + (f5-14 (-> src data 2)) + (f3-7 (-> src data 8)) + (f6-7 (-> src data 9)) + (f10-7 (-> src data 10)) + (f4-21 (-> src data 12)) + (f7-14 (-> src data 13)) + (f1-46 (-> src data 14)) ) (set! - (-> arg0 data 7) + (-> dst data 7) (/ (- (+ @@ -1498,18 +1460,18 @@ ) ) ) - (let ((f9-16 (-> arg1 data 1)) - (f2-16 (-> arg1 data 2)) - (f5-16 (-> arg1 data 3)) - (f3-8 (-> arg1 data 5)) - (f6-8 (-> arg1 data 6)) - (f10-8 (-> arg1 data 7)) - (f4-24 (-> arg1 data 13)) - (f7-16 (-> arg1 data 14)) - (f1-52 (-> arg1 data 15)) + (let ((f9-16 (-> src data 1)) + (f2-16 (-> src data 2)) + (f5-16 (-> src data 3)) + (f3-8 (-> src data 5)) + (f6-8 (-> src data 6)) + (f10-8 (-> src data 7)) + (f4-24 (-> src data 13)) + (f7-16 (-> src data 14)) + (f1-52 (-> src data 15)) ) (set! - (-> arg0 data 8) + (-> dst data 8) (/ (- (+ @@ -1525,18 +1487,18 @@ ) ) ) - (let ((f9-18 (-> arg1 data 0)) - (f2-18 (-> arg1 data 2)) - (f5-18 (-> arg1 data 3)) - (f3-9 (-> arg1 data 4)) - (f6-9 (-> arg1 data 6)) - (f10-9 (-> arg1 data 7)) - (f4-27 (-> arg1 data 12)) - (f7-18 (-> arg1 data 14)) - (f1-58 (-> arg1 data 15)) + (let ((f9-18 (-> src data 0)) + (f2-18 (-> src data 2)) + (f5-18 (-> src data 3)) + (f3-9 (-> src data 4)) + (f6-9 (-> src data 6)) + (f10-9 (-> src data 7)) + (f4-27 (-> src data 12)) + (f7-18 (-> src data 14)) + (f1-58 (-> src data 15)) ) (set! - (-> arg0 data 9) + (-> dst data 9) (- (/ (- @@ -1554,18 +1516,18 @@ ) ) ) - (let ((f9-20 (-> arg1 data 0)) - (f2-20 (-> arg1 data 1)) - (f5-20 (-> arg1 data 3)) - (f3-10 (-> arg1 data 4)) - (f6-10 (-> arg1 data 5)) - (f10-10 (-> arg1 data 7)) - (f4-30 (-> arg1 data 12)) - (f7-20 (-> arg1 data 13)) - (f1-65 (-> arg1 data 15)) + (let ((f9-20 (-> src data 0)) + (f2-20 (-> src data 1)) + (f5-20 (-> src data 3)) + (f3-10 (-> src data 4)) + (f6-10 (-> src data 5)) + (f10-10 (-> src data 7)) + (f4-30 (-> src data 12)) + (f7-20 (-> src data 13)) + (f1-65 (-> src data 15)) ) (set! - (-> arg0 data 10) + (-> dst data 10) (/ (- (+ @@ -1581,18 +1543,18 @@ ) ) ) - (let ((f9-22 (-> arg1 data 0)) - (f2-22 (-> arg1 data 1)) - (f5-22 (-> arg1 data 2)) - (f3-11 (-> arg1 data 4)) - (f6-11 (-> arg1 data 5)) - (f10-11 (-> arg1 data 6)) - (f4-33 (-> arg1 data 12)) - (f7-22 (-> arg1 data 13)) - (f1-71 (-> arg1 data 14)) + (let ((f9-22 (-> src data 0)) + (f2-22 (-> src data 1)) + (f5-22 (-> src data 2)) + (f3-11 (-> src data 4)) + (f6-11 (-> src data 5)) + (f10-11 (-> src data 6)) + (f4-33 (-> src data 12)) + (f7-22 (-> src data 13)) + (f1-71 (-> src data 14)) ) (set! - (-> arg0 data 11) + (-> dst data 11) (- (/ (- @@ -1610,18 +1572,18 @@ ) ) ) - (let ((f9-24 (-> arg1 data 1)) - (f2-24 (-> arg1 data 2)) - (f5-24 (-> arg1 data 3)) - (f3-12 (-> arg1 data 5)) - (f6-12 (-> arg1 data 6)) - (f10-12 (-> arg1 data 7)) - (f4-36 (-> arg1 data 9)) - (f7-24 (-> arg1 data 10)) - (f1-78 (-> arg1 data 11)) + (let ((f9-24 (-> src data 1)) + (f2-24 (-> src data 2)) + (f5-24 (-> src data 3)) + (f3-12 (-> src data 5)) + (f6-12 (-> src data 6)) + (f10-12 (-> src data 7)) + (f4-36 (-> src data 9)) + (f7-24 (-> src data 10)) + (f1-78 (-> src data 11)) ) (set! - (-> arg0 data 12) + (-> dst data 12) (- (/ (- @@ -1639,18 +1601,18 @@ ) ) ) - (let ((f9-26 (-> arg1 data 0)) - (f2-26 (-> arg1 data 2)) - (f5-26 (-> arg1 data 3)) - (f3-13 (-> arg1 data 4)) - (f6-13 (-> arg1 data 6)) - (f10-13 (-> arg1 data 7)) - (f4-39 (-> arg1 data 8)) - (f7-26 (-> arg1 data 10)) - (f1-85 (-> arg1 data 11)) + (let ((f9-26 (-> src data 0)) + (f2-26 (-> src data 2)) + (f5-26 (-> src data 3)) + (f3-13 (-> src data 4)) + (f6-13 (-> src data 6)) + (f10-13 (-> src data 7)) + (f4-39 (-> src data 8)) + (f7-26 (-> src data 10)) + (f1-85 (-> src data 11)) ) (set! - (-> arg0 data 13) + (-> dst data 13) (/ (- (+ @@ -1666,18 +1628,18 @@ ) ) ) - (let ((f9-28 (-> arg1 data 0)) - (f2-28 (-> arg1 data 1)) - (f5-28 (-> arg1 data 3)) - (f3-14 (-> arg1 data 4)) - (f6-14 (-> arg1 data 5)) - (f10-14 (-> arg1 data 7)) - (f4-42 (-> arg1 data 8)) - (f7-28 (-> arg1 data 9)) - (f1-91 (-> arg1 data 11)) + (let ((f9-28 (-> src data 0)) + (f2-28 (-> src data 1)) + (f5-28 (-> src data 3)) + (f3-14 (-> src data 4)) + (f6-14 (-> src data 5)) + (f10-14 (-> src data 7)) + (f4-42 (-> src data 8)) + (f7-28 (-> src data 9)) + (f1-91 (-> src data 11)) ) (set! - (-> arg0 data 14) + (-> dst data 14) (- (/ (- @@ -1695,18 +1657,18 @@ ) ) ) - (let ((f8-60 (-> arg1 data 0)) - (f1-98 (-> arg1 data 1)) - (f5-30 (-> arg1 data 2)) - (f2-30 (-> arg1 data 4)) - (f6-15 (-> arg1 data 5)) - (f9-30 (-> arg1 data 6)) - (f4-45 (-> arg1 data 8)) - (f7-30 (-> arg1 data 9)) - (f3-15 (-> arg1 data 10)) + (let ((f8-60 (-> src data 0)) + (f1-98 (-> src data 1)) + (f5-30 (-> src data 2)) + (f2-30 (-> src data 4)) + (f6-15 (-> src data 5)) + (f9-30 (-> src data 6)) + (f4-45 (-> src data 8)) + (f7-30 (-> src data 9)) + (f3-15 (-> src data 10)) ) (set! - (-> arg0 data 15) + (-> dst data 15) (/ (- (+ @@ -1723,13 +1685,13 @@ ) ) ) - arg0 + dst ) ;; definition for function matrix-y-angle -(defun matrix-y-angle ((arg0 matrix)) - (let ((v1-0 (&-> arg0 data 8))) - (atan (-> v1-0 0) (-> v1-0 2)) +(defun matrix-y-angle ((mat matrix)) + (let ((z-row (&-> mat data 8))) + (atan (-> z-row 0) (-> z-row 2)) ) ) @@ -1738,4 +1700,3 @@ ;; failed to figure out what this is: (none) - diff --git a/test/decompiler/reference/vector-h_REF.gc b/test/decompiler/reference/vector-h_REF.gc index e3bfb9c692..e348021333 100644 --- a/test/decompiler/reference/vector-h_REF.gc +++ b/test/decompiler/reference/vector-h_REF.gc @@ -822,12 +822,11 @@ ) ;; definition for function vector-dot -;; INFO: Return type mismatch int vs float. -;; WARN: Unsupported inline assembly instruction kind - [153] -;; WARN: Unsupported inline assembly instruction kind - [154] -;; WARN: Unsupported inline assembly instruction kind - [157] +;; WARN: Unsupported inline assembly instruction kind - [mula.s f0, f3] +;; WARN: Unsupported inline assembly instruction kind - [madda.s f1, f4] +;; WARN: Unsupported inline assembly instruction kind - [madd.s f0, f2, f5] (defun vector-dot ((arg0 vector) (arg1 vector)) - (local-vars (f0-1 int)) + (local-vars (f0-1 float)) (let ((f0-0 (-> arg0 data 0)) (f1-0 (-> arg0 data 1)) (f2-0 (-> arg0 data 2)) @@ -839,7 +838,7 @@ (.madda.s f1-0 f4-0) (.madd.s f0-1 f2-0 f5-0) ) - (the-as float f0-1) + f0-1 ) ;; definition for function vector-dot-vu @@ -860,13 +859,12 @@ ) ;; definition for function vector4-dot -;; INFO: Return type mismatch int vs float. -;; WARN: Unsupported inline assembly instruction kind - [153] -;; WARN: Unsupported inline assembly instruction kind - [154] -;; WARN: Unsupported inline assembly instruction kind - [154] -;; WARN: Unsupported inline assembly instruction kind - [157] +;; WARN: Unsupported inline assembly instruction kind - [mula.s f0, f4] +;; WARN: Unsupported inline assembly instruction kind - [madda.s f1, f5] +;; WARN: Unsupported inline assembly instruction kind - [madda.s f2, f6] +;; WARN: Unsupported inline assembly instruction kind - [madd.s f0, f3, f7] (defun vector4-dot ((arg0 vector) (arg1 vector)) - (local-vars (f0-1 int)) + (local-vars (f0-1 float)) (let ((f0-0 (-> arg0 data 0)) (f1-0 (-> arg0 data 1)) (f2-0 (-> arg0 data 2)) @@ -881,7 +879,7 @@ (.madda.s f2-0 f6-0) (.madd.s f0-1 f3-0 f7-0) ) - (the-as float f0-1) + f0-1 ) ;; definition for function vector4-dot-vu diff --git a/test/goalc/source_templates/with_game/test-matrix.gc b/test/goalc/source_templates/with_game/test-matrix.gc new file mode 100644 index 0000000000..9340c92445 --- /dev/null +++ b/test/goalc/source_templates/with_game/test-matrix.gc @@ -0,0 +1,164 @@ +(defmacro inspect-mat (obj) + `(begin + (format #t "~T[~F] [~F] [~F] [~F]~%" + (-> ,obj data 0) + (-> ,obj data 1) + (-> ,obj data 2) + (-> ,obj data 3) + ) + (format #t "~T[~F] [~F] [~F] [~F]~%" + (-> ,obj data 4) + (-> ,obj data 5) + (-> ,obj data 6) + (-> ,obj data 7) + ) + (format #t "~T[~F] [~F] [~F] [~F]~%" + (-> ,obj data 8) + (-> ,obj data 9) + (-> ,obj data 10) + (-> ,obj data 11) + ) + (format #t "~T[~F] [~F] [~F] [~F]~%" + (-> ,obj data 12) + (-> ,obj data 13) + (-> ,obj data 14) + (-> ,obj data 15) + ) + ) + ) + + +(format #t "mat-mult~%") +(let ((dst (new 'stack 'matrix)) + (src1 (new 'stack 'matrix)) + (src2 (new 'stack 'matrix))) + (dotimes (i 16) + (set! (-> src1 data i) (the float (+ i 1))) + (set! (-> src2 data i) (the float (- 16 i))) + ) + + (matrix*! dst src1 src2) + (inspect-mat dst) + ) + +(format #t "transpose~%") +(let ((dst (new 'stack 'matrix)) + (src (new 'stack 'matrix))) + (dotimes (i 16) + (set! (-> src data i) (the float (+ i 1))) + ) + + (matrix-transpose! dst src) + (inspect-mat dst) + ) + +(format #t "inv-4x4~%") +(let ((dst (new 'stack 'matrix)) + (prod (new 'stack 'matrix)) + (src (new 'static 'matrix :data (new 'static 'array float 16 + 3. 2. 1. 0. + 2. -1. 3. 0. + -8. 2. 2. 0. + 1. 2. 3. 1.)))) + (matrix-4x4-inverse! dst src) + (matrix*! prod src dst) + (inspect-mat prod) + ) + + +(format #t "axis-angle~%") +(defun test-axis-angle ((axis vector)) + (let ((mat (new 'stack 'matrix))) + + (let* ((norm-squared (+ (* (-> axis x) (-> axis x)) + (* (-> axis y) (-> axis y)) + (* (-> axis z) (-> axis z)) + ) + ) + + (norm (sqrtf norm-squared))) + + (when (> norm-squared 0) + (dotimes (i 3) + (set! (-> axis data i) (/ (-> axis data i) norm)) + ) + ) + (matrix-axis-angle! mat axis (degrees 10)) + (inspect-mat mat) + (format #t "~%") + ) + ) + ) + + +(test-axis-angle (new 'static 'vector :x 1.0 :y 0.5 :z -0.3 :w 0.0)) +(test-axis-angle (new 'static 'vector :x 0.2)) +(test-axis-angle (new 'static 'vector :y 0.2)) +(test-axis-angle (new 'static 'vector :z 0.2)) +(test-axis-angle (new 'static 'vector :w 0.2)) + +(format #t "3x3-inverse~%") +(let ((dst (new 'stack 'matrix)) + (src (new 'static 'matrix :data (new 'static 'array float 16 + 3. 2. 1. 0. + 2. -1. 3. 0. + -8. 2. 2. 0. + 0. 0. 0. 0.)))) + (matrix-3x3-inverse! dst src) + (inspect-mat dst) + (format #t "~%") + (matrix3-inverse-transpose! dst src) + (inspect-mat dst) + ) + +(deftype vec-array (structure) + ((data vector 32 :inline)) + ) + +(defmethod inspect vec-array ((obj vec-array)) + (format #t "vec-array~%") + (dotimes (i 12) + (format #t "~T[~F] [~F] [~F] [~F]~%" + (-> obj data i x) + (-> obj data i y) + (-> obj data i z) + (-> obj data i w) + ) + ) + obj + ) + +(format #t "transform-many~%") +(let ((dst (new 'stack 'vec-array)) + (dst-ref (new 'stack 'vec-array)) + (src (new 'stack 'vec-array)) + (val 0.0) + (mat (new 'static 'matrix :data (new 'static 'array float 16 + 3. 2. 1. 0. + 2. -1. 3. 0. + -8. 2. 2. 0. + 1. 2. 3. 1.)))) + + ;; init source + (dotimes (i 12) + (set! (-> dst data i quad) (the uint128 0)) + (dotimes (j 3) + (set! (-> src data i data j) val) + (set! val (+ val 1.0)) + ) + (set! (-> src data i w) 1.0) + ) + + ;;(inspect src) + + ;; compute reference: + (dotimes (i 12) + (vector-matrix*! (-> dst-ref data i) (-> src data i) mat) + ) + ;;(inspect dst-ref) + + ;; compute fancy thing + (transform-vectors! mat (-> dst data) (-> src data) 11) + (inspect dst) + 0 + ) \ No newline at end of file diff --git a/test/goalc/source_templates/with_game/test-pextlw.gc b/test/goalc/source_templates/with_game/test-pextlw.gc new file mode 100644 index 0000000000..35c099c203 --- /dev/null +++ b/test/goalc/source_templates/with_game/test-pextlw.gc @@ -0,0 +1,54 @@ +(let ((v1 (new 'stack 'array 'uint8 16)) + (v2 (new 'stack 'array 'uint8 16)) + (v3 (new 'stack 'array 'uint8 16)) + ) + + ;; initialize stack arrays + (dotimes (i 16) + (set! (-> v1 i) i) + (set! (-> v2 i) (+ i 16)) + ) + + (let ((v1-quad (-> (the (pointer uint128) v1))) + (v2-quad (-> (the (pointer uint128) v2))) + (v3-quad (the uint128 0)) + ) + (.pextlw v3-quad v1-quad v2-quad) + ;;(print128 v1-quad) (format #t "~%") + ;;(print128 v2-quad) (format #t "~%") + ;; expect #x07060504171615140302010013121110 + (print128 v3-quad) (format #t "~%") + + ;; expect #x0f0e0d0c1f1e1d1c0b0a09081b1a1918 + (.pextuw v3-quad v1-quad v2-quad) + (print128 v3-quad) (format #t "~%") + (.pcpyld v3-quad v1-quad v2-quad) + (print128 v3-quad) (format #t "~%") + (.pcpyud v3-quad v1-quad v2-quad) + (print128 v3-quad) (format #t "~%") + (.ppach v3-quad v1-quad v2-quad) + (print128 v3-quad) (format #t "~%") + ) + + (let ((s1 (new 'stack 'array 'uint32 4)) + (s2 (new 'stack 'array 'uint32 4))) + (set! (-> s1 0) #xdeadbeef) + (set! (-> s1 1) #x12312323) + (set! (-> s1 2) #x11112222) + (set! (-> s1 3) #x11112223) + + (set! (-> s2 0) #xdeadbeee) ;; different + (set! (-> s2 1) #x12312323) + (set! (-> s2 2) #x91112222) ;; different + (set! (-> s2 3) #x11112223) + + (let ((s1q (-> (the (pointer uint128) s1))) + (s2q (-> (the (pointer uint128) s2))) + (s3q (the uint128 0)) + ) + + (.pceqw s3q s1q s2q) + (print128 s3q) (format #t "~%") + ) + ) + ) \ No newline at end of file diff --git a/test/goalc/test_with_game.cpp b/test/goalc/test_with_game.cpp index 927fbbcbba..68d9aa13df 100644 --- a/test/goalc/test_with_game.cpp +++ b/test/goalc/test_with_game.cpp @@ -579,6 +579,87 @@ TEST_F(WithGameTests, I128Simple) { "12344321\n"}); } +TEST_F(WithGameTests, Pextlw) { + runner.run_static_test(env, testCategory, "test-pextlw.gc", + {"#x07060504171615140302010013121110\n" + "#x0f0e0d0c1f1e1d1c0b0a09081b1a1918\n" + "#x07060504030201001716151413121110\n" + "#x1f1e1d1c1b1a19180f0e0d0c0b0a0908\n" + "#x0d0c0908050401001d1c191815141110\n" + "#xffffffff00000000ffffffff00000000\n" + "0\n"}); +} + +TEST_F(WithGameTests, Matrix) { + runner.run_static_test(env, testCategory, "test-matrix.gc", + {"mat-mult\n" + "\t[ 80.0000] [ 70.0000] [ 60.0000] [ 50.0000]\n" + "\t[ 240.0000] [ 214.0000] [ 188.0000] [ 162.0000]\n" + "\t[ 400.0000] [ 358.0000] [ 316.0000] [ 274.0000]\n" + "\t[ 560.0000] [ 502.0000] [ 444.0000] [ 386.0000]\n" + "transpose\n" + "\t[ 1.0000] [ 5.0000] [ 9.0000] [ 13.0000]\n" + "\t[ 2.0000] [ 6.0000] [ 10.0000] [ 14.0000]\n" + "\t[ 3.0000] [ 7.0000] [ 11.0000] [ 15.0000]\n" + "\t[ 4.0000] [ 8.0000] [ 12.0000] [ 16.0000]\n" + "inv-4x4\n" + "\t[ 1.0000] [ 0.0000] [ 0.0000] [ 0.0000]\n" + "\t[ 0.0000] [ 1.0000] [ 0.0000] [ 0.0000]\n" + "\t[ 0.0000] [ 0.0000] [ 1.0000] [ 0.0000]\n" + "\t[ 0.0000] [ 0.0000] [ 0.0000] [ 1.0000]\n" + "axis-angle\n" + "\t[ 0.9961] [ 0.0506] [ 0.0715] [ 0.0000]\n" + "\t[ -0.0393] [ 0.9876] [ -0.1516] [ 0.0000]\n" + "\t[ -0.0783] [ 0.1482] [ 0.9858] [ 0.0000]\n" + "\t[ 0.0000] [ 0.0000] [ 0.0000] [ 1.0000]\n" + "\n" + "\t[ 1.0000] [ 0.0000] [ 0.0000] [ 0.0000]\n" + "\t[ 0.0000] [ 0.9848] [ -0.1736] [ 0.0000]\n" + "\t[ 0.0000] [ 0.1736] [ 0.9848] [ 0.0000]\n" + "\t[ 0.0000] [ 0.0000] [ 0.0000] [ 1.0000]\n" + "\n" + "\t[ 0.9848] [ 0.0000] [ 0.1736] [ 0.0000]\n" + "\t[ 0.0000] [ 1.0000] [ 0.0000] [ 0.0000]\n" + "\t[ -0.1736] [ 0.0000] [ 0.9848] [ 0.0000]\n" + "\t[ 0.0000] [ 0.0000] [ 0.0000] [ 1.0000]\n" + "\n" + "\t[ 0.9848] [ -0.1736] [ 0.0000] [ 0.0000]\n" + "\t[ 0.1736] [ 0.9848] [ 0.0000] [ 0.0000]\n" + "\t[ 0.0000] [ 0.0000] [ 1.0000] [ 0.0000]\n" + "\t[ 0.0000] [ 0.0000] [ 0.0000] [ 1.0000]\n" + "\n" + "\t[ 1.0000] [ 0.0000] [ 0.0000] [ 0.0000]\n" + "\t[ 0.0000] [ 1.0000] [ 0.0000] [ 0.0000]\n" + "\t[ 0.0000] [ 0.0000] [ 1.0000] [ 0.0000]\n" + "\t[ 0.0000] [ 0.0000] [ 0.0000] [ 1.0000]\n" + "\n" + "3x3-inverse\n" + "\t[ 0.0952] [ 0.0238] [ -0.0833] [ 0.0000]\n" + "\t[ 0.3333] [ -0.1666] [ 0.0833] [ 0.0000]\n" + "\t[ 0.0476] [ 0.2619] [ 0.0833] [ 0.0000]\n" + "\t[ 0.0000] [ 0.0000] [ 0.0000] [ 0.0000]\n" + "\n" + "\t[ 0.0952] [ 0.3333] [ 0.0476] [ 0.0000]\n" + "\t[ 0.0238] [ -0.1666] [ 0.2619] [ 0.0000]\n" + "\t[ -0.0833] [ 0.0833] [ 0.0833] [ 0.0000]\n" + "\t[ 0.0000] [ 0.0000] [ 0.0000] [ 0.0000]\n" + "transform-many\n" + "vec-array\n" + "\t[ -13.0000] [ 5.0000] [ 10.0000] [ 1.0000]\n" + "\t[ -22.0000] [ 14.0000] [ 28.0000] [ 1.0000]\n" + "\t[ -31.0000] [ 23.0000] [ 46.0000] [ 1.0000]\n" + "\t[ -40.0000] [ 32.0000] [ 64.0000] [ 1.0000]\n" + "\t[ -49.0000] [ 41.0000] [ 82.0000] [ 1.0000]\n" + "\t[ -58.0000] [ 50.0000] [ 100.0000] [ 1.0000]\n" + "\t[ -67.0000] [ 59.0000] [ 118.0000] [ 1.0000]\n" + "\t[ -76.0000] [ 68.0000] [ 136.0000] [ 1.0000]\n" + "\t[ -85.0000] [ 77.0000] [ 154.0000] [ 1.0000]\n" + "\t[ -94.0000] [ 86.0000] [ 172.0000] [ 1.0000]\n" + "\t[ -103.0000] [ 95.0000] [ 190.0000] [ 1.0000]\n" + "\t[ 0.0000] [ 0.0000] [ 0.0000] [ 0.0000]\n" + "0\n"}); +} + TEST(TypeConsistency, TypeConsistency) { Compiler compiler; compiler.enable_throw_on_redefines(); diff --git a/test/offline/offline_test_main.cpp b/test/offline/offline_test_main.cpp index 99a0dab0b7..51012b976e 100644 --- a/test/offline/offline_test_main.cpp +++ b/test/offline/offline_test_main.cpp @@ -92,10 +92,6 @@ const std::unordered_set skip_in_compiling = { "(method 3 vector)", // this function appears twice, which confuses the compiler. "vector-dot", // fpu acc "vector4-dot", // fpu acc - - /// MATRIX - "matrix-transpose!", // unsupported asm ops - "matrix-4x4-inverse!", // compiler fails to regalloc this... }; // default location for the data. It can be changed with a command line argument. diff --git a/test/test_emitter_avx.cpp b/test/test_emitter_avx.cpp index 78b204166c..83e54da831 100644 --- a/test/test_emitter_avx.cpp +++ b/test/test_emitter_avx.cpp @@ -371,4 +371,139 @@ TEST(EmitterAVX, VPSLLD) { tester.emit(IGen::pw_sll(XMM0 + 13, XMM0 + 4, 5)); tester.emit(IGen::pw_sll(XMM0 + 13, XMM0 + 14, 6)); EXPECT_EQ(tester.dump_to_hex_string(true), "C5E172F403C4C16172F604C59172F405C4C11172F606"); +} + +TEST(EmitterAVX, VPUNPCKLDQ) { + CodeTester tester; + tester.init_code_buffer(1024); + tester.emit(IGen::pextlw_swapped(XMM0 + 3, XMM0 + 3, XMM0 + 3)); + tester.emit(IGen::pextlw_swapped(XMM0 + 3, XMM0 + 3, XMM0 + 13)); + tester.emit(IGen::pextlw_swapped(XMM0 + 3, XMM0 + 13, XMM0 + 3)); + tester.emit(IGen::pextlw_swapped(XMM0 + 3, XMM0 + 13, XMM0 + 13)); + tester.emit(IGen::pextlw_swapped(XMM0 + 13, XMM0 + 3, XMM0 + 3)); + tester.emit(IGen::pextlw_swapped(XMM0 + 13, XMM0 + 3, XMM0 + 13)); + tester.emit(IGen::pextlw_swapped(XMM0 + 13, XMM0 + 13, XMM0 + 3)); + tester.emit(IGen::pextlw_swapped(XMM0 + 13, XMM0 + 13, XMM0 + 13)); + EXPECT_EQ(tester.dump_to_hex_string(true), + "C5E162DBC4C16162DDC59162DBC4C11162DDC56162EBC4416162EDC51162EBC4411162ED"); +} + +TEST(EmitterAVX, VPUNPCKHDQ) { + CodeTester tester; + tester.init_code_buffer(1024); + tester.emit(IGen::pextuw_swapped(XMM0 + 3, XMM0 + 3, XMM0 + 3)); + tester.emit(IGen::pextuw_swapped(XMM0 + 3, XMM0 + 3, XMM0 + 13)); + tester.emit(IGen::pextuw_swapped(XMM0 + 3, XMM0 + 13, XMM0 + 3)); + tester.emit(IGen::pextuw_swapped(XMM0 + 3, XMM0 + 13, XMM0 + 13)); + tester.emit(IGen::pextuw_swapped(XMM0 + 13, XMM0 + 3, XMM0 + 3)); + tester.emit(IGen::pextuw_swapped(XMM0 + 13, XMM0 + 3, XMM0 + 13)); + tester.emit(IGen::pextuw_swapped(XMM0 + 13, XMM0 + 13, XMM0 + 3)); + tester.emit(IGen::pextuw_swapped(XMM0 + 13, XMM0 + 13, XMM0 + 13)); + EXPECT_EQ(tester.dump_to_hex_string(true), + "C5E16ADBC4C1616ADDC5916ADBC4C1116ADDC5616AEBC441616AEDC5116AEBC441116AED"); +} + +TEST(EmitterAVX, VPUNPCKLQDQ) { + CodeTester tester; + tester.init_code_buffer(1024); + tester.emit(IGen::pcpyld_swapped(XMM0 + 3, XMM0 + 3, XMM0 + 3)); + tester.emit(IGen::pcpyld_swapped(XMM0 + 3, XMM0 + 3, XMM0 + 13)); + tester.emit(IGen::pcpyld_swapped(XMM0 + 3, XMM0 + 13, XMM0 + 3)); + tester.emit(IGen::pcpyld_swapped(XMM0 + 3, XMM0 + 13, XMM0 + 13)); + tester.emit(IGen::pcpyld_swapped(XMM0 + 13, XMM0 + 3, XMM0 + 3)); + tester.emit(IGen::pcpyld_swapped(XMM0 + 13, XMM0 + 3, XMM0 + 13)); + tester.emit(IGen::pcpyld_swapped(XMM0 + 13, XMM0 + 13, XMM0 + 3)); + tester.emit(IGen::pcpyld_swapped(XMM0 + 13, XMM0 + 13, XMM0 + 13)); + EXPECT_EQ(tester.dump_to_hex_string(true), + "C5E16CDBC4C1616CDDC5916CDBC4C1116CDDC5616CEBC441616CEDC5116CEBC441116CED"); +} + +TEST(EmitterAVX, VPUNPCKHQDQ) { + CodeTester tester; + tester.init_code_buffer(1024); + tester.emit(IGen::pcpyud(XMM0 + 3, XMM0 + 3, XMM0 + 3)); + tester.emit(IGen::pcpyud(XMM0 + 3, XMM0 + 3, XMM0 + 13)); + tester.emit(IGen::pcpyud(XMM0 + 3, XMM0 + 13, XMM0 + 3)); + tester.emit(IGen::pcpyud(XMM0 + 3, XMM0 + 13, XMM0 + 13)); + tester.emit(IGen::pcpyud(XMM0 + 13, XMM0 + 3, XMM0 + 3)); + tester.emit(IGen::pcpyud(XMM0 + 13, XMM0 + 3, XMM0 + 13)); + tester.emit(IGen::pcpyud(XMM0 + 13, XMM0 + 13, XMM0 + 3)); + tester.emit(IGen::pcpyud(XMM0 + 13, XMM0 + 13, XMM0 + 13)); + EXPECT_EQ(tester.dump_to_hex_string(true), + "C5E16DDBC4C1616DDDC5916DDBC4C1116DDDC5616DEBC441616DEDC5116DEBC441116DED"); +} + +TEST(EmitterAVX, VPCMPEQD) { + CodeTester tester; + tester.init_code_buffer(1024); + tester.emit(IGen::pceqw(XMM0 + 3, XMM0 + 3, XMM0 + 3)); + tester.emit(IGen::pceqw(XMM0 + 3, XMM0 + 3, XMM0 + 13)); + tester.emit(IGen::pceqw(XMM0 + 3, XMM0 + 13, XMM0 + 3)); + tester.emit(IGen::pceqw(XMM0 + 3, XMM0 + 13, XMM0 + 13)); + tester.emit(IGen::pceqw(XMM0 + 13, XMM0 + 3, XMM0 + 3)); + tester.emit(IGen::pceqw(XMM0 + 13, XMM0 + 3, XMM0 + 13)); + tester.emit(IGen::pceqw(XMM0 + 13, XMM0 + 13, XMM0 + 3)); + tester.emit(IGen::pceqw(XMM0 + 13, XMM0 + 13, XMM0 + 13)); + EXPECT_EQ(tester.dump_to_hex_string(true), + "C5E176DBC4C16176DDC59176DBC4C11176DDC56176EBC4416176EDC51176EBC4411176ED"); +} + +TEST(EmitterAVX, VPSRLDQ) { + CodeTester tester; + tester.init_code_buffer(1024); + tester.emit(IGen::vpsrldq(XMM0 + 3, XMM0 + 4, 3)); + tester.emit(IGen::vpsrldq(XMM0 + 3, XMM0 + 14, 4)); + tester.emit(IGen::vpsrldq(XMM0 + 13, XMM0 + 4, 5)); + tester.emit(IGen::vpsrldq(XMM0 + 13, XMM0 + 14, 6)); + EXPECT_EQ(tester.dump_to_hex_string(true), "C5E173DC03C4C16173DE04C59173DC05C4C11173DE06"); +} + +TEST(EmitterAVX, VPSLLDQ) { + CodeTester tester; + tester.init_code_buffer(1024); + tester.emit(IGen::vpslldq(XMM0 + 3, XMM0 + 4, 3)); + tester.emit(IGen::vpslldq(XMM0 + 3, XMM0 + 14, 4)); + tester.emit(IGen::vpslldq(XMM0 + 13, XMM0 + 4, 5)); + tester.emit(IGen::vpslldq(XMM0 + 13, XMM0 + 14, 6)); + EXPECT_EQ(tester.dump_to_hex_string(true), "C5E173FC03C4C16173FE04C59173FC05C4C11173FE06"); +} + +TEST(EmitterAVX, VPSHUFLW) { + CodeTester tester; + tester.init_code_buffer(1024); + tester.emit(IGen::vpshuflw(XMM0 + 3, XMM0 + 4, 3)); + tester.emit(IGen::vpshuflw(XMM0 + 3, XMM0 + 14, 4)); + tester.emit(IGen::vpshuflw(XMM0 + 13, XMM0 + 4, 5)); + tester.emit(IGen::vpshuflw(XMM0 + 13, XMM0 + 14, 6)); + EXPECT_EQ(tester.dump_to_hex_string(true), "C5FB70DC03C4C17B70DE04C57B70EC05C4417B70EE06"); +} + +TEST(EmitterAVX, VPSHUFHW) { + CodeTester tester; + tester.init_code_buffer(1024); + tester.emit(IGen::vpshufhw(XMM0 + 3, XMM0 + 4, 3)); + tester.emit(IGen::vpshufhw(XMM0 + 3, XMM0 + 14, 4)); + tester.emit(IGen::vpshufhw(XMM0 + 13, XMM0 + 4, 5)); + tester.emit(IGen::vpshufhw(XMM0 + 13, XMM0 + 14, 6)); + EXPECT_EQ(tester.dump_to_hex_string(true), "C5FA70DC03C4C17A70DE04C57A70EC05C4417A70EE06"); +} + +TEST(EmitrerAVX, movq_to_gpr_from_xmm) { + CodeTester tester; + tester.init_code_buffer(1024); + tester.emit(IGen::movq_gpr64_xmm64(RSP, XMM0 + 3)); + tester.emit(IGen::movq_gpr64_xmm64(RSP, XMM0 + 13)); + tester.emit(IGen::movq_gpr64_xmm64(R12, XMM0 + 3)); + tester.emit(IGen::movq_gpr64_xmm64(R12, XMM0 + 13)); + EXPECT_EQ(tester.dump_to_hex_string(true), "66480F7EDC664C0F7EEC66490F7EDC664D0F7EEC"); +} + +TEST(EmitrerAVX, movq_to_xmm_from_gpr) { + CodeTester tester; + tester.init_code_buffer(1024); + tester.emit(IGen::movq_xmm64_gpr64(XMM0 + 3, RSP)); + tester.emit(IGen::movq_xmm64_gpr64(XMM0 + 13, RSP)); + tester.emit(IGen::movq_xmm64_gpr64(XMM0 + 3, R12)); + tester.emit(IGen::movq_xmm64_gpr64(XMM0 + 13, R12)); + EXPECT_EQ(tester.dump_to_hex_string(true), "66480F6EDC664C0F6EEC66490F6EDC664D0F6EEC"); } \ No newline at end of file