-;;; FIXME: test typing macros. Should(?) be in type-vops.lisp, except
-;;; that they're also used in subprim.lisp
-
-(defun cost-to-test-types (type-codes)
- (+ (* 2 (length type-codes))
- (if (> (apply #'max type-codes) lowtag-limit) 7 2)))
-
-(defparameter *immediate-types*
- (list base-char-widetag unbound-marker-widetag))
-
-(defparameter *fun-header-widetags*
- (list funcallable-instance-header-widetag
- simple-fun-header-widetag
- closure-fun-header-widetag
- closure-header-widetag))
-
-(defun gen-range-test (reg target not-target not-p min seperation max values)
- (let ((tests nil)
- (start nil)
- (end nil)
- (insts nil))
- (multiple-value-bind (equal less-or-equal greater-or-equal label)
- (if not-p
- (values :ne :gt :lt not-target)
- (values :eq :le :ge target))
- (flet ((emit-test ()
- (if (= start end)
- (push start tests)
- (push (cons start end) tests))))
- (dolist (value values)
- (cond ((< value min)
- (error "~S is less than the specified minimum of ~S"
- value min))
- ((> value max)
- (error "~S is greater than the specified maximum of ~S"
- value max))
- ((not (zerop (rem (- value min) seperation)))
- (error "~S isn't an even multiple of ~S from ~S"
- value seperation min))
- ((null start)
- (setf start value))
- ((> value (+ end seperation))
- (emit-test)
- (setf start value)))
- (setf end value))
- (emit-test))
- (macrolet ((inst (name &rest args)
- `(push (list 'inst ',name ,@args) insts)))
- (do ((remaining (nreverse tests) (cdr remaining)))
- ((null remaining))
- (let ((test (car remaining))
- (last (null (cdr remaining))))
- (if (atom test)
- (progn
- (inst cmp reg test)
- (if last
- (inst b equal target)
- (inst b :eq label)))
- (let ((start (car test))
- (end (cdr test)))
- (cond ((and (= start min) (= end max))
- (warn "The values ~S cover the entire range from ~
- ~S to ~S [step ~S]."
- values min max seperation)
- (push `(unless ,not-p (inst b ,target)) insts))
- ((= start min)
- (inst cmp reg end)
- (if last
- (inst b less-or-equal target)
- (inst b :le label)))
- ((= end max)
- (inst cmp reg start)
- (if last
- (inst b greater-or-equal target)
- (inst b :ge label)))
- (t
- (inst cmp reg start)
- (inst b :lt (if not-p target not-target))
- (inst cmp reg end)
- (if last
- (inst b less-or-equal target)
- (inst b :le label))))))))))
- (nreverse insts)))
-
-(defun gen-other-immediate-test (reg target not-target not-p values)
- (gen-range-test reg target not-target not-p
- (+ other-immediate-0-lowtag lowtag-limit)
- (- other-immediate-1-lowtag other-immediate-0-lowtag)
- (ash 1 n-widetag-bits)
- values))
-
-(defun test-type-aux (reg temp target not-target not-p lowtags immed hdrs
- function-p)
- (let* ((fixnump (and (member even-fixnum-lowtag lowtags :test #'eql)
- (member odd-fixnum-lowtag lowtags :test #'eql)))
- (lowtags (sort (if fixnump
- (delete even-fixnum-lowtag
- (remove odd-fixnum-lowtag lowtags
- :test #'eql)
- :test #'eql)
- (copy-list lowtags))
- #'<))
- (lowtag (if function-p
- fun-pointer-lowtag
- other-pointer-lowtag))
- (hdrs (sort (copy-list hdrs) #'<))
- (immed (sort (copy-list immed) #'<)))
- (append
- (when immed
- `((inst and ,temp ,reg widetag-mask)
- ,@(if (or fixnump lowtags hdrs)
- (let ((fall-through (gensym)))
- `((let (,fall-through (gen-label))
- ,@(gen-other-immediate-test
- temp (if not-p not-target target)
- fall-through nil immed)
- (emit-label ,fall-through))))
- (gen-other-immediate-test temp target not-target not-p immed))))
- (when fixnump
- `((inst andcc zero-tn ,reg fixnum-tag-mask)
- ,(if (or lowtags hdrs)
- `(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
- (if hdrs
- (let ((fall-through (gensym)))
- `((let ((,fall-through (gen-label)))
- ,@(gen-range-test temp (if not-p not-target target)
- fall-through nil
- 0 1 (1- lowtag-limit) lowtags)
- (emit-label ,fall-through))))
- (gen-range-test temp target not-target not-p 0 1
- (1- lowtag-limit) lowtags)))
- (when hdrs
- `((inst cmp ,temp ,lowtag)
- (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))))))