1.0.2.1: DATA-VECTOR-{REF,SET}-WITH-OFFSET for the x86
[sbcl.git] / src / compiler / generic / utils.lisp
index b63b3c6..1ebf85d 100644 (file)
@@ -1,4 +1,5 @@
-;;;; utility functions needed by the back end to generate code
+;;;; utility functions and macros needed by the back end to generate
+;;;; code
 
 ;;;; This software is part of the SBCL system. See the README file for
 ;;;; more information.
 \f
 ;;; Make a fixnum out of NUM. (I.e. shift by two bits if it will fit.)
 (defun fixnumize (num)
-  (if (<= #x-20000000 num #x1fffffff)
-      (ash num 2)
+  (if (fixnump num)
+      (ash num (1- n-lowtag-bits))
       (error "~W is too big for a fixnum." num)))
+
+;;; Determining whether a constant offset fits in an addressing mode.
+#!+x86
+(defun foldable-constant-offset-p (element-size lowtag data-offset offset)
+  (if (< element-size n-byte-bits)
+      nil
+      (multiple-value-bind (min max)
+          (sb!impl::displacement-bounds lowtag element-size data-offset)
+        (<= min offset max))))
+
 \f
 ;;;; routines for dealing with static symbols
 
 (defun static-symbol-offset (symbol)
   (if symbol
       (let ((posn (position symbol *static-symbols*)))
-       (unless posn (error "~S is not a static symbol." symbol))
-       (+ (* posn (pad-data-block symbol-size))
-          (pad-data-block (1- symbol-size))
-          other-pointer-lowtag
-          (- list-pointer-lowtag)))
+        (unless posn (error "~S is not a static symbol." symbol))
+        (+ (* posn (pad-data-block symbol-size))
+           (pad-data-block (1- symbol-size))
+           other-pointer-lowtag
+           (- list-pointer-lowtag)))
       0))
 
 ;;; Given a byte offset, OFFSET, return the appropriate static symbol.
   (if (zerop offset)
       nil
       (multiple-value-bind (n rem)
-         (truncate (+ offset list-pointer-lowtag (- other-pointer-lowtag)
-                      (- (pad-data-block (1- symbol-size))))
-                   (pad-data-block symbol-size))
-       (unless (and (zerop rem) (<= 0 n (1- (length *static-symbols*))))
-         (error "The byte offset ~W is not valid." offset))
-       (elt *static-symbols* n))))
+          (truncate (+ offset list-pointer-lowtag (- other-pointer-lowtag)
+                       (- (pad-data-block (1- symbol-size))))
+                    (pad-data-block symbol-size))
+        (unless (and (zerop rem) (<= 0 n (1- (length *static-symbols*))))
+          (error "The byte offset ~W is not valid." offset))
+        (elt *static-symbols* n))))
 
 ;;; Return the (byte) offset from NIL to the start of the fdefn object
 ;;; for the static function NAME.
 (defun static-fun-offset (name)
   (let ((static-syms (length *static-symbols*))
-       (static-fun-index (position name *static-funs*)))
+        (static-fun-index (position name *static-funs*)))
     (unless static-fun-index
       (error "~S isn't a static function." name))
     (+ (* static-syms (pad-data-block symbol-size))
        (- list-pointer-lowtag)
        (* static-fun-index (pad-data-block fdefn-size))
        (* fdefn-raw-addr-slot n-word-bytes))))
+\f
+;;; Various error-code generating helpers
+(defvar *adjustable-vectors* nil)
+
+(defmacro with-adjustable-vector ((var) &rest body)
+  `(let ((,var (or (pop *adjustable-vectors*)
+                   (make-array 16
+                               :element-type '(unsigned-byte 8)
+                               :fill-pointer 0
+                               :adjustable t))))
+     (declare (type (vector (unsigned-byte 8) 16) ,var))
+     (setf (fill-pointer ,var) 0)
+     (unwind-protect
+         (progn
+           ,@body)
+       (push ,var *adjustable-vectors*))))