X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcompiler%2Fgeneric%2Futils.lisp;h=d4192d316f3e720fc4efdcc204d7e1cc47a2c182;hb=a189a69454ef7635149319ae213b337f17c50d20;hp=065b672bdec1acd045dbac2f4849c1a053c0559e;hpb=a530bbe337109d898d5b4a001fc8f1afa3b5dc39;p=sbcl.git diff --git a/src/compiler/generic/utils.lisp b/src/compiler/generic/utils.lisp index 065b672..d4192d3 100644 --- a/src/compiler/generic/utils.lisp +++ b/src/compiler/generic/utils.lisp @@ -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. @@ -10,16 +11,22 @@ ;;;; files for more information. (in-package "SB!VM") - -(file-comment - "$Header$") +;;; Make a fixnum out of NUM. (I.e. shift by two bits if it will fit.) (defun fixnumize (num) - #!+sb-doc - "Make a fixnum out of NUM. (i.e. shift by two bits if it will fit.)" - (if (<= #x-20000000 num #x1fffffff) - (ash num 2) - (error "~D is too big for a fixnum." num))) + (if (fixnump num) + (ash num n-fixnum-tag-bits) + (error "~W is too big for a fixnum." num))) + +;;; Determining whether a constant offset fits in an addressing mode. +#!+(or x86 x86-64) +(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)))) + ;;;; routines for dealing with static symbols @@ -27,41 +34,61 @@ (or (null symbol) (and (member symbol *static-symbols*) t))) +;;; the byte offset of the static symbol SYMBOL (defun static-symbol-offset (symbol) - #!+sb-doc - "the byte offset of the static symbol 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-type - (- list-pointer-type))) + (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. (defun offset-static-symbol (offset) - #!+sb-doc - "Given a byte offset, OFFSET, return the appropriate static symbol." (if (zerop offset) nil (multiple-value-bind (n rem) - (truncate (+ offset list-pointer-type (- other-pointer-type) - (- (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 ~D 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)))) -(defun static-function-offset (name) - #!+sb-doc - "Return the (byte) offset from NIL to the start of the fdefn object - for the static function NAME." +;;; Return the (byte) offset from NIL to the start of the fdefn object +;;; for the static function NAME. +(defun static-fdefn-offset (name) (let ((static-syms (length *static-symbols*)) - (static-function-index (position name *static-functions*))) - (unless static-function-index + (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)) (pad-data-block (1- symbol-size)) - (- list-pointer-type) - (* static-function-index (pad-data-block fdefn-size)) - (* fdefn-raw-addr-slot word-bytes)))) + (- list-pointer-lowtag) + (* static-fun-index (pad-data-block fdefn-size)) + other-pointer-lowtag))) + +;;; Return the (byte) offset from NIL to the raw-addr slot of the +;;; fdefn object for the static function NAME. +(defun static-fun-offset (name) + (+ (static-fdefn-offset name) + (- other-pointer-lowtag) + (* fdefn-raw-addr-slot n-word-bytes))) + +;;; 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*))))