mirror of
git://git.code.sf.net/p/sbcl/sbcl
synced 2026-09-10 07:26:40 -04:00
arm64: use fmov to move complex immediates
This commit is contained in:
parent
ed6a7c9a44
commit
cd361d1a4d
|
|
@ -41,8 +41,29 @@
|
|||
(inst fmov y zr-tn))
|
||||
((encode-fp-immediate x)
|
||||
(inst fmov y x))
|
||||
((when (and (typep x '(complex float))
|
||||
(eql (realpart x) (imagpart x)))
|
||||
(let* ((real (realpart x))
|
||||
(vector-size (typecase real
|
||||
(double-float :2d)
|
||||
(t :2s))))
|
||||
(cond ((encode-fp-immediate real)
|
||||
(inst fmov y real vector-size)
|
||||
t)
|
||||
((let ((bits (if (double-float-p real)
|
||||
(ldb (byte 64 0)
|
||||
(double-float-bits real))
|
||||
(ldb (byte 32 0)
|
||||
(single-float-bits real)))))
|
||||
(when (movi-immediate-p bits vector-size)
|
||||
(inst movi y bits vector-size)
|
||||
t)))))))
|
||||
((and (typep x '(complex float))
|
||||
(member (imagpart x) '(0f0 0d0))
|
||||
(encode-fp-immediate (realpart x)))
|
||||
(inst fmov y (realpart x)))
|
||||
((block nil
|
||||
(load-immediate-word tmp-tn (typecase x
|
||||
(load-immediate-word tmp-tn (etypecase x
|
||||
(double-float
|
||||
(double-float-bits x))
|
||||
(single-float
|
||||
|
|
@ -52,8 +73,10 @@
|
|||
(logior (ash (single-float-bits (imagpart x)) 32)
|
||||
(ldb (byte 32 0)
|
||||
(single-float-bits (realpart x))))))
|
||||
(t
|
||||
(return)))
|
||||
((complex double-float)
|
||||
(if (eql (imagpart x) 0d0)
|
||||
(double-float-bits (realpart x))
|
||||
(return))))
|
||||
t))
|
||||
(inst fmov y tmp-tn))
|
||||
(t
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
add-sub-immediate-p fixnum-add-sub-immediate-p
|
||||
negative-add-sub-immediate-p
|
||||
encode-logical-immediate fixnum-encode-logical-immediate
|
||||
movi-immediate-p
|
||||
ldr-str-offset-encodable ldp-stp-offset-p
|
||||
extend lsl lsr asr ror @ encode-fp-immediate) "SB-VM")
|
||||
;; Imports from SB-VM into this package
|
||||
|
|
@ -120,6 +121,8 @@
|
|||
(define-arg-type simd-modified-imm :printer #'print-simd-modified-imm)
|
||||
(define-arg-type 64-bit-modified-imm :printer #'print-64-bit-modified-imm)
|
||||
(define-arg-type simd-reg-cmode :printer #'print-simd-reg-cmode)
|
||||
(define-arg-type simd-fp-imm :printer #'print-simd-fp-imm)
|
||||
(define-arg-type simd-fmov-imm-reg :printer #'print-simd-fmov-imm-reg)
|
||||
(define-arg-type simd-table-regs :printer #'print-simd-table-regs)
|
||||
(define-arg-type simd-b-reg :printer #'print-simd-b-reg)
|
||||
(define-arg-type simd-high-vector :printer #'print-simd-high-vector)
|
||||
|
|
@ -2793,6 +2796,26 @@
|
|||
(#b0 :field (byte 5 5))
|
||||
(rd :field (byte 5 0) :type 'float-reg))
|
||||
|
||||
(define-instruction-format (simd-modified-imm 32
|
||||
:default-printer '(:name :tab rd ", #" imm))
|
||||
(o1 :field (byte 1 31) :value #b0)
|
||||
(q :field (byte 1 30))
|
||||
(op :field (byte 1 29))
|
||||
(op2 :field (byte 10 19) :value #b0111100000)
|
||||
(cmode :field (byte 4 12))
|
||||
(o2 :field (byte 1 11))
|
||||
(op3 :field (byte 1 10) :value #b1)
|
||||
(imm :fields (list (byte 3 16) (byte 4 12) (byte 5 5)) :type 'simd-modified-imm)
|
||||
(rd :fields (list (byte 1 30) (byte 4 12) (byte 5 0) (byte 1 29)) :type 'simd-reg-cmode))
|
||||
|
||||
(define-instruction-format (simd-modified-fp-imm 32
|
||||
:include simd-modified-imm
|
||||
:default-printer '(:name :tab rd ", #" imm))
|
||||
(imm :fields (list (byte 1 29) (byte 3 16) (byte 5 5)) :type 'simd-fp-imm)
|
||||
(cmode :value #b1111)
|
||||
(o2 :value 0)
|
||||
(rd :fields (list (byte 1 30) (byte 1 29) (byte 5 0)) :type 'simd-fmov-imm-reg))
|
||||
|
||||
(define-instruction fmov (segment rd rn &optional vector-index)
|
||||
(:printer fp-conversion ((op #b00110) (rd nil :type 'reg)))
|
||||
(:printer fp-conversion ((op #b00111) (rn nil :type 'reg)))
|
||||
|
|
@ -2802,19 +2825,46 @@
|
|||
(rd nil :type 'simd-high-vector)))
|
||||
(:printer fp-data-processing-1 ((op #b0)))
|
||||
(:printer fp-immediate ())
|
||||
(:printer simd-modified-fp-imm ())
|
||||
(:emitter
|
||||
(cond ((double-float-p rn)
|
||||
(aver (sc-is rd double-reg))
|
||||
(emit-fp-immediate segment 0 0 #b01
|
||||
(encode-fp-immediate rn)
|
||||
0
|
||||
(fpr-offset rd)))
|
||||
((single-float-p rn)
|
||||
(aver (sc-is rd single-reg))
|
||||
(emit-fp-immediate segment 0 0 #b00
|
||||
(encode-fp-immediate rn)
|
||||
0
|
||||
(fpr-offset rd)))
|
||||
(cond ((floatp rn)
|
||||
(sc-case rd
|
||||
((complex-single-reg complex-double-reg)
|
||||
(if vector-index
|
||||
(let* ((imm (encode-fp-immediate rn))
|
||||
(abc (ldb (byte 3 5) imm))
|
||||
(defgh (ldb (byte 5 0) imm)))
|
||||
(emit-simd-modified-imm segment
|
||||
(encode-vector-size vector-index)
|
||||
(ecase vector-index
|
||||
((:4s :2s) 0)
|
||||
(:2d 1))
|
||||
abc
|
||||
#b1111
|
||||
0
|
||||
defgh
|
||||
(fpr-offset rd)))
|
||||
(sc-case rd
|
||||
(complex-double-reg
|
||||
(emit-fp-immediate segment 0 0 #b01
|
||||
(encode-fp-immediate rn)
|
||||
0
|
||||
(fpr-offset rd)))
|
||||
(complex-single-reg
|
||||
(emit-fp-immediate segment 0 0 #b00
|
||||
(encode-fp-immediate rn)
|
||||
0
|
||||
(fpr-offset rd))))))
|
||||
(double-reg
|
||||
(emit-fp-immediate segment 0 0 #b01
|
||||
(encode-fp-immediate rn)
|
||||
0
|
||||
(fpr-offset rd)))
|
||||
(single-reg
|
||||
(emit-fp-immediate segment 0 0 #b00
|
||||
(encode-fp-immediate rn)
|
||||
0
|
||||
(fpr-offset rd)))))
|
||||
((and (fp-register-p rd)
|
||||
(fp-register-p rn))
|
||||
(assert (and (eq (tn-sc rd) (tn-sc rn))) (rd rn)
|
||||
|
|
@ -3584,29 +3634,50 @@
|
|||
(defgh 5 5)
|
||||
(rd 5 0))
|
||||
|
||||
(define-instruction-format (simd-modified-imm 32
|
||||
:default-printer '(:name :tab rd ", #" imm))
|
||||
(o1 :field (byte 1 31) :value #b0)
|
||||
(q :field (byte 1 30))
|
||||
(op :field (byte 1 29))
|
||||
(op2 :field (byte 10 19) :value #b0111100000)
|
||||
(cmode :field (byte 4 12))
|
||||
(o2 :field (byte 1 11))
|
||||
(op3 :field (byte 1 10) :value #b1)
|
||||
(imm :fields (list (byte 3 16) (byte 4 12) (byte 5 5)) :type 'simd-modified-imm)
|
||||
(rd :fields (list (byte 1 30) (byte 4 12) (byte 5 0) (byte 1 29)) :type 'simd-reg-cmode))
|
||||
(defun movi-immediate-p (value &optional size)
|
||||
(ecase size
|
||||
((:8b :16b :4h :8h)
|
||||
(typep value '(unsigned-byte 8)))
|
||||
((:4s :2s)
|
||||
(cond ((typep value '(unsigned-byte 8)))
|
||||
((typep value '(unsigned-byte 16))
|
||||
(let ((low (ldb (byte 8 0) value)))
|
||||
(or (zerop low)
|
||||
(= low #xFF))))
|
||||
((typep value '(unsigned-byte 24))
|
||||
(let ((low (ldb (byte 16 0) value)))
|
||||
(or (zerop low)
|
||||
(= low #xFFFF))))
|
||||
((typep value '(unsigned-byte 32))
|
||||
(zerop (ldb (byte 24 0) value)))))
|
||||
((nil :2d)
|
||||
(and
|
||||
(typep (ldb (byte 8 56) value) '(member 255 0))
|
||||
(typep (ldb (byte 8 48) value) '(member 255 0))
|
||||
(typep (ldb (byte 8 32) value) '(member 255 0))
|
||||
(typep (ldb (byte 8 24) value) '(member 255 0))
|
||||
(typep (ldb (byte 8 16) value) '(member 255 0))
|
||||
(typep (ldb (byte 8 8) value) '(member 255 0))
|
||||
(typep (ldb (byte 8 0) value) '(member 255 0))))))
|
||||
|
||||
(macrolet
|
||||
((def (name o2 op)
|
||||
`(define-instruction ,name (segment rd imm size)
|
||||
(:printer simd-modified-imm ((o2 ,o2)
|
||||
(op ,op)))
|
||||
((def (name o2 op cmodes)
|
||||
`(define-instruction ,name (segment rd imm &optional size)
|
||||
,@(loop for cmode in cmodes
|
||||
for fields = (loop for bit in cmode
|
||||
for i downfrom 15
|
||||
unless (eq bit 'x)
|
||||
collect `(byte 1 ,i))
|
||||
for bits = (remove 'x cmode)
|
||||
collect `(:printer simd-modified-imm ((o2 ,o2)
|
||||
(op ,op)
|
||||
(cmodes ',bits
|
||||
:fields (list ,@fields)))))
|
||||
,@(when (eq name 'movi)
|
||||
`((:printer simd-modified-imm ((o2 ,o2)
|
||||
(op 1)
|
||||
(cmode #b1110)
|
||||
(imm nil :type '64-bit-modified-imm))
|
||||
'('movi :tab rd ", #" imm))))
|
||||
(imm nil :type '64-bit-modified-imm)))))
|
||||
(:emitter
|
||||
(let ((abc 0)
|
||||
(defgh 0)
|
||||
|
|
@ -3615,8 +3686,9 @@
|
|||
(setf abc (ldb (byte 3 5) imm)
|
||||
defgh (ldb (byte 5 0) imm))
|
||||
(ecase size
|
||||
((:8b :16b)
|
||||
(setf cmode #b1110))
|
||||
,@(when (eq name 'movi)
|
||||
`(((:8b :16b)
|
||||
(setf cmode #b1110))))
|
||||
((:4h :8h)
|
||||
(cond ((typep imm '(unsigned-byte 8))
|
||||
(setf cmode #b1000))
|
||||
|
|
@ -3652,35 +3724,44 @@
|
|||
defgh (ldb (byte 5 24) imm)
|
||||
cmode #b0110))))
|
||||
(error "~x bad immediate" imm)))
|
||||
((:2d)
|
||||
(let ((a (the (member 255 0) (ldb (byte 8 56) imm)))
|
||||
(b (the (member 255 0) (ldb (byte 8 48) imm)))
|
||||
(c (the (member 255 0) (ldb (byte 8 40) imm)))
|
||||
(d (the (member 255 0) (ldb (byte 8 32) imm)))
|
||||
(e (the (member 255 0) (ldb (byte 8 24) imm)))
|
||||
(f (the (member 255 0) (ldb (byte 8 16) imm)))
|
||||
(g (the (member 255 0) (ldb (byte 8 8) imm)))
|
||||
(h (the (member 255 0) (ldb (byte 8 0) imm))))
|
||||
(setf (ldb (byte 1 2) abc) a
|
||||
(ldb (byte 1 1) abc) b
|
||||
(ldb (byte 1 0) abc) c
|
||||
(ldb (byte 1 4) defgh) d
|
||||
(ldb (byte 1 3) defgh) e
|
||||
(ldb (byte 1 2) defgh) f
|
||||
(ldb (byte 1 1) defgh) g
|
||||
(ldb (byte 1 0) defgh) h)
|
||||
(setf op 1
|
||||
cmode #b1110))))
|
||||
,@(when (eq name 'movi)
|
||||
`(((nil :2d)
|
||||
(let ((a (the (member 255 0) (ldb (byte 8 56) imm)))
|
||||
(b (the (member 255 0) (ldb (byte 8 48) imm)))
|
||||
(c (the (member 255 0) (ldb (byte 8 40) imm)))
|
||||
(d (the (member 255 0) (ldb (byte 8 32) imm)))
|
||||
(e (the (member 255 0) (ldb (byte 8 24) imm)))
|
||||
(f (the (member 255 0) (ldb (byte 8 16) imm)))
|
||||
(g (the (member 255 0) (ldb (byte 8 8) imm)))
|
||||
(h (the (member 255 0) (ldb (byte 8 0) imm))))
|
||||
(setf (ldb (byte 1 2) abc) a
|
||||
(ldb (byte 1 1) abc) b
|
||||
(ldb (byte 1 0) abc) c
|
||||
(ldb (byte 1 4) defgh) d
|
||||
(ldb (byte 1 3) defgh) e
|
||||
(ldb (byte 1 2) defgh) f
|
||||
(ldb (byte 1 1) defgh) g
|
||||
(ldb (byte 1 0) defgh) h)
|
||||
(setf op 1
|
||||
cmode #b1110))))))
|
||||
(emit-simd-modified-imm segment
|
||||
(encode-vector-size size)
|
||||
(if size
|
||||
(encode-vector-size size)
|
||||
0)
|
||||
op
|
||||
abc
|
||||
cmode
|
||||
,o2
|
||||
defgh
|
||||
(fpr-offset rd)))))))
|
||||
(def movi 0 0)
|
||||
(def mvni 0 1))
|
||||
|
||||
(def movi 0 0 ((0 x x 0)
|
||||
(1 0 x 0)
|
||||
(1 1 0 x)
|
||||
(1 1 1 0)))
|
||||
(def mvni 0 1 ((0 x x 0)
|
||||
(1 0 x 0)
|
||||
(1 1 0 x))))
|
||||
|
||||
(def-emitter fp-cond-select
|
||||
(0 1 31)
|
||||
|
|
|
|||
|
|
@ -333,24 +333,48 @@
|
|||
(defun print-simd-reg-cmode (value stream dstate)
|
||||
(declare (ignore dstate))
|
||||
(destructuring-bind (q cmode offset op) value
|
||||
(if (and (eql q 0)
|
||||
(eql cmode #b1110)
|
||||
(eql op 1))
|
||||
(format stream "D~d" offset)
|
||||
(format stream "V~d.~a" offset
|
||||
(cond ((eq cmode #b1110)
|
||||
(if (eq op 1)
|
||||
(if (zerop q)
|
||||
""
|
||||
"2D")
|
||||
(if (zerop q)
|
||||
"8B"
|
||||
"16B")))
|
||||
((eq (logandc2 cmode #b10) #b1000)
|
||||
(if (zerop q)
|
||||
"4H"
|
||||
"8H"))
|
||||
((or (zerop (logand cmode #b1001))
|
||||
(= (ldb (byte 3 13) cmode) #b110))
|
||||
(if (zerop q)
|
||||
"2S"
|
||||
"4S")))))))
|
||||
|
||||
(defun print-simd-fp-imm (value stream dstate)
|
||||
(declare (ignore dstate))
|
||||
(destructuring-bind (op abc defgh) value
|
||||
(let ((value (dpb abc (byte 3 5) defgh)))
|
||||
(format stream "~s" (decode-fp-immediate value (case op
|
||||
(1 'double-float)
|
||||
(0 'single-float)))))))
|
||||
|
||||
(defun print-simd-fmov-imm-reg (value stream dstate)
|
||||
(declare (ignore dstate))
|
||||
(destructuring-bind (q op offset) value
|
||||
(format stream "V~d.~a" offset
|
||||
(cond ((eq cmode #b1110)
|
||||
(if (eq op 1)
|
||||
(if (zerop q)
|
||||
""
|
||||
"2D")
|
||||
(if (zerop q)
|
||||
"8B"
|
||||
"16B")))
|
||||
((eq (logandc2 cmode #b10) #b1000)
|
||||
(if (zerop q)
|
||||
"4H"
|
||||
"8H"))
|
||||
((or (zerop (logand cmode #b1001))
|
||||
(= (ldb (byte 3 13) cmode) #b110))
|
||||
(if (zerop q)
|
||||
"2S"
|
||||
"4S"))))))
|
||||
(case op
|
||||
(0
|
||||
(case q
|
||||
(0 "2S")
|
||||
(1 "4S")))
|
||||
(1
|
||||
"2D")))))
|
||||
|
||||
(defun print-simd-table-regs (value stream dstate)
|
||||
(declare (ignore dstate))
|
||||
|
|
|
|||
|
|
@ -1732,5 +1732,8 @@
|
|||
(let ((b (& (>> val 1) #xf)))
|
||||
(let ((a (>> (<< val 25) 28)))
|
||||
(^ a (aref tab b))))))")
|
||||
(#(0 991CAE6F 9E1CB64E C60DEABC D10DFC0D D5FEF962 D6D10A2B DFFF0920)
|
||||
"(:|2D| NIL :|2S| :|4S| :|8H| :|4H| :|16B| :|8B|)"
|
||||
"((& (^ val (>> val 31)) 7))")
|
||||
)
|
||||
;; EOF
|
||||
|
|
|
|||
Loading…
Reference in a new issue