-
-(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
- sb!vm:fun-pointer-lowtag
- sb!vm:other-pointer-lowtag))
- (hdrs (sort (copy-list hdrs) #'<))
- (immed (sort (copy-list immed) #'<)))
- (append
- (when immed
- `((inst andi. ,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 andi. ,temp ,reg 3)
- ,(if (or lowtags hdrs)
- `(inst beq ,(if not-p not-target target))
- `(inst b? ,(if not-p :ne :eq) ,target))))
- (when (or lowtags hdrs)
- `((inst andi. ,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 cmpwi ,temp ,lowtag)
- (inst bne ,(if not-p target not-target))
- (load-type ,temp ,reg (- ,lowtag))
- ,@(gen-other-immediate-test temp target not-target not-p hdrs))))))
-
-(defparameter immediate-types
- (list base-char-widetag unbound-marker-widetag))
-
-(defparameter function-subtypes
- (list funcallable-instance-header-widetag
- simple-fun-header-widetag closure-fun-header-widetag
- closure-header-widetag))
-
-(defmacro test-type (register temp target not-p &rest type-codes)
- (let* ((type-codes (mapcar #'eval type-codes))
- (lowtags (remove lowtag-limit type-codes :test #'<))
- (extended (remove lowtag-limit type-codes :test #'>))
- (immediates (intersection extended immediate-types :test #'eql))
- (headers (set-difference extended immediate-types :test #'eql))
- (function-p nil))
- (unless type-codes
- (error "Must supply at least on type for test-type."))
- (when (and headers (member other-pointer-lowtag lowtags))
- (warn "OTHER-POINTER-LOWTAG supersedes the use of ~S" headers)
- (setf headers nil))
- (when (and immediates
- (or (member other-immediate-0-lowtag lowtags)
- (member other-immediate-1-lowtag lowtags)))
- (warn "OTHER-IMMEDIATE-n-LOWTAG supersedes the use of ~S" immediates)
- (setf immediates nil))
- (when (intersection headers function-subtypes)
- (unless (subsetp headers function-subtypes)
- (error "Can't test for mix of function subtypes and normal ~
- header types."))
- (setq function-p t))
-
- (let ((n-reg (gensym))
- (n-temp (gensym))
- (n-target (gensym))
- (not-target (gensym)))
- `(let ((,n-reg ,register)
- (,n-temp ,temp)
- (,n-target ,target)
- (,not-target (gen-label)))
- (declare (ignorable ,n-temp))
- ,@(if (constantp not-p)
- (test-type-aux n-reg n-temp n-target not-target
- (eval not-p) lowtags immediates headers
- function-p)
- `((cond (,not-p
- ,@(test-type-aux n-reg n-temp n-target not-target t
- lowtags immediates headers
- function-p))
- (t
- ,@(test-type-aux n-reg n-temp n-target not-target nil
- lowtags immediates headers
- function-p)))))
- (emit-label ,not-target)))))
-|#