mirror of
git://git.code.sf.net/p/sbcl/sbcl
synced 2026-09-10 07:26:40 -04:00
sb-simd: Fix a bunch of bugs
64-bit integer min/max don't have actual instructions, fake instead Fix signed lane extraction not sign-extending Add float abs/neg Fix fsqrt encoding Fix u32.4-from-u64.2/s32.4-from-s64.2 family, wrong size Remove 64-bit integer vector mul, instruction doesn't exist Add missing exports for integer min/max Align spilled neon registers properly Validate more vector instruction forms properly Fix movi immediates
This commit is contained in:
parent
62f4bd1032
commit
e4e628ab84
|
|
@ -109,6 +109,12 @@
|
|||
(define-fake-vop u64.2-horizontal+ (a)
|
||||
(sb-simd::%two-arg-u64+ (%u64.2-lane-extract a 0) (%u64.2-lane-extract a 1)))
|
||||
|
||||
(define-fake-vop two-arg-u64.2-min (a b)
|
||||
(%u64.2-bit-select (%two-arg-u64.2> b a) a b))
|
||||
|
||||
(define-fake-vop two-arg-u64.2-max (a b)
|
||||
(%u64.2-bit-select (%two-arg-u64.2> a b) a b))
|
||||
|
||||
(define-fake-vop s64.2-pair-min (a b)
|
||||
(%make-s64.2 (sb-simd::%two-arg-s64-min (%s64.2-lane-extract a 0) (%s64.2-lane-extract a 1))
|
||||
(sb-simd::%two-arg-s64-min (%s64.2-lane-extract b 0) (%s64.2-lane-extract b 1))))
|
||||
|
|
@ -129,3 +135,9 @@
|
|||
|
||||
(define-fake-vop s64.2-horizontal+ (a)
|
||||
(sb-simd::%two-arg-s64+ (%s64.2-lane-extract a 0) (%s64.2-lane-extract a 1)))
|
||||
|
||||
(define-fake-vop two-arg-s64.2-min (a b)
|
||||
(%s64.2-bit-select (%two-arg-s64.2> b a) a b))
|
||||
|
||||
(define-fake-vop two-arg-s64.2-max (a b)
|
||||
(%s64.2-bit-select (%two-arg-s64.2> a b) a b))
|
||||
|
|
|
|||
|
|
@ -313,7 +313,10 @@
|
|||
(:info lane)
|
||||
(:results (dst :scs (,scalar-reg)))
|
||||
(:generator
|
||||
(inst umov dst src lane ,element)))
|
||||
(inst ,(if (and (eql sign :s) (not (eql width 64)))
|
||||
'smov
|
||||
'umov)
|
||||
dst src lane ,element)))
|
||||
(define-custom-vop ,(name "~a~d.~d-LANE-INSERT" sign width count)
|
||||
(:args (src1 :scs (int-neon-reg) :target dst)
|
||||
(src2 :scs (,scalar-reg) :to :save))
|
||||
|
|
|
|||
|
|
@ -85,6 +85,8 @@
|
|||
(f32.4-andc2 #:bic (f32.4) (f32.4 f32.4) :cost 1 :suffix '(:16b))
|
||||
(f32.4-not #:not (f32.4) (f32.4) :cost 1 :suffix '(:16b))
|
||||
(f32.4-sqrt #:fsqrt (f32.4) (f32.4) :cost 15 :suffix '(:4s))
|
||||
(f32.4-abs #:fabs (f32.4) (f32.4) :cost 1 :suffix '(:4s))
|
||||
(f32.4-neg #:fneg (f32.4) (f32.4) :cost 1 :suffix '(:4s))
|
||||
(f32.4-bit-select #:bsl (f32.4) (u32.4 f32.4 f32.4) :cost 1 :encoding :neon-rmw :suffix '(:16b))
|
||||
(f32.4-lane-extract nil (f32) (f32.4 imm2) :cost 1 :encoding :custom)
|
||||
(f32.4-lane-insert nil (f32.4) (f32.4 f32 imm2) :cost 1 :encoding :custom)
|
||||
|
|
@ -133,6 +135,8 @@
|
|||
(f64.2-andc2 #:bic (f64.2) (f64.2 f64.2) :cost 1 :suffix '(:16b))
|
||||
(f64.2-not #:not (f64.2) (f64.2) :cost 1 :suffix '(:16b))
|
||||
(f64.2-sqrt #:fsqrt (f64.2) (f64.2) :cost 15 :suffix '(:2d))
|
||||
(f64.2-abs #:fabs (f64.2) (f64.2) :cost 1 :suffix '(:2d))
|
||||
(f64.2-neg #:fneg (f64.2) (f64.2) :cost 1 :suffix '(:2d))
|
||||
(f64.2-bit-select #:bsl (f64.2) (u64.2 f64.2 f64.2) :cost 1 :encoding :neon-rmw :suffix '(:16b))
|
||||
(f64.2-lane-extract nil (f64) (f64.2 imm1) :cost 1 :encoding :custom)
|
||||
(f64.2-lane-insert nil (f64.2) (f64.2 f64 imm1) :cost 1 :encoding :custom)
|
||||
|
|
@ -266,10 +270,10 @@
|
|||
(u32.4-from-f32.4 #:fcvtnu (u32.4) (f32.4) :cost 5 :suffix '(:4s))
|
||||
(u32.4-from-u16.8 nil (u32.4) (u16.8) :cost 1 :encoding :custom)
|
||||
(u32.4-from-u16.8-hi nil (u32.4) (u16.8) :cost 1 :encoding :custom)
|
||||
(u32.4-from-u64.2 #:xtn (u32.4) (u64.2) :cost 1 :suffix '(:4h))
|
||||
(u32.4-from-u64.2-hi #:xtn2 (u32.4) (u32.4 u64.2) :cost 1 :encoding :neon-rmw :suffix '(:8h))
|
||||
(u32.4-from-u64.2-saturating #:uqxtn (u32.4) (u64.2) :cost 1 :suffix '(:4h))
|
||||
(u32.4-from-u64.2-saturating-hi #:uqxtn2 (u32.4) (u32.4 u64.2) :cost 1 :encoding :neon-rmw :suffix '(:8h))
|
||||
(u32.4-from-u64.2 #:xtn (u32.4) (u64.2) :cost 1 :suffix '(:2s))
|
||||
(u32.4-from-u64.2-hi #:xtn2 (u32.4) (u32.4 u64.2) :cost 1 :encoding :neon-rmw :suffix '(:4s))
|
||||
(u32.4-from-u64.2-saturating #:uqxtn (u32.4) (u64.2) :cost 1 :suffix '(:2s))
|
||||
(u32.4-from-u64.2-saturating-hi #:uqxtn2 (u32.4) (u32.4 u64.2) :cost 1 :encoding :neon-rmw :suffix '(:4s))
|
||||
(make-u32.4 nil (u32.4) (u32 u32 u32 u32) :cost 1 :encoding :fake-vop)
|
||||
(u32.4-values nil (u32 u32 u32 u32) (u32.4) :cost 1 :encoding :fake-vop)
|
||||
(u32.4-broadcast #:dup (u32.4) (u32) :cost 1 :suffix '(:4s))
|
||||
|
|
@ -329,8 +333,8 @@
|
|||
(two-arg-u64.2-and #:and (u64.2) (u64.2 u64.2) :cost 1 :associative t :suffix '(:16b))
|
||||
(two-arg-u64.2-or #:orr (u64.2) (u64.2 u64.2) :cost 1 :associative t :suffix '(:16b))
|
||||
(two-arg-u64.2-xor #:eor (u64.2) (u64.2 u64.2) :cost 1 :associative t :suffix '(:16b))
|
||||
(two-arg-u64.2-max #:umax (u64.2) (u64.2 u64.2) :cost 3 :associative t :suffix '(:2d))
|
||||
(two-arg-u64.2-min #:umin (u64.2) (u64.2 u64.2) :cost 3 :associative t :suffix '(:2d))
|
||||
(two-arg-u64.2-max nil (u64.2) (u64.2 u64.2) :cost 3 :associative t :encoding :fake-vop)
|
||||
(two-arg-u64.2-min nil (u64.2) (u64.2 u64.2) :cost 3 :associative t :encoding :fake-vop)
|
||||
(u64.2-andc1 nil (u64.2) (u64.2 u64.2) :cost 1 :encoding :fake-vop)
|
||||
(u64.2-andc2 #:bic (u64.2) (u64.2 u64.2) :cost 1 :suffix '(:16b))
|
||||
(u64.2-not #:not (u64.2) (u64.2) :cost 1 :suffix '(:16b))
|
||||
|
|
@ -338,7 +342,6 @@
|
|||
(two-arg-u64.2+-saturating #:uqadd (u64.2) (u64.2 u64.2) :cost 2 :suffix '(:2d) :associative t)
|
||||
(two-arg-u64.2- #:sub (u64.2) (u64.2 u64.2) :cost 2 :suffix '(:2d))
|
||||
(two-arg-u64.2--saturating #:uqsub (u64.2) (u64.2 u64.2) :cost 2 :suffix '(:2d))
|
||||
(two-arg-u64.2* #:mul (u64.2) (u64.2 u64.2) :cost 2 :suffix '(:2d) :associative t)
|
||||
(two-arg-u64.2= #:cmeq (u64.2) (u64.2 u64.2) :cost 1 :suffix '(:2d))
|
||||
(two-arg-u64.2/= nil (u64.2) (u64.2 u64.2) :cost 2 :associative t :encoding :fake-vop)
|
||||
(two-arg-u64.2> #:cmhi (u64.2) (u64.2 u64.2) :cost 1 :suffix '(:2d))
|
||||
|
|
@ -478,10 +481,10 @@
|
|||
(s32.4-from-f32.4 #:fcvtns (s32.4) (f32.4) :cost 5 :suffix '(:4s))
|
||||
(s32.4-from-s16.8 nil (s32.4) (s16.8) :cost 1 :encoding :custom)
|
||||
(s32.4-from-s16.8-hi nil (s32.4) (s16.8) :cost 1 :encoding :custom)
|
||||
(s32.4-from-s64.2 #:xtn (s32.4) (s64.2) :cost 1 :suffix '(:4h))
|
||||
(s32.4-from-s64.2-hi #:xtn2 (s32.4) (s32.4 s64.2) :cost 1 :encoding :neon-rmw :suffix '(:8h))
|
||||
(s32.4-from-s64.2-saturating #:sqxtn (s32.4) (s64.2) :cost 1 :suffix '(:4h))
|
||||
(s32.4-from-s64.2-saturating-hi #:sqxtn2 (s32.4) (s32.4 s64.2) :cost 1 :encoding :neon-rmw :suffix '(:8h))
|
||||
(s32.4-from-s64.2 #:xtn (s32.4) (s64.2) :cost 1 :suffix '(:2s))
|
||||
(s32.4-from-s64.2-hi #:xtn2 (s32.4) (s32.4 s64.2) :cost 1 :encoding :neon-rmw :suffix '(:4s))
|
||||
(s32.4-from-s64.2-saturating #:sqxtn (s32.4) (s64.2) :cost 1 :suffix '(:2s))
|
||||
(s32.4-from-s64.2-saturating-hi #:sqxtn2 (s32.4) (s32.4 s64.2) :cost 1 :encoding :neon-rmw :suffix '(:4s))
|
||||
(make-s32.4 nil (s32.4) (s32 s32 s32 s32) :cost 1 :encoding :fake-vop)
|
||||
(s32.4-values nil (s32 s32 s32 s32) (s32.4) :cost 1 :encoding :fake-vop)
|
||||
(s32.4-broadcast #:dup (s32.4) (s32) :cost 1 :suffix '(:4s))
|
||||
|
|
@ -539,8 +542,8 @@
|
|||
(two-arg-s64.2-and #:and (s64.2) (s64.2 s64.2) :cost 1 :associative t :suffix '(:16b))
|
||||
(two-arg-s64.2-or #:orr (s64.2) (s64.2 s64.2) :cost 1 :associative t :suffix '(:16b))
|
||||
(two-arg-s64.2-xor #:eor (s64.2) (s64.2 s64.2) :cost 1 :associative t :suffix '(:16b))
|
||||
(two-arg-s64.2-max #:smax (s64.2) (s64.2 s64.2) :cost 3 :associative t :suffix '(:2d))
|
||||
(two-arg-s64.2-min #:smin (s64.2) (s64.2 s64.2) :cost 3 :associative t :suffix '(:2d))
|
||||
(two-arg-s64.2-max nil (s64.2) (s64.2 s64.2) :cost 3 :associative t :encoding :fake-vop)
|
||||
(two-arg-s64.2-min nil (s64.2) (s64.2 s64.2) :cost 3 :associative t :encoding :fake-vop)
|
||||
(s64.2-andc1 nil (s64.2) (s64.2 s64.2) :cost 1 :encoding :fake-vop)
|
||||
(s64.2-andc2 #:bic (s64.2) (s64.2 s64.2) :cost 1 :suffix '(:16b))
|
||||
(s64.2-not #:not (s64.2) (s64.2) :cost 1 :suffix '(:16b))
|
||||
|
|
@ -548,7 +551,6 @@
|
|||
(two-arg-s64.2+-saturating #:sqadd (s64.2) (s64.2 s64.2) :cost 2 :suffix '(:2d) :associative t)
|
||||
(two-arg-s64.2- #:sub (s64.2) (s64.2 s64.2) :cost 2 :suffix '(:2d))
|
||||
(two-arg-s64.2--saturating #:sqsub (s64.2) (s64.2 s64.2) :cost 2 :suffix '(:2d))
|
||||
(two-arg-s64.2* #:mul (s64.2) (s64.2 s64.2) :cost 2 :suffix '(:2d) :associative t)
|
||||
(two-arg-s64.2= #:cmeq (u64.2) (s64.2 s64.2) :cost 1 :suffix '(:2d))
|
||||
(two-arg-s64.2/= nil (u64.2) (s64.2 s64.2) :cost 2 :associative t :encoding :fake-vop)
|
||||
(two-arg-s64.2> #:cmgt (u64.2) (s64.2 s64.2) :cost 1 :suffix '(:2d))
|
||||
|
|
@ -646,7 +648,6 @@
|
|||
(u64.2-min two-arg-u64.2-min nil)
|
||||
(u64.2+ two-arg-u64.2+ 0)
|
||||
(u64.2+-saturating two-arg-u64.2+-saturating 0)
|
||||
(u64.2* two-arg-u64.2* 1)
|
||||
(s8.16-and two-arg-s8.16-and +s8-true+)
|
||||
(s8.16-or two-arg-s8.16-or +s8-false+)
|
||||
(s8.16-xor two-arg-s8.16-xor +s8-false+)
|
||||
|
|
@ -677,8 +678,7 @@
|
|||
(s64.2-max two-arg-s64.2-max nil)
|
||||
(s64.2-min two-arg-s64.2-min nil)
|
||||
(s64.2+ two-arg-s64.2+ 0)
|
||||
(s64.2+-saturating two-arg-s64.2+-saturating 0)
|
||||
(s64.2* two-arg-s64.2* 1))
|
||||
(s64.2+-saturating two-arg-s64.2+-saturating 0))
|
||||
(:comparisons
|
||||
(f32.4= two-arg-f32.4= u32.4-and +u32-true+)
|
||||
(f32.4< two-arg-f32.4< u32.4-and +u32-true+)
|
||||
|
|
|
|||
|
|
@ -2170,6 +2170,8 @@
|
|||
#:f32.4-max
|
||||
#:f32.4-min
|
||||
#:f32.4-sqrt
|
||||
#:f32.4-abs
|
||||
#:f32.4-neg
|
||||
#:f32.4+
|
||||
#:f32.4-
|
||||
#:f32.4*
|
||||
|
|
@ -2220,6 +2222,8 @@
|
|||
#:f64.2-max
|
||||
#:f64.2-min
|
||||
#:f64.2-sqrt
|
||||
#:f64.2-abs
|
||||
#:f64.2-neg
|
||||
#:f64.2+
|
||||
#:f64.2-
|
||||
#:f64.2*
|
||||
|
|
@ -2268,6 +2272,8 @@
|
|||
#:u8.16-andc1
|
||||
#:u8.16-andc2
|
||||
#:u8.16-not
|
||||
#:u8.16-min
|
||||
#:u8.16-max
|
||||
#:u8.16+
|
||||
#:u8.16+-saturating
|
||||
#:u8.16*
|
||||
|
|
@ -2326,6 +2332,8 @@
|
|||
#:u16.8-andc1
|
||||
#:u16.8-andc2
|
||||
#:u16.8-not
|
||||
#:u16.8-min
|
||||
#:u16.8-max
|
||||
#:u16.8+
|
||||
#:u16.8+-saturating
|
||||
#:u16.8*
|
||||
|
|
@ -2382,6 +2390,8 @@
|
|||
#:u32.4-andc1
|
||||
#:u32.4-andc2
|
||||
#:u32.4-not
|
||||
#:u32.4-min
|
||||
#:u32.4-max
|
||||
#:u32.4+
|
||||
#:u32.4+-saturating
|
||||
#:u32.4*
|
||||
|
|
@ -2438,9 +2448,10 @@
|
|||
#:u64.2-andc1
|
||||
#:u64.2-andc2
|
||||
#:u64.2-not
|
||||
#:u64.2-min
|
||||
#:u64.2-max
|
||||
#:u64.2+
|
||||
#:u64.2+-saturating
|
||||
#:u64.2*
|
||||
#:u64.2-
|
||||
#:u64.2--saturating
|
||||
#:u64.2=
|
||||
|
|
@ -2487,6 +2498,8 @@
|
|||
#:s8.16-andc1
|
||||
#:s8.16-andc2
|
||||
#:s8.16-not
|
||||
#:s8.16-min
|
||||
#:s8.16-max
|
||||
#:s8.16+
|
||||
#:s8.16+-saturating
|
||||
#:s8.16*
|
||||
|
|
@ -2540,6 +2553,8 @@
|
|||
#:s16.8-andc1
|
||||
#:s16.8-andc2
|
||||
#:s16.8-not
|
||||
#:s16.8-min
|
||||
#:s16.8-max
|
||||
#:s16.8+
|
||||
#:s16.8+-saturating
|
||||
#:s16.8*
|
||||
|
|
@ -2594,6 +2609,8 @@
|
|||
#:s32.4-andc1
|
||||
#:s32.4-andc2
|
||||
#:s32.4-not
|
||||
#:s32.4-min
|
||||
#:s32.4-max
|
||||
#:s32.4+
|
||||
#:s32.4+-saturating
|
||||
#:s32.4*
|
||||
|
|
@ -2644,9 +2661,10 @@
|
|||
#:s64.2-andc1
|
||||
#:s64.2-andc2
|
||||
#:s64.2-not
|
||||
#:s64.2-min
|
||||
#:s64.2-max
|
||||
#:s64.2+
|
||||
#:s64.2+-saturating
|
||||
#:s64.2*
|
||||
#:s64.2-
|
||||
#:s64.2--saturating
|
||||
#:s64.2=
|
||||
|
|
|
|||
179
contrib/sb-simd/test-suite/test-arm64-regressions.lisp
Normal file
179
contrib/sb-simd/test-suite/test-arm64-regressions.lisp
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
;;; Regression tests for AdvSIMD bugs found by auditing sb-simd against
|
||||
;;; the A64 instruction set. Each test targets a bug that once produced
|
||||
;;; wrong results or illegal instructions rather than a clean error.
|
||||
|
||||
(in-package #:sb-simd-neon)
|
||||
|
||||
;;; Values that sit on both sides of the signed/unsigned wrap-around
|
||||
;;; point. Random sampling almost never generates pairs like
|
||||
;;; (0, #xFFFFFFFFFFFFFFFF), so test them exhaustively.
|
||||
(defparameter *u64-boundary-values*
|
||||
(list 0 1 2 3 5
|
||||
#x7FFFFFFFFFFFFFFE #x7FFFFFFFFFFFFFFF
|
||||
#x8000000000000000 #x8000000000000001
|
||||
#xFFFFFFFFFFFFFFFD #xFFFFFFFFFFFFFFFE #xFFFFFFFFFFFFFFFF))
|
||||
|
||||
(defparameter *s64-boundary-values*
|
||||
(list -9223372036854775808 -9223372036854775807 -1 0 1 42
|
||||
9223372036854775806 9223372036854775807))
|
||||
|
||||
;;; Issue: UMAX/UMIN/SMAX/SMIN have no .2d form; max/min are fake vops
|
||||
;;; built from CMHI/CMGT plus BSL.
|
||||
(sb-simd-test-suite:define-test u64.2-max-min-boundaries
|
||||
(dolist (a *u64-boundary-values*)
|
||||
(dolist (b *u64-boundary-values*)
|
||||
(let ((pa (make-u64.2 a a))
|
||||
(pb (make-u64.2 b b)))
|
||||
(sb-simd-test-suite:is (= (u64.2-lane-extract (u64.2-max pa pb) 0) (max a b)))
|
||||
(sb-simd-test-suite:is (= (u64.2-lane-extract (u64.2-min pa pb) 0) (min a b)))))))
|
||||
|
||||
(sb-simd-test-suite:define-test s64.2-max-min-boundaries
|
||||
(dolist (a *s64-boundary-values*)
|
||||
(dolist (b *s64-boundary-values*)
|
||||
(let ((pa (make-s64.2 a a))
|
||||
(pb (make-s64.2 b b)))
|
||||
(sb-simd-test-suite:is (= (s64.2-lane-extract (s64.2-max pa pb) 0) (max a b)))
|
||||
(sb-simd-test-suite:is (= (s64.2-lane-extract (s64.2-min pa pb) 0) (min a b)))))))
|
||||
|
||||
;;; Random cross-check of the same fake vops against the scalar
|
||||
;;; reference implementation.
|
||||
(sb-simd-test-suite:define-test u64.2-max-min-random
|
||||
(flet ((to-signed (x) (if (logbitp 63 x) (- x (ash 1 64)) x)))
|
||||
(dotimes (i 2000)
|
||||
(let* ((bits (lambda () (logior (ash (random (ash 1 32)) 32)
|
||||
(random (ash 1 32)))))
|
||||
(a0 (funcall bits)) (a1 (funcall bits))
|
||||
(b0 (funcall bits)) (b1 (funcall bits))
|
||||
(ua (make-u64.2 a0 a1))
|
||||
(ub (make-u64.2 b0 b1))
|
||||
(sa (make-s64.2 (to-signed a0) (to-signed a1)))
|
||||
(sb (make-s64.2 (to-signed b0) (to-signed b1))))
|
||||
(sb-simd-test-suite:is (= (u64.2-lane-extract (u64.2-max ua ub) 0) (max a0 b0)))
|
||||
(sb-simd-test-suite:is (= (u64.2-lane-extract (u64.2-min ua ub) 1) (min a1 b1)))
|
||||
(sb-simd-test-suite:is (= (s64.2-lane-extract (s64.2-max sa sb) 0)
|
||||
(max (to-signed a0) (to-signed b0))))
|
||||
(sb-simd-test-suite:is (= (s64.2-lane-extract (s64.2-min sa sb) 1)
|
||||
(min (to-signed a1) (to-signed b1))))))))
|
||||
|
||||
;;; Issue: the XTN-family narrowing records used .4h/.8h suffixes,
|
||||
;;; silently computing a 32-to-16-bit narrowing on 64-bit lanes.
|
||||
(sb-simd-test-suite:define-test u32.4-from-u64.2-narrowing
|
||||
;; Plain narrowing takes the low half of each lane and zeroes the rest.
|
||||
(let ((r (u32.4-from-u64.2 (make-u64.2 #x1111111122222222
|
||||
#x3333333344444444))))
|
||||
(sb-simd-test-suite:is (= (u32.4-lane-extract r 0) #x22222222))
|
||||
(sb-simd-test-suite:is (= (u32.4-lane-extract r 1) #x44444444))
|
||||
(sb-simd-test-suite:is (= (u32.4-lane-extract r 2) 0))
|
||||
(sb-simd-test-suite:is (= (u32.4-lane-extract r 3) 0)))
|
||||
;; Saturating narrowing clamps into the target range.
|
||||
(let ((r (u32.4-from-u64.2-saturating (make-u64.2 #xFFFFFFFFFFFFFFFF 3))))
|
||||
(sb-simd-test-suite:is (= (u32.4-lane-extract r 0) #xFFFFFFFF))
|
||||
(sb-simd-test-suite:is (= (u32.4-lane-extract r 1) 3)))
|
||||
;; The -hi variants append to the high half and preserve the low half.
|
||||
(let ((r (u32.4-from-u64.2-hi (make-u32.4 10 20 30 40)
|
||||
(make-u64.2 #x1111111122222222
|
||||
#x3333333344444444))))
|
||||
(sb-simd-test-suite:is (= (u32.4-lane-extract r 0) 10))
|
||||
(sb-simd-test-suite:is (= (u32.4-lane-extract r 1) 20))
|
||||
(sb-simd-test-suite:is (= (u32.4-lane-extract r 2) #x22222222))
|
||||
(sb-simd-test-suite:is (= (u32.4-lane-extract r 3) #x44444444)))
|
||||
(let ((r (u32.4-from-u64.2-saturating-hi
|
||||
(make-u32.4 10 20 30 40)
|
||||
(make-u64.2 #xFFFFFFFFFFFFFFFF #xFFFFFFFFFFFFFFFF))))
|
||||
(sb-simd-test-suite:is (= (u32.4-lane-extract r 0) 10))
|
||||
(sb-simd-test-suite:is (= (u32.4-lane-extract r 1) 20))
|
||||
(sb-simd-test-suite:is (= (u32.4-lane-extract r 2) #xFFFFFFFF))
|
||||
(sb-simd-test-suite:is (= (u32.4-lane-extract r 3) #xFFFFFFFF))))
|
||||
|
||||
(sb-simd-test-suite:define-test s32.4-from-s64.2-narrowing
|
||||
(let ((r (s32.4-from-s64.2 (make-s64.2 -5 #x7000000011112222))))
|
||||
(sb-simd-test-suite:is (= (s32.4-lane-extract r 0) -5))
|
||||
(sb-simd-test-suite:is (= (s32.4-lane-extract r 1) #x11112222))
|
||||
(sb-simd-test-suite:is (= (s32.4-lane-extract r 2) 0))
|
||||
(sb-simd-test-suite:is (= (s32.4-lane-extract r 3) 0)))
|
||||
;; Saturation clamps in both directions.
|
||||
(let ((r (s32.4-from-s64.2-saturating
|
||||
(make-s64.2 #x7FFFFFFFFFFFFFFF -99999999999999))))
|
||||
(sb-simd-test-suite:is (= (s32.4-lane-extract r 0) most-positive-s32))
|
||||
(sb-simd-test-suite:is (= (s32.4-lane-extract r 1) most-negative-s32)))
|
||||
(let ((r (s32.4-from-s64.2-hi (make-s32.4 10 20 30 40)
|
||||
(make-s64.2 -5 #x7000000011112222))))
|
||||
(sb-simd-test-suite:is (= (s32.4-lane-extract r 0) 10))
|
||||
(sb-simd-test-suite:is (= (s32.4-lane-extract r 1) 20))
|
||||
(sb-simd-test-suite:is (= (s32.4-lane-extract r 2) -5))
|
||||
(sb-simd-test-suite:is (= (s32.4-lane-extract r 3) #x11112222))))
|
||||
|
||||
;;; Issue: signed lane extraction returned zero-extended values because
|
||||
;;; the custom vops emitted UMOV instead of SMOV.
|
||||
(sb-simd-test-suite:define-test signed-lane-extraction-sign-extends
|
||||
(let ((v (make-s8.16 -128 -1 127 42 0 -42 1 -127 2 -2 3 -3 4 -4 5 -5)))
|
||||
(loop for expected in '(-128 -1 127 42 0 -42 1 -127 2 -2 3 -3 4 -4 5 -5)
|
||||
for i from 0
|
||||
do (sb-simd-test-suite:is (= (s8.16-lane-extract v i) expected))))
|
||||
(let ((v (make-s16.8 -32768 -1 32767 12345 -5432 0 1 -1)))
|
||||
(loop for expected in '(-32768 -1 32767 12345 -5432 0 1 -1)
|
||||
for i from 0
|
||||
do (sb-simd-test-suite:is (= (s16.8-lane-extract v i) expected))))
|
||||
(let ((v (make-s32.4 -2147483648 -1 2147483647 42)))
|
||||
(loop for expected in '(-2147483648 -1 2147483647 42)
|
||||
for i from 0
|
||||
do (sb-simd-test-suite:is (= (s32.4-lane-extract v i) expected))))
|
||||
;; Unsigned shapes must remain unaffected.
|
||||
(let ((v (make-u8.16 255 254 253 252 0 1 2 3 4 5 6 7 8 9 10 11)))
|
||||
(sb-simd-test-suite:is (= (u8.16-lane-extract v 0) 255))
|
||||
(sb-simd-test-suite:is (= (u8.16-lane-extract v 3) 252))))
|
||||
|
||||
;;; Issue: emit-movi-vector-imm passed replicated broadcast patterns to
|
||||
;;; MOVI instead of lane immediates, aborting compilation with "bad
|
||||
;;; immediate". Every constant below is materialized through that code
|
||||
;;; path; several exercise the shifted-cmode forms. The tests are split
|
||||
;;; into several functions because packing too many distinct vector
|
||||
;;; constants into one function currently overflows the LDR spill
|
||||
;;; offset range - see issue about large SIMD constant pools.
|
||||
(sb-simd-test-suite:define-test integer-broadcast-constants-simple
|
||||
;; The original reproducer: 1 does not fit MOVI's simple .8h form.
|
||||
(let ((r (u16.8-and (u16.8-broadcast 5) 1)))
|
||||
(sb-simd-test-suite:is (= (u16.8-lane-extract r 0) 1))
|
||||
(sb-simd-test-suite:is (= (u16.8-lane-extract r 7) 1)))
|
||||
;; Shifted immediates (low byte zero).
|
||||
(let ((r (u16.8-and (u16.8-broadcast #x0100) #x0100)))
|
||||
(sb-simd-test-suite:is (= (u16.8-lane-extract r 3) #x0100)))
|
||||
;; Byte-replicated patterns.
|
||||
(dolist (c (list 0 1 #x7F #x80 #xFF))
|
||||
(let ((r (u8.16-or (u8.16-broadcast c) (u8.16-broadcast c))))
|
||||
(sb-simd-test-suite:is (= (u8.16-lane-extract r 15) c)))))
|
||||
|
||||
(sb-simd-test-suite:define-test integer-broadcast-constants-word
|
||||
;; 32-bit constants with shifted bytes.
|
||||
(dolist (c (list 0 1 255 256 #xFFFF #x10000 #xFF0000 #xFF000000))
|
||||
(let ((r (u32.4-and (u32.4-broadcast c) (u32.4-broadcast c))))
|
||||
(sb-simd-test-suite:is (= (u32.4-lane-extract r 0) c)))))
|
||||
|
||||
;;; Bit-replication patterns (.2d MOVI form): every byte is 0 or #xFF.
|
||||
(sb-simd-test-suite:define-test integer-broadcast-constants-bit-replicated
|
||||
(dolist (c (list #xFF00FF00FF00FF00
|
||||
#x8000000000000000
|
||||
#xFFFFFFFFFFFFFFFF
|
||||
#x7F7F7F7F7F7F7F7F
|
||||
#x00FF00FF00FF00FF))
|
||||
(let ((r (u64.2-and (u64.2-broadcast c) (u64.2-broadcast c))))
|
||||
(sb-simd-test-suite:is (= (u64.2-lane-extract r 0) c))
|
||||
(sb-simd-test-suite:is (= (u64.2-lane-extract r 1) c)))))
|
||||
|
||||
;;; Patterns that fit no MOVI form fall back to register synthesis
|
||||
;;; (MOVZ/DUP or logical-immediate ORR).
|
||||
(sb-simd-test-suite:define-test integer-broadcast-constants-synthesized
|
||||
(dolist (c (list #x0102030405060708 #xDEADBEEFCAFEBABE))
|
||||
(let ((r (u64.2-and (u64.2-broadcast c) (u64.2-broadcast c))))
|
||||
(sb-simd-test-suite:is (= (u64.2-lane-extract r 1) c)))))
|
||||
|
||||
;;; Float constants take a different path (movi-immediate-p guarded);
|
||||
;;; keep them covered too.
|
||||
(sb-simd-test-suite:define-test float-broadcast-constants
|
||||
(let ((r (f32.4-max (make-f32.4 0.5 -1.0 2.0 3.0) 1.0f0)))
|
||||
(sb-simd-test-suite:is (= (f32.4-lane-extract r 0) 1.0f0))
|
||||
(sb-simd-test-suite:is (= (f32.4-lane-extract r 1) 1.0f0))
|
||||
(sb-simd-test-suite:is (= (f32.4-lane-extract r 2) 2.0f0)))
|
||||
(let ((r (f64.2-min (make-f64.2 0.5d0 -5d0) -1d0)))
|
||||
(sb-simd-test-suite:is (= (f64.2-lane-extract r 0) -1d0))
|
||||
(sb-simd-test-suite:is (= (f64.2-lane-extract r 1) -5d0))))
|
||||
|
|
@ -8,6 +8,8 @@
|
|||
(sb-simd-test-suite:define-simple-simd-test f32.4-not (f32.4) (f32.4) f32-not)
|
||||
(sb-simd-test-suite:define-simple-simd-test f32.4-max (f32.4) (f32.4 &rest f32.4) f32-max)
|
||||
(sb-simd-test-suite:define-simple-simd-test f32.4-min (f32.4) (f32.4 &rest f32.4) f32-min)
|
||||
(sb-simd-test-suite:define-simple-simd-test f32.4-abs (f32.4) (f32.4) abs)
|
||||
(sb-simd-test-suite:define-simple-simd-test f32.4-neg (f32.4) (f32.4) -)
|
||||
(sb-simd-test-suite:define-simple-simd-test f32.4+ (f32.4) (&rest f32.4) f32+)
|
||||
(sb-simd-test-suite:define-simple-simd-test f32.4- (f32.4) (f32.4 &rest f32.4) f32-)
|
||||
(sb-simd-test-suite:define-simple-simd-test f32.4* (f32.4) (&rest f32.4) f32*)
|
||||
|
|
@ -26,6 +28,8 @@
|
|||
(sb-simd-test-suite:define-simple-simd-test f64.2-not (f64.2) (f64.2) f64-not)
|
||||
(sb-simd-test-suite:define-simple-simd-test f64.2-max (f64.2) (f64.2 &rest f64.2) f64-max)
|
||||
(sb-simd-test-suite:define-simple-simd-test f64.2-min (f64.2) (f64.2 &rest f64.2) f64-min)
|
||||
(sb-simd-test-suite:define-simple-simd-test f64.2-abs (f64.2) (f64.2) abs)
|
||||
(sb-simd-test-suite:define-simple-simd-test f64.2-neg (f64.2) (f64.2) -)
|
||||
(sb-simd-test-suite:define-simple-simd-test f64.2+ (f64.2) (&rest f64.2) f64+)
|
||||
(sb-simd-test-suite:define-simple-simd-test f64.2- (f64.2) (f64.2 &rest f64.2) f64-)
|
||||
(sb-simd-test-suite:define-simple-simd-test f64.2* (f64.2) (&rest f64.2) f64*)
|
||||
|
|
@ -42,6 +46,8 @@
|
|||
(sb-simd-test-suite:define-simple-simd-test u8.16-xor (u8.16) (&rest u8.16) u8-xor)
|
||||
(sb-simd-test-suite:define-simple-simd-test u8.16-andc1 (u8.16) (u8.16 u8.16) u8-andc1)
|
||||
(sb-simd-test-suite:define-simple-simd-test u8.16-not (u8.16) (u8.16) u8-not)
|
||||
(sb-simd-test-suite:define-simple-simd-test u8.16-max (u8.16) (u8.16 &rest u8.16) u8-max)
|
||||
(sb-simd-test-suite:define-simple-simd-test u8.16-min (u8.16) (u8.16 &rest u8.16) u8-min)
|
||||
(sb-simd-test-suite:define-simple-simd-test u8.16+ (u8.16) (&rest u8.16) u8+)
|
||||
(sb-simd-test-suite:define-simple-simd-test u8.16- (u8.16) (u8.16 &rest u8.16) u8-)
|
||||
(sb-simd-test-suite:define-simple-simd-test u8.16= (u8.16) (u8.16 &rest u8.16) u8=)
|
||||
|
|
@ -56,6 +62,8 @@
|
|||
(sb-simd-test-suite:define-simple-simd-test u16.8-xor (u16.8) (&rest u16.8) u16-xor)
|
||||
(sb-simd-test-suite:define-simple-simd-test u16.8-andc1 (u16.8) (u16.8 u16.8) u16-andc1)
|
||||
(sb-simd-test-suite:define-simple-simd-test u16.8-not (u16.8) (u16.8) u16-not)
|
||||
(sb-simd-test-suite:define-simple-simd-test u16.8-max (u16.8) (u16.8 &rest u16.8) u16-max)
|
||||
(sb-simd-test-suite:define-simple-simd-test u16.8-min (u16.8) (u16.8 &rest u16.8) u16-min)
|
||||
(sb-simd-test-suite:define-simple-simd-test u16.8+ (u16.8) (&rest u16.8) u16+)
|
||||
(sb-simd-test-suite:define-simple-simd-test u16.8- (u16.8) (u16.8 &rest u16.8) u16-)
|
||||
(sb-simd-test-suite:define-simple-simd-test u16.8= (u16.8) (u16.8 &rest u16.8) u16=)
|
||||
|
|
@ -70,6 +78,8 @@
|
|||
(sb-simd-test-suite:define-simple-simd-test u32.4-xor (u32.4) (&rest u32.4) u32-xor)
|
||||
(sb-simd-test-suite:define-simple-simd-test u32.4-andc1 (u32.4) (u32.4 u32.4) u32-andc1)
|
||||
(sb-simd-test-suite:define-simple-simd-test u32.4-not (u32.4) (u32.4) u32-not)
|
||||
(sb-simd-test-suite:define-simple-simd-test u32.4-max (u32.4) (u32.4 &rest u32.4) u32-max)
|
||||
(sb-simd-test-suite:define-simple-simd-test u32.4-min (u32.4) (u32.4 &rest u32.4) u32-min)
|
||||
(sb-simd-test-suite:define-simple-simd-test u32.4+ (u32.4) (&rest u32.4) u32+)
|
||||
(sb-simd-test-suite:define-simple-simd-test u32.4- (u32.4) (u32.4 &rest u32.4) u32-)
|
||||
(sb-simd-test-suite:define-simple-simd-test u32.4= (u32.4) (u32.4 &rest u32.4) u32=)
|
||||
|
|
@ -84,6 +94,8 @@
|
|||
(sb-simd-test-suite:define-simple-simd-test u64.2-xor (u64.2) (&rest u64.2) u64-xor)
|
||||
(sb-simd-test-suite:define-simple-simd-test u64.2-andc1 (u64.2) (u64.2 u64.2) u64-andc1)
|
||||
(sb-simd-test-suite:define-simple-simd-test u64.2-not (u64.2) (u64.2) u64-not)
|
||||
(sb-simd-test-suite:define-simple-simd-test u64.2-max (u64.2) (u64.2 &rest u64.2) u64-max)
|
||||
(sb-simd-test-suite:define-simple-simd-test u64.2-min (u64.2) (u64.2 &rest u64.2) u64-min)
|
||||
(sb-simd-test-suite:define-simple-simd-test u64.2+ (u64.2) (&rest u64.2) u64+)
|
||||
(sb-simd-test-suite:define-simple-simd-test u64.2- (u64.2) (u64.2 &rest u64.2) u64-)
|
||||
(sb-simd-test-suite:define-simple-simd-test u64.2= (u64.2) (u64.2 &rest u64.2) u64=)
|
||||
|
|
@ -98,6 +110,8 @@
|
|||
(sb-simd-test-suite:define-simple-simd-test s8.16-xor (s8.16) (&rest s8.16) s8-xor)
|
||||
(sb-simd-test-suite:define-simple-simd-test s8.16-andc1 (s8.16) (s8.16 s8.16) s8-andc1)
|
||||
(sb-simd-test-suite:define-simple-simd-test s8.16-not (s8.16) (s8.16) s8-not)
|
||||
(sb-simd-test-suite:define-simple-simd-test s8.16-max (s8.16) (s8.16 &rest s8.16) s8-max)
|
||||
(sb-simd-test-suite:define-simple-simd-test s8.16-min (s8.16) (s8.16 &rest s8.16) s8-min)
|
||||
(sb-simd-test-suite:define-simple-simd-test s8.16+ (s8.16) (&rest s8.16) s8+)
|
||||
(sb-simd-test-suite:define-simple-simd-test s8.16- (s8.16) (s8.16 &rest s8.16) s8-)
|
||||
(sb-simd-test-suite:define-simple-simd-test s8.16= (u8.16) (s8.16 &rest s8.16) s8=)
|
||||
|
|
@ -112,6 +126,8 @@
|
|||
(sb-simd-test-suite:define-simple-simd-test s16.8-xor (s16.8) (&rest s16.8) s16-xor)
|
||||
(sb-simd-test-suite:define-simple-simd-test s16.8-andc1 (s16.8) (s16.8 s16.8) s16-andc1)
|
||||
(sb-simd-test-suite:define-simple-simd-test s16.8-not (s16.8) (s16.8) s16-not)
|
||||
(sb-simd-test-suite:define-simple-simd-test s16.8-max (s16.8) (s16.8 &rest s16.8) s16-max)
|
||||
(sb-simd-test-suite:define-simple-simd-test s16.8-min (s16.8) (s16.8 &rest s16.8) s16-min)
|
||||
(sb-simd-test-suite:define-simple-simd-test s16.8+ (s16.8) (&rest s16.8) s16+)
|
||||
(sb-simd-test-suite:define-simple-simd-test s16.8- (s16.8) (s16.8 &rest s16.8) s16-)
|
||||
(sb-simd-test-suite:define-simple-simd-test s16.8= (u16.8) (s16.8 &rest s16.8) s16=)
|
||||
|
|
@ -126,6 +142,8 @@
|
|||
(sb-simd-test-suite:define-simple-simd-test s32.4-xor (s32.4) (&rest s32.4) s32-xor)
|
||||
(sb-simd-test-suite:define-simple-simd-test s32.4-andc1 (s32.4) (s32.4 s32.4) s32-andc1)
|
||||
(sb-simd-test-suite:define-simple-simd-test s32.4-not (s32.4) (s32.4) s32-not)
|
||||
(sb-simd-test-suite:define-simple-simd-test s32.4-max (s32.4) (s32.4 &rest s32.4) s32-max)
|
||||
(sb-simd-test-suite:define-simple-simd-test s32.4-min (s32.4) (s32.4 &rest s32.4) s32-min)
|
||||
(sb-simd-test-suite:define-simple-simd-test s32.4+ (s32.4) (&rest s32.4) s32+)
|
||||
(sb-simd-test-suite:define-simple-simd-test s32.4- (s32.4) (s32.4 &rest s32.4) s32-)
|
||||
(sb-simd-test-suite:define-simple-simd-test s32.4= (u32.4) (s32.4 &rest s32.4) s32=)
|
||||
|
|
@ -140,6 +158,8 @@
|
|||
(sb-simd-test-suite:define-simple-simd-test s64.2-xor (s64.2) (&rest s64.2) s64-xor)
|
||||
(sb-simd-test-suite:define-simple-simd-test s64.2-andc1 (s64.2) (s64.2 s64.2) s64-andc1)
|
||||
(sb-simd-test-suite:define-simple-simd-test s64.2-not (s64.2) (s64.2) s64-not)
|
||||
(sb-simd-test-suite:define-simple-simd-test s64.2-max (s64.2) (s64.2 &rest s64.2) s64-max)
|
||||
(sb-simd-test-suite:define-simple-simd-test s64.2-min (s64.2) (s64.2 &rest s64.2) s64-min)
|
||||
(sb-simd-test-suite:define-simple-simd-test s64.2+ (s64.2) (&rest s64.2) s64+)
|
||||
(sb-simd-test-suite:define-simple-simd-test s64.2- (s64.2) (s64.2 &rest s64.2) s64-)
|
||||
(sb-simd-test-suite:define-simple-simd-test s64.2= (u64.2) (s64.2 &rest s64.2) s64=)
|
||||
|
|
|
|||
|
|
@ -2810,38 +2810,42 @@
|
|||
(fpr-offset rd)))))
|
||||
|
||||
(defmacro def-fp-data-processing-1+simd (name op
|
||||
simd-u simd-neg simd-op)
|
||||
simd-u simd-neg simd-op6 simd-op)
|
||||
`(define-instruction ,name (segment rd rn &optional vector-size)
|
||||
(:printer fp-data-processing-1 ((op ,op)))
|
||||
(:printer simd-two-same-float ((u ,simd-u) (neg ,simd-neg) (op ,simd-op)))
|
||||
(:printer simd-two-same-float ((u ,simd-u) (neg ,simd-neg) (op6 ,simd-op6)
|
||||
(op ,simd-op)))
|
||||
(:emitter
|
||||
(assert (and (eq (tn-sc rd)
|
||||
(tn-sc rn)))
|
||||
(rd rn)
|
||||
"Arguments should have the same FP storage class: ~s ~s." rd rn)
|
||||
(if vector-size
|
||||
(multiple-value-bind (q size) (encode-vector-size vector-size)
|
||||
(emit-simd-two-same-float
|
||||
segment
|
||||
q
|
||||
,simd-u
|
||||
,simd-neg
|
||||
(logand 1 size)
|
||||
,simd-op
|
||||
(fpr-offset rn)
|
||||
(fpr-offset rd)))
|
||||
(emit-fp-data-processing-1 segment
|
||||
(fp-reg-type rn)
|
||||
,op
|
||||
(fpr-offset rn)
|
||||
(fpr-offset rd))))))
|
||||
(cond (vector-size
|
||||
(aver (member vector-size '(:2s :4s :2d)))
|
||||
(multiple-value-bind (q size) (encode-vector-size vector-size)
|
||||
(emit-simd-two-same-float
|
||||
segment
|
||||
q
|
||||
,simd-u
|
||||
,simd-neg
|
||||
(logand 1 size)
|
||||
,simd-op6
|
||||
,simd-op
|
||||
(fpr-offset rn)
|
||||
(fpr-offset rd))))
|
||||
(t
|
||||
(emit-fp-data-processing-1 segment
|
||||
(fp-reg-type rn)
|
||||
,op
|
||||
(fpr-offset rn)
|
||||
(fpr-offset rd)))))))
|
||||
|
||||
(def-fp-data-processing-1+simd fabs #b0001
|
||||
#b0 #b1 #b11111)
|
||||
#b0 #b1 #b00000 #b11111)
|
||||
(def-fp-data-processing-1+simd fneg #b0010
|
||||
#b1 #b1 #b11111)
|
||||
#b1 #b1 #b00000 #b11111)
|
||||
(def-fp-data-processing-1+simd fsqrt #b0011
|
||||
#b1 #b0 #b11111)
|
||||
#b1 #b1 #b00001 #b11111)
|
||||
(def-fp-data-processing-1 frintn #b1000)
|
||||
(def-fp-data-processing-1 frintp #b1001)
|
||||
(def-fp-data-processing-1 frintm #b1010)
|
||||
|
|
@ -2888,24 +2892,26 @@
|
|||
(:printer fp-data-processing-2 ((op ,op)))
|
||||
(:printer simd-three-same-float ((u ,simd-u) (neg ,simd-neg) (op ,simd-op)))
|
||||
(:emitter
|
||||
(if vector-size
|
||||
(multiple-value-bind (q size) (encode-vector-size vector-size)
|
||||
(emit-simd-three-same-float
|
||||
segment
|
||||
q
|
||||
,simd-u
|
||||
,simd-neg
|
||||
(logand 1 size)
|
||||
(fpr-offset rm)
|
||||
,simd-op
|
||||
(fpr-offset rn)
|
||||
(fpr-offset rd)))
|
||||
(emit-fp-data-processing-2 segment
|
||||
(fp-reg-type rn)
|
||||
(fpr-offset rm)
|
||||
,op
|
||||
(fpr-offset rn)
|
||||
(fpr-offset rd))))))
|
||||
(cond (vector-size
|
||||
(aver (member vector-size '(:2s :4s :2d)))
|
||||
(multiple-value-bind (q size) (encode-vector-size vector-size)
|
||||
(emit-simd-three-same-float
|
||||
segment
|
||||
q
|
||||
,simd-u
|
||||
,simd-neg
|
||||
(logand 1 size)
|
||||
(fpr-offset rm)
|
||||
,simd-op
|
||||
(fpr-offset rn)
|
||||
(fpr-offset rd))))
|
||||
(t
|
||||
(emit-fp-data-processing-2 segment
|
||||
(fp-reg-type rn)
|
||||
(fpr-offset rm)
|
||||
,op
|
||||
(fpr-offset rn)
|
||||
(fpr-offset rd)))))))
|
||||
|
||||
(def-fp-data-processing-2+simd fmul #b0000
|
||||
#b1 #b0 #b11011)
|
||||
|
|
@ -3479,8 +3485,8 @@
|
|||
(neg 1 23)
|
||||
(size 1 22)
|
||||
(#b1 1 21)
|
||||
(#b00000 5 16)
|
||||
(opc 5 11)
|
||||
(op6 5 16)
|
||||
(op 5 11)
|
||||
(#b0 1 10)
|
||||
(rn 5 5)
|
||||
(rd 5 0))
|
||||
|
|
@ -3533,10 +3539,10 @@
|
|||
(op3 :field (byte 1 31) :value #b0)
|
||||
(u :field (byte 1 29))
|
||||
(op4 :field (byte 5 24) :value #b01110)
|
||||
(neg :field (byte 1 23))
|
||||
(neg :field (byte 1 23) :value #b1)
|
||||
(size :field (byte 1 22))
|
||||
(op5 :field (byte 1 21) :value #b1)
|
||||
(op6 :field (byte 5 16) :value #b00000)
|
||||
(op6 :field (byte 5 16))
|
||||
(op :field (byte 5 11))
|
||||
(op7 :field (byte 1 10) :value #b0)
|
||||
(rn :fields (list (byte 1 30) (byte 1 22) (byte 5 5)) :type 'simd-float-reg)
|
||||
|
|
@ -3612,7 +3618,9 @@
|
|||
(def bit #b1 #b10 #b00011)
|
||||
(def bif #b1 #b11 #b00011))
|
||||
|
||||
(macrolet ((def (name u op &optional zero-u zero)
|
||||
(macrolet ((def (name u op &optional
|
||||
(2d t)
|
||||
zero-u zero)
|
||||
`(define-instruction ,name (segment rd rn rm size)
|
||||
,@(when op
|
||||
`((:printer simd-three-same-sized ((u ,u) (op ,op)))))
|
||||
|
|
@ -3620,6 +3628,9 @@
|
|||
`((:printer simd-two-misc ((u ,zero-u) (op ,zero))
|
||||
'(:name :tab rd ", " rn ", " "#0"))))
|
||||
(:emitter
|
||||
(aver (member size ',(if 2d
|
||||
'(:8b :16b :4h :8h :2s :4s :2d)
|
||||
'(:8b :16b :4h :8h :2s :4s))))
|
||||
(multiple-value-bind (q size) (encode-vector-size size)
|
||||
(cond ,@(when zero
|
||||
`(((eql rm 0)
|
||||
|
|
@ -3644,32 +3655,32 @@
|
|||
(fpr-offset rd))
|
||||
`(error "Can be compared only with zero, not ~s" rm)))))))))
|
||||
(def cmtst #b0 #b10001)
|
||||
(def cmeq #b1 #b10001 0 #b01001)
|
||||
(def cmgt #b0 #b00110 0 #b01000)
|
||||
(def cmge #b0 #b00111 1 #b01000)
|
||||
(def cmlt nil nil 0 #b01010)
|
||||
(def cmle nil nil 1 #b01001)
|
||||
(def cmeq #b1 #b10001 t 0 #b01001)
|
||||
(def cmgt #b0 #b00110 t 0 #b01000)
|
||||
(def cmge #b0 #b00111 t 1 #b01000)
|
||||
(def cmlt nil nil t 0 #b01010)
|
||||
(def cmle nil nil t 1 #b01001)
|
||||
(def cmhi #b1 #b00110)
|
||||
(def cmhs #b1 #b00111)
|
||||
(def umin #b1 #b01101)
|
||||
(def umax #b1 #b01100)
|
||||
(def smin #b0 #b01101)
|
||||
(def smax #b0 #b01100)
|
||||
(def uhadd #b1 #b00000)
|
||||
(def umin #b1 #b01101 nil)
|
||||
(def umax #b1 #b01100 nil)
|
||||
(def smin #b0 #b01101 nil)
|
||||
(def smax #b0 #b01100 nil)
|
||||
(def uhadd #b1 #b00000 nil)
|
||||
(def uqadd #b1 #b00001)
|
||||
(def urhadd #b1 #b00010)
|
||||
(def uhsub #b1 #b00100)
|
||||
(def urhadd #b1 #b00010 nil)
|
||||
(def uhsub #b1 #b00100 nil)
|
||||
(def uqsub #b1 #b00101)
|
||||
(def addp #b0 #b10111)
|
||||
(def shadd #b0 #b00000)
|
||||
(def shadd #b0 #b00000 nil)
|
||||
(def sqadd #b0 #b00001)
|
||||
(def srhadd #b0 #b00010)
|
||||
(def shsub #b0 #b00100)
|
||||
(def srhadd #b0 #b00010 nil)
|
||||
(def shsub #b0 #b00100 nil)
|
||||
(def sqsub #b0 #b00101)
|
||||
(def uminp #b1 #b10101)
|
||||
(def umaxp #b1 #b10100)
|
||||
(def sminp #b0 #b10101)
|
||||
(def smaxp #b0 #b10100)
|
||||
(def uminp #b1 #b10101 nil)
|
||||
(def umaxp #b1 #b10100 nil)
|
||||
(def sminp #b0 #b10101 nil)
|
||||
(def smaxp #b0 #b10100 nil)
|
||||
(def sshl #b0 #b01001)
|
||||
(def ushl #b1 #b01001))
|
||||
|
||||
|
|
@ -3677,6 +3688,7 @@
|
|||
`(define-instruction ,name (segment rd rn rm size)
|
||||
(:printer simd-three-same-float ((u ,u) (neg ,neg) (op ,op)))
|
||||
(:emitter
|
||||
(aver (member size '(:2s :4s :2d)))
|
||||
(multiple-value-bind (q size) (encode-vector-size size)
|
||||
(emit-simd-three-same-float
|
||||
segment
|
||||
|
|
@ -3759,6 +3771,7 @@
|
|||
(fpr-offset rn)
|
||||
(fpr-offset rd)))
|
||||
(t
|
||||
(aver (member vector-size '(:2s :4s :2d)))
|
||||
(multiple-value-bind (q size) (encode-vector-size vector-size)
|
||||
(emit-simd-three-same-float
|
||||
segment
|
||||
|
|
@ -4082,6 +4095,7 @@
|
|||
(:printer simd-across-lanes ((u ,u) (op ,op)
|
||||
(rd nil :type 'vbhs)))
|
||||
(:emitter
|
||||
(aver (member size '(:8b :16b :4h :8h :2s :4s)))
|
||||
(multiple-value-bind (q size) (encode-vector-size size)
|
||||
(emit-simd-across-lanes
|
||||
segment
|
||||
|
|
@ -4171,6 +4185,7 @@
|
|||
`(define-instruction ,name (segment rd rn size)
|
||||
(:printer simd-two-misc ((u ,u) (op ,op) (rd nil :type 'simd-reg-2x)))
|
||||
(:emitter
|
||||
(aver (member size '(:8b :16b :4h :8h :2s :4s)))
|
||||
(multiple-value-bind (q size) (encode-vector-size size)
|
||||
(emit-simd-two-misc segment
|
||||
q
|
||||
|
|
@ -4366,8 +4381,8 @@
|
|||
(fpr-offset rn)
|
||||
(fpr-offset rd)))))))
|
||||
(def shl #b0 #b01010 nil t)
|
||||
(def sli #b1 #b01010)
|
||||
(def sri #b1 #b01000 t)
|
||||
(def sli #b1 #b01010 nil t)
|
||||
(def sri #b1 #b01000 t t)
|
||||
(def sshr #b0 #b00000 t t)
|
||||
(def shrn #b0 #b10000 t)
|
||||
(def ssra #b0 #b00010 t t)
|
||||
|
|
|
|||
|
|
@ -35,13 +35,13 @@
|
|||
(zerop (dpb 0 (byte 8 8) (ldb (byte 32 0) value)))
|
||||
(zerop (dpb 0 (byte 8 16) (ldb (byte 32 0) value)))
|
||||
(zerop (dpb 0 (byte 8 24) (ldb (byte 32 0) value)))))
|
||||
(inst movi dst value :4s))
|
||||
(inst movi dst (ldb (byte 32 0) value) :4s))
|
||||
((and wordp
|
||||
(or (zerop (dpb 0 (byte 8 0) (ldb (byte 16 0) value)))
|
||||
(zerop (dpb 0 (byte 8 8) (ldb (byte 16 0) value)))))
|
||||
(inst movi dst value :8h))
|
||||
(inst movi dst (ldb (byte 16 0) value) :8h))
|
||||
(bytep
|
||||
(inst movi dst value :16b))
|
||||
(inst movi dst (ldb (byte 8 0) value) :16b))
|
||||
((and (member (ldb (byte 8 0) value) '(0 #xFF))
|
||||
(member (ldb (byte 8 8) value) '(0 #xFF))
|
||||
(member (ldb (byte 8 16) value) '(0 #xFF))
|
||||
|
|
@ -50,7 +50,7 @@
|
|||
(member (ldb (byte 8 40) value) '(0 #xFF))
|
||||
(member (ldb (byte 8 48) value) '(0 #xFF))
|
||||
(member (ldb (byte 8 56) value) '(0 #xFF)))
|
||||
(inst movi value :2d))
|
||||
(inst movi dst value :2d))
|
||||
;; Can't do movi, try via the scalar regs.
|
||||
(wordp
|
||||
(inst movz tmp-tn (ldb (byte 16 0) value))
|
||||
|
|
|
|||
|
|
@ -148,11 +148,11 @@
|
|||
(complex-single-stack non-descriptor-stack)
|
||||
(complex-double-stack non-descriptor-stack :element-size 2 :alignment 2)
|
||||
#+sb-simd-pack
|
||||
(int-neon-stack non-descriptor-stack :element-size 2)
|
||||
(int-neon-stack non-descriptor-stack :element-size 2 :alignment 2)
|
||||
#+sb-simd-pack
|
||||
(double-neon-stack non-descriptor-stack :element-size 2)
|
||||
(double-neon-stack non-descriptor-stack :element-size 2 :alignment 2)
|
||||
#+sb-simd-pack
|
||||
(single-neon-stack non-descriptor-stack :element-size 2)
|
||||
(single-neon-stack non-descriptor-stack :element-size 2 :alignment 2)
|
||||
|
||||
;; **** Things that can go in the integer registers.
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
"test-horizontal-functions.lisp"
|
||||
#+x86-64 "test-horizontal-functions-x86-64.lisp"
|
||||
#+arm64 "test-horizontal-functions-arm64.lisp"
|
||||
#+arm64 "test-arm64-regressions.lisp"
|
||||
"test-hairy-simd-functions.lisp"
|
||||
"test-packages.lisp"))
|
||||
(load (merge-pathnames file #P"../contrib/sb-simd/test-suite/"))))
|
||||
|
|
|
|||
Loading…
Reference in a new issue