From f644ad38dfa09b81aa53972dc4c549ffca13cc4e Mon Sep 17 00:00:00 2001
From: rtoy <rtoy>
Date: Thu, 10 Jul 2008 21:31:34 +0000
Subject: [PATCH] Fix minor issue:

(defun zot (x)
  (declare (type (INTEGER -536871936 536871934) x)
	   (optimize (speed 3)))
  (kernel::%double-float x))

produces a compiler note being unable to optimize due to type
uncertainty x.  This is confusing because the vop does get used, and
we get a nice single intruction.  This is caused by the unsigned-byte
32 deftransform for %single-float/%double-float

Work around the issue by

o adding new deftransform to convert %single-float/%double-float to
  %%single-float/%%double-float,
o adjusting the deftransform for unsigned 32-bit to call %%foo,
o adding a deftransform to always convert %foo to %%foo for signed
  32-bit arg,
o changing the vop translation to %%foo instead of %foo.
---
 compiler/sparc/float.lisp | 92 +++++++++++++++++++++++----------------
 1 file changed, 55 insertions(+), 37 deletions(-)

diff --git a/compiler/sparc/float.lisp b/compiler/sparc/float.lisp
index 21672a8e8..25010de17 100644
--- a/compiler/sparc/float.lisp
+++ b/compiler/sparc/float.lisp
@@ -5,7 +5,7 @@
 ;;; Carnegie Mellon University, and has been placed in the public domain.
 ;;;
 (ext:file-comment
-  "$Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/compiler/sparc/float.lisp,v 1.57 2008/06/24 17:12:35 rtoy Exp $")
+  "$Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/compiler/sparc/float.lisp,v 1.58 2008/07/10 21:31:34 rtoy Exp $")
 ;;;
 ;;; **********************************************************************
 ;;;
@@ -1011,6 +1011,58 @@
 
 ;;;; Conversion:
 
+;; Tell the compiler about %%single-float and %%double-float.  Add
+;; functions for byte-compiled code.
+(macrolet
+    ((frob (name type)
+       `(progn
+	  (defknown ,name ((signed-byte 32))
+	    ,type)
+	  (defun ,name (n)
+	    (declare (type (signed-byte 32) n))
+	    (,name n)))))
+  (frob %%single-float single-float)
+  (frob %%double-float double-float))
+
+;; Sparc doesn't have an instruction to convert a 32-bit unsigned
+;; integer to a float, but does have one for a 32-bit signed integer.
+;; What we do here is break up the 32-bit number into 2 smaller
+;; pieces.  Each of these are converted to a float, and the higher
+;; order piece is scaled appropriately, and finally everything is
+;; summed together.  The pieces are done in a way such that no
+;; roundoff occurs.  The scaling should not produce any roundoff
+;; either, since the scale factor is an exact power of two.  The final
+;; sum will produce the correct rounded result.  (I think,)
+;;
+;; But need to be careful because we still want to call the VOP for
+;; the small pieces, so we need the transform to give up if it's known
+;; that the argument is smaller than a 32-bit unsigned integer.
+(macrolet ((frob (name vop-trans limit unit)
+	     `(progn
+		(deftransform ,name ((n) ((unsigned-byte 32)))
+		  ;; Should this be extended to a (unsigned-byte 53)?  We could.  Just
+		  ;; take the low 31 bits, and the rest, and float them and combine
+		  ;; them as before.
+		  (when (csubtypep (c::continuation-type n)
+				   (c::specifier-type '(unsigned-byte 31)))
+		    ;; We want to give-up if we know the number can't have the
+		    ;; MSB set.  The signed 32-bit vop can handle that.
+		    (c::give-up))
+		  `(+ (,',vop-trans (ldb (byte ,',limit 0) n))
+		      (* (,',vop-trans (ldb (byte ,',(- 32 limit) ,',limit) n))
+			 (scale-float ,',unit ,',limit))))
+		;; Always convert %foo to %%foo for 32-bit signed values.
+		(deftransform ,name ((n) ((signed-byte 32)))
+		  `(,',vop-trans n)))))
+  ;; If we break up the numbers into the low 12 bits and the high 20
+  ;; bits, we can use a single AND instruction to get the low 12 bits.
+  ;; This is a microoptimization for Sparc.  Otherwise, the only
+  ;; constraint is that the pieces must be small enough to fit in the
+  ;; desired float format without rounding.
+  (frob %single-float %%single-float 12 1f0)
+  (frob %double-float %%double-float 12 1f0))
+
+
 (macrolet ((frob (name translate inst to-sc to-type)
 	     `(define-vop (,name)
 		(:args (x :scs (signed-reg) :target stack-temp
@@ -1040,45 +1092,11 @@
 			  (* (tn-offset stack-tn) vm:word-bytes))
 		    (note-this-location vop :internal-error)
 		    (inst ,inst y temp))))))
-  (frob %single-float/signed %single-float fitos single-reg single-float)
-  (frob %double-float/signed %double-float fitod double-reg double-float)
+  (frob %single-float/signed %%single-float fitos single-reg single-float)
+  (frob %double-float/signed %%double-float fitod double-reg double-float)
   #+long-float
   (frob %long-float/signed %long-float fitoq long-reg long-float))
 
-;; Sparc doesn't have an instruction to convert a 32-bit unsigned
-;; integer to a float, but does have one for a 32-bit signed integer.
-;; What we do here is break up the 32-bit number into 2 smaller
-;; pieces.  Each of these are converted to a float, and the higher
-;; order piece is scaled appropriately, and finally everything is
-;; summed together.  The pieces are done in a way such that no
-;; roundoff occurs.  The scaling should not produce any roundoff
-;; either, since the scale factor is an exact power of two.  The final
-;; sum will produce the correct rounded result.  (I think,)
-;;
-;; But need to be careful because we still want to call the VOP for
-;; the small pieces, so we need the transform to give up if it's known
-;; that the argument is smaller than a 32-bit unsigned integer.
-(macrolet ((frob (name limit unit)
-	     `(deftransform ,name ((n) ((unsigned-byte 32)))
-		;; Should this be extended to a (unsigned-byte 53)?  We could.  Just
-		;; take the low 31 bits, and the rest, and float them and combine
-		;; them as before.
-		(when (csubtypep (c::continuation-type n)
-				 (c::specifier-type '(unsigned-byte 31)))
-		  ;; We want to give-up if we know the number can't have the
-		  ;; MSB set.  The signed 32-bit vop can handle that.
-		  (c::give-up))
-		`(+ (,',name (ldb (byte ,',limit 0) n))
-		    (* (,',name (ldb (byte ,',(- 32 limit) ,',limit) n))
-		       (scale-float ,',unit ,',limit))))))
-  ;; If we break up the numbers into the low 12 bits and the high 20
-  ;; bits, we can use a single AND instruction to get the low 12 bits.
-  ;; This is a microoptimization for Sparc.  Otherwise, the only
-  ;; constraint is that the pieces must be small enough to fit in the
-  ;; desired float format without rounding.
-  (frob %single-float 12 1f0)
-  (frob %double-float 12 1f0))
-
 (macrolet ((frob (name translate inst from-sc from-type to-sc to-type)
 	     `(define-vop (,name)
 		(:args (x :scs (,from-sc)))
-- 
GitLab