[Decompile] vector.gc (finally) (#394)

* support psubw

* do half of vector

* rest of vector

* add test

* format
This commit is contained in:
water111 2021-04-28 17:14:54 -04:00 committed by GitHub
parent 53a70d8e43
commit 14028b90bc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 2166 additions and 443 deletions

View file

@ -8,10 +8,9 @@ typedef OpenGOALAsm::InstructionModifiers MOD;
const std::map<InstructionKind, OpenGOALAsm::Function> 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", {}}},

View file

@ -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
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

View file

@ -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)",

View file

@ -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" }

View file

@ -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 <typename>` 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).

View file

@ -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,27 +358,69 @@
)
)
(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))))
;; 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
((>= 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)
((>= 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))
)
)
)
)
)
)
vec
)
(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 (!= 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 ((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)
(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)
)
)
)
@ -382,30 +428,38 @@
)
)
)
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-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) (!= 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))))
(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
((>= 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)
((>= 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 ((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)
(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)
)
)
)
@ -413,66 +467,35 @@
)
)
)
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)))
)
(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))))
)
(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
((>= 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)
((< step min-step)
(set! step min-step)
)
)
(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)
((< max-step step)
(set! step max-step)
)
)
)
)
)
)
)
arg0
)
(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)
)
((< arg2 f0-2)
(set! f0-2 arg2)
)
)
)
(+ f0-2 arg0)
(+ step value)
)
)
)
)
(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,32 +543,37 @@
)
)
(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)))
(let ((v0-0 delta-p))
(let ((v1-0 velocity)
(f0-1 (* scale (-> *display* seconds-per-frame)))
)
(.lvf vf1 v1-0)
(.lvf vf1 (&-> v1-0 quad))
(let ((v1-1 f0-1))
(.mov vf2 v1-1)
)
@ -555,12 +586,15 @@
)
)
(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,6 +634,7 @@
)
(defun vector-length ((arg0 vector))
"Get the length of the xyz part."
(local-vars (v0-0 float))
(rlet ((acc :class vf)
(Q :class vf)
@ -623,6 +659,7 @@
)
(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)
@ -642,22 +679,22 @@
)
(defun vector-xz-length-squared ((arg0 vector))
(+
(* (-> arg0 data 0) (-> arg0 data 0))
"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))
"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)
@ -686,6 +723,7 @@
)
(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)
@ -703,6 +741,7 @@
)
(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)
@ -730,6 +769,7 @@
)
(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)
@ -746,6 +786,7 @@
)
(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,6 +850,9 @@
)
(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))
@ -824,13 +870,12 @@
)
(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)
)
(set! (-> arg0 data 2) (* (-> arg0 data 2) v1-1))
)
)
)
@ -838,15 +883,16 @@
)
(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)
)
(set! (-> arg0 data 2) (/ (-> arg0 data 2) f0-0))
)
)
)
@ -854,6 +900,9 @@
)
(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,13 +932,14 @@
)
(defun rotate-y<-vector+vector ((arg0 vector) (arg1 vector))
(atan
(- (-> arg1 data 0) (-> arg0 data 0))
"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)
@ -898,6 +949,7 @@
)
(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)
@ -907,6 +959,8 @@
)
(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))
@ -924,6 +978,8 @@
)
(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))
@ -940,8 +996,9 @@
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)
@ -949,23 +1006,21 @@
(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)
(.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 (&-> arg0 quad) vf3)
arg0
(.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)
@ -974,17 +1029,17 @@
)
(.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))
((>= 0.0 alpha)
(set! (-> out quad) (-> a quad))
)
((>= arg3 1.0)
(set! (-> arg0 quad) (-> arg2 quad))
((>= alpha 1.0)
(set! (-> out quad) (-> b quad))
)
(else
(let ((v1-2 arg0))
(let ((f0-2 arg3))
(.lvf vf1 (&-> arg1 quad))
(.lvf vf2 (&-> arg2 quad))
(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)
)
@ -997,50 +1052,47 @@
)
)
)
arg0
out
)
)
;; 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)
(.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 (&-> arg0 quad) vf3)
arg0
(.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))
((>= 0.0 alpha)
(set! (-> out quad) (-> a quad))
)
((>= arg3 1.0)
(set! (-> arg0 quad) (-> arg2 quad))
((>= alpha 1.0)
(set! (-> out quad) (-> b quad))
)
(else
(let ((v1-2 arg0))
(let ((f0-2 arg3))
(.lvf vf1 (&-> arg1 quad))
(.lvf vf2 (&-> arg2 quad))
(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)
)
@ -1052,12 +1104,16 @@
)
)
)
arg0
out
)
)
(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,6 +1125,9 @@
)
(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)))
@ -1082,7 +1141,9 @@
)
(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)
@ -1096,40 +1157,75 @@
)
)
;; 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))
)
)
((>= arg3 1.0)
(let ((v1-1 arg0))
(set! (-> v1-1 quad) (-> arg2 quad))
((>= in 1.0)
(let ((v1-1 out))
(set! (-> v1-1 quad) (-> max-val quad))
)
)
(else
(set!
(-> arg0 data 0)
(deg-lerp-clamp (-> arg1 data 0) (-> arg2 data 0) arg3)
(set! (-> out data 0)
(deg-lerp-clamp (-> min-val data 0) (-> max-val data 0) in)
)
(set!
(-> arg0 data 1)
(deg-lerp-clamp (-> arg1 data 1) (-> arg2 data 1) arg3)
(set! (-> out data 1)
(deg-lerp-clamp (-> min-val data 1) (-> max-val data 1) in)
)
(set!
(-> arg0 data 2)
(deg-lerp-clamp (-> arg1 data 2) (-> arg2 data 2) arg3)
(set! (-> out data 2)
(deg-lerp-clamp (-> min-val data 2) (-> max-val data 2) in)
)
(let ((f0-11 1.0))
(set! (-> arg0 data 3) f0-11)
(set! (-> out data 3) 1.0)
)
)
out
)
arg0
)
;; 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)
@ -1192,6 +1289,7 @@
)
(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)
@ -1200,17 +1298,20 @@
)
(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)))
(vector-normalize! arg0 (rand-vu-float-range 0.0 arg1))
)

View file

@ -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)
)
)
)

View file

@ -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

View file

@ -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);
}

View file

@ -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,

View file

@ -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, {{}, {}, {}}, {});

View file

@ -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},

View file

@ -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());

View file

@ -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))

File diff suppressed because it is too large Load diff

View file

@ -51,4 +51,24 @@
(print128 s3q) (format #t "~%")
)
)
(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
)
)
)

View file

@ -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)
)

View file

@ -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"});
}

View file

@ -17,7 +17,7 @@ const std::unordered_set<std::string> 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<std::string> 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<std::string> 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<std::string> 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

View file

@ -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));
@ -507,3 +507,18 @@ TEST(EmitrerAVX, movq_to_xmm_from_gpr) {
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");
}