From ea775867d48327bf1179eb570263427f28083880 Mon Sep 17 00:00:00 2001 From: Christophe Rhodes Date: Tue, 9 Apr 2002 09:29:04 +0000 Subject: [PATCH] 0.7.2.8: SPARC backend cleanups (more or less from CSR sbcl-devel 2002-04-05) ... s/fixnum-tag-bits/n-fixnum-tag-bits/ ... s/positive-fixnum-bits/n-positive-fixnum-bits/ ... a relative-branch on the SPARC is 22 bits, not 13 (thanks to Raymond Toy for discussion) ... implement proper *backend-subfeatures* conditionalization --- NEWS | 6 +- src/assembly/sparc/arith.lisp | 146 +++++++++---------- src/compiler/sparc/arith.lisp | 231 +++++++++++++++--------------- src/compiler/sparc/array.lisp | 8 +- src/compiler/sparc/call.lisp | 6 +- src/compiler/sparc/char.lisp | 4 +- src/compiler/sparc/float.lisp | 301 ++++++++++++++++++++++------------------ src/compiler/sparc/insts.lisp | 114 +++++++++------ src/compiler/sparc/macros.lisp | 15 +- src/compiler/sparc/move.lisp | 16 +-- src/compiler/sparc/parms.lisp | 8 +- version.lisp-expr | 2 +- 12 files changed, 461 insertions(+), 396 deletions(-) diff --git a/NEWS b/NEWS index 1f76c35..99f246e 100644 --- a/NEWS +++ b/NEWS @@ -1066,14 +1066,16 @@ changes in sbcl-0.7.3 relative to sbcl-0.7.2: (thanks to Christophe Rhodes's port of the CMUCL runtime) * cleanups to the runtime on SPARC, both Linux and Solaris, and for gcc>=3 (thanks to Nathan Froyd and Ingvar Mattsson) + * SPARC backend cleanups, allowing builds of cores optimized for V8 + and V9 SPARCS, and also emission of code targeted to a particular + backend chosen at runtime (thanks to Christophe Rhodes and Raymond + Toy) * ANSI's DEFINE-SYMBOL-MACRO is now supported. (thanks to Nathan Froyd porting CMU CL code originally by Douglas Thomas Crosher) * The fasl file format has changed again, to allow the compiler's INFO database to support symbol macros. * The user manual (in doc/) is formatted into HTML more nicely. (thanks to coreythomas) - -changes in sbcl-0.7.3 relative to sbcl-0.7.2: * The system is smarter about SUBTYPEP relationships, especially those involving NOT types (including types such as ATOM which are represented internally using NOT types). Thus SUBTYPEP is less diff --git a/src/assembly/sparc/arith.lisp b/src/assembly/sparc/arith.lisp index 3864d7b..05d3b8c 100644 --- a/src/assembly/sparc/arith.lisp +++ b/src/assembly/sparc/arith.lisp @@ -38,8 +38,8 @@ (inst b :vc done) (inst nop) - (inst sra temp x fixnum-tag-bits) - (inst sra temp2 y fixnum-tag-bits) + (inst sra temp x n-fixnum-tag-bits) + (inst sra temp2 y n-fixnum-tag-bits) (inst add temp2 temp) (with-fixed-allocation (res temp bignum-widetag (1+ bignum-digits-offset)) (storew temp2 res bignum-digits-offset other-pointer-lowtag)) @@ -82,8 +82,8 @@ (inst b :vc done) (inst nop) - (inst sra temp x fixnum-tag-bits) - (inst sra temp2 y fixnum-tag-bits) + (inst sra temp x n-fixnum-tag-bits) + (inst sra temp2 y n-fixnum-tag-bits) (inst sub temp2 temp temp2) (with-fixed-allocation (res temp bignum-widetag (1+ bignum-digits-offset)) (storew temp2 res bignum-digits-offset other-pointer-lowtag)) @@ -131,46 +131,36 @@ ;; Remove the tag from one arg so that the result will have the correct ;; fixnum tag. - (inst sra temp x fixnum-tag-bits) + (inst sra temp x n-fixnum-tag-bits) ;; Compute the produce temp * y and return the double-word product ;; in hi:lo. - ;; - ;; FIXME: Note that the below shebang read-time conditionals aren't - ;; actually shebang. This is because the assembly files are also - ;; built in warm-init, when #! is not a defined read-macro. This - ;; problem will actually go away when we rewrite these low-level - ;; bits and pieces to use the backend-subfeatures machinery, as we - ;; will then conditionalize at code-emission time or assembly time - ;; for the VOP and the assembly routine respectively. - CSR, - ;; 2002-02-11 - #+:sparc-64 - ;; Sign extend y to a full 64-bits. temp was already - ;; sign-extended by the sra instruction above. - (progn - (inst sra y 0) - (inst mulx hi temp y) - (inst move lo hi) - (inst srax hi 32)) - #+(and (not :sparc-64) (or :sparc-v8 :sparc-v9)) - (progn - (inst smul lo temp y) - (inst rdy hi)) - #+(and (not :sparc-64) (not (or :sparc-v8 :sparc-v9))) - (let ((MULTIPLIER-POSITIVE (gen-label))) - (inst wry temp) - (inst andcc hi zero-tn) - (inst nop) - (inst nop) - (dotimes (i 32) - (inst mulscc hi y)) - (inst mulscc hi zero-tn) - (inst cmp x) - (inst b :ge MULTIPLIER-POSITIVE) - (inst nop) - (inst sub hi y) - (emit-label MULTIPLIER-POSITIVE) - (inst rdy lo)) - + (cond + ((member :sparc-64 *backend-subfeatures*) + ;; Sign extend y to a full 64-bits. temp was already + ;; sign-extended by the sra instruction above. + (inst sra y 0) + (inst mulx hi temp y) + (inst move lo hi) + (inst srax hi 32)) + ((or (member :sparc-v8 *backend-subfeatures*) + (member :sparc-v9 *backend-subfeatures*)) + (inst smul lo temp y) + (inst rdy hi)) + (t + (let ((MULTIPLIER-POSITIVE (gen-label))) + (inst wry temp) + (inst andcc hi zero-tn) + (inst nop) + (inst nop) + (dotimes (i 32) + (inst mulscc hi y)) + (inst mulscc hi zero-tn) + (inst cmp x) + (inst b :ge MULTIPLIER-POSITIVE) + (inst nop) + (inst sub hi y) + (emit-label MULTIPLIER-POSITIVE) + (inst rdy lo)))) ;; Check to see if the result will fit in a fixnum. (I.e. the high word ;; is just 32 copies of the sign bit of the low word). (inst sra temp lo 31) @@ -178,27 +168,27 @@ (inst b :eq LOW-FITS-IN-FIXNUM) ;; Shift the double word hi:lo down two bits to get rid of the fixnum tag. (inst sll temp hi 30) - (inst srl lo fixnum-tag-bits) + (inst srl lo n-fixnum-tag-bits) (inst or lo temp) - (inst sra hi fixnum-tag-bits) + (inst sra hi n-fixnum-tag-bits) ;; Allocate a BIGNUM for the result. #+nil (pseudo-atomic (:extra (pad-data-block (1+ bignum-digits-offset))) - (let ((one-word (gen-label))) - (inst or res alloc-tn other-pointer-lowtag) - ;; We start out assuming that we need one word. Is that correct? - (inst sra temp lo 31) - (inst xorcc temp hi) - (inst b :eq one-word) - (inst li temp (logior (ash 1 n-widetag-bits) bignum-widetag)) - ;; Nope, we need two, so allocate the addition space. - (inst add alloc-tn (- (pad-data-block (+ 2 bignum-digits-offset)) - (pad-data-block (1+ bignum-digits-offset)))) - (inst li temp (logior (ash 2 n-widetag-bits) bignum-widetag)) - (storew hi res (1+ bignum-digits-offset) other-pointer-lowtag) - (emit-label one-word) - (storew temp res 0 other-pointer-lowtag) - (storew lo res bignum-digits-offset other-pointer-lowtag))) + (let ((one-word (gen-label))) + (inst or res alloc-tn other-pointer-lowtag) + ;; We start out assuming that we need one word. Is that correct? + (inst sra temp lo 31) + (inst xorcc temp hi) + (inst b :eq one-word) + (inst li temp (logior (ash 1 n-widetag-bits) bignum-widetag)) + ;; Nope, we need two, so allocate the addition space. + (inst add alloc-tn (- (pad-data-block (+ 2 bignum-digits-offset)) + (pad-data-block (1+ bignum-digits-offset)))) + (inst li temp (logior (ash 2 n-widetag-bits) bignum-widetag)) + (storew hi res (1+ bignum-digits-offset) other-pointer-lowtag) + (emit-label one-word) + (storew temp res 0 other-pointer-lowtag) + (storew lo res bignum-digits-offset other-pointer-lowtag))) ;; Always allocate 2 words for the bignum result, even if we only ;; need one. The copying GC will take care of the extra word if it ;; isn't needed. @@ -220,7 +210,7 @@ (storew lo res bignum-digits-offset other-pointer-lowtag))) ;; Out of here (lisp-return lra :offset 2) - + DO-STATIC-FUN (inst ld code-tn null-tn (static-fun-offset 'two-arg-*)) (inst li nargs (fixnumize 2)) @@ -247,24 +237,24 @@ (:temp temp ,sc nl2-offset)) ,@(when (eq type 'tagged-num) `((inst sra x 2))) - #+:sparc-64 - ;; Sign extend, then multiply - (progn - (inst sra x 0) - (inst sra y 0) - (inst mulx res x y)) - #+(and (not :sparc-64) (or :sparc-v8 :sparc-v9)) - (inst smul res x y) - #+(and (not :sparc-64) (not (or :sparc-v8 :sparc-v9))) - (progn - (inst wry x) - (inst andcc temp zero-tn) - (inst nop) - (inst nop) - (dotimes (i 32) - (inst mulscc temp y)) - (inst mulscc temp zero-tn) - (inst rdy res))))) + (cond + ((member :sparc-64 *backend-subfeatures*) + ;; Sign extend, then multiply + (inst sra x 0) + (inst sra y 0) + (inst mulx res x y)) + ((or (member :sparc-v8 *backend-subfeatures*) + (member :sparc-v9 *backend-subfeatures*)) + (inst smul res x y)) + (t + (inst wry x) + (inst andcc temp zero-tn) + (inst nop) + (inst nop) + (dotimes (i 32) + (inst mulscc temp y)) + (inst mulscc temp zero-tn) + (inst rdy res)))))) (frob unsigned-* "unsigned *" 40 unsigned-num unsigned-reg) (frob signed-* "unsigned *" 41 signed-num signed-reg) (frob fixnum-* "fixnum *" 30 tagged-num any-reg)) diff --git a/src/compiler/sparc/arith.lisp b/src/compiler/sparc/arith.lisp index 515f49e..cadcdab 100644 --- a/src/compiler/sparc/arith.lisp +++ b/src/compiler/sparc/arith.lisp @@ -228,8 +228,9 @@ (:temporary (:scs (signed-reg)) y-int) (:vop-var vop) (:save-p :compute-only) - (:guard #!+(or :sparc-v8 (and :sparc-v9 (not :sparc-64))) t - #!-(or :sparc-v8 (and :sparc-v9 (not :sparc-64))) nil) + (:guard (or (member :sparc-v8 *backend-subfeatures*) + (and (member :sparc-v9 *backend-subfeatures*) + (not (member :sparc-64 *backend-subfeatures*))))) (:generator 12 (let ((zero (generate-error-code vop division-by-zero-error x y))) (inst cmp y zero-tn) @@ -238,7 +239,7 @@ (inst sra r x 31) (inst wry r) ;; Remove tag bits so Q and R will be tagged correctly. - (inst sra y-int y fixnum-tag-bits) + (inst sra y-int y n-fixnum-tag-bits) (inst nop) (inst nop) @@ -262,14 +263,17 @@ (:temporary (:scs (signed-reg)) r) (:vop-var vop) (:save-p :compute-only) - (:guard #!+(or :sparc-v8 (and :sparc-v9 (not :sparc-64))) t - #!-(or :sparc-v8 (and :sparc-v9 (not :sparc-64))) nil) + (:guard (or (member :sparc-v8 *backend-subfeatures*) + (and (member :sparc-v9 *backend-subfeatures*) + (not (member :sparc-64 *backend-subfeatures*))))) (:generator 12 (let ((zero (generate-error-code vop division-by-zero-error x y))) (inst cmp y zero-tn) - (inst b :eq zero #!+:sparc-v9 :pn) + (if (member :sparc-v9 *backend-subfeatures*) + (inst b :eq zero :pn) + (inst b :eq zero)) ;; Extend the sign of X into the Y register - (inst sra r x 31) + (inst sra r x 31) (inst wry r) (inst nop) (inst nop) @@ -295,13 +299,16 @@ (:temporary (:scs (unsigned-reg)) r) (:vop-var vop) (:save-p :compute-only) - (:guard #!+(or :sparc-v8 (and :sparc-v9 (not :sparc-64))) t - #!-(or :sparc-v8 (and :sparc-v9 (not :sparc-64))) nil) + (:guard (or (member :sparc-v8 *backend-subfeatures*) + (and (member :sparc-v9 *backend-subfeatures*) + (not (member :sparc-64 *backend-subfeatures*))))) (:generator 8 (let ((zero (generate-error-code vop division-by-zero-error x y))) (inst cmp y zero-tn) - (inst b :eq zero #!+:sparc-v9 :pn) - (inst wry zero-tn) ; Clear out high part + (if (member :sparc-v9 *backend-subfeatures*) + (inst b :eq zero :pn) + (inst b :eq zero)) + (inst wry zero-tn) ; Clear out high part (inst nop) (inst nop) (inst nop) @@ -313,7 +320,6 @@ (unless (location= quo q) (inst move quo q))))) -#!+:sparc-v9 (define-vop (fast-v9-truncate/signed=>signed fast-safe-arith-op) (:translate truncate) (:args (x :scs (signed-reg)) @@ -327,13 +333,13 @@ (:temporary (:scs (signed-reg)) r) (:vop-var vop) (:save-p :compute-only) - (:guard #!+:sparc-64 t #!-:sparc-64 nil) + (:guard (member :sparc-64 *backend-subfeatures*)) (:generator 8 (let ((zero (generate-error-code vop division-by-zero-error x y))) (inst cmp y zero-tn) - (inst b :eq zero #!+:sparc-v9 :pn) + (inst b :eq zero :pn) ;; Sign extend the numbers, just in case. - (inst sra x 0) + (inst sra x 0) (inst sra y 0) (inst sdivx q x y) ;; Compute remainder @@ -355,13 +361,13 @@ (:temporary (:scs (unsigned-reg)) r) (:vop-var vop) (:save-p :compute-only) - (:guard #!+:sparc-64 t #!-:sparc-64 nil) + (:guard (member :sparc-64 *backend-subfeatures*)) (:generator 8 (let ((zero (generate-error-code vop division-by-zero-error x y))) (inst cmp y zero-tn) - (inst b :eq zero #!+:sparc-v9 :pn) + (inst b :eq zero :pn) ;; Zap the higher 32 bits, just in case - (inst srl x 0) + (inst srl x 0) (inst srl y 0) (inst udivx q x y) ;; Compute remainder @@ -386,42 +392,42 @@ (:temporary (:sc non-descriptor-reg) ndesc) (:generator 5 (sc-case amount - #!+:sparc-v9 - (signed-reg - (let ((done (gen-label)) - (positive (gen-label))) - (inst cmp amount) - (inst b :ge positive) - (inst neg ndesc amount) - ;; ndesc = max(-amount, 31) - (inst cmp ndesc 31) - (inst cmove :ge ndesc 31) - (inst b done) - (inst ,shift-right-inst result number ndesc) - (emit-label positive) - ;; The result-type assures us that this shift will not - ;; overflow. - (inst sll result number amount) - ;; We want a right shift of the appropriate size. - (emit-label done))) - #!-:sparc-v9 (signed-reg - (let ((positive (gen-label)) - (done (gen-label))) - (inst cmp amount) - (inst b :ge positive) - (inst neg ndesc amount) - (inst cmp ndesc 31) - (inst b :le done) - (inst ,shift-right-inst result number ndesc) - (inst b done) - (inst ,shift-right-inst result number 31) - - (emit-label positive) - ;; The result-type assures us that this shift will not overflow. - (inst sll result number amount) - - (emit-label done))) + (cond + ;; FIXME: These two don't look different enough. + ((member :sparc-v9 *backend-subfeatures*) + (let ((done (gen-label)) + (positive (gen-label))) + (inst cmp amount) + (inst b :ge positive) + (inst neg ndesc amount) + ;; ndesc = max(-amount, 31) + (inst cmp ndesc 31) + (inst cmove :ge ndesc 31) + (inst b done) + (inst ,shift-right-inst result number ndesc) + (emit-label positive) + ;; The result-type assures us that this shift will + ;; not overflow. + (inst sll result number amount) + ;; We want a right shift of the appropriate size. + (emit-label done))) + (t + (let ((positive (gen-label)) + (done (gen-label))) + (inst cmp amount) + (inst b :ge positive) + (inst neg ndesc amount) + (inst cmp ndesc 31) + (inst b :le done) + (inst ,shift-right-inst result number ndesc) + (inst b done) + (inst ,shift-right-inst result number 31) + (emit-label positive) + ;; The result-type assures us that this shift will + ;; not overflow. + (inst sll result number amount) + (emit-label done))))) (immediate (let ((amount (tn-value amount))) (if (minusp amount) @@ -575,27 +581,30 @@ (define-vop (fast-v8-*/fixnum=>fixnum fast-fixnum-binop) (:temporary (:scs (non-descriptor-reg)) temp) (:translate *) - (:guard #!+(or :sparc-v8 (and :sparc-v9 (not :sparc-64))) t - #!-(or :sparc-v8 (and :sparc-v9 (not :sparc-64))) nil) + (:guard (or (member :sparc-v8 *backend-subfeatures*) + (and (member :sparc-v9 *backend-subfeatures*) + (not (member :sparc-64 *backend-subfeatures*))))) (:generator 2 ;; The cost here should be less than the cost for ;; */signed=>signed. Why? A fixnum product using signed=>signed ;; has to convert both args to signed-nums. But using this, we ;; don't have to and that saves an instruction. - (inst sra temp y fixnum-tag-bits) + (inst sra temp y n-fixnum-tag-bits) (inst smul r x temp))) (define-vop (fast-v8-*/signed=>signed fast-signed-binop) (:translate *) - (:guard #!+(or :sparc-v8 (and :sparc-v9 (not :sparc-64))) t - #!-(or :sparc-v8 (and :sparc-v9 (not :sparc-64))) nil) + (:guard (or (member :sparc-v8 *backend-subfeatures*) + (and (member :sparc-v9 *backend-subfeatures*) + (not (member :sparc-64 *backend-subfeatures*))))) (:generator 3 (inst smul r x y))) (define-vop (fast-v8-*/unsigned=>unsigned fast-unsigned-binop) (:translate *) - (:guard #!+(or :sparc-v8 (and :sparc-v9 (not :sparc-64))) t - #!-(or :sparc-v8 (and :sparc-v9 (not :sparc-64))) nil) + (:guard (or (member :sparc-v8 *backend-subfeatures*) + (and (member :sparc-v9 *backend-subfeatures*) + (not (member :sparc-64 *backend-subfeatures*))))) (:generator 3 (inst umul r x y))) @@ -604,20 +613,20 @@ (define-vop (fast-v9-*/fixnum=>fixnum fast-fixnum-binop) (:temporary (:scs (non-descriptor-reg)) temp) (:translate *) - (:guard #!+:sparc-64 t #!-:sparc-64 nil) + (:guard (member :sparc-64 *backend-subfeatures*)) (:generator 4 - (inst sra temp y fixnum-tag-bits) + (inst sra temp y n-fixnum-tag-bits) (inst mulx r x temp))) (define-vop (fast-v9-*/signed=>signed fast-signed-binop) (:translate *) - (:guard #!+:sparc-64 t #!-:sparc-64 nil) + (:guard (member :sparc-64 *backend-subfeatures*)) (:generator 3 (inst mulx r x y))) (define-vop (fast-v9-*/unsigned=>unsigned fast-unsigned-binop) (:translate *) - (:guard #!+:sparc-64 t #!-:sparc-64 nil) + (:guard (member :sparc-64 *backend-subfeatures*)) (:generator 3 (inst mulx r x y))) @@ -880,7 +889,7 @@ (:args (digit :scs (unsigned-reg))) (:arg-types unsigned-num) (:results (result :scs (descriptor-reg))) - (:guard #!-:sparc-v9 t #!+:sparc-v9 nil) + (:guard (not (member :sparc-v9 *backend-subfeatures*))) (:generator 3 (let ((done (gen-label))) (inst cmp digit) @@ -895,7 +904,7 @@ (:args (digit :scs (unsigned-reg))) (:arg-types unsigned-num) (:results (result :scs (descriptor-reg))) - (:guard #!+:sparc-v9 t #!-:sparc-v9 nil) + (:guard (member :sparc-v9 *backend-subfeatures*)) (:generator 3 (inst cmp digit) (load-symbol result t) @@ -959,46 +968,46 @@ (type (or tn (signed-byte 13)) multiplicand)) ;; It seems that emit-multiply is only used to do an unsigned ;; multiply, so the code only does an unsigned multiply. - #!+:sparc-64 - (progn - ;; Take advantage of V9's 64-bit multiplier. - ;; - ;; Make sure the multiplier and multiplicand are really - ;; unsigned 64-bit numbers. - (inst srl multiplier 0) - (inst srl multiplicand 0) + (cond + ((member :sparc-64 *backend-subfeatures*) + ;; Take advantage of V9's 64-bit multiplier. + ;; + ;; Make sure the multiplier and multiplicand are really + ;; unsigned 64-bit numbers. + (inst srl multiplier 0) + (inst srl multiplicand 0) - ;; Multiply the two numbers and put the result in - ;; result-high. Copy the low 32-bits to result-low. Then - ;; shift result-high so the high 32-bits end up in the low - ;; 32-bits. - (inst mulx result-high multiplier multiplicand) - (inst move result-low result-high) - (inst srax result-high 32)) - #!+(and (not :sparc-64) (or :sparc-v8 :sparc-v9)) - (progn - ;; V8 has a multiply instruction. This should also work for - ;; the V9, but umul and the Y register is deprecated on the - ;; V9. - (inst umul result-low multiplier multiplicand) - (inst rdy result-high)) - #!+(and (not :sparc-64) (not (or :sparc-v8 :sparc-v9))) - (let ((label (gen-label))) - (inst wry multiplier) - (inst andcc result-high zero-tn) - ;; Note: we can't use the Y register until three insts - ;; after it's written. - (inst nop) - (inst nop) - (dotimes (i 32) - (inst mulscc result-high multiplicand)) - (inst mulscc result-high zero-tn) - (inst cmp multiplicand) - (inst b :ge label) - (inst nop) - (inst add result-high multiplier) - (emit-label label) - (inst rdy result-low))) + ;; Multiply the two numbers and put the result in + ;; result-high. Copy the low 32-bits to result-low. Then + ;; shift result-high so the high 32-bits end up in the low + ;; 32-bits. + (inst mulx result-high multiplier multiplicand) + (inst move result-low result-high) + (inst srax result-high 32)) + ((or (member :sparc-v8 *backend-subfeatures*) + (member :sparc-v9 *backend-subfeatures*)) + ;; V8 has a multiply instruction. This should also work for + ;; the V9, but umul and the Y register is deprecated on the + ;; V9. + (inst umul result-low multiplier multiplicand) + (inst rdy result-high)) + (t + (let ((label (gen-label))) + (inst wry multiplier) + (inst andcc result-high zero-tn) + ;; Note: we can't use the Y register until three insts + ;; after it's written. + (inst nop) + (inst nop) + (dotimes (i 32) + (inst mulscc result-high multiplicand)) + (inst mulscc result-high zero-tn) + (inst cmp multiplicand) + (inst b :ge label) + (inst nop) + (inst add result-high multiplier) + (emit-label label) + (inst rdy result-low))))) (define-vop (bignum-mult-and-add-3-arg) (:translate sb!bignum::%multiply-and-add) @@ -1063,7 +1072,7 @@ (:results (digit :scs (unsigned-reg))) (:result-types unsigned-num) (:generator 1 - (inst sra digit fixnum fixnum-tag-bits))) + (inst sra digit fixnum n-fixnum-tag-bits))) (define-vop (bignum-floor) (:translate sb!bignum::%floor) @@ -1075,8 +1084,6 @@ (:results (quo :scs (unsigned-reg) :from (:argument 1)) (rem :scs (unsigned-reg) :from (:argument 0))) (:result-types unsigned-num unsigned-num) - (:guard #!+(not (or :sparc-v8 :sparc-v9)) t - #!-(not (or :sparc-v8 :sparc-v9)) nil) (:generator 300 (move rem div-high) (move quo div-low) @@ -1104,8 +1111,8 @@ (:temporary (:scs (unsigned-reg) :target quo) q) ;; This vop is for a v8 or v9, provided we're also not using ;; sparc-64, for which there a special sparc-64 vop. - (:guard #!+(or :sparc-v8 (and :sparc-v9 (not :sparc-64))) t - #!-(or :sparc-v8 (and :sparc-v9 (not :sparc-64))) nil) + (:guard (or (member :sparc-v8 *backend-subfeatures*) + (member :sparc-v9 *backend-subfeatures*))) (:generator 15 (inst wry div-high) (inst nop) @@ -1131,7 +1138,7 @@ (:results (quo :scs (unsigned-reg)) (rem :scs (unsigned-reg))) (:result-types unsigned-num unsigned-num) - (:guard #!+:sparc-64 t #!-:sparc-64 nil) + (:guard (member :sparc-64 *backend-subfeatures*)) (:generator 5 ;; Set dividend to be div-high and div-low (inst sllx dividend div-high 32) @@ -1152,7 +1159,7 @@ (:generator 1 (sc-case res (any-reg - (inst sll res digit fixnum-tag-bits)) + (inst sll res digit n-fixnum-tag-bits)) (signed-reg (move res digit))))) diff --git a/src/compiler/sparc/array.lisp b/src/compiler/sparc/array.lisp index 8bbceaa..b40e455 100644 --- a/src/compiler/sparc/array.lisp +++ b/src/compiler/sparc/array.lisp @@ -33,7 +33,7 @@ (inst or ndescr ndescr type) ;; Remove the extraneous fixnum tag bits because TYPE and RANK ;; were fixnums - (inst srl ndescr ndescr fixnum-tag-bits) + (inst srl ndescr ndescr n-fixnum-tag-bits) (storew ndescr header 0 other-pointer-lowtag)) (move result header))) @@ -69,7 +69,7 @@ (loadw temp x 0 other-pointer-lowtag) (inst sra temp n-widetag-bits) (inst sub temp (1- array-dimensions-offset)) - (inst sll res temp fixnum-tag-bits))) + (inst sll res temp n-fixnum-tag-bits))) @@ -168,7 +168,7 @@ (:temporary (:scs (non-descriptor-reg) :to (:result 0)) temp result) (:generator 20 (inst srl temp index ,bit-shift) - (inst sll temp fixnum-tag-bits) + (inst sll temp n-fixnum-tag-bits) (inst add temp (- (* vector-data-offset n-word-bytes) other-pointer-lowtag)) (inst ld result object temp) @@ -217,7 +217,7 @@ (:temporary (:scs (non-descriptor-reg) :from (:argument 1)) shift) (:generator 25 (inst srl offset index ,bit-shift) - (inst sll offset fixnum-tag-bits) + (inst sll offset n-fixnum-tag-bits) (inst add offset (- (* vector-data-offset n-word-bytes) other-pointer-lowtag)) (inst ld old object offset) diff --git a/src/compiler/sparc/call.lisp b/src/compiler/sparc/call.lisp index 8cde5f8..6d8098e 100644 --- a/src/compiler/sparc/call.lisp +++ b/src/compiler/sparc/call.lisp @@ -1163,8 +1163,10 @@ default-value-8 (let ((err-lab (generate-error-code vop invalid-arg-count-error nargs))) (inst cmp nargs (fixnumize count)) - ;; Assume we don't take the branch - (inst b :ne err-lab #!+sparc-v9 :pn) + (if (member :sparc-v9 *backend-subfeatures*) + ;; Assume we don't take the branch + (inst b :ne err-lab :pn) + (inst b :ne err-lab)) (inst nop)))) ;;; Signal various errors. diff --git a/src/compiler/sparc/char.lisp b/src/compiler/sparc/char.lisp index bce3b41..900342a 100644 --- a/src/compiler/sparc/char.lisp +++ b/src/compiler/sparc/char.lisp @@ -90,7 +90,7 @@ (:results (res :scs (any-reg))) (:result-types positive-fixnum) (:generator 1 - (inst sll res ch fixnum-tag-bits))) + (inst sll res ch n-fixnum-tag-bits))) (define-vop (code-char) (:translate code-char) @@ -100,7 +100,7 @@ (:results (res :scs (base-char-reg))) (:result-types base-char) (:generator 1 - (inst srl res code fixnum-tag-bits))) + (inst srl res code n-fixnum-tag-bits))) ;;; Comparison of base-chars. diff --git a/src/compiler/sparc/float.lisp b/src/compiler/sparc/float.lisp index ba28bba..64b67e3 100644 --- a/src/compiler/sparc/float.lisp +++ b/src/compiler/sparc/float.lisp @@ -37,24 +37,25 @@ ;;; The offset may be an integer or a TN in which case it will be ;;; temporarily modified but is restored if restore-offset is true. (defun load-long-reg (reg base offset &optional (restore-offset t)) - #!+:sparc-v9 - (inst ldqf reg base offset) - #!-:sparc-v9 - (let ((reg0 (make-random-tn :kind :normal - :sc (sc-or-lose 'double-reg) - :offset (tn-offset reg))) - (reg2 (make-random-tn :kind :normal - :sc (sc-or-lose 'double-reg) - :offset (+ 2 (tn-offset reg))))) - (cond ((integerp offset) - (inst lddf reg0 base offset) - (inst lddf reg2 base (+ offset (* 2 n-word-bytes)))) - (t - (inst lddf reg0 base offset) - (inst add offset (* 2 n-word-bytes)) - (inst lddf reg2 base offset) - (when restore-offset - (inst sub offset (* 2 n-word-bytes))))))) + (cond + ((member :sparc-v9 *backend-subfeatures*) + (inst ldqf reg base offset)) + (t + (let ((reg0 (make-random-tn :kind :normal + :sc (sc-or-lose 'double-reg) + :offset (tn-offset reg))) + (reg2 (make-random-tn :kind :normal + :sc (sc-or-lose 'double-reg) + :offset (+ 2 (tn-offset reg))))) + (cond ((integerp offset) + (inst lddf reg0 base offset) + (inst lddf reg2 base (+ offset (* 2 n-word-bytes)))) + (t + (inst lddf reg0 base offset) + (inst add offset (* 2 n-word-bytes)) + (inst lddf reg2 base offset) + (when restore-offset + (inst sub offset (* 2 n-word-bytes))))))))) #!+long-float (define-move-fun (load-long 2) (vop x y) @@ -66,24 +67,25 @@ ;;; The offset may be an integer or a TN in which case it will be ;;; temporarily modified but is restored if restore-offset is true. (defun store-long-reg (reg base offset &optional (restore-offset t)) - #!+:sparc-v9 - (inst stqf reg base offset) - #!-:sparc-v9 - (let ((reg0 (make-random-tn :kind :normal - :sc (sc-or-lose 'double-reg) - :offset (tn-offset reg))) - (reg2 (make-random-tn :kind :normal - :sc (sc-or-lose 'double-reg) - :offset (+ 2 (tn-offset reg))))) - (cond ((integerp offset) - (inst stdf reg0 base offset) - (inst stdf reg2 base (+ offset (* 2 n-word-bytes)))) - (t - (inst stdf reg0 base offset) - (inst add offset (* 2 n-word-bytes)) - (inst stdf reg2 base offset) - (when restore-offset - (inst sub offset (* 2 n-word-bytes))))))) + (cond + ((member :sparc-v9 *backend-subfeatures*) + (inst stqf reg base offset)) + (t + (let ((reg0 (make-random-tn :kind :normal + :sc (sc-or-lose 'double-reg) + :offset (tn-offset reg))) + (reg2 (make-random-tn :kind :normal + :sc (sc-or-lose 'double-reg) + :offset (+ 2 (tn-offset reg))))) + (cond ((integerp offset) + (inst stdf reg0 base offset) + (inst stdf reg2 base (+ offset (* 2 n-word-bytes)))) + (t + (inst stdf reg0 base offset) + (inst add offset (* 2 n-word-bytes)) + (inst stdf reg2 base offset) + (when restore-offset + (inst sub offset (* 2 n-word-bytes))))))))) #!+long-float (define-move-fun (store-long 2) (vop x y) @@ -98,32 +100,34 @@ ;;; Exploit the V9 double-float move instruction. This is conditional ;;; on the :sparc-v9 feature. (defun move-double-reg (dst src) - #!+:sparc-v9 - (inst fmovd dst src) - #!-:sparc-v9 - (dotimes (i 2) - (let ((dst (make-random-tn :kind :normal - :sc (sc-or-lose 'single-reg) - :offset (+ i (tn-offset dst)))) - (src (make-random-tn :kind :normal - :sc (sc-or-lose 'single-reg) - :offset (+ i (tn-offset src))))) - (inst fmovs dst src)))) + (cond + ((member :sparc-v9 *backend-subfeatures*) + (inst fmovd dst src)) + (t + (dotimes (i 2) + (let ((dst (make-random-tn :kind :normal + :sc (sc-or-lose 'single-reg) + :offset (+ i (tn-offset dst)))) + (src (make-random-tn :kind :normal + :sc (sc-or-lose 'single-reg) + :offset (+ i (tn-offset src))))) + (inst fmovs dst src)))))) ;;; Exploit the V9 long-float move instruction. This is conditional ;;; on the :sparc-v9 feature. (defun move-long-reg (dst src) - #!+:sparc-v9 - (inst fmovq dst src) - #!-:sparc-v9 - (dotimes (i 4) - (let ((dst (make-random-tn :kind :normal - :sc (sc-or-lose 'single-reg) - :offset (+ i (tn-offset dst)))) - (src (make-random-tn :kind :normal - :sc (sc-or-lose 'single-reg) - :offset (+ i (tn-offset src))))) - (inst fmovs dst src)))) + (cond + ((member :sparc-v9 *backend-subfeatures*) + (inst fmovq dst src) + (t + (dotimes (i 4) + (let ((dst (make-random-tn :kind :normal + :sc (sc-or-lose 'single-reg) + :offset (+ i (tn-offset dst)))) + (src (make-random-tn :kind :normal + :sc (sc-or-lose 'single-reg) + :offset (+ i (tn-offset src))))) + (inst fmovs dst src))))))) (macrolet ((frob (vop sc format) `(progn @@ -662,34 +666,36 @@ (frob %negate/single-float fnegs %negate single-reg single-float)) (defun negate-double-reg (dst src) - #!+:sparc-v9 - (inst fnegd dst src) - #!-:sparc-v9 - ;; Negate the MS part of the numbers, then copy over the rest - ;; of the bits. - (inst fnegs dst src) - (let ((dst-odd (make-random-tn :kind :normal - :sc (sc-or-lose 'single-reg) - :offset (+ 1 (tn-offset dst)))) - (src-odd (make-random-tn :kind :normal - :sc (sc-or-lose 'single-reg) - :offset (+ 1 (tn-offset src))))) - (inst fmovs dst-odd src-odd))) + (cond + ((member :sparc-v9 *backend-subfeatures*) + (inst fnegd dst src)) + (t + ;; Negate the MS part of the numbers, then copy over the rest + ;; of the bits. + (inst fnegs dst src) + (let ((dst-odd (make-random-tn :kind :normal + :sc (sc-or-lose 'single-reg) + :offset (+ 1 (tn-offset dst)))) + (src-odd (make-random-tn :kind :normal + :sc (sc-or-lose 'single-reg) + :offset (+ 1 (tn-offset src))))) + (inst fmovs dst-odd src-odd))))) (defun abs-double-reg (dst src) - #!+:sparc-v9 - (inst fabsd dst src) - #!-:sparc-v9 - ;; Abs the MS part of the numbers, then copy over the rest - ;; of the bits. - (inst fabss dst src) - (let ((dst-2 (make-random-tn :kind :normal - :sc (sc-or-lose 'single-reg) - :offset (+ 1 (tn-offset dst)))) - (src-2 (make-random-tn :kind :normal - :sc (sc-or-lose 'single-reg) - :offset (+ 1 (tn-offset src))))) - (inst fmovs dst-2 src-2))) + (cond + ((member :sparc-v9 *backend-subfeatures*) + (inst fabsd dst src)) + (t + ;; Abs the MS part of the numbers, then copy over the rest + ;; of the bits. + (inst fabss dst src) + (let ((dst-2 (make-random-tn :kind :normal + :sc (sc-or-lose 'single-reg) + :offset (+ 1 (tn-offset dst)))) + (src-2 (make-random-tn :kind :normal + :sc (sc-or-lose 'single-reg) + :offset (+ 1 (tn-offset src))))) + (inst fmovs dst-2 src-2))))) (define-vop (abs/double-float) (:args (x :scs (double-reg))) @@ -732,20 +738,21 @@ (:save-p :compute-only) (:generator 1 (note-this-location vop :internal-error) - #!+:sparc-v9 - (inst fabsq y x) - #!-:sparc-v9 - (inst fabss y x) - (dotimes (i 3) - (let ((y-odd (make-random-tn - :kind :normal - :sc (sc-or-lose 'single-reg) - :offset (+ i 1 (tn-offset y)))) - (x-odd (make-random-tn - :kind :normal - :sc (sc-or-lose 'single-reg) - :offset (+ i 1 (tn-offset x))))) - (inst fmovs y-odd x-odd))))) + (cond + ((member :sparc-v9 *backend-subfeatures*) + (inst fabsq y x)) + (t + (inst fabss y x) + (dotimes (i 3) + (let ((y-odd (make-random-tn + :kind :normal + :sc (sc-or-lose 'single-reg) + :offset (+ i 1 (tn-offset y)))) + (x-odd (make-random-tn + :kind :normal + :sc (sc-or-lose 'single-reg) + :offset (+ i 1 (tn-offset x))))) + (inst fmovs y-odd x-odd))))))) #!+long-float (define-vop (%negate/long-float) @@ -760,20 +767,21 @@ (:save-p :compute-only) (:generator 1 (note-this-location vop :internal-error) - #!+:sparc-v9 - (inst fnegq y x) - #!-:sparc-v9 - (inst fnegs y x) - (dotimes (i 3) - (let ((y-odd (make-random-tn - :kind :normal - :sc (sc-or-lose 'single-reg) - :offset (+ i 1 (tn-offset y)))) - (x-odd (make-random-tn - :kind :normal - :sc (sc-or-lose 'single-reg) - :offset (+ i 1 (tn-offset x))))) - (inst fmovs y-odd x-odd))))) + (cond + ((member :sparc-v9 *backend-subfeatures*) + (inst fnegq y x)) + (t + (inst fnegs y x) + (dotimes (i 3) + (let ((y-odd (make-random-tn + :kind :normal + :sc (sc-or-lose 'single-reg) + :offset (+ i 1 (tn-offset y)))) + (x-odd (make-random-tn + :kind :normal + :sc (sc-or-lose 'single-reg) + :offset (+ i 1 (tn-offset x))))) + (inst fmovs y-odd x-odd))))))) ;;;; Comparison: @@ -795,7 +803,8 @@ (:long (inst fcmpq x y))) ;; The SPARC V9 doesn't need an instruction between a ;; floating-point compare and a floating-point branch. - #!-:sparc-v9 (inst nop) + (unless (member :sparc-v9 *backend-subfeatures*) + (inst nop)) (inst fb (if not-p nope yep) target) (inst nop))) @@ -1342,8 +1351,9 @@ (:results (y :scs (double-reg))) (:translate %sqrt) (:policy :fast-safe) - (:guard #!+(or :sparc-v7 :sparc-v8 :sparc-v9) t - #!-(or :sparc-v7 :sparc-v8 :sparc-v9) nil) + (:guard (or (member :sparc-v7 *backend-subfeatures*) + (member :sparc-v8 *backend-subfeatures*) + (member :sparc-v9 *backend-subfeatures*))) (:arg-types double-float) (:result-types double-float) (:note "inline float arithmetic") @@ -1947,7 +1957,8 @@ (,@fabs ratio yr) (,@fabs den yi) (inst ,fcmp ratio den) - #!-:sparc-v9 (inst nop) + (unless (member :sparc-v9 *backend-subfeatures*) + (inst nop)) (inst fb :ge bigger) (inst nop) ;; The case of |yi| <= |yr| @@ -2021,7 +2032,8 @@ (,@fabs ratio yr) (,@fabs den yi) (inst ,fcmp ratio den) - #!-:sparc-v9 (inst nop) + (unless (member :sparc-v9 *backend-subfeatures*) + (inst nop)) (inst fb :ge bigger) (inst nop) ;; The case of |yi| <= |yr| @@ -2120,7 +2132,8 @@ (,@fabs ratio yr) (,@fabs den yi) (inst ,fcmp ratio den) - #!-:sparc-v9 (inst nop) + (unless (member :sparc-v9 *backend-subfeatures*) + (inst nop)) (inst fb :ge bigger) (inst nop) ;; The case of |yi| <= |yr| @@ -2294,7 +2307,6 @@ (:note "inline complex float comparison") (:vop-var vop) (:save-p :compute-only) - (:guard #!-:sparc-v9 t #!+:sparc-v9 nil) (:generator 6 (note-this-location vop :internal-error) (let ((xr (,real-part x)) @@ -2332,8 +2344,8 @@ (:vop-var vop) (:save-p :compute-only) (:temporary (:sc descriptor-reg) true) - (:guard #!+:sparc-v9 t #!-:sparc-v9 nil) - (:generator 6 + (:guard (member :sparc-v9 *backend-subfeatures*)) + (:generator 5 (note-this-location vop :internal-error) (let ((xr (,real-part x)) (xi (,imag-part x)) @@ -2353,7 +2365,12 @@ ) ; end progn complex-fp-vops -#!+sparc-v9 + +;;; XXX FIXME: +;;; +;;; The stuff below looks good, but we already have transforms for max +;;; and min. How should we arrange that? +#+nil (progn ;; Vops to take advantage of the conditional move instruction @@ -2370,19 +2387,25 @@ single-float double-float) (movable foldable flushable)) -;; We need these definitions for byte-compiled code +;; We need these definitions for byte-compiled code +;; +;; Well, we (SBCL) probably don't, having deleted the byte +;; compiler. Let's see what happens if we comment out these +;; definitions: +#+nil (defun %%min (x y) (declare (type (or (unsigned-byte 32) (signed-byte 32) single-float double-float) x y)) (if (< x y) x y)) +#+nil (defun %%max (x y) (declare (type (or (unsigned-byte 32) (signed-byte 32) single-float double-float) x y)) (if (> x y) x y)) - +#+nil (macrolet ((frob (name sc-type type compare cmov cost cc max min note) (let ((vop-name (symbolicate name "-" type "=>" type)) @@ -2396,7 +2419,7 @@ (:policy :fast-safe) (:note ,note) (:translate ,trans-name) - (:guard #!+:sparc-v9 t #!-:sparc-v9 nil) + (:guard (member :sparc-v9 *backend-subfeatures*)) (:generator ,cost (inst ,compare x y) (cond ((location= r x) @@ -2477,26 +2500,30 @@ ) ; PROGN +#+nil (in-package "SB!C") ;;; FIXME -#| #!+sparc-v9 |# #+nil (progn ;;; The sparc-v9 architecture has conditional move instructions that ;;; can be used. This should be faster than using the obvious if ;;; expression since we don't have to do branches. -(def-source-transform min (&rest args) - (case (length args) - ((0 2) (values nil t)) - (1 `(values ,(first args))) - (t (sb!c::associate-arguments 'min (first args) (rest args))))) - -(def-source-transform max (&rest args) - (case (length args) - ((0 2) (values nil t)) - (1 `(values ,(first args))) - (t (sb!c::associate-arguments 'max (first args) (rest args))))) +(define-source-transform min (&rest args) + (if (member :sparc-v9 sb!vm:*backend-subfeatures*) + (case (length args) + ((0 2) (values nil t)) + (1 `(values ,(first args))) + (t (sb!c::associate-arguments 'min (first args) (rest args)))) + (values nil t))) + +(define-source-transform max (&rest args) + (if (member :sparc-v9 sb!vm:*backend-subfeatures*) + (case (length args) + ((0 2) (values nil t)) + (1 `(values ,(first args))) + (t (sb!c::associate-arguments 'max (first args) (rest args)))) + (values nil t))) ;; Derive the types of max and min (defoptimizer (max derive-type) ((x y)) diff --git a/src/compiler/sparc/insts.lisp b/src/compiler/sparc/insts.lisp index 1da4730..c378b73 100644 --- a/src/compiler/sparc/insts.lisp +++ b/src/compiler/sparc/insts.lisp @@ -33,9 +33,7 @@ (error "~S isn't a floating-point register." tn)) (let ((offset (tn-offset tn))) (cond ((> offset 31) - ;; Use the sparc v9 double float register encoding. - #!-:sparc-v9 (error ":sparc-v9 should be on the target features") - ;; (assert (backend-featurep :sparc-v9)) + (assert (member :sparc-v9 *backend-subfeatures*)) ;; No single register encoding greater than reg 31. (assert (zerop (mod offset 2))) ;; Upper bit of the register number is encoded in the low bit. @@ -360,9 +358,9 @@ about function addresses and register values.") (sb!disassem:define-arg-type relative-label :sign-extend t :use-label (lambda (value dstate) - (declare (type (signed-byte 13) value) - (type sb!disassem:disassem-state dstate)) - (+ (ash value 2) (sb!disassem:dstate-cur-addr dstate)))) + (declare (type (signed-byte 22) value) + (type sb!disassem:disassem-state dstate)) + (+ (ash value 2) (sb!disassem:dstate-cur-addr dstate)))) (defconstant-eqx branch-conditions '(:f :eq :le :lt :leu :ltu :n :vs :t :ne :gt :ge :gtu :geu :p :vc) @@ -1326,9 +1324,9 @@ about function addresses and register values.") (error "Offset of BA must be positive")) offset))))) -#!+sparc-v9 (defun emit-relative-branch-integer (segment a op2 cond-or-target target &optional (cc :icc) (pred :pt)) (declare (type integer-condition-register cc)) + (assert (member :sparc-v9 *backend-subfeatures*)) (emit-back-patch segment 4 (lambda (segment posn) (unless target @@ -1345,8 +1343,8 @@ about function addresses and register values.") (error "Offset of BA must be positive")) offset))))) -#!+sparc-v9 (defun emit-relative-branch-fp (segment a op2 cond-or-target target &optional (cc :fcc0) (pred :pt)) + (assert (member :sparc-v9 *backend-subfeatures*)) (emit-back-patch segment 4 (lambda (segment posn) (unless target @@ -1368,19 +1366,24 @@ about function addresses and register values.") ;; just get translated to the branch with prediction ;; instructions. However, the disassembler uses the correct V9 ;; mnemonic. -#!-sparc-v9 -(define-instruction b (segment cond-or-target &optional target) - (:declare (type (or label branch-condition) cond-or-target) - (type (or label null) target)) +(define-instruction b (segment cond-or-target &rest args) + (:declare (type (or label branch-condition) cond-or-target)) (:printer format-2-branch ((op #b00) (op2 #b010))) (:attributes branch) (:dependencies (reads :psr)) (:delay 1) (:emitter - (emit-relative-branch segment 0 #b010 cond-or-target target))) - -#!+sparc-v9 -(define-instruction b (segment cond-or-target &optional target pred cc) + (cond + ((member :sparc-v9 *backend-subfeatures*) + (destructuring-bind (&optional target pred cc) args + (declare (type (or label null) target)) + (emit-relative-branch-integer segment 0 #b001 cond-or-target target (or cc :icc) (or pred :pt)))) + (t + (destructuring-bind (&optional target) args + (declare (type (or label null) target)) + (emit-relative-branch segment 0 #b010 cond-or-target target)))))) + +(define-instruction bp (segment cond-or-target &optional target pred cc) (:declare (type (or label branch-condition) cond-or-target) (type (or label null) target)) (:printer format-2-branch-pred ((op #b00) (op2 #b001)) @@ -1392,10 +1395,8 @@ about function addresses and register values.") (:emitter (emit-relative-branch-integer segment 0 #b001 cond-or-target target (or cc :icc) (or pred :pt)))) -#!-sparc-v9 -(define-instruction ba (segment cond-or-target &optional target) - (:declare (type (or label branch-condition) cond-or-target) - (type (or label null) target)) +(define-instruction ba (segment cond-or-target &rest args) + (:declare (type (or label branch-condition) cond-or-target)) (:printer format-2-branch ((op #b00) (op2 #b010) (a 1)) nil :print-name 'b) @@ -1403,10 +1404,17 @@ about function addresses and register values.") (:dependencies (reads :psr)) (:delay 0) (:emitter - (emit-relative-branch segment 1 #b010 cond-or-target target))) - -#!+sparc-v9 -(define-instruction ba (segment cond-or-target &optional target pred cc) + (cond + ((member :sparc-v9 *backend-subfeatures*) + (destructuring-bind (&optional target pred cc) args + (declare (type (or label null) target)) + (emit-relative-branch-integer segment 1 #b001 cond-or-target target (or cc :icc) (or pred :pt)))) + (t + (destructuring-bind (&optional target) args + (declare (type (or label null) target)) + (emit-relative-branch segment 1 #b010 cond-or-target target)))))) + +(define-instruction bpa (segment cond-or-target &optional target pred cc) (:declare (type (or label branch-condition) cond-or-target) (type (or label null) target)) (:printer format-2-branch ((op #b00) (op2 #b001) (a 1)) @@ -1424,10 +1432,11 @@ about function addresses and register values.") ;; Definition 2.4.1 says only trap numbers 16-31 are allowed for user ;; code. All other trap numbers have other uses. The restriction on ;; target will prevent us from using bad trap numbers by mistake. -#!-sparc-v9 -(define-instruction t (segment condition target) + +(define-instruction t (segment condition target &optional cc) (:declare (type branch-condition condition) - ;; KLUDGE + ;; KLUDGE: see comments in vm.lisp regarding + ;; pseudo-atomic-trap. #!-linux (type (integer 16 31) target)) (:printer format-3-immed ((op #b10) @@ -1438,12 +1447,30 @@ about function addresses and register values.") (:attributes branch) (:dependencies (reads :psr)) (:delay 0) - (:emitter (emit-format-3-immed segment #b10 (branch-condition condition) - #b111010 0 1 target))) - -#!+sparc-v9 -(define-instruction t (segment condition target &optional (cc #!-sparc-64 :icc #!+sparc-64 :xcc)) + (:emitter + (cond + ((member :sparc-v9 *backend-subfeatures*) + (unless cc + (setf cc :icc)) + (emit-format-4-trap segment + #b10 + (branch-condition condition) + #b111010 0 1 + (integer-condition cc) + target)) + (t + (assert (null cc)) + (emit-format-3-immed segment #b10 (branch-condition condition) + #b111010 0 1 target))))) + +;;; KLUDGE: we leave this commented out, as these two (T and TCC) +;;; operations are actually indistinguishable from their bitfields, +;;; breaking the disassembler if these are left in. The printer isn't +;;; terribly smart, but the emitted code is right. - CSR, 2002-08-04 +#+nil +(define-instruction tcc (segment condition target &optional (cc #!-sparc-64 :icc #!+sparc-64 :xcc)) (:declare (type branch-condition condition) + ;; KLUDGE: see above. #!-linux (type (integer 16 31) target) (type integer-condition-register cc)) @@ -1464,8 +1491,8 @@ about function addresses and register values.") ;; Same as for the branch instructions. On the Sparc V9, we will use ;; the FP branch with prediction instructions instead. -#!-sparc-v9 -(define-instruction fb (segment condition target) + +(define-instruction fb (segment condition target &rest args) (:declare (type fp-branch-condition condition) (type label target)) (:printer format-2-branch ((op #B00) (cond nil :type 'branch-fp-condition) @@ -1474,10 +1501,15 @@ about function addresses and register values.") (:dependencies (reads :fsr)) (:delay 1) (:emitter - (emit-relative-branch segment 0 #b110 condition target t))) - -#!+sparc-v9 -(define-instruction fb (segment condition target &optional fcc pred) + (cond + ((member :sparc-v9 *backend-subfeatures*) + (destructuring-bind (&optional fcc pred) args + (emit-relative-branch-fp segment 0 #b101 condition target (or fcc :fcc0) (or pred :pt)))) + (t + (assert (null args)) + (emit-relative-branch segment 0 #b110 condition target t))))) + +(define-instruction fbp (segment condition target &optional fcc pred) (:declare (type fp-branch-condition condition) (type label target)) (:printer format-2-fp-branch-pred ((op #b00) (op2 #b101)) fp-branch-pred-printer @@ -1620,7 +1652,11 @@ about function addresses and register values.") (reads src2) (writes :fsr)) ;; The Sparc V9 doesn't need a delay after a FP compare. - (:delay #!-sparc-v9 1 #!+sparc-v9 0) + ;; + ;; KLUDGE FIXME YAARGH -- how to express that? I guess for now we + ;; do the worst case, and hope to fix it. + ;; (:delay #-sparc-v9 1 #+sparc-v9 0) + (:delay 1) (:emitter (emit-format-3-fpop2 segment #b10 (or (position fcc '(:fcc0 :fcc1 :fcc2 :fcc3)) diff --git a/src/compiler/sparc/macros.lisp b/src/compiler/sparc/macros.lisp index d897cf2..bfe10f0 100644 --- a/src/compiler/sparc/macros.lisp +++ b/src/compiler/sparc/macros.lisp @@ -371,10 +371,12 @@ (when fixnump `((inst andcc zero-tn ,reg fixnum-tag-mask) ,(if (or lowtags hdrs) - `(inst b :eq ,(if not-p not-target target) - #!+sparc-v9 ,(if not-p :pn :pt)) - `(inst b ,(if not-p :ne :eq) ,target - #!+sparc-v9 ,(if not-p :pn :pt))))) + `(if (member :sparc-v9 *backend-subfeatures*) + (inst b :eq ,(if not-p not-target target) ,(if not-p :pn :pt)) + (inst b :eq ,(if not-p not-target target))) + `(if (member :sparc-v9 *backend-subfeatures*) + (inst b ,(if not-p :ne :eq) ,target ,(if not-p :pn :pt)) + (inst b ,(if not-p :ne :eq) ,target))))) (when (or lowtags hdrs) `((inst and ,temp ,reg lowtag-mask))) (when lowtags @@ -389,8 +391,9 @@ (1- lowtag-limit) lowtags))) (when hdrs `((inst cmp ,temp ,lowtag) - (inst b :ne ,(if not-p target not-target) - #!+sparc-v9 ,(if not-p :pn :pt)) + (if (member :sparc-v9 *backend-subfeatures*) + (inst b :ne ,(if not-p target not-target) ,(if not-p :pn :pt)) + (inst b :ne ,(if not-p target not-target))) (inst nop) (load-type ,temp ,reg (- ,lowtag)) ,@(gen-other-immediate-test temp target not-target not-p hdrs)))))) diff --git a/src/compiler/sparc/move.lisp b/src/compiler/sparc/move.lisp index f3b7566..4ff9eb5 100644 --- a/src/compiler/sparc/move.lisp +++ b/src/compiler/sparc/move.lisp @@ -139,7 +139,7 @@ (:arg-types tagged-num) (:note "fixnum untagging") (:generator 1 - (inst sra y x fixnum-tag-bits))) + (inst sra y x n-fixnum-tag-bits))) (define-move-vop move-to-word/fixnum :move (any-reg descriptor-reg) (signed-reg unsigned-reg)) @@ -166,7 +166,7 @@ (let ((done (gen-label))) (inst andcc temp x fixnum-tag-mask) (inst b :eq done) - (inst sra y x fixnum-tag-bits) + (inst sra y x n-fixnum-tag-bits) (loadw y x bignum-digits-offset other-pointer-lowtag) @@ -183,7 +183,7 @@ (:result-types tagged-num) (:note "fixnum tagging") (:generator 1 - (inst sll y x fixnum-tag-bits))) + (inst sll y x n-fixnum-tag-bits))) (define-move-vop move-from-word/fixnum :move (signed-reg unsigned-reg) (any-reg descriptor-reg)) @@ -200,12 +200,12 @@ (move x arg) (let ((fixnum (gen-label)) (done (gen-label))) - (inst sra temp x positive-fixnum-bits) + (inst sra temp x n-positive-fixnum-bits) (inst cmp temp) (inst b :eq fixnum) (inst orncc temp zero-tn temp) (inst b :eq done) - (inst sll y x fixnum-tag-bits) + (inst sll y x n-fixnum-tag-bits) (with-fixed-allocation (y temp bignum-widetag (1+ bignum-digits-offset)) @@ -214,7 +214,7 @@ (inst nop) (emit-label fixnum) - (inst sll y x fixnum-tag-bits) + (inst sll y x n-fixnum-tag-bits) (emit-label done)))) (define-move-vop move-from-signed :move @@ -234,10 +234,10 @@ (let ((done (gen-label)) (one-word (gen-label)) (initial-alloc (pad-data-block (1+ bignum-digits-offset)))) - (inst sra temp x positive-fixnum-bits) + (inst sra temp x n-positive-fixnum-bits) (inst cmp temp) (inst b :eq done) - (inst sll y x fixnum-tag-bits) + (inst sll y x n-fixnum-tag-bits) ;; We always allocate 2 words even if we don't need it. (The ;; copying GC will take care of freeing the unused extra word.) diff --git a/src/compiler/sparc/parms.lisp b/src/compiler/sparc/parms.lisp index 7bee941..bfa49e2 100644 --- a/src/compiler/sparc/parms.lisp +++ b/src/compiler/sparc/parms.lisp @@ -28,17 +28,15 @@ #!+sb-doc "Number of bytes in a word.") -;;; FIXME: The following three should probably be rationalized or at -;;; least prefixed with n- where applicable -(defconstant fixnum-tag-bits (1- n-lowtag-bits) +(defconstant n-fixnum-tag-bits (1- n-lowtag-bits) #!+sb-doc "Number of tag bits used for a fixnum") -(defconstant fixnum-tag-mask (1- (ash 1 fixnum-tag-bits)) +(defconstant fixnum-tag-mask (1- (ash 1 n-fixnum-tag-bits)) #!+sb-doc "Mask to get the fixnum tag") -(defconstant positive-fixnum-bits (- n-word-bits fixnum-tag-bits 1) +(defconstant n-positive-fixnum-bits (- n-word-bits n-fixnum-tag-bits 1) #!+sb-doc "Maximum number of bits in a positive fixnum") diff --git a/version.lisp-expr b/version.lisp-expr index 5671450..d438300 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -18,4 +18,4 @@ ;;; for internal versions, especially for internal versions off the ;;; main CVS branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"0.7.2.7" +"0.7.2.8" -- 1.7.10.4