diff --git a/decompiler/IR2/OpenGoalMapping.cpp b/decompiler/IR2/OpenGoalMapping.cpp index a63d03a4f..512bda474 100644 --- a/decompiler/IR2/OpenGoalMapping.cpp +++ b/decompiler/IR2/OpenGoalMapping.cpp @@ -8,10 +8,9 @@ typedef OpenGOALAsm::InstructionModifiers MOD; const std::map MIPS_ASM_TO_OPEN_GOAL_FUNCS = { // ----- EE ------- - // TODO - these are waiting on proper 128-bit int support in OpenGOAL {InstructionKind::PSLLW, {".pw.sll", {}}}, {InstructionKind::PSRAW, {".pw.sra", {}}}, - {InstructionKind::PSUBW, {"TODO.PSUBW", {}}}, + {InstructionKind::PSUBW, {".psubw", {}}}, {InstructionKind::PEXTUW, {".pextuw", {}}}, {InstructionKind::PEXTLW, {".pextlw", {}}}, diff --git a/decompiler/config/all-types.gc b/decompiler/config/all-types.gc index fb44708d8..3e55fb4be 100644 --- a/decompiler/config/all-types.gc +++ b/decompiler/config/all-types.gc @@ -2694,7 +2694,7 @@ (deftype dma-packet (structure) ((dma dma-tag :offset-assert 0) (vif0 vif-tag :offset-assert 8) - (vif1 vif-tag :offset-assert 12) ;; doesn't have to be a vif tag. + (vif1 vif-tag :offset-assert 12) (quad uint128 :offset 0) ) :method-count-assert 9 @@ -3672,7 +3672,7 @@ (define-extern vector-v+! (function vector vector vector vector)) (define-extern vector-v*float+! (function vector vector vector float vector)) (define-extern vector-v++! (function vector vector vector)) -(define-extern vector-v*float! (function vector float float vector)) +(define-extern vector-v*float! (function vector vector float vector)) (define-extern vector-v*float++! (function vector vector float vector)) (define-extern vector-to-ups! (function vector vector vector)) (define-extern vector-from-ups! (function vector vector vector)) @@ -3703,16 +3703,16 @@ (define-extern vector-degi (function vector vector vector)) (define-extern vector-degf (function vector vector vector)) (define-extern vector-degmod (function vector vector vector)) -(define-extern vector-deg-diff (function vector vector vector vector)) +(define-extern vector-deg-diff (function vector vector vector none)) (define-extern vector-deg-lerp-clamp! (function vector vector vector float vector)) ;; todo (define-extern vector3s-copy! (function vector vector vector)) (define-extern vector3s+! (function vector vector vector vector)) (define-extern vector3s*float! (function vector vector float vector)) (define-extern vector3s-! (function vector vector vector vector)) -(define-extern spheres-overlap? (function vector vector symbol)) +(define-extern spheres-overlap? (function sphere sphere symbol)) (define-extern sphere<-vector! (function sphere vector sphere)) (define-extern sphere<-vector+r! (function sphere vector float sphere)) -(define-extern rand-vu-sphere-point! (function vector sphere vector)) ;; todo +(define-extern rand-vu-sphere-point! (function vector float vector)) ;; todo ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/decompiler/config/jak1_ntsc_black_label.jsonc b/decompiler/config/jak1_ntsc_black_label.jsonc index d2dcf84b2..79bed70a9 100644 --- a/decompiler/config/jak1_ntsc_black_label.jsonc +++ b/decompiler/config/jak1_ntsc_black_label.jsonc @@ -164,6 +164,9 @@ "vif1-handler", // F: weird asm for interrupt handler "vif1-handler-debug", + // vector + "vector=", // asm branching + // texture "adgif-shader<-texture-with-update!", // F: asm branching "(method 9 texture-page-dir)", diff --git a/decompiler/config/jak1_ntsc_black_label/var_names.jsonc b/decompiler/config/jak1_ntsc_black_label/var_names.jsonc index a73c696c1..65ff67423 100644 --- a/decompiler/config/jak1_ntsc_black_label/var_names.jsonc +++ b/decompiler/config/jak1_ntsc_black_label/var_names.jsonc @@ -780,7 +780,7 @@ }, "(method 0 display-frame)": { - "vars": {"gp-0": "obj"} + "vars": { "gp-0": "obj" } }, "(method 0 draw-context)": { @@ -800,6 +800,88 @@ "vars": { "gp-0": "obj" } }, + "vector-seek-2d-xz-smooth!": { + "args": ["vec", "target", "max-step", "alpha"], + "vars": { + "f0-1": "x-diff", + "f2-1": "z-diff", + "f1-5": "x-step", + "f0-3": "z-step", + "f2-4": "step-len" + } + }, + + "vector-seek-2d-yz-smooth!": { + "args": ["vec", "target", "max-step", "alpha"], + "vars": { + "f0-1": "y-diff", + "f2-1": "z-diff", + "f1-5": "y-step", + "f0-3": "z-step", + "f2-4": "step-len", + "f2-6": "step-scale" + } + }, + + "vector-seek-3d-smooth!": { + "args": ["vec", "target", "max-step", "alpha"], + "vars": { + "f0-1": "x-diff", + "f1-2": "y-diff", + "f3-1": "z-diff", + "f2-6": "x-step", + "f1-3": "y-step", + "f0-4": "z-step", + "f3-5": "step-len", + "f3-7": "step-scale" + } + }, + + "seek-with-smooth": { + "args": ["value", "target", "max-step", "alpha", "deadband"], + "vars": { "f0-1": "diff", "f0-2": "step", "f1-4": "min-step" } + }, + + "vector-v+!": { + "args": ["result", "position", "velocity"] + }, + + "vector-v*float+!": { + "args": ["result", "position", "velocity", "velocity-scale"] + }, + + "vector-v++!": { + "args": ["position", "velocity"] + }, + + "vector-v*float!": { + "args": ["delta-p", "velocity", "scale"] + }, + + "vector-v*float++!": { + "args": ["position", "velocity", "scale"] + }, + + "vector-lerp!": { + "args": ["out", "a", "b", "alpha"] + }, + + "vector-lerp-clamp!": { + "args": ["out", "a", "b", "alpha"] + }, + + "vector4-lerp!": { + "args": ["out", "a", "b", "alpha"] + }, + + "vector4-lerp-clamp!": { + "args": ["out", "a", "b", "alpha"] + }, + + "vector-deg-lerp-clamp!": { + "args": ["out", "min-val", "max-val", "in"] + }, + "(method 9 display)": { "args": ["obj", "delta-seconds"], "vars": { "gp-0": "obj", "s5-0": "delta" } diff --git a/doc/changelog.md b/doc/changelog.md index 8df114ef2..1efc10687 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -140,3 +140,5 @@ - `defenum` now creates real types. Boxed arrays of enums and bitfields correctly have runtime type of the parent integer. - Added a `:copy-entries ` to copy entries from a previous bitfield. - Adding a duplicate entry to an enum now generates a compiler error. +- Added `.psubw` assembly form +- Changed `.ftoi` to `VCVTTPS2DQ` to make the rounding behavior match the PS2 (truncate). \ No newline at end of file diff --git a/goal_src/engine/math/vector.gc b/goal_src/engine/math/vector.gc index 209796c62..767b72556 100644 --- a/goal_src/engine/math/vector.gc +++ b/goal_src/engine/math/vector.gc @@ -6,7 +6,7 @@ ;; dgos: GAME, ENGINE (defun vector-cross! ((arg0 vector) (arg1 vector) (arg2 vector)) - "Compute the cross product." + "Compute the cross product. The w component is set to junk." (rlet ((acc :class vf) (vf1 :class vf) (vf2 :class vf) @@ -320,9 +320,13 @@ (.lvf vf2 (&-> arg1 quad)) (.sub.vf vf1 vf2 vf1) (.abs.vf vf1 vf1) + ;; put abs.x in acc.w (.mul.x.vf acc vf0 vf1 :mask #b1000) + ;; add abs.y (.add.mul.y.vf acc vf0 vf1 acc :mask #b1000) + ;; add abs.z (.add.mul.z.vf vf3 vf0 vf1 acc :mask #b1000) + ;; set acc.x = acc.w (.add.w.vf vf3 vf0 vf3 :mask #b1) (.mov v0-0 vf3) v0-0 @@ -354,125 +358,144 @@ ) ) -(defun vector-seek-2d-xz-smooth! ((arg0 vector) (arg1 vector) (arg2 float) (arg3 float)) - (let ((f0-1 (- (-> arg1 data 0) (-> arg0 data 0))) - (f2-1 (- (-> arg1 data 2) (-> arg0 data 2))) +(defun vector-seek-2d-xz-smooth! ((vec vector) (target vector) (max-step float) (alpha float)) + "Smoothly seek vec's x and z components toward target. + The step always points toward the target and has length (dist * alpha) + If the step is longer than max-step, the step is projected onto a circle of radius max-step. + Doesn't touch y or w." + ;; how much we have to go to get to the target + (let ((x-diff (- (-> target data 0) (-> vec data 0))) + (z-diff (- (-> target data 2) (-> vec data 2))) ) - (if (or (!= f0-1 0.0) (!= f2-1 0.0)) - (let* ((f1-5 (* f0-1 arg3)) - (f0-3 (* f2-1 arg3)) - (f2-4 (sqrtf (+ (* f1-5 f1-5) (* f0-3 f0-3)))) - ) - (cond - ((>= arg2 f2-4) - (set! (-> arg0 data 0) (+ (-> arg0 data 0) f1-5)) - (let ((f0-4 (+ (-> arg0 data 2) f0-3))) - (set! (-> arg0 data 2) f0-4) + ;; do we have to move? + (if (or (!= x-diff 0.0) (!= z-diff 0.0)) + ;; if so, scale by alpha, + (let* ((x-step (* x-diff alpha)) + (z-step (* z-diff alpha)) + ;; and get the length of this step + (step-len (sqrtf (+ (* x-step x-step) (* z-step z-step)))) + ) + (cond + ((>= max-step step-len) + ;; step is within max-step, just do it. + (+! (-> vec data 0) x-step) + (+! (-> vec data 2) z-step) + ) + (else + ;; not in range. + (let ((f2-6 (/ max-step step-len))) + (+! (-> vec data 0) (* f2-6 x-step)) + (+! (-> vec data 2) (* f2-6 z-step)) + ) + ) + ) + ) ) - ) - (else - (let ((f2-6 (/ arg2 f2-4))) - (set! (-> arg0 data 0) (+ (-> arg0 data 0) (* f2-6 f1-5))) - (let ((f0-6 (+ (-> arg0 data 2) (* f2-6 f0-3)))) - (set! (-> arg0 data 2) f0-6) - ) - ) - ) - ) - ) ) - ) - arg0 + vec ) -(defun vector-seek-2d-yz-smooth! ((arg0 vector) (arg1 vector) (arg2 float) (arg3 float)) - (let ((f0-1 (- (-> arg1 data 1) (-> arg0 data 1))) - (f2-1 (- (-> arg1 data 2) (-> arg0 data 2))) + +(defun vector-seek-2d-yz-smooth! ((vec vector) (target vector) (max-step float) (alpha float)) + "Smoothly seek vec's y and z components toward target. + The step always points toward the target and has length (dist * alpha) + If the step is longer than max-step, the step is projected onto a circle of radius max-step. + Doesn't touch x or w." + (let ((y-diff (- (-> target data 1) (-> vec data 1))) + (z-diff (- (-> target data 2) (-> vec data 2))) ) - (if (or (!= f0-1 0.0) (!= f2-1 0.0)) - (let* ((f1-5 (* f0-1 arg3)) - (f0-3 (* f2-1 arg3)) - (f2-4 (sqrtf (+ (* f1-5 f1-5) (* f0-3 f0-3)))) - ) - (cond - ((>= arg2 f2-4) - (set! (-> arg0 data 1) (+ (-> arg0 data 1) f1-5)) - (let ((f0-4 (+ (-> arg0 data 2) f0-3))) - (set! (-> arg0 data 2) f0-4) + (if (or (!= y-diff 0.0) (!= z-diff 0.0)) + (let* ((y-step (* y-diff alpha)) + (z-step (* z-diff alpha)) + (step-len (sqrtf (+ (* y-step y-step) (* z-step z-step)))) + ) + (cond + ((>= max-step step-len) + (set! (-> vec data 1) (+ (-> vec data 1) y-step)) + (let ((f0-4 (+ (-> vec data 2) z-step))) + (set! (-> vec data 2) f0-4) + ) + ) + (else + (let ((step-scale (/ max-step step-len))) + (set! (-> vec data 1) (+ (-> vec data 1) (* step-scale y-step))) + (let ((f0-6 (+ (-> vec data 2) (* step-scale z-step)))) + (set! (-> vec data 2) f0-6) + ) + ) + ) + ) + ) ) - ) - (else - (let ((f2-6 (/ arg2 f2-4))) - (set! (-> arg0 data 1) (+ (-> arg0 data 1) (* f2-6 f1-5))) - (let ((f0-6 (+ (-> arg0 data 2) (* f2-6 f0-3)))) - (set! (-> arg0 data 2) f0-6) - ) - ) - ) - ) - ) ) - ) - arg0 + vec ) -(defun vector-seek-3d-smooth! ((arg0 vector) (arg1 vector) (arg2 float) (arg3 float)) - (let ((f0-1 (- (-> arg1 data 0) (-> arg0 data 0))) - (f1-2 (- (-> arg1 data 1) (-> arg0 data 1))) - (f3-1 (- (-> arg1 data 2) (-> arg0 data 2))) +(defun vector-seek-3d-smooth! ((vec vector) (target vector) (max-step float) (alpha float)) + "Smoothly seek vec's x, y, and z components toward target. + The step always points toward the target and has length (dist * alpha) + If the step is longer than max-step, the step is projected onto a circle of radius max-step. + Doesn't touch w." + (let ((x-diff (- (-> target data 0) (-> vec data 0))) + (y-diff (- (-> target data 1) (-> vec data 1))) + (z-diff (- (-> target data 2) (-> vec data 2))) ) - (if (or (!= f0-1 0.0) (!= f1-2 0.0) (!= f3-1 0.0)) - (let* ((f2-6 (* f0-1 arg3)) - (f1-3 (* f1-2 arg3)) - (f0-4 (* f3-1 arg3)) - (f3-5 (sqrtf (+ (+ (* f2-6 f2-6) (* f1-3 f1-3)) (* f0-4 f0-4)))) - ) - (cond - ((>= arg2 f3-5) - (set! (-> arg0 data 0) (+ (-> arg0 data 0) f2-6)) - (set! (-> arg0 data 1) (+ (-> arg0 data 1) f1-3)) - (let ((f0-5 (+ (-> arg0 data 2) f0-4))) - (set! (-> arg0 data 2) f0-5) + (if (or (!= x-diff 0.0) (!= y-diff 0.0) (!= z-diff 0.0)) + (let* ((x-step (* x-diff alpha)) + (y-step (* y-diff alpha)) + (z-step (* z-diff alpha)) + (step-len (sqrtf (+ (+ (* x-step x-step) (* y-step y-step)) (* z-step z-step)))) + ) + (cond + ((>= max-step step-len) + (set! (-> vec data 0) (+ (-> vec data 0) x-step)) + (set! (-> vec data 1) (+ (-> vec data 1) y-step)) + (let ((f0-5 (+ (-> vec data 2) z-step))) + (set! (-> vec data 2) f0-5) + ) + ) + (else + (let ((step-scale (/ max-step step-len))) + (set! (-> vec data 0) (+ (-> vec data 0) (* step-scale x-step))) + (set! (-> vec data 1) (+ (-> vec data 1) (* step-scale y-step))) + (let ((f0-7 (+ (-> vec data 2) (* step-scale z-step)))) + (set! (-> vec data 2) f0-7) + ) + ) + ) + ) + ) ) - ) - (else - (let ((f3-7 (/ arg2 f3-5))) - (set! (-> arg0 data 0) (+ (-> arg0 data 0) (* f3-7 f2-6))) - (set! (-> arg0 data 1) (+ (-> arg0 data 1) (* f3-7 f1-3))) - (let ((f0-7 (+ (-> arg0 data 2) (* f3-7 f0-4)))) - (set! (-> arg0 data 2) f0-7) - ) - ) - ) - ) - ) ) - ) - arg0 + vec ) -(defun seek-with-smooth ((arg0 float) (arg1 float) (arg2 float) (arg3 float) (arg4 float)) - (let ((f0-1 (- arg1 arg0))) - (if (>= arg4 (fabs f0-1)) - arg1 - (let ((f0-2 (* f0-1 arg3))) - (let ((f1-4 (- arg2))) - (cond - ((< f0-2 f1-4) - (set! f0-2 f1-4) +(defun seek-with-smooth ((value float) (target float) (max-step float) (alpha float) (deadband float)) + "Move value closer to target. + If we are within deadband, just go straight to target. + If not, try to go alpha*err. If that is a larger step than max-step, limit to max-step" + (let ((diff (- target value))) + (if (>= deadband (fabs diff)) + target + (let ((step (* diff alpha))) + (let ((min-step (- max-step))) + (cond + ((< step min-step) + (set! step min-step) + ) + ((< max-step step) + (set! step max-step) + ) + ) + ) + (+ step value) + ) ) - ((< arg2 f0-2) - (set! f0-2 arg2) - ) - ) - ) - (+ f0-2 arg0) - ) ) - ) ) (defun vector-identity! ((arg0 vector)) + "Set arg0 to 1, 1, 1, 1" (set! (-> arg0 data 0) 1.0) (set! (-> arg0 data 1) 1.0) (set! (-> arg0 data 2) 1.0) @@ -481,20 +504,23 @@ ) (defun vector-seconds ((arg0 vector) (arg1 vector)) - (set! (-> arg0 data 0) (* 300.0 (-> arg1 data 0))) - (set! (-> arg0 data 1) (* 300.0 (-> arg1 data 1))) - (set! (-> arg0 data 2) (* 300.0 (-> arg1 data 2))) + "Convert from actual seconds to the seconds unit." + (set! (-> arg0 data 0) (seconds (-> arg1 data 0))) + (set! (-> arg0 data 1) (seconds (-> arg1 data 1))) + (set! (-> arg0 data 2) (seconds (-> arg1 data 2))) arg0 ) (defun vector-seconds! ((arg0 vector)) - (set! (-> arg0 data 0) (* 300.0 (-> arg0 data 0))) - (set! (-> arg0 data 1) (* 300.0 (-> arg0 data 1))) - (set! (-> arg0 data 2) (* 300.0 (-> arg0 data 2))) + "Convert from actual seconds to seconds, in place" + (set! (-> arg0 data 0) (seconds (-> arg0 data 0))) + (set! (-> arg0 data 1) (seconds (-> arg0 data 1))) + (set! (-> arg0 data 2) (seconds (-> arg0 data 2))) arg0 ) (defun vector-v! ((arg0 vector)) + "Convert a velocity to a displacement per frame. The velocity should be in X/actual_second" (rlet ((vf0 :class vf) (vf1 :class vf) (vf2 :class vf) @@ -517,50 +543,58 @@ ) ) -(defun vector-v+! ((arg0 vector) (arg1 vector) (arg2 vector)) - (vector+float*! arg0 arg1 arg2 (-> *display* seconds-per-frame)) - arg0 +(defun vector-v+! ((result vector) (position vector) (velocity vector)) + "Euler forward step, using the current display time settings" + (vector+float*! result position velocity (-> *display* seconds-per-frame)) + result ) -(defun vector-v*float+! ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 float)) - (vector+float*! arg0 arg1 arg2 (* arg3 (-> *display* seconds-per-frame))) - arg0 + +(defun vector-v*float+! ((result vector) (position vector) (velocity vector) (velocity-scale float)) + "Euler forward step, scaling velocity by velocity-scale" + (vector+float*! result position velocity (* velocity-scale (-> *display* seconds-per-frame))) + result ) -(defun vector-v++! ((arg0 vector) (arg1 vector)) - (vector+float*! arg0 arg0 arg1 (-> *display* seconds-per-frame)) - arg0 +(defun vector-v++! ((position vector) (velocity vector)) + "Update position in place, using display's current timing" + (vector+float*! position position velocity (-> *display* seconds-per-frame)) + position ) -(defun vector-v*float! ((arg0 vector) (arg1 float) (arg2 float)) +(defun vector-v*float! ((delta-p vector) (velocity vector) (scale float)) + "Go from velocity to delta-p per frame, scaling by scale" (rlet ((vf0 :class vf) (vf1 :class vf) (vf2 :class vf) ) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (let ((v0-0 arg0)) - (let ((v1-0 arg1) - (f0-1 (* arg2 (-> *display* seconds-per-frame))) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (let ((v0-0 delta-p)) + (let ((v1-0 velocity) + (f0-1 (* scale (-> *display* seconds-per-frame))) + ) + (.lvf vf1 (&-> v1-0 quad)) + (let ((v1-1 f0-1)) + (.mov vf2 v1-1) ) - (.lvf vf1 v1-0) - (let ((v1-1 f0-1)) - (.mov vf2 v1-1) + ) + (.add.x.vf vf1 vf0 vf0 :mask #b1000) + (.mul.x.vf vf1 vf1 vf2 :mask #b111) + (.svf (&-> v0-0 quad) vf1) + v0-0 ) - ) - (.add.x.vf vf1 vf0 vf0 :mask #b1000) - (.mul.x.vf vf1 vf1 vf2 :mask #b111) - (.svf (&-> v0-0 quad) vf1) - v0-0 ) - ) ) -(defun vector-v*float++! ((arg0 vector) (arg1 vector) (arg2 float)) - (vector+float*! arg0 arg0 arg1 (* arg2 (-> *display* seconds-per-frame))) - arg0 +(defun vector-v*float++! ((position vector) (velocity vector) (scale float)) + "update position with given velocity, scaled by scale." + (vector+float*! position position velocity (* scale (-> *display* seconds-per-frame))) + position ) + (defun vector-to-ups! ((arg0 vector) (arg1 vector)) + "Go from units per frame to units per second?" (local-vars (at-0 int)) (rlet ((vf0 :class vf) (vf1 :class vf) @@ -580,6 +614,7 @@ ) (defun vector-from-ups! ((arg0 vector) (arg1 vector)) + "Go from units per second to units per frame?" (local-vars (at-0 int)) (rlet ((vf0 :class vf) (vf1 :class vf) @@ -599,65 +634,67 @@ ) (defun vector-length ((arg0 vector)) + "Get the length of the xyz part." (local-vars (v0-0 float)) (rlet ((acc :class vf) (Q :class vf) (vf0 :class vf) (vf1 :class vf) ) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (.lvf vf1 (&-> arg0 quad)) - (.mul.vf vf1 vf1 vf1) - (.mul.x.vf acc vf0 vf1 :mask #b1000) - (.add.mul.y.vf acc vf0 vf1 acc :mask #b1000) - (.add.mul.z.vf vf1 vf0 vf1 acc :mask #b1000) - (.sqrt.vf Q vf1 :ftf #b11) - (.add.w.vf vf1 vf0 vf0 :mask #b1) - (.wait.vf) - (.mul.vf vf1 vf1 Q :mask #b1) - (.nop.vf) - (.nop.vf) - (.mov v0-0 vf1) - v0-0 - ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg0 quad)) + (.mul.vf vf1 vf1 vf1) + (.mul.x.vf acc vf0 vf1 :mask #b1000) + (.add.mul.y.vf acc vf0 vf1 acc :mask #b1000) + (.add.mul.z.vf vf1 vf0 vf1 acc :mask #b1000) + (.sqrt.vf Q vf1 :ftf #b11) + (.add.w.vf vf1 vf0 vf0 :mask #b1) + (.wait.vf) + (.mul.vf vf1 vf1 Q :mask #b1) + (.nop.vf) + (.nop.vf) + (.mov v0-0 vf1) + v0-0 + ) ) (defun vector-length-squared ((arg0 vector)) + "Get the squared length of the xyz part." (local-vars (v0-0 float)) (rlet ((acc :class vf) (vf0 :class vf) (vf1 :class vf) (vf2 :class vf) ) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (.lvf vf1 (&-> arg0 quad)) - (.add.w.vf vf2 vf0 vf0 :mask #b1) - (.mul.vf vf1 vf1 vf1) - (.mul.x.vf acc vf2 vf1 :mask #b1) - (.add.mul.y.vf acc vf2 vf1 acc :mask #b1) - (.add.mul.z.vf vf1 vf2 vf1 acc :mask #b1) - (.mov v0-0 vf1) - v0-0 - ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg0 quad)) + (.add.w.vf vf2 vf0 vf0 :mask #b1) + (.mul.vf vf1 vf1 vf1) + (.mul.x.vf acc vf2 vf1 :mask #b1) + (.add.mul.y.vf acc vf2 vf1 acc :mask #b1) + (.add.mul.z.vf vf1 vf2 vf1 acc :mask #b1) + (.mov v0-0 vf1) + v0-0 + ) ) (defun vector-xz-length-squared ((arg0 vector)) - (+ - (* (-> arg0 data 0) (-> arg0 data 0)) - (* (-> arg0 data 2) (-> arg0 data 2)) - ) + "Get the length of the xz part, squared." + (+ (* (-> arg0 data 0) (-> arg0 data 0)) + (* (-> arg0 data 2) (-> arg0 data 2)) + ) ) (defun vector-xz-length ((arg0 vector)) - (sqrtf - (+ - (* (-> arg0 data 0) (-> arg0 data 0)) - (* (-> arg0 data 2) (-> arg0 data 2)) - ) - ) + "Get the length of the xz part, squared" + (sqrtf (+ (* (-> arg0 data 0) (-> arg0 data 0)) + (* (-> arg0 data 2) (-> arg0 data 2)) + ) + ) ) (defun vector-vector-distance ((arg0 vector) (arg1 vector)) + "Subtract the xyz parts and get the norm" (local-vars (v0-0 float)) (rlet ((acc :class vf) (Q :class vf) @@ -666,43 +703,45 @@ (vf2 :class vf) (vf3 :class vf) ) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (.lvf vf2 (&-> arg0 quad)) - (.lvf vf3 (&-> arg1 quad)) - (.sub.vf vf1 vf3 vf2) - (.mul.vf vf1 vf1 vf1) - (.mul.x.vf acc vf0 vf1 :mask #b1000) - (.add.mul.y.vf acc vf0 vf1 acc :mask #b1000) - (.add.mul.z.vf vf1 vf0 vf1 acc :mask #b1000) - (.sqrt.vf Q vf1 :ftf #b11) - (.add.w.vf vf1 vf0 vf0 :mask #b1) - (.wait.vf) - (.mul.vf vf1 vf1 Q :mask #b1) - (.nop.vf) - (.nop.vf) - (.mov v0-0 vf1) - v0-0 - ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf2 (&-> arg0 quad)) + (.lvf vf3 (&-> arg1 quad)) + (.sub.vf vf1 vf3 vf2) + (.mul.vf vf1 vf1 vf1) + (.mul.x.vf acc vf0 vf1 :mask #b1000) + (.add.mul.y.vf acc vf0 vf1 acc :mask #b1000) + (.add.mul.z.vf vf1 vf0 vf1 acc :mask #b1000) + (.sqrt.vf Q vf1 :ftf #b11) + (.add.w.vf vf1 vf0 vf0 :mask #b1) + (.wait.vf) + (.mul.vf vf1 vf1 Q :mask #b1) + (.nop.vf) + (.nop.vf) + (.mov v0-0 vf1) + v0-0 + ) ) (defun vector-vector-distance-squared ((arg0 vector) (arg1 vector)) + "Squared norm of the difference of the xyz parts" (local-vars (v0-0 float)) (rlet ((vf1 :class vf) (vf2 :class vf) (vf3 :class vf) ) - (.lvf vf2 (&-> arg0 quad)) - (.lvf vf3 (&-> arg1 quad)) - (.sub.vf vf1 vf3 vf2) - (.mul.vf vf1 vf1 vf1) - (.add.y.vf vf1 vf1 vf1 :mask #b1) - (.add.z.vf vf1 vf1 vf1 :mask #b1) - (.mov v0-0 vf1) - v0-0 - ) + (.lvf vf2 (&-> arg0 quad)) + (.lvf vf3 (&-> arg1 quad)) + (.sub.vf vf1 vf3 vf2) + (.mul.vf vf1 vf1 vf1) + (.add.y.vf vf1 vf1 vf1 :mask #b1) + (.add.z.vf vf1 vf1 vf1 :mask #b1) + (.mov v0-0 vf1) + v0-0 + ) ) (defun vector-vector-xz-distance ((arg0 vector) (arg1 vector)) + "Distance on the xz plane" (local-vars (v0-0 float)) (rlet ((acc :class vf) (Q :class vf) @@ -711,41 +750,43 @@ (vf2 :class vf) (vf3 :class vf) ) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (.lvf vf2 (&-> arg0 quad)) - (.lvf vf3 (&-> arg1 quad)) - (.sub.vf vf1 vf3 vf2) - (.mul.vf vf1 vf1 vf1) - (.mul.x.vf acc vf0 vf1 :mask #b1000) - (.add.mul.z.vf vf1 vf0 vf1 acc :mask #b1000) - (.sqrt.vf Q vf1 :ftf #b11) - (.add.w.vf vf1 vf0 vf0 :mask #b1) - (.wait.vf) - (.mul.vf vf1 vf1 Q :mask #b1) - (.nop.vf) - (.nop.vf) - (.mov v0-0 vf1) - v0-0 - ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf2 (&-> arg0 quad)) + (.lvf vf3 (&-> arg1 quad)) + (.sub.vf vf1 vf3 vf2) + (.mul.vf vf1 vf1 vf1) + (.mul.x.vf acc vf0 vf1 :mask #b1000) + (.add.mul.z.vf vf1 vf0 vf1 acc :mask #b1000) + (.sqrt.vf Q vf1 :ftf #b11) + (.add.w.vf vf1 vf0 vf0 :mask #b1) + (.wait.vf) + (.mul.vf vf1 vf1 Q :mask #b1) + (.nop.vf) + (.nop.vf) + (.mov v0-0 vf1) + v0-0 + ) ) (defun vector-vector-xz-distance-squared ((arg0 vector) (arg1 vector)) + "Squared distance on the xz plane" (local-vars (v0-0 float)) (rlet ((vf1 :class vf) (vf2 :class vf) (vf3 :class vf) ) - (.lvf vf2 (&-> arg0 quad)) - (.lvf vf3 (&-> arg1 quad)) - (.sub.vf vf1 vf3 vf2) - (.mul.vf vf1 vf1 vf1) - (.add.z.vf vf1 vf1 vf1 :mask #b1) - (.mov v0-0 vf1) - v0-0 - ) + (.lvf vf2 (&-> arg0 quad)) + (.lvf vf3 (&-> arg1 quad)) + (.sub.vf vf1 vf3 vf2) + (.mul.vf vf1 vf1 vf1) + (.add.z.vf vf1 vf1 vf1 :mask #b1) + (.mov v0-0 vf1) + v0-0 + ) ) (defun vector-normalize! ((arg0 vector) (arg1 float)) + "Modify arg0 in place to have length arg1 for its xyz components. The w part is not changed." (rlet ((acc :class vf) (Q :class vf) (vf0 :class vf) @@ -774,6 +815,8 @@ ) (defun vector-normalize-ret-len! ((arg0 vector) (arg1 float)) + "Modify arg0 in place to have length arg1 for its xyz components. + The w part isn't changed and the _original_ length is returned." (local-vars (v1-1 float)) (rlet ((acc :class vf) (Q :class vf) @@ -807,53 +850,59 @@ ) (defun vector-normalize-copy! ((arg0 vector) (arg1 vector) (arg2 float)) + "Normalize, but not in place. + This implementation is very good compared to the vector-normalize! one. + The w component is set to 1." (let ((f0-0 (vector-length arg1))) - (if (= f0-0 0.0) - (set! (-> arg0 quad) (-> arg1 quad)) - (let ((v1-1 (/ arg2 f0-0))) - (set! (-> arg0 data 0) (* (-> arg1 data 0) v1-1)) - (set! (-> arg0 data 1) (* (-> arg1 data 1) v1-1)) - (let ((f0-7 (* (-> arg1 data 2) v1-1))) - (set! (-> arg0 data 2) f0-7) - ) - ) + (if (= f0-0 0.0) + (set! (-> arg0 quad) (-> arg1 quad)) + (let ((v1-1 (/ arg2 f0-0))) + (set! (-> arg0 data 0) (* (-> arg1 data 0) v1-1)) + (set! (-> arg0 data 1) (* (-> arg1 data 1) v1-1)) + (let ((f0-7 (* (-> arg1 data 2) v1-1))) + (set! (-> arg0 data 2) f0-7) + ) + ) + ) ) - ) (set! (-> arg0 data 3) 1.0) arg0 ) (defun vector-xz-normalize! ((arg0 vector) (arg1 float)) + "Normalize, xz components only" (let ((f0-0 (vector-xz-length arg0))) - (if (!= f0-0 0.0) - (let ((v1-1 (/ arg1 f0-0))) - (set! (-> arg0 data 0) (* (-> arg0 data 0) v1-1)) - (let ((f0-5 (* (-> arg0 data 2) v1-1))) - (set! (-> arg0 data 2) f0-5) - ) - ) + (if (!= f0-0 0.0) + (let ((v1-1 (/ arg1 f0-0))) + (set! (-> arg0 data 0) (* (-> arg0 data 0) v1-1)) + (set! (-> arg0 data 2) (* (-> arg0 data 2) v1-1)) + ) + ) ) - ) arg0 ) (defun vector-length-max! ((arg0 vector) (arg1 float)) + "Make vector at most arg1 length (xyz only). + If it is larger, project onto sphere. + Doesn't touch w" (let ((f0-0 (vector-length arg0))) - (when (not (or (= f0-0 0.0) (< f0-0 arg1))) - (set! f0-0 (/ f0-0 arg1)) - (when (!= f0-0 0.0) - (set! (-> arg0 data 0) (/ (-> arg0 data 0) f0-0)) - (set! (-> arg0 data 1) (/ (-> arg0 data 1) f0-0)) - (let ((f0-1 (/ (-> arg0 data 2) f0-0))) - (set! (-> arg0 data 2) f0-1) + (when (not (or (= f0-0 0.0) (< f0-0 arg1))) + (set! f0-0 (/ f0-0 arg1)) + (when (!= f0-0 0.0) + (set! (-> arg0 data 0) (/ (-> arg0 data 0) f0-0)) + (set! (-> arg0 data 1) (/ (-> arg0 data 1) f0-0)) + (set! (-> arg0 data 2) (/ (-> arg0 data 2) f0-0)) + ) ) - ) ) - ) arg0 ) (defun vector-xz-length-max! ((arg0 vector) (arg1 float)) + "Make vector at most arg1 length (xz only). + It it is larger, project onto circle. + Doesn't touch w or y" (let ((f0-0 (vector-xz-length arg0))) (when (not (or (= f0-0 0.0) (< f0-0 arg1))) (set! f0-0 (/ f0-0 arg1)) @@ -869,6 +918,7 @@ ) (defun vector-rotate-around-y! ((arg0 vector) (arg1 vector) (arg2 float)) + "Rotate a vector around the y axis" (let ((f26-0 (-> arg1 data 2)) (f30-0 (-> arg1 data 0)) (f28-0 (cos arg2)) @@ -882,182 +932,188 @@ ) (defun rotate-y<-vector+vector ((arg0 vector) (arg1 vector)) - (atan - (- (-> arg1 data 0) (-> arg0 data 0)) - (- (-> arg1 data 2) (-> arg0 data 2)) - ) + "Get the y rotation between vectors. These should have the same length." + (atan (- (-> arg1 data 0) (-> arg0 data 0)) + (- (-> arg1 data 2) (-> arg0 data 2)) + ) ) (defun vector-cvt.w.s! ((arg0 vector) (arg1 vector)) + "Convert float to int32. Truncate." (rlet ((vf1 :class vf)) - (.lvf vf1 (&-> arg1 quad)) - (.ftoi.vf vf1 vf1) - (.svf (&-> arg0 quad) vf1) - arg0 - ) + (.lvf vf1 (&-> arg1 quad)) + (.ftoi.vf vf1 vf1) + (.svf (&-> arg0 quad) vf1) + arg0 + ) ) (defun vector-cvt.s.w! ((arg0 vector) (arg1 vector)) + "Convert float to int32." (rlet ((vf1 :class vf)) - (.lvf vf1 (&-> arg1 quad)) - (.itof.vf vf1 vf1) - (.svf (&-> arg0 quad) vf1) - arg0 - ) + (.lvf vf1 (&-> arg1 quad)) + (.itof.vf vf1 vf1) + (.svf (&-> arg0 quad) vf1) + arg0 + ) ) (defun rot-zxy-from-vector! ((arg0 vector) (arg1 vector)) + "I think this gives you a vector of euler angles to rotate some unit vector + to arg1." (let* ((f28-0 (-> arg1 data 2)) (f30-0 (-> arg1 data 0)) (f0-0 (atan f30-0 f28-0)) ) - (set! (-> arg0 data 1) f0-0) - (let* ((f26-0 (- f0-0)) - (f0-4 (- (* f28-0 (cos f26-0)) (* f30-0 (sin f26-0)))) - (f0-5 (atan (- (-> arg1 data 1)) f0-4)) - ) - (set! (-> arg0 data 0) f0-5) + (set! (-> arg0 data 1) f0-0) + (let* ((f26-0 (- f0-0)) + (f0-4 (- (* f28-0 (cos f26-0)) (* f30-0 (sin f26-0)))) + (f0-5 (atan (- (-> arg1 data 1)) f0-4)) + ) + (set! (-> arg0 data 0) f0-5) + ) ) - ) (set! (-> arg0 data 2) 0.0) arg0 ) (defun rot-zyx-from-vector! ((arg0 vector) (arg1 vector)) + "I think this gives you a vector of euler angles to rotate some unit vector + to arg1." (let* ((f28-0 (-> arg1 data 2)) (f30-0 (- (-> arg1 data 1))) (f0-1 (atan f30-0 f28-0)) ) - (set! (-> arg0 data 0) f0-1) - (let* ((f26-0 (- f0-1)) - (f0-5 (- (* f28-0 (cos f26-0)) (* f30-0 (sin f26-0)))) - (f0-6 (atan (-> arg1 data 0) f0-5)) - ) - (set! (-> arg0 data 1) f0-6) + (set! (-> arg0 data 0) f0-1) + (let* ((f26-0 (- f0-1)) + (f0-5 (- (* f28-0 (cos f26-0)) (* f30-0 (sin f26-0)))) + (f0-6 (atan (-> arg1 data 0) f0-5)) + ) + (set! (-> arg0 data 1) f0-6) + ) ) - ) (set! (-> arg0 data 2) 0.0) arg0 ) -;; definition for function vector-lerp! -(defun vector-lerp! ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 float)) +(defun vector-lerp! ((out vector) (a vector) (b vector) (alpha float)) + "Linearly interpolate between two vectors. Alpha isn't clampled. + w will be set to 1." (rlet ((vf0 :class vf) (vf1 :class vf) (vf2 :class vf) (vf3 :class vf) (vf4 :class vf) ) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (.lvf vf1 (&-> arg1 quad)) - (.lvf vf2 (&-> arg2 quad)) - (.mov vf4 arg3) - (.add.x.vf vf3 vf0 vf0 :mask #b1000) - (.sub.vf vf2 vf2 vf1) - (.mul.x.vf vf2 vf2 vf4) - (.add.vf vf3 vf1 vf2 :mask #b111) - (.svf (&-> arg0 quad) vf3) - arg0 - ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> a quad)) + (.lvf vf2 (&-> b quad)) + (.mov vf4 alpha) + (.add.x.vf vf3 vf0 vf0 :mask #b1000) + (.sub.vf vf2 vf2 vf1) + (.mul.x.vf vf2 vf2 vf4) + (.add.vf vf3 vf1 vf2 :mask #b111) + (.svf (&-> out quad) vf3) + out + ) ) -;; definition for function vector-lerp-clamp! -;; Used lq/sq -(defun - vector-lerp-clamp! - ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 float)) +(defun vector-lerp-clamp! ((out vector) (a vector) (b vector) (alpha float)) + "Linearly interpolate between two vectors, clamping alpha to 0, 1 + w will be set to 1." (rlet ((vf0 :class vf) (vf1 :class vf) (vf2 :class vf) (vf3 :class vf) (vf4 :class vf) ) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (cond - ((>= 0.0 arg3) - (set! (-> arg0 quad) (-> arg1 quad)) - ) - ((>= arg3 1.0) - (set! (-> arg0 quad) (-> arg2 quad)) - ) - (else - (let ((v1-2 arg0)) - (let ((f0-2 arg3)) - (.lvf vf1 (&-> arg1 quad)) - (.lvf vf2 (&-> arg2 quad)) - (let ((a1-1 f0-2)) - (.mov vf4 a1-1) - ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (cond + ((>= 0.0 alpha) + (set! (-> out quad) (-> a quad)) + ) + ((>= alpha 1.0) + (set! (-> out quad) (-> b quad)) + ) + (else + (let ((v1-2 out)) + (let ((f0-2 alpha)) + (.lvf vf1 (&-> a quad)) + (.lvf vf2 (&-> b quad)) + (let ((a1-1 f0-2)) + (.mov vf4 a1-1) + ) + ) + (.add.x.vf vf3 vf0 vf0 :mask #b1000) + (.sub.vf vf2 vf2 vf1) + (.mul.x.vf vf2 vf2 vf4) + (.add.vf vf3 vf1 vf2 :mask #b111) + (.svf (&-> v1-2 quad) vf3) + ) ) - (.add.x.vf vf3 vf0 vf0 :mask #b1000) - (.sub.vf vf2 vf2 vf1) - (.mul.x.vf vf2 vf2 vf4) - (.add.vf vf3 vf1 vf2 :mask #b111) - (.svf (&-> v1-2 quad) vf3) ) - ) + out ) - arg0 - ) ) -;; definition for function vector4-lerp! -(defun vector4-lerp! ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 float)) +(defun vector4-lerp! ((out vector) (a vector) (b vector) (alpha float)) + "Interpolate all 4 elements of a vector. Alpha is not clamped" (rlet ((vf1 :class vf) (vf2 :class vf) (vf3 :class vf) (vf4 :class vf) ) - (.lvf vf1 (&-> arg1 quad)) - (.lvf vf2 (&-> arg2 quad)) - (.mov vf4 arg3) - (.sub.vf vf2 vf2 vf1) - (.mul.x.vf vf2 vf2 vf4) - (.add.vf vf3 vf1 vf2) - (.svf (&-> arg0 quad) vf3) - arg0 - ) + (.lvf vf1 (&-> a quad)) + (.lvf vf2 (&-> b quad)) + (.mov vf4 alpha) + (.sub.vf vf2 vf2 vf1) + (.mul.x.vf vf2 vf2 vf4) + (.add.vf vf3 vf1 vf2) + (.svf (&-> out quad) vf3) + out + ) ) -;; definition for function vector4-lerp-clamp! -;; Used lq/sq -(defun - vector4-lerp-clamp! - ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 float)) +(defun vector4-lerp-clamp! ((out vector) (a vector) (b vector) (alpha float)) + "Interpolate all 4 elements of a vector. Alpha is clamped to [0, 1]" (rlet ((vf1 :class vf) (vf2 :class vf) (vf3 :class vf) (vf4 :class vf) ) - (cond - ((>= 0.0 arg3) - (set! (-> arg0 quad) (-> arg1 quad)) - ) - ((>= arg3 1.0) - (set! (-> arg0 quad) (-> arg2 quad)) - ) - (else - (let ((v1-2 arg0)) - (let ((f0-2 arg3)) - (.lvf vf1 (&-> arg1 quad)) - (.lvf vf2 (&-> arg2 quad)) - (let ((a1-1 f0-2)) - (.mov vf4 a1-1) - ) + (cond + ((>= 0.0 alpha) + (set! (-> out quad) (-> a quad)) + ) + ((>= alpha 1.0) + (set! (-> out quad) (-> b quad)) + ) + (else + (let ((v1-2 out)) + (let ((f0-2 alpha)) + (.lvf vf1 (&-> a quad)) + (.lvf vf2 (&-> b quad)) + (let ((a1-1 f0-2)) + (.mov vf4 a1-1) + ) + ) + (.sub.vf vf2 vf2 vf1) + (.mul.x.vf vf2 vf2 vf4) + (.add.vf vf3 vf1 vf2) + (.svf (&-> v1-2 quad) vf3) + ) ) - (.sub.vf vf2 vf2 vf1) - (.mul.x.vf vf2 vf2 vf4) - (.add.vf vf3 vf1 vf2) - (.svf (&-> v1-2 quad) vf3) ) - ) + out ) - arg0 - ) ) (defun vector-degi ((arg0 vector) (arg1 vector)) - (local-vars (v1-0 float) (v1-1 uint128)) + "Convert a vector (in _rotations_) to degrees units, stored in an int. + Truncates to the nearest _rotation_. + Neither the input or output is a commonly used form. + Unsurprisingly, this strange function is never used." + (local-vars (v1-0 uint128) (v1-1 uint128)) (rlet ((vf1 :class vf)) (.lvf vf1 (&-> arg1 quad)) (.ftoi.vf vf1 vf1) @@ -1069,68 +1125,108 @@ ) (defun vector-degf ((arg0 vector) (arg1 vector)) + "Convert a vector (in integer degree units) to floating point rotations. + Truncates to the nearest _rotation_. + Like the previous function, this is stupid and unused" (local-vars (v1-1 uint128)) (rlet ((vf1 :class vf)) - (let ((v1-0 (-> arg1 quad))) - (.pw.sra v1-1 v1-0 16) + (let ((v1-0 (-> arg1 quad))) + (.pw.sra v1-1 v1-0 16) + ) + (.mov vf1 v1-1) + (.itof.vf vf1 vf1) + (.svf (&-> arg0 quad) vf1) + arg0 ) - (.mov vf1 v1-1) - (.itof.vf vf1 vf1) - (.svf (&-> arg0 quad) vf1) - arg0 - ) ) (defun vector-degmod ((arg0 vector) (arg1 vector)) - (local-vars (v1-0 float) (v1-1 uint128) (v1-2 uint128)) + "This one is actually right. Wraps degrees units (in floats, like they should be) + to +/- half a rotation." + (local-vars (v1-0 uint128) (v1-1 uint128) (v1-2 uint128)) (rlet ((vf1 :class vf)) - (.lvf vf1 (&-> arg1 quad)) - (.ftoi.vf vf1 vf1) - (.mov v1-0 vf1) - (.pw.sll v1-1 v1-0 16) - (.pw.sra v1-2 v1-1 16) - (.mov vf1 v1-2) - (.itof.vf vf1 vf1) - (.svf (&-> arg0 quad) vf1) - arg0 - ) + (.lvf vf1 (&-> arg1 quad)) + (.ftoi.vf vf1 vf1) + (.mov v1-0 vf1) + (.pw.sll v1-1 v1-0 16) + (.pw.sra v1-2 v1-1 16) + (.mov vf1 v1-2) + (.itof.vf vf1 vf1) + (.svf (&-> arg0 quad) vf1) + arg0 + ) ) -;; todo: vector-deg-diff -(defun vector-deg-lerp-clamp! ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 float)) +(defun vector-deg-diff ((arg0 vector) (arg1 vector) (arg2 vector)) + "Wrapped difference, degrees units. Will have the usual 16-bit accuracy issue" + (local-vars + (v0-0 float) + (v1-0 uint128) + (v1-1 uint128) + (v1-2 uint128) + (v1-3 uint128) + (a1-1 uint128) + (a1-2 uint128) + ) + (rlet ((vf1 :class vf) + (vf2 :class vf) + ) + (.lvf vf1 (&-> arg1 quad)) + (.lvf vf2 (&-> arg2 quad)) + (.ftoi.vf vf1 vf1) + (.ftoi.vf vf2 vf2) + (.mov a1-1 vf1) + (.mov v1-0 vf2) + (.pw.sll a1-2 a1-1 16) + (.pw.sll v1-1 v1-0 16) + (.psubw v1-2 a1-2 v1-1) + (.pw.sra v1-3 v1-2 16) + (.mov vf1 v1-3) + (.itof.vf vf1 vf1) + (.svf (&-> arg0 quad) vf1) + (.mov v0-0 vf1) + (none) + ) + ) + +(defun vector-deg-lerp-clamp! ((out vector) (min-val vector) (max-val vector) (in float)) + "Apply deg-lerp-clamp to the xyz components of a vector. Sets w = 1." (cond - ((>= 0.0 arg3) - (let ((v1-0 arg0)) - (set! (-> v1-0 quad) (-> arg1 quad)) + ((>= 0.0 in) + ;; there is actually something weird here where it is not possible + ;; this was written like you would expect. Perhaps this is from a macro? + (let ((v1-0 out)) + (set! (-> v1-0 quad) (-> min-val quad)) + ) + ) + ((>= in 1.0) + (let ((v1-1 out)) + (set! (-> v1-1 quad) (-> max-val quad)) + ) + ) + (else + (set! (-> out data 0) + (deg-lerp-clamp (-> min-val data 0) (-> max-val data 0) in) + ) + (set! (-> out data 1) + (deg-lerp-clamp (-> min-val data 1) (-> max-val data 1) in) + ) + (set! (-> out data 2) + (deg-lerp-clamp (-> min-val data 2) (-> max-val data 2) in) + ) + (set! (-> out data 3) 1.0) ) ) - ((>= arg3 1.0) - (let ((v1-1 arg0)) - (set! (-> v1-1 quad) (-> arg2 quad)) - ) - ) - (else - (set! - (-> arg0 data 0) - (deg-lerp-clamp (-> arg1 data 0) (-> arg2 data 0) arg3) - ) - (set! - (-> arg0 data 1) - (deg-lerp-clamp (-> arg1 data 1) (-> arg2 data 1) arg3) - ) - (set! - (-> arg0 data 2) - (deg-lerp-clamp (-> arg1 data 2) (-> arg2 data 2) arg3) - ) - (let ((f0-11 1.0)) - (set! (-> arg0 data 3) f0-11) - ) - ) - ) - arg0 + out ) + +;; The weird docstrings for the next 4 functions were left behind in the game. +;; We suspect they accidentally put something before the docstring, turning it +;; into a string constant. GOAL doesn't eliminate dead code and +;; loads into registers greedily, so it decompiles into a variable assignment. + (defun vector3s-copy! ((arg0 vector) (arg1 vector)) (let ((v1-0 "Copy a vector3s")) ) @@ -1167,7 +1263,8 @@ arg0 ) -(defun spheres-overlap? ((arg0 vector) (arg1 vector)) +(defun spheres-overlap? ((arg0 sphere) (arg1 sphere)) + "Do the spheres overlap?" (local-vars (v1-0 float) (a0-1 float)) (rlet ((vf0 :class vf) (vf1 :class vf) @@ -1175,42 +1272,46 @@ (vf3 :class vf) (vf4 :class vf) ) - (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) - (.lvf vf1 (&-> arg0 quad)) - (.lvf vf2 (&-> arg1 quad)) - (.sub.vf vf3 vf1 vf2 :mask #b111) - (.mul.vf vf3 vf3 vf3 :mask #b111) - (.add.w.vf vf4 vf1 vf2 :mask #b1000) - (.mul.w.vf vf4 vf4 vf4 :mask #b1000) - (.add.y.vf vf3 vf3 vf3 :mask #b1) - (.add.z.vf vf3 vf3 vf3 :mask #b1) - (.add.w.vf vf4 vf0 vf4 :mask #b1) - (.mov a0-1 vf4) - (.mov v1-0 vf3) - (>= a0-1 v1-0) - ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg0 quad)) + (.lvf vf2 (&-> arg1 quad)) + (.sub.vf vf3 vf1 vf2 :mask #b111) + (.mul.vf vf3 vf3 vf3 :mask #b111) + (.add.w.vf vf4 vf1 vf2 :mask #b1000) + (.mul.w.vf vf4 vf4 vf4 :mask #b1000) + (.add.y.vf vf3 vf3 vf3 :mask #b1) + (.add.z.vf vf3 vf3 vf3 :mask #b1) + (.add.w.vf vf4 vf0 vf4 :mask #b1) + (.mov a0-1 vf4) + (.mov v1-0 vf3) + (>= a0-1 v1-0) + ) ) (defun sphere<-vector! ((arg0 sphere) (arg1 vector)) + "Set the position of the sphere to arg1. Does not change the radius" (let ((f0-0 (-> arg0 data 3))) - (set! (-> arg0 quad) (-> arg1 quad)) - (set! (-> arg0 data 3) f0-0) - ) + (set! (-> arg0 quad) (-> arg1 quad)) + (set! (-> arg0 data 3) f0-0) + ) arg0 ) (defun sphere<-vector+r! ((arg0 sphere) (arg1 vector) (arg2 float)) + "Set the position of the sphere from arg1 and the radius from arg2" (set! (-> arg0 quad) (-> arg1 quad)) (set! (-> arg0 data 3) arg2) arg0 ) -(defun rand-vu-sphere-point! ((arg0 vector) (arg1 sphere)) +(defun rand-vu-sphere-point! ((arg0 vector) (arg1 float)) + "Get a random point on the sphere at the origin with radius arg1. + The point is on the surface of the sphere." (let ((s4-0 arg0)) - (set! (-> s4-0 data 0) (rand-vu-float-range -1.0 1.0)) - (set! (-> s4-0 data 1) (rand-vu-float-range -1.0 1.0)) - (set! (-> s4-0 data 2) (rand-vu-float-range -1.0 1.0)) - (set! (-> s4-0 data 3) 1.0) - ) - (vector-normalize! arg0 (rand-vu-float-range 0.0 (the-as float arg1))) + (set! (-> s4-0 data 0) (rand-vu-float-range -1.0 1.0)) + (set! (-> s4-0 data 1) (rand-vu-float-range -1.0 1.0)) + (set! (-> s4-0 data 2) (rand-vu-float-range -1.0 1.0)) + (set! (-> s4-0 data 3) 1.0) + ) + (vector-normalize! arg0 (rand-vu-float-range 0.0 arg1)) ) diff --git a/goal_src/engine/util/types-h.gc b/goal_src/engine/util/types-h.gc index d619300a2..89b60d27a 100644 --- a/goal_src/engine/util/types-h.gc +++ b/goal_src/engine/util/types-h.gc @@ -53,3 +53,18 @@ ) ) ) + +(defmacro seconds (x) + "Convert number to seconds unit." + (cond + ((float? x) + (* 300.0 x) + ) + ((integer? x) + (* 300 x) + ) + (#t + `(* 300.0 ,x) + ) + ) + ) \ No newline at end of file diff --git a/goalc/compiler/Compiler.h b/goalc/compiler/Compiler.h index 8c2783323..9e862cee8 100644 --- a/goalc/compiler/Compiler.h +++ b/goalc/compiler/Compiler.h @@ -429,6 +429,7 @@ class Compiler { 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_psubw(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 1a95b1087..fa7c13475 100644 --- a/goalc/compiler/IR.cpp +++ b/goalc/compiler/IR.cpp @@ -1471,6 +1471,9 @@ std::string IR_Int128Math3Asm::print() { case Kind::PCEQW: function = ".pceqw"; break; + case Kind::PSUBW: + function = ".psubw"; + break; default: assert(false); } @@ -1514,6 +1517,10 @@ void IR_Int128Math3Asm::do_codegen(emitter::ObjectGenerator* gen, case Kind::PCEQW: gen->add_instr(IGen::pceqw(dst, src1, src2), irec); break; + case Kind::PSUBW: + // psubW on mips is psubD on x86... + gen->add_instr(IGen::vpsubd(dst, src1, src2), irec); + break; default: assert(false); } diff --git a/goalc/compiler/IR.h b/goalc/compiler/IR.h index cdf283afd..8b8930bdc 100644 --- a/goalc/compiler/IR.h +++ b/goalc/compiler/IR.h @@ -548,7 +548,8 @@ class IR_VFMath3Asm : public IR_Asm { class IR_Int128Math3Asm : public IR_Asm { public: - enum class Kind { PEXTLW, PEXTUW, PCPYUD, PCPYLD, PCEQW }; + // these are MIPS names, not x86 names. + enum class Kind { PEXTLW, PEXTUW, PCPYUD, PCPYLD, PCEQW, PSUBW }; IR_Int128Math3Asm(bool use_color, const RegVal* dst, const RegVal* src1, diff --git a/goalc/compiler/compilation/Asm.cpp b/goalc/compiler/compilation/Asm.cpp index 6f0f1bd11..a34a3fc0c 100644 --- a/goalc/compiler/compilation/Asm.cpp +++ b/goalc/compiler/compilation/Asm.cpp @@ -627,6 +627,10 @@ Val* Compiler::compile_asm_pceqw(const goos::Object& form, const goos::Object& r return compile_asm_int128_math3(form, rest, IR_Int128Math3Asm::Kind::PCEQW, env); } +Val* Compiler::compile_asm_psubw(const goos::Object& form, const goos::Object& rest, Env* env) { + return compile_asm_int128_math3(form, rest, IR_Int128Math3Asm::Kind::PSUBW, 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, {{}, {}, {}}, {}); diff --git a/goalc/compiler/compilation/Atoms.cpp b/goalc/compiler/compilation/Atoms.cpp index 139eb8a30..22612b50d 100644 --- a/goalc/compiler/compilation/Atoms.cpp +++ b/goalc/compiler/compilation/Atoms.cpp @@ -102,6 +102,7 @@ const std::unordered_map< {".pcpyud", &Compiler::compile_asm_pcpyud}, {".pceqw", &Compiler::compile_asm_pceqw}, {".ppach", &Compiler::compile_asm_ppach}, + {".psubw", &Compiler::compile_asm_psubw}, // BLOCK FORMS {"top-level", &Compiler::compile_top_level}, diff --git a/goalc/emitter/IGen.h b/goalc/emitter/IGen.h index 1bf67281b..6a231743b 100644 --- a/goalc/emitter/IGen.h +++ b/goalc/emitter/IGen.h @@ -2391,9 +2391,10 @@ class IGen { static Instruction ftoi_vf(Register dst, Register src) { assert(dst.is_xmm()); assert(src.is_xmm()); - Instruction instr(0x5b); // VCVTDQ2PS + // VEX.128.F3.0F.WIG 5B /r VCVTTPS2DQ xmm1, xmm2/m128 + Instruction instr(0x5b); // VCVTTPS2DQ instr.set_vex_modrm_and_rex(dst.hw_id(), src.hw_id(), VEX3::LeadingBytes::P_0F, 0, false, - VexPrefix::P_66); + VexPrefix::P_F3); return instr; } @@ -2494,6 +2495,18 @@ class IGen { return instr; } + static Instruction vpsubd(Register dst, Register src0, Register src1) { + assert(dst.is_xmm()); + assert(src0.is_xmm()); + assert(src1.is_xmm()); + // VEX.128.66.0F.WIG FA /r VPSUBD xmm1, xmm2, xmm3/m128 + // reg, vec, r/m + Instruction instr(0xfa); + 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()); diff --git a/test/decompiler/reference/all_forward_declarations.gc b/test/decompiler/reference/all_forward_declarations.gc index 88e5b7fd5..053c8f132 100644 --- a/test/decompiler/reference/all_forward_declarations.gc +++ b/test/decompiler/reference/all_forward_declarations.gc @@ -286,5 +286,9 @@ ;; display-h (declare-type display basic) (define-extern set-display (function display int int int int int display)) - (define-extern *display* display) + + +;; vector +;; only because trig isn't in the reference yet. +(define-extern deg-lerp-clamp (function float float float float)) diff --git a/test/decompiler/reference/vector_REF.gc b/test/decompiler/reference/vector_REF.gc new file mode 100644 index 000000000..cf3727170 --- /dev/null +++ b/test/decompiler/reference/vector_REF.gc @@ -0,0 +1,1278 @@ +;;-*-Lisp-*- +(in-package goal) + +;; definition for function vector-cross! +(defun vector-cross! ((arg0 vector) (arg1 vector) (arg2 vector)) + (rlet ((acc :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + ) + (.lvf vf1 (&-> arg1 quad)) + (.lvf vf2 (&-> arg2 quad)) + (.outer.product.vf vf3 vf1 vf2) + (.svf (&-> arg0 quad) vf3) + arg0 + ) + ) + +;; definition for function vector+float! +(defun vector+float! ((arg0 vector) (arg1 vector) (arg2 float)) + (rlet ((vf0 :class vf) + (vf4 :class vf) + (vf5 :class vf) + (vf6 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.mov vf6 arg2) + (.lvf vf4 (&-> arg1 quad)) + (.add.x.vf vf5 vf0 vf0 :mask #b1000) + (.add.x.vf vf5 vf4 vf6 :mask #b111) + (.svf (&-> arg0 quad) vf5) + arg0 + ) + ) + +;; definition for function vector*! +(defun vector*! ((arg0 vector) (arg1 vector) (arg2 vector)) + (rlet ((vf0 :class vf) + (vf4 :class vf) + (vf5 :class vf) + (vf6 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf4 (&-> arg1 quad)) + (.lvf vf5 (&-> arg2 quad)) + (.add.x.vf vf6 vf0 vf0 :mask #b1000) + (.mul.vf vf6 vf4 vf5 :mask #b111) + (.svf (&-> arg0 quad) vf6) + arg0 + ) + ) + +;; definition for function vector+*! +(defun vector+*! ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 float)) + (rlet ((acc :class vf) + (vf0 :class vf) + (vf4 :class vf) + (vf5 :class vf) + (vf6 :class vf) + (vf7 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.mov vf7 arg3) + (.lvf vf5 (&-> arg2 quad)) + (.lvf vf4 (&-> arg1 quad)) + (.add.x.vf vf6 vf0 vf0 :mask #b1000) + (.mul.x.vf acc vf5 vf7 :mask #b111) + (.add.mul.w.vf vf6 vf4 vf0 acc :mask #b111) + (.svf (&-> arg0 quad) vf6) + arg0 + ) + ) + +;; definition for function vector-*! +(defun vector-*! ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 float)) + (rlet ((acc :class vf) + (vf0 :class vf) + (vf4 :class vf) + (vf5 :class vf) + (vf6 :class vf) + (vf7 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.mov vf7 arg3) + (.lvf vf5 (&-> arg2 quad)) + (.lvf vf4 (&-> arg1 quad)) + (.add.x.vf vf6 vf0 vf0 :mask #b1000) + (.mul.w.vf acc vf4 vf0 :mask #b111) + (.sub.mul.x.vf vf6 vf5 vf7 acc :mask #b111) + (.svf (&-> arg0 quad) vf6) + arg0 + ) + ) + +;; definition for function vector/! +(defun vector/! ((arg0 vector) (arg1 vector) (arg2 vector)) + (rlet ((Q :class vf) + (vf0 :class vf) + (vf4 :class vf) + (vf5 :class vf) + (vf6 :class vf) + (vf7 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf5 (&-> arg2 quad)) + (.div.vf Q vf0 vf5 :fsf #b11 :ftf #b1) + (.add.x.vf vf6 vf0 vf0 :mask #b1000) + (.lvf vf4 (&-> arg1 quad)) + (let ((v1-0 (/ (-> arg1 data 0) (-> arg2 data 0)))) + (.wait.vf) + (.mul.vf vf6 vf4 Q :mask #b10) + (.nop.vf) + (.nop.vf) + (.div.vf Q vf0 vf5 :fsf #b11 :ftf #b10) + (.mov vf7 v1-0) + ) + (.add.x.vf vf6 vf0 vf7 :mask #b1) + (.wait.vf) + (.mul.vf vf6 vf4 Q :mask #b100) + (.nop.vf) + (.nop.vf) + (.svf (&-> arg0 quad) vf6) + arg0 + ) + ) + +;; definition for function vector-float*! +(defun vector-float*! ((arg0 vector) (arg1 vector) (arg2 float)) + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg1 quad)) + (.mov vf2 arg2) + (.add.x.vf vf1 vf0 vf0 :mask #b1000) + (.mul.x.vf vf1 vf1 vf2 :mask #b111) + (.svf (&-> arg0 quad) vf1) + arg0 + ) + ) + +;; definition for function vector-average! +(defun vector-average! ((arg0 vector) (arg1 vector) (arg2 vector)) + (rlet ((acc :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (let ((v1-0 #x3f000000)) + (.lvf vf1 (&-> arg1 quad)) + (.lvf vf2 (&-> arg2 quad)) + (.mov vf3 v1-0) + ) + (.add.x.vf vf4 vf0 vf0 :mask #b1000) + (.mul.x.vf acc vf1 vf3) + (.add.mul.x.vf vf4 vf2 vf3 acc :mask #b111) + (.svf (&-> arg0 quad) vf4) + arg0 + ) + ) + +;; definition for function vector+float*! +(defun vector+float*! ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 float)) + (rlet ((acc :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf2 (&-> arg2 quad)) + (.lvf vf1 (&-> arg1 quad)) + (.mov vf3 arg3) + (.add.x.vf vf4 vf0 vf0 :mask #b1000) + (.mul.x.vf acc vf2 vf3) + (.add.mul.w.vf vf4 vf1 vf0 acc :mask #b111) + (.svf (&-> arg0 quad) vf4) + arg0 + ) + ) + +;; definition for function vector--float*! +(defun vector--float*! ((arg0 vector) (arg1 vector) (arg2 vector) (arg3 float)) + (rlet ((acc :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf2 (&-> arg2 quad)) + (.lvf vf1 (&-> arg1 quad)) + (.mov vf3 arg3) + (.add.x.vf vf4 vf0 vf0 :mask #b1000) + (.mul.w.vf acc vf1 vf0) + (.sub.mul.x.vf vf4 vf2 vf3 acc :mask #b111) + (.svf (&-> arg0 quad) vf4) + arg0 + ) + ) + +;; definition for function vector-float/! +(defun vector-float/! ((arg0 vector) (arg1 vector) (arg2 float)) + (rlet ((Q :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf3 :class vf) + (vf4 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.mov vf3 arg2) + (.div.vf Q vf0 vf3 :fsf #b11 :ftf #b0) + (.lvf vf1 (&-> arg1 quad)) + (.add.x.vf vf4 vf0 vf0 :mask #b1000) + (.wait.vf) + (.mul.vf vf4 vf1 Q :mask #b111) + (.nop.vf) + (.nop.vf) + (.svf (&-> arg0 quad) vf4) + arg0 + ) + ) + +;; definition for function vector-negate! +(defun vector-negate! ((arg0 vector) (arg1 vector)) + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf4 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg1 quad)) + (.sub.vf vf4 vf0 vf1 :mask #b111) + (.add.x.vf vf4 vf0 vf0 :mask #b1000) + (.svf (&-> arg0 quad) vf4) + arg0 + ) + ) + +;; definition for function vector-negate-in-place! +(defun vector-negate-in-place! ((arg0 vector)) + (rlet ((vf0 :class vf) + (vf1 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg0 quad)) + (.sub.vf vf1 vf0 vf1 :mask #b111) + (.svf (&-> arg0 quad) vf1) + arg0 + ) + ) + +;; definition for function vector= +;; ERROR: function was not converted to expressions. Cannot decompile. + +;; definition for function vector-delta +(defun vector-delta ((arg0 vector) (arg1 vector)) + (local-vars (v0-0 float)) + (rlet ((acc :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg0 quad)) + (.lvf vf2 (&-> arg1 quad)) + (.sub.vf vf1 vf2 vf1) + (.abs.vf vf1 vf1) + (.mul.x.vf acc vf0 vf1 :mask #b1000) + (.add.mul.y.vf acc vf0 vf1 acc :mask #b1000) + (.add.mul.z.vf vf3 vf0 vf1 acc :mask #b1000) + (.add.w.vf vf3 vf0 vf3 :mask #b1) + (.mov v0-0 vf3) + v0-0 + ) + ) + +;; definition for function vector-seek! +(defun vector-seek! ((arg0 vector) (arg1 vector) (arg2 float)) + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + (vf5 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.mov vf4 arg2) + (.lvf vf1 (&-> arg1 quad)) + (.lvf vf2 (&-> arg0 quad)) + (.add.x.vf vf1 vf0 vf0 :mask #b1000) + (.sub.x.vf vf5 vf0 vf4 :mask #b1) + (.sub.vf vf3 vf1 vf2 :mask #b111) + (.min.x.vf vf3 vf3 vf4 :mask #b111) + (.max.x.vf vf3 vf3 vf5 :mask #b111) + (.add.vf vf1 vf2 vf3 :mask #b111) + (.svf (&-> arg0 quad) vf1) + arg0 + ) + ) + +;; definition for function vector-seek-2d-xz-smooth! +(defun + vector-seek-2d-xz-smooth! + ((vec vector) (target vector) (max-step float) (alpha float)) + (let ((x-diff (- (-> target data 0) (-> vec data 0))) + (z-diff (- (-> target data 2) (-> vec data 2))) + ) + (if (or (!= x-diff 0.0) (!= z-diff 0.0)) + (let* ((x-step (* x-diff alpha)) + (z-step (* z-diff alpha)) + (step-len (sqrtf (+ (* x-step x-step) (* z-step z-step)))) + ) + (cond + ((>= max-step step-len) + (set! (-> vec data 0) (+ (-> vec data 0) x-step)) + (let ((f0-4 (+ (-> vec data 2) z-step))) + (set! (-> vec data 2) f0-4) + ) + ) + (else + (let ((f2-6 (/ max-step step-len))) + (set! (-> vec data 0) (+ (-> vec data 0) (* f2-6 x-step))) + (let ((f0-6 (+ (-> vec data 2) (* f2-6 z-step)))) + (set! (-> vec data 2) f0-6) + ) + ) + ) + ) + ) + ) + ) + vec + ) + +;; definition for function vector-seek-2d-yz-smooth! +(defun + vector-seek-2d-yz-smooth! + ((vec vector) (target vector) (max-step float) (alpha float)) + (let ((y-diff (- (-> target data 1) (-> vec data 1))) + (z-diff (- (-> target data 2) (-> vec data 2))) + ) + (if (or (!= y-diff 0.0) (!= z-diff 0.0)) + (let* ((y-step (* y-diff alpha)) + (z-step (* z-diff alpha)) + (step-len (sqrtf (+ (* y-step y-step) (* z-step z-step)))) + ) + (cond + ((>= max-step step-len) + (set! (-> vec data 1) (+ (-> vec data 1) y-step)) + (let ((f0-4 (+ (-> vec data 2) z-step))) + (set! (-> vec data 2) f0-4) + ) + ) + (else + (let ((step-scale (/ max-step step-len))) + (set! (-> vec data 1) (+ (-> vec data 1) (* step-scale y-step))) + (let ((f0-6 (+ (-> vec data 2) (* step-scale z-step)))) + (set! (-> vec data 2) f0-6) + ) + ) + ) + ) + ) + ) + ) + vec + ) + +;; definition for function vector-seek-3d-smooth! +(defun + vector-seek-3d-smooth! + ((vec vector) (target vector) (max-step float) (alpha float)) + (let ((x-diff (- (-> target data 0) (-> vec data 0))) + (y-diff (- (-> target data 1) (-> vec data 1))) + (z-diff (- (-> target data 2) (-> vec data 2))) + ) + (if (or (!= x-diff 0.0) (!= y-diff 0.0) (!= z-diff 0.0)) + (let* ((x-step (* x-diff alpha)) + (y-step (* y-diff alpha)) + (z-step (* z-diff alpha)) + (step-len + (sqrtf + (+ (+ (* x-step x-step) (* y-step y-step)) (* z-step z-step)) + ) + ) + ) + (cond + ((>= max-step step-len) + (set! (-> vec data 0) (+ (-> vec data 0) x-step)) + (set! (-> vec data 1) (+ (-> vec data 1) y-step)) + (let ((f0-5 (+ (-> vec data 2) z-step))) + (set! (-> vec data 2) f0-5) + ) + ) + (else + (let ((step-scale (/ max-step step-len))) + (set! (-> vec data 0) (+ (-> vec data 0) (* step-scale x-step))) + (set! (-> vec data 1) (+ (-> vec data 1) (* step-scale y-step))) + (let ((f0-7 (+ (-> vec data 2) (* step-scale z-step)))) + (set! (-> vec data 2) f0-7) + ) + ) + ) + ) + ) + ) + ) + vec + ) + +;; definition for function seek-with-smooth +(defun + seek-with-smooth + ((value float) (target float) (max-step float) (alpha float) (deadband float)) + (let ((diff (- target value))) + (if (>= deadband (fabs diff)) + target + (let ((step (* diff alpha))) + (let ((min-step (- max-step))) + (cond + ((< step min-step) + (set! step min-step) + ) + ((< max-step step) + (set! step max-step) + ) + ) + ) + (+ step value) + ) + ) + ) + ) + +;; definition for function vector-identity! +(defun vector-identity! ((arg0 vector)) + (set! (-> arg0 data 0) 1.0) + (set! (-> arg0 data 1) 1.0) + (set! (-> arg0 data 2) 1.0) + (set! (-> arg0 data 3) 1.0) + arg0 + ) + +;; definition for function vector-seconds +(defun vector-seconds ((arg0 vector) (arg1 vector)) + (set! (-> arg0 data 0) (* 300.0 (-> arg1 data 0))) + (set! (-> arg0 data 1) (* 300.0 (-> arg1 data 1))) + (set! (-> arg0 data 2) (* 300.0 (-> arg1 data 2))) + arg0 + ) + +;; definition for function vector-seconds! +(defun vector-seconds! ((arg0 vector)) + (set! (-> arg0 data 0) (* 300.0 (-> arg0 data 0))) + (set! (-> arg0 data 1) (* 300.0 (-> arg0 data 1))) + (set! (-> arg0 data 2) (* 300.0 (-> arg0 data 2))) + arg0 + ) + +;; definition for function vector-v! +(defun vector-v! ((arg0 vector)) + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (let ((v1-0 arg0)) + (let ((a1-0 arg0) + (f0-0 (-> *display* seconds-per-frame)) + ) + (.lvf vf1 (&-> a1-0 quad)) + (let ((a1-1 f0-0)) + (.mov vf2 a1-1) + ) + ) + (.add.x.vf vf1 vf0 vf0 :mask #b1000) + (.mul.x.vf vf1 vf1 vf2 :mask #b111) + (.svf (&-> v1-0 quad) vf1) + ) + arg0 + ) + ) + +;; definition for function vector-v+! +(defun vector-v+! ((result vector) (position vector) (velocity vector)) + (vector+float*! result position velocity (-> *display* seconds-per-frame)) + result + ) + +;; definition for function vector-v*float+! +(defun + vector-v*float+! + ((result vector) (position vector) (velocity vector) (velocity-scale float)) + (vector+float*! + result + position + velocity + (* velocity-scale (-> *display* seconds-per-frame)) + ) + result + ) + +;; definition for function vector-v++! +(defun vector-v++! ((position vector) (velocity vector)) + (vector+float*! position position velocity (-> *display* seconds-per-frame)) + position + ) + +;; definition for function vector-v*float! +(defun vector-v*float! ((delta-p vector) (velocity vector) (scale float)) + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (let ((v0-0 delta-p)) + (let ((v1-0 velocity) + (f0-1 (* scale (-> *display* seconds-per-frame))) + ) + (.lvf vf1 (&-> v1-0 quad)) + (let ((v1-1 f0-1)) + (.mov vf2 v1-1) + ) + ) + (.add.x.vf vf1 vf0 vf0 :mask #b1000) + (.mul.x.vf vf1 vf1 vf2 :mask #b111) + (.svf (&-> v0-0 quad) vf1) + v0-0 + ) + ) + ) + +;; definition for function vector-v*float++! +(defun vector-v*float++! ((position vector) (velocity vector) (scale float)) + (vector+float*! + position + position + velocity + (* scale (-> *display* seconds-per-frame)) + ) + position + ) + +;; definition for function vector-to-ups! +(defun vector-to-ups! ((arg0 vector) (arg1 vector)) + (local-vars (at-0 int)) + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg1 quad)) + (let ((f0-0 (-> *display* frames-per-second))) + (.mov at-0 f0-0) + ) + (.mov vf2 at-0) + (.mov.vf vf1 vf0 :mask #b1000) + (.mul.x.vf vf1 vf1 vf2 :mask #b111) + (.svf (&-> arg0 quad) vf1) + arg0 + ) + ) + +;; definition for function vector-from-ups! +(defun vector-from-ups! ((arg0 vector) (arg1 vector)) + (local-vars (at-0 int)) + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg1 quad)) + (let ((f0-0 (-> *display* seconds-per-frame))) + (.mov at-0 f0-0) + ) + (.mov vf2 at-0) + (.mov.vf vf1 vf0 :mask #b1000) + (.mul.x.vf vf1 vf1 vf2 :mask #b111) + (.svf (&-> arg0 quad) vf1) + arg0 + ) + ) + +;; definition for function vector-length +(defun vector-length ((arg0 vector)) + (local-vars (v0-0 float)) + (rlet ((acc :class vf) + (Q :class vf) + (vf0 :class vf) + (vf1 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg0 quad)) + (.mul.vf vf1 vf1 vf1) + (.mul.x.vf acc vf0 vf1 :mask #b1000) + (.add.mul.y.vf acc vf0 vf1 acc :mask #b1000) + (.add.mul.z.vf vf1 vf0 vf1 acc :mask #b1000) + (.sqrt.vf Q vf1 :ftf #b11) + (.add.w.vf vf1 vf0 vf0 :mask #b1) + (.wait.vf) + (.mul.vf vf1 vf1 Q :mask #b1) + (.nop.vf) + (.nop.vf) + (.mov v0-0 vf1) + v0-0 + ) + ) + +;; definition for function vector-length-squared +(defun vector-length-squared ((arg0 vector)) + (local-vars (v0-0 float)) + (rlet ((acc :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg0 quad)) + (.add.w.vf vf2 vf0 vf0 :mask #b1) + (.mul.vf vf1 vf1 vf1) + (.mul.x.vf acc vf2 vf1 :mask #b1) + (.add.mul.y.vf acc vf2 vf1 acc :mask #b1) + (.add.mul.z.vf vf1 vf2 vf1 acc :mask #b1) + (.mov v0-0 vf1) + v0-0 + ) + ) + +;; definition for function vector-xz-length-squared +(defun vector-xz-length-squared ((arg0 vector)) + (+ + (* (-> arg0 data 0) (-> arg0 data 0)) + (* (-> arg0 data 2) (-> arg0 data 2)) + ) + ) + +;; definition for function vector-xz-length +(defun vector-xz-length ((arg0 vector)) + (sqrtf + (+ + (* (-> arg0 data 0) (-> arg0 data 0)) + (* (-> arg0 data 2) (-> arg0 data 2)) + ) + ) + ) + +;; definition for function vector-vector-distance +(defun vector-vector-distance ((arg0 vector) (arg1 vector)) + (local-vars (v0-0 float)) + (rlet ((acc :class vf) + (Q :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf2 (&-> arg0 quad)) + (.lvf vf3 (&-> arg1 quad)) + (.sub.vf vf1 vf3 vf2) + (.mul.vf vf1 vf1 vf1) + (.mul.x.vf acc vf0 vf1 :mask #b1000) + (.add.mul.y.vf acc vf0 vf1 acc :mask #b1000) + (.add.mul.z.vf vf1 vf0 vf1 acc :mask #b1000) + (.sqrt.vf Q vf1 :ftf #b11) + (.add.w.vf vf1 vf0 vf0 :mask #b1) + (.wait.vf) + (.mul.vf vf1 vf1 Q :mask #b1) + (.nop.vf) + (.nop.vf) + (.mov v0-0 vf1) + v0-0 + ) + ) + +;; definition for function vector-vector-distance-squared +(defun vector-vector-distance-squared ((arg0 vector) (arg1 vector)) + (local-vars (v0-0 float)) + (rlet ((vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + ) + (.lvf vf2 (&-> arg0 quad)) + (.lvf vf3 (&-> arg1 quad)) + (.sub.vf vf1 vf3 vf2) + (.mul.vf vf1 vf1 vf1) + (.add.y.vf vf1 vf1 vf1 :mask #b1) + (.add.z.vf vf1 vf1 vf1 :mask #b1) + (.mov v0-0 vf1) + v0-0 + ) + ) + +;; definition for function vector-vector-xz-distance +(defun vector-vector-xz-distance ((arg0 vector) (arg1 vector)) + (local-vars (v0-0 float)) + (rlet ((acc :class vf) + (Q :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf2 (&-> arg0 quad)) + (.lvf vf3 (&-> arg1 quad)) + (.sub.vf vf1 vf3 vf2) + (.mul.vf vf1 vf1 vf1) + (.mul.x.vf acc vf0 vf1 :mask #b1000) + (.add.mul.z.vf vf1 vf0 vf1 acc :mask #b1000) + (.sqrt.vf Q vf1 :ftf #b11) + (.add.w.vf vf1 vf0 vf0 :mask #b1) + (.wait.vf) + (.mul.vf vf1 vf1 Q :mask #b1) + (.nop.vf) + (.nop.vf) + (.mov v0-0 vf1) + v0-0 + ) + ) + +;; definition for function vector-vector-xz-distance-squared +(defun vector-vector-xz-distance-squared ((arg0 vector) (arg1 vector)) + (local-vars (v0-0 float)) + (rlet ((vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + ) + (.lvf vf2 (&-> arg0 quad)) + (.lvf vf3 (&-> arg1 quad)) + (.sub.vf vf1 vf3 vf2) + (.mul.vf vf1 vf1 vf1) + (.add.z.vf vf1 vf1 vf1 :mask #b1) + (.mov v0-0 vf1) + v0-0 + ) + ) + +;; definition for function vector-normalize! +(defun vector-normalize! ((arg0 vector) (arg1 float)) + (rlet ((acc :class vf) + (Q :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg0 quad)) + (.mul.vf vf2 vf1 vf1 :mask #b111) + (let ((v1-0 arg1)) + (.mov vf3 v1-0) + ) + (.mul.x.vf acc vf0 vf2 :mask #b1000) + (.add.mul.y.vf acc vf0 vf2 acc :mask #b1000) + (.add.mul.z.vf vf2 vf0 vf2 acc :mask #b1000) + (.isqrt.vf Q vf3 vf2 :fsf #b0 :ftf #b11) + (.wait.vf) + (.mul.vf vf1 vf1 Q :mask #b111) + (.nop.vf) + (.nop.vf) + (.nop.vf) + (.svf (&-> arg0 quad) vf1) + arg0 + ) + ) + +;; definition for function vector-normalize-ret-len! +(defun vector-normalize-ret-len! ((arg0 vector) (arg1 float)) + (local-vars (v1-1 float)) + (rlet ((acc :class vf) + (Q :class vf) + (vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg0 quad)) + (.mul.vf vf2 vf1 vf1 :mask #b111) + (let ((v1-0 arg1)) + (.mov vf3 v1-0) + ) + (.mul.x.vf acc vf0 vf2 :mask #b1000) + (.add.mul.y.vf acc vf0 vf2 acc :mask #b1000) + (.add.mul.z.vf vf2 vf0 vf2 acc :mask #b1000) + (.isqrt.vf Q vf3 vf2 :fsf #b0 :ftf #b11) + (.add.w.vf vf2 vf0 vf2 :mask #b1) + (.mov v1-1 vf2) + (let ((v0-0 (sqrtf v1-1))) + (.wait.vf) + (.mul.vf vf1 vf1 Q :mask #b111) + (.nop.vf) + (.nop.vf) + (.nop.vf) + (.svf (&-> arg0 quad) vf1) + v0-0 + ) + ) + ) + +;; definition for function vector-normalize-copy! +;; Used lq/sq +(defun vector-normalize-copy! ((arg0 vector) (arg1 vector) (arg2 float)) + (let ((f0-0 (vector-length arg1))) + (if (= f0-0 0.0) + (set! (-> arg0 quad) (-> arg1 quad)) + (let ((v1-1 (/ arg2 f0-0))) + (set! (-> arg0 data 0) (* (-> arg1 data 0) v1-1)) + (set! (-> arg0 data 1) (* (-> arg1 data 1) v1-1)) + (let ((f0-7 (* (-> arg1 data 2) v1-1))) + (set! (-> arg0 data 2) f0-7) + ) + ) + ) + ) + (set! (-> arg0 data 3) 1.0) + arg0 + ) + +;; definition for function vector-xz-normalize! +(defun vector-xz-normalize! ((arg0 vector) (arg1 float)) + (let ((f0-0 (vector-xz-length arg0))) + (if (!= f0-0 0.0) + (let ((v1-1 (/ arg1 f0-0))) + (set! (-> arg0 data 0) (* (-> arg0 data 0) v1-1)) + (let ((f0-5 (* (-> arg0 data 2) v1-1))) + (set! (-> arg0 data 2) f0-5) + ) + ) + ) + ) + arg0 + ) + +;; definition for function vector-length-max! +(defun vector-length-max! ((arg0 vector) (arg1 float)) + (let ((f0-0 (vector-length arg0))) + (when (not (or (= f0-0 0.0) (< f0-0 arg1))) + (set! f0-0 (/ f0-0 arg1)) + (when (!= f0-0 0.0) + (set! (-> arg0 data 0) (/ (-> arg0 data 0) f0-0)) + (set! (-> arg0 data 1) (/ (-> arg0 data 1) f0-0)) + (let ((f0-1 (/ (-> arg0 data 2) f0-0))) + (set! (-> arg0 data 2) f0-1) + ) + ) + ) + ) + arg0 + ) + +;; definition for function vector-xz-length-max! +(defun vector-xz-length-max! ((arg0 vector) (arg1 float)) + (let ((f0-0 (vector-xz-length arg0))) + (when (not (or (= f0-0 0.0) (< f0-0 arg1))) + (set! f0-0 (/ f0-0 arg1)) + (when (!= f0-0 0.0) + (set! (-> arg0 data 0) (/ (-> arg0 data 0) f0-0)) + (let ((f0-1 (/ (-> arg0 data 2) f0-0))) + (set! (-> arg0 data 2) f0-1) + ) + ) + ) + ) + arg0 + ) + +;; definition for function vector-rotate-around-y! +;; Used lq/sq +(defun vector-rotate-around-y! ((arg0 vector) (arg1 vector) (arg2 float)) + (let ((f26-0 (-> arg1 data 2)) + (f30-0 (-> arg1 data 0)) + (f28-0 (cos arg2)) + (f0-0 (sin arg2)) + ) + (set! (-> arg0 quad) (-> arg1 quad)) + (set! (-> arg0 data 2) (- (* f26-0 f28-0) (* f30-0 f0-0))) + (set! (-> arg0 data 0) (+ (* f26-0 f0-0) (* f30-0 f28-0))) + ) + arg0 + ) + +;; definition for function rotate-y<-vector+vector +(defun rotate-y<-vector+vector ((arg0 vector) (arg1 vector)) + (atan + (- (-> arg1 data 0) (-> arg0 data 0)) + (- (-> arg1 data 2) (-> arg0 data 2)) + ) + ) + +;; definition for function vector-cvt.w.s! +(defun vector-cvt.w.s! ((arg0 vector) (arg1 vector)) + (rlet ((vf1 :class vf)) + (.lvf vf1 (&-> arg1 quad)) + (.ftoi.vf vf1 vf1) + (.svf (&-> arg0 quad) vf1) + arg0 + ) + ) + +;; definition for function vector-cvt.s.w! +(defun vector-cvt.s.w! ((arg0 vector) (arg1 vector)) + (rlet ((vf1 :class vf)) + (.lvf vf1 (&-> arg1 quad)) + (.itof.vf vf1 vf1) + (.svf (&-> arg0 quad) vf1) + arg0 + ) + ) + +;; definition for function rot-zxy-from-vector! +(defun rot-zxy-from-vector! ((arg0 vector) (arg1 vector)) + (let* ((f28-0 (-> arg1 data 2)) + (f30-0 (-> arg1 data 0)) + (f0-0 (atan f30-0 f28-0)) + ) + (set! (-> arg0 data 1) f0-0) + (let* ((f26-0 (- f0-0)) + (f0-4 (- (* f28-0 (cos f26-0)) (* f30-0 (sin f26-0)))) + (f0-5 (atan (- (-> arg1 data 1)) f0-4)) + ) + (set! (-> arg0 data 0) f0-5) + ) + ) + (set! (-> arg0 data 2) 0.0) + arg0 + ) + +;; definition for function rot-zyx-from-vector! +(defun rot-zyx-from-vector! ((arg0 vector) (arg1 vector)) + (let* ((f28-0 (-> arg1 data 2)) + (f30-0 (- (-> arg1 data 1))) + (f0-1 (atan f30-0 f28-0)) + ) + (set! (-> arg0 data 0) f0-1) + (let* ((f26-0 (- f0-1)) + (f0-5 (- (* f28-0 (cos f26-0)) (* f30-0 (sin f26-0)))) + (f0-6 (atan (-> arg1 data 0) f0-5)) + ) + (set! (-> arg0 data 1) f0-6) + ) + ) + (set! (-> arg0 data 2) 0.0) + arg0 + ) + +;; definition for function vector-lerp! +(defun vector-lerp! ((out vector) (a vector) (b vector) (alpha float)) + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> a quad)) + (.lvf vf2 (&-> b quad)) + (.mov vf4 alpha) + (.add.x.vf vf3 vf0 vf0 :mask #b1000) + (.sub.vf vf2 vf2 vf1) + (.mul.x.vf vf2 vf2 vf4) + (.add.vf vf3 vf1 vf2 :mask #b111) + (.svf (&-> out quad) vf3) + out + ) + ) + +;; definition for function vector-lerp-clamp! +;; Used lq/sq +(defun vector-lerp-clamp! ((out vector) (a vector) (b vector) (alpha float)) + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (cond + ((>= 0.0 alpha) + (set! (-> out quad) (-> a quad)) + ) + ((>= alpha 1.0) + (set! (-> out quad) (-> b quad)) + ) + (else + (let ((v1-2 out)) + (let ((f0-2 alpha)) + (.lvf vf1 (&-> a quad)) + (.lvf vf2 (&-> b quad)) + (let ((a1-1 f0-2)) + (.mov vf4 a1-1) + ) + ) + (.add.x.vf vf3 vf0 vf0 :mask #b1000) + (.sub.vf vf2 vf2 vf1) + (.mul.x.vf vf2 vf2 vf4) + (.add.vf vf3 vf1 vf2 :mask #b111) + (.svf (&-> v1-2 quad) vf3) + ) + ) + ) + out + ) + ) + +;; definition for function vector4-lerp! +(defun vector4-lerp! ((out vector) (a vector) (b vector) (alpha float)) + (rlet ((vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + ) + (.lvf vf1 (&-> a quad)) + (.lvf vf2 (&-> b quad)) + (.mov vf4 alpha) + (.sub.vf vf2 vf2 vf1) + (.mul.x.vf vf2 vf2 vf4) + (.add.vf vf3 vf1 vf2) + (.svf (&-> out quad) vf3) + out + ) + ) + +;; definition for function vector4-lerp-clamp! +;; Used lq/sq +(defun vector4-lerp-clamp! ((out vector) (a vector) (b vector) (alpha float)) + (rlet ((vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + ) + (cond + ((>= 0.0 alpha) + (set! (-> out quad) (-> a quad)) + ) + ((>= alpha 1.0) + (set! (-> out quad) (-> b quad)) + ) + (else + (let ((v1-2 out)) + (let ((f0-2 alpha)) + (.lvf vf1 (&-> a quad)) + (.lvf vf2 (&-> b quad)) + (let ((a1-1 f0-2)) + (.mov vf4 a1-1) + ) + ) + (.sub.vf vf2 vf2 vf1) + (.mul.x.vf vf2 vf2 vf4) + (.add.vf vf3 vf1 vf2) + (.svf (&-> v1-2 quad) vf3) + ) + ) + ) + out + ) + ) + +;; definition for function vector-degi +;; Used lq/sq +(defun vector-degi ((arg0 vector) (arg1 vector)) + (local-vars (v1-0 float) (v1-1 int)) + (rlet ((vf1 :class vf)) + (.lvf vf1 (&-> arg1 quad)) + (.ftoi.vf vf1 vf1) + (.mov v1-0 vf1) + (.pw.sll v1-1 v1-0 16) + (set! (-> arg0 quad) (the-as uint128 v1-1)) + arg0 + ) + ) + +;; definition for function vector-degf +;; Used lq/sq +(defun vector-degf ((arg0 vector) (arg1 vector)) + (local-vars (v1-1 uint128)) + (rlet ((vf1 :class vf)) + (let ((v1-0 (-> arg1 quad))) + (.pw.sra v1-1 v1-0 16) + ) + (.mov vf1 v1-1) + (.itof.vf vf1 vf1) + (.svf (&-> arg0 quad) vf1) + arg0 + ) + ) + +;; definition for function vector-degmod +(defun vector-degmod ((arg0 vector) (arg1 vector)) + (local-vars (v1-0 float) (v1-1 int) (v1-2 int)) + (rlet ((vf1 :class vf)) + (.lvf vf1 (&-> arg1 quad)) + (.ftoi.vf vf1 vf1) + (.mov v1-0 vf1) + (.pw.sll v1-1 v1-0 16) + (.pw.sra v1-2 v1-1 16) + (.mov vf1 v1-2) + (.itof.vf vf1 vf1) + (.svf (&-> arg0 quad) vf1) + arg0 + ) + ) + +;; definition for function vector-deg-diff +;; INFO: Return type mismatch float vs none. +(defun vector-deg-diff ((arg0 vector) (arg1 vector) (arg2 vector)) + (local-vars + (v0-0 float) + (v1-0 float) + (v1-1 int) + (v1-2 int) + (v1-3 int) + (a1-1 float) + (a1-2 int) + ) + (rlet ((vf1 :class vf) + (vf2 :class vf) + ) + (.lvf vf1 (&-> arg1 quad)) + (.lvf vf2 (&-> arg2 quad)) + (.ftoi.vf vf1 vf1) + (.ftoi.vf vf2 vf2) + (.mov a1-1 vf1) + (.mov v1-0 vf2) + (.pw.sll a1-2 a1-1 16) + (.pw.sll v1-1 v1-0 16) + (.psubw v1-2 a1-2 v1-1) + (.pw.sra v1-3 v1-2 16) + (.mov vf1 v1-3) + (.itof.vf vf1 vf1) + (.svf (&-> arg0 quad) vf1) + (.mov v0-0 vf1) + (none) + ) + ) + +;; definition for function vector-deg-lerp-clamp! +;; Used lq/sq +(defun + vector-deg-lerp-clamp! + ((out vector) (min-val vector) (max-val vector) (in float)) + (cond + ((>= 0.0 in) + (let ((v1-0 out)) + (set! (-> v1-0 quad) (-> min-val quad)) + ) + ) + ((>= in 1.0) + (let ((v1-1 out)) + (set! (-> v1-1 quad) (-> max-val quad)) + ) + ) + (else + (set! + (-> out data 0) + (deg-lerp-clamp (-> min-val data 0) (-> max-val data 0) in) + ) + (set! + (-> out data 1) + (deg-lerp-clamp (-> min-val data 1) (-> max-val data 1) in) + ) + (set! + (-> out data 2) + (deg-lerp-clamp (-> min-val data 2) (-> max-val data 2) in) + ) + (let ((f0-11 1.0)) + (set! (-> out data 3) f0-11) + ) + ) + ) + out + ) + +;; definition for function vector3s-copy! +(defun vector3s-copy! ((arg0 vector) (arg1 vector)) + (let ((v1-0 "Copy a vector3s")) + ) + (set! (-> arg0 data 0) (-> arg1 data 0)) + (set! (-> arg0 data 1) (-> arg1 data 1)) + (set! (-> arg0 data 2) (-> arg1 data 2)) + arg0 + ) + +;; definition for function vector3s+! +(defun vector3s+! ((arg0 vector) (arg1 vector) (arg2 vector)) + (let ((v1-0 "Add 2 vectors3.")) + ) + (set! (-> arg0 data 0) (+ (-> arg1 data 0) (-> arg2 data 0))) + (set! (-> arg0 data 1) (+ (-> arg1 data 1) (-> arg2 data 1))) + (set! (-> arg0 data 2) (+ (-> arg1 data 2) (-> arg2 data 2))) + arg0 + ) + +;; definition for function vector3s*float! +(defun vector3s*float! ((arg0 vector) (arg1 vector) (arg2 float)) + (let ((v1-0 "mult vectors3 by float")) + ) + (set! (-> arg0 data 0) (* (-> arg1 data 0) arg2)) + (set! (-> arg0 data 1) (* (-> arg1 data 1) arg2)) + (set! (-> arg0 data 2) (* (-> arg1 data 2) arg2)) + arg0 + ) + +;; definition for function vector3s-! +(defun vector3s-! ((arg0 vector) (arg1 vector) (arg2 vector)) + (let ((v1-0 "Subtract 2 vectors3: c = (a - b).")) + ) + (set! (-> arg0 data 0) (- (-> arg1 data 0) (-> arg2 data 0))) + (set! (-> arg0 data 1) (- (-> arg1 data 1) (-> arg2 data 1))) + (set! (-> arg0 data 2) (- (-> arg1 data 2) (-> arg2 data 2))) + arg0 + ) + +;; definition for function spheres-overlap? +(defun spheres-overlap? ((arg0 sphere) (arg1 sphere)) + (local-vars (v1-0 float) (a0-1 float)) + (rlet ((vf0 :class vf) + (vf1 :class vf) + (vf2 :class vf) + (vf3 :class vf) + (vf4 :class vf) + ) + (.lvf vf0 (new 'static 'vector :x 0.0 :y 0.0 :z 0.0 :w 1.0)) + (.lvf vf1 (&-> arg0 quad)) + (.lvf vf2 (&-> arg1 quad)) + (.sub.vf vf3 vf1 vf2 :mask #b111) + (.mul.vf vf3 vf3 vf3 :mask #b111) + (.add.w.vf vf4 vf1 vf2 :mask #b1000) + (.mul.w.vf vf4 vf4 vf4 :mask #b1000) + (.add.y.vf vf3 vf3 vf3 :mask #b1) + (.add.z.vf vf3 vf3 vf3 :mask #b1) + (.add.w.vf vf4 vf0 vf4 :mask #b1) + (.mov a0-1 vf4) + (.mov v1-0 vf3) + (>= a0-1 v1-0) + ) + ) + +;; definition for function sphere<-vector! +;; Used lq/sq +(defun sphere<-vector! ((arg0 sphere) (arg1 vector)) + (let ((f0-0 (-> arg0 data 3))) + (set! (-> arg0 quad) (-> arg1 quad)) + (set! (-> arg0 data 3) f0-0) + ) + arg0 + ) + +;; definition for function sphere<-vector+r! +;; Used lq/sq +(defun sphere<-vector+r! ((arg0 sphere) (arg1 vector) (arg2 float)) + (set! (-> arg0 quad) (-> arg1 quad)) + (set! (-> arg0 data 3) arg2) + arg0 + ) + +;; definition for function rand-vu-sphere-point! +(defun rand-vu-sphere-point! ((arg0 vector) (arg1 float)) + (let ((s4-0 arg0)) + (set! (-> s4-0 data 0) (rand-vu-float-range -1.0 1.0)) + (set! (-> s4-0 data 1) (rand-vu-float-range -1.0 1.0)) + (set! (-> s4-0 data 2) (rand-vu-float-range -1.0 1.0)) + (set! (-> s4-0 data 3) 1.0) + ) + (vector-normalize! arg0 (rand-vu-float-range 0.0 arg1)) + ) + + + + diff --git a/test/goalc/source_templates/with_game/test-pextlw.gc b/test/goalc/source_templates/with_game/test-pextlw.gc index 35c099c20..cfb95739f 100644 --- a/test/goalc/source_templates/with_game/test-pextlw.gc +++ b/test/goalc/source_templates/with_game/test-pextlw.gc @@ -51,4 +51,24 @@ (print128 s3q) (format #t "~%") ) ) - ) \ No newline at end of file + + (let ((s1 (new 'stack 'array 'uint32 4)) + (s2 (new 'stack 'array 'uint32 4))) + (set! (-> s1 0) #x300) + (set! (-> s1 1) #x3) + (set! (-> s1 2) #x100) + (set! (-> s1 3) #x100000) + (set! (-> s2 0) #x1) + (set! (-> s2 1) #x5) + (set! (-> s2 2) #x2) + (set! (-> s2 3) #x70000) + + (let ((s1q (-> (the (pointer uint128) s1))) + (s2q (-> (the (pointer uint128) s2))) + (s3q (the uint128 0))) + (.psubw s3q s1q s2q) + (print128 s3q) (format #t "~%") + ;; #x00090000000000fefffffffe000002ff + ) + ) + ) diff --git a/test/goalc/source_templates/with_game/test-vector.gc b/test/goalc/source_templates/with_game/test-vector.gc new file mode 100644 index 000000000..5abb53feb --- /dev/null +++ b/test/goalc/source_templates/with_game/test-vector.gc @@ -0,0 +1,138 @@ +(defmacro stack-vec-xyzw (x y z w) + `(let ((vec (new 'stack 'vector))) + (set! (-> vec x) ,x) + (set! (-> vec y) ,y) + (set! (-> vec z) ,z) + (set! (-> vec w) ,w) + vec + ) + ) + +(defmacro print-vec (x) + `(begin + (format #t "[~F] [~F] [~F] [~F]~%" (-> ,x x) (-> ,x y) (-> ,x z) (-> ,x w)) + ) + ) + +(defmacro print-veci (x) + `(begin + (let ((veci (the (pointer int32) ,x))) + (format #t "~d ~d ~d ~d~%" (-> veci 0) (-> veci 1) (-> veci 2) (-> veci 3)) + ) + ) + ) + +(defmacro print-vec-deg-i (x) + `(begin + (let ((veci (the (pointer int32) ,x))) + (format #t "~r ~r ~r ~r~%" + (the float (-> veci 0)) + (the float (-> veci 1)) + (the float (-> veci 2)) + (the float (-> veci 3))) + ) + ) + ) + +(defmacro print-vec-deg-f (x) + `(format #t "~r ~r ~r ~r~%" + (-> ,x x) + (-> ,x y) + (-> ,x z) + (-> ,x w) + ) + ) + +(defmacro set-veci! (vec x y z w) + `(begin + (let ((veci (the (pointer int32) ,vec))) + (set! (-> veci 0) ,x) + (set! (-> veci 1) ,y) + (set! (-> veci 2) ,z) + (set! (-> veci 3) ,w) + ) + ) + ) + +(defmacro set-vecd! (vec x y z w) + `(begin + (set! (-> ,vec x) (degrees ,x)) + (set! (-> ,vec y) (degrees ,y)) + (set! (-> ,vec z) (degrees ,z)) + (set! (-> ,vec w) (degrees ,w)) + ) + ) + + +(let ((v1 (stack-vec-xyzw 1. 2. 3. 4.)) + (v2 (stack-vec-xyzw 5. 6. 7. 8.)) + (v4 (new 'stack 'vector)) + (v3 (new 'stack 'vector))) + ;; part 1 + ;; w gets set to junk by vector-cross! + (vector-cross! v3 v1 v2) (set! (-> v3 w) 0.0) (print-vec v3) + (vector+float! v3 v1 2.0) (print-vec v3) + (vector*! v3 v1 v2) (print-vec v3) + (vector+*! v3 v1 v2 2.0) (print-vec v3) + (vector-*! v3 v1 v2 2.0) (print-vec v3) + (vector/! v3 v1 v2) (print-vec v3) + (vector-float*! v3 v1 -2.0) (print-vec v3) + (vector-average! v3 v1 v2) (print-vec v3) + (vector+float*! v3 v1 v2 2.0) (print-vec v3) + (vector--float*! v3 v1 v2 2.0) (print-vec v3) + (vector-float/! v3 v1 -2.0) (print-vec v3) + (vector-negate! v3 v1) (print-vec v3) + + + ;; part 2 + (format #t "part 2~%") + (vector-negate-in-place! v1) (print-vec v1) + (vector-negate-in-place! v1) + + (format #t "~A ~A ~A ~A~%" + (vector= v1 v2) ;; no + (vector= v1 v1) ;; yes + (vector= v1 (stack-vec-xyzw 1. 2. 3. 5.)) ;; yes + (vector= v1 (stack-vec-xyzw 1. 2. 3.1 4.)) ;; no + ) + + (format #t "~f~%" (vector-delta (stack-vec-xyzw 1.0 -2.0 3.0 -4.0) + (stack-vec-xyzw 2.0 -3.0 1.0 -20.0))) + + ;; part 3 + (format #t "part 3~%") + (vector-copy! v3 v1) + (vector-seek! v3 v2 0.5) + (print-vec v3) + (vector-seek! v3 v2 100.0) + (print-vec v3) + + ;; 2,3,6 -> 7 pythagorean quadruple (is that even a thing) + (format #t "~f~%" (vector-length (stack-vec-xyzw 2.0 3.0 6.0 99.99))) + (format #t "~f~%" (vector-length-squared (stack-vec-xyzw 2.0 3.0 6.0 99.99))) + (format #t "~f~%" (vector-vector-distance + (stack-vec-xyzw 4.0 5.0 7.0 1.0) + (stack-vec-xyzw 6.0 2.0 1.0 99.99))) + (print-vec (vector-normalize! + (stack-vec-xyzw 1.0 1.5 3. 10.0) + 49.0)) + + (format #t "~f~%" (vector-normalize-ret-len! + (stack-vec-xyzw 1.0 1.5 3. 10.0) + 49.0)) + + (vector-cvt.w.s! v3 (stack-vec-xyzw -1.9 2.9 -3.1 4.1)) + (print-veci v3) + (vector-cvt.s.w! v3 v3) + (print-vec v3) + + (vector-degi v3 (stack-vec-xyzw (/ 10.0 360.0) (/ 721.0 360.0) (/ 370.0 360.0) (/ -187.0 360.0))) + (print-vec-deg-i v3) + + (set-vecd! v3 25 45 -25 (+ -360 -25)) + (set-vecd! v4 45 25 (+ 360 -45) -45) + + (vector-deg-diff v3 v3 v4) + (print-vec-deg-f v3) + + ) \ No newline at end of file diff --git a/test/goalc/test_with_game.cpp b/test/goalc/test_with_game.cpp index 4529efe39..202ff125e 100644 --- a/test/goalc/test_with_game.cpp +++ b/test/goalc/test_with_game.cpp @@ -488,6 +488,39 @@ TEST_F(WithGameTests, Trig) { "0\n"}); } +TEST_F(WithGameTests, Vector) { + runner.run_static_test(env, testCategory, "test-vector.gc", + {"[ -4.0000] [ 8.0000] [ -4.0000] [ 0.0000]\n" + "[ 3.0000] [ 4.0000] [ 5.0000] [ 1.0000]\n" + "[ 5.0000] [ 12.0000] [ 21.0000] [ 1.0000]\n" + "[ 11.0000] [ 14.0000] [ 17.0000] [ 1.0000]\n" + "[ -9.0000] [ -10.0000] [ -11.0000] [ 1.0000]\n" + "[ 0.2000] [ 0.3333] [ 0.4285] [ 1.0000]\n" + "[ -2.0000] [ -4.0000] [ -6.0000] [ 1.0000]\n" + "[ 3.0000] [ 4.0000] [ 5.0000] [ 1.0000]\n" + "[ 11.0000] [ 14.0000] [ 17.0000] [ 1.0000]\n" + "[ -9.0000] [ -10.0000] [ -11.0000] [ 1.0000]\n" + "[ -0.5000] [ -1.0000] [ -1.5000] [ 1.0000]\n" + "[ -1.0000] [ -2.0000] [ -3.0000] [ 1.0000]\n" + "part 2\n" + "[ -1.0000] [ -2.0000] [ -3.0000] [ 4.0000]\n" + "#f #t #t #f\n" + "4.0000\n" + "part 3\n" + "[ 1.5000] [ 2.5000] [ 3.5000] [ 1.0000]\n" + "[ 5.0000] [ 6.0000] [ 7.0000] [ 1.0000]\n" + "7.0000\n" + "49.0000\n" + "7.0000\n" + "[ 14.0000] [ 21.0000] [ 42.0000] [ 10.0000]\n" + "3.5000\n" + "-1 2 -3 4\n" + "[ -1.0000] [ 2.0000] [ -3.0000] [ 4.0000]\n" + "0.0000 720.0000 360.0000 0.0000\n" + "-20.0006 20.0006 20.0006 20.0006\n" + "0\n"}); +} + TEST_F(WithGameTests, InlinedPackedBasics) { runner.run_static_test(env, testCategory, "inlined-packed-basics.gc", {"rec stride: 48\n" @@ -607,6 +640,7 @@ TEST_F(WithGameTests, Pextlw) { "#x1f1e1d1c1b1a19180f0e0d0c0b0a0908\n" "#x0d0c0908050401001d1c191815141110\n" "#xffffffff00000000ffffffff00000000\n" + "#x00090000000000fefffffffe000002ff\n" "0\n"}); } diff --git a/test/offline/offline_test_main.cpp b/test/offline/offline_test_main.cpp index 899c5b7ab..1107b6fd5 100644 --- a/test/offline/offline_test_main.cpp +++ b/test/offline/offline_test_main.cpp @@ -17,7 +17,7 @@ const std::unordered_set g_object_files_to_decompile = { "trigonometry-h", /* transformq-h */ "matrix", "transform", "quaternion", "euler", /* geometry, trigonometry, */ "gsound-h", "timer-h", "timer", "vif-h", "dma-h", "video-h", "vu1-user-h", "dma", "dma-buffer", - "dma-bucket", "dma-disasm", "pad", "gs", "display-h", + "dma-bucket", "dma-disasm", "pad", "gs", "display-h", "vector", /* gap */ "bounding-box", /* gap */ @@ -32,7 +32,7 @@ const std::vector g_object_files_to_check_against_reference = { /* transformq-h, */ "matrix", "transform", "quaternion", "euler", /* geometry, trigonometry */ "gsound-h", "timer-h", /* timer, */ "vif-h", "dma-h", "video-h", "vu1-user-h", "dma", - "dma-buffer", "dma-bucket", "dma-disasm", "pad", "gs", "display-h", + "dma-buffer", "dma-bucket", "dma-disasm", "pad", "gs", "display-h", "vector", /* gap */ "bounding-box", /* gap */ "sync-info-h", "sync-info"}; @@ -71,6 +71,7 @@ const std::unordered_set expected_skip_in_decompiler = { "dma-sync-with-count", "dma-send-no-scratch", "dma-sync-fast", // dma "symlink2", "symlink3", "dma-sync-hang", // handwritten asm + "vector=", // asm branching // sync-info "(method 15 sync-info)", // needs *res-static-buf* "(method 15 sync-info-eased)", // needs *res-static-buf* @@ -126,6 +127,10 @@ const std::unordered_set skip_in_compiling = { // display-h "put-draw-env", + // vector + // bad decisions on float vs int128 + "vector-degf", "vector-degmod", "vector-deg-diff", "vector-degi", + // sync-info "(method 15 sync-info)", // needs display stuff first "(method 15 sync-info-eased)", // needs display stuff first diff --git a/test/test_emitter_avx.cpp b/test/test_emitter_avx.cpp index 83e54da83..fbd9882ba 100644 --- a/test/test_emitter_avx.cpp +++ b/test/test_emitter_avx.cpp @@ -340,7 +340,7 @@ TEST(EmitterAVX, FTOI) { tester.emit(IGen::ftoi_vf(XMM0 + 3, XMM0 + 14)); tester.emit(IGen::ftoi_vf(XMM0 + 13, XMM0 + 4)); tester.emit(IGen::ftoi_vf(XMM0 + 13, XMM0 + 14)); - EXPECT_EQ(tester.dump_to_hex_string(true), "C5F95BDCC4C1795BDEC5795BECC441795BEE"); + EXPECT_EQ(tester.dump_to_hex_string(true), "C5FA5BDCC4C17A5BDEC57A5BECC4417A5BEE"); } TEST(EmitterAVX, VPSRAD) { @@ -488,7 +488,7 @@ TEST(EmitterAVX, VPSHUFHW) { EXPECT_EQ(tester.dump_to_hex_string(true), "C5FA70DC03C4C17A70DE04C57A70EC05C4417A70EE06"); } -TEST(EmitrerAVX, movq_to_gpr_from_xmm) { +TEST(EmitterAVX, movq_to_gpr_from_xmm) { CodeTester tester; tester.init_code_buffer(1024); tester.emit(IGen::movq_gpr64_xmm64(RSP, XMM0 + 3)); @@ -498,7 +498,7 @@ TEST(EmitrerAVX, movq_to_gpr_from_xmm) { EXPECT_EQ(tester.dump_to_hex_string(true), "66480F7EDC664C0F7EEC66490F7EDC664D0F7EEC"); } -TEST(EmitrerAVX, movq_to_xmm_from_gpr) { +TEST(EmitterAVX, movq_to_xmm_from_gpr) { CodeTester tester; tester.init_code_buffer(1024); tester.emit(IGen::movq_xmm64_gpr64(XMM0 + 3, RSP)); @@ -506,4 +506,19 @@ TEST(EmitrerAVX, movq_to_xmm_from_gpr) { 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"); +} + +TEST(EmitterAVX, VPSUBD) { + CodeTester tester; + tester.init_code_buffer(1024); + tester.emit(IGen::vpsubd(XMM0 + 3, XMM0 + 3, XMM0 + 3)); + tester.emit(IGen::vpsubd(XMM0 + 3, XMM0 + 3, XMM0 + 13)); + tester.emit(IGen::vpsubd(XMM0 + 3, XMM0 + 13, XMM0 + 3)); + tester.emit(IGen::vpsubd(XMM0 + 3, XMM0 + 13, XMM0 + 13)); + tester.emit(IGen::vpsubd(XMM0 + 13, XMM0 + 3, XMM0 + 3)); + tester.emit(IGen::vpsubd(XMM0 + 13, XMM0 + 3, XMM0 + 13)); + tester.emit(IGen::vpsubd(XMM0 + 13, XMM0 + 13, XMM0 + 3)); + tester.emit(IGen::vpsubd(XMM0 + 13, XMM0 + 13, XMM0 + 13)); + EXPECT_EQ(tester.dump_to_hex_string(true), + "C5E1FADBC4C161FADDC591FADBC4C111FADDC561FAEBC44161FAEDC511FAEBC44111FAED"); } \ No newline at end of file