1 ;;;; type testing and checking VOPs for the Alpha VM
3 ;;;; This software is part of the SBCL system. See the README file for
6 ;;;; This software is derived from the CMU CL system, which was
7 ;;;; written at Carnegie Mellon University and released into the
8 ;;;; public domain. The software is in the public domain and is
9 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
10 ;;;; files for more information.
14 (defun %test-fixnum
(value target not-p
&key temp
)
16 (inst and value fixnum-tag-mask temp
)
18 (inst bne temp target
)
19 (inst beq temp target
))))
21 (defun %test-fixnum-and-headers
(value target not-p headers
&key temp
)
22 (let ((drop-through (gen-label)))
24 (inst and value fixnum-tag-mask temp
)
25 (inst beq temp
(if not-p drop-through target
)))
26 (%test-headers value target not-p nil headers
27 :drop-through drop-through
:temp temp
)))
29 (defun %test-immediate
(value target not-p immediate
&key temp
)
31 (inst and value
255 temp
)
32 (inst xor temp immediate temp
)
34 (inst bne temp target
)
35 (inst beq temp target
))))
37 (defun %test-lowtag
(value target not-p lowtag
&key temp
)
39 (inst and value lowtag-mask temp
)
40 (inst xor temp lowtag temp
)
42 (inst bne temp target
)
43 (inst beq temp target
))))
45 (defun %test-headers
(value target not-p function-p headers
46 &key
(drop-through (gen-label)) temp
)
47 (let ((lowtag (if function-p fun-pointer-lowtag other-pointer-lowtag
)))
49 (when-true when-false
)
50 ;; WHEN-TRUE and WHEN-FALSE are the labels to branch to when
51 ;; we know it's true and when we know it's false respectively.
53 (values drop-through target
)
54 (values target drop-through
))
56 (%test-lowtag value when-false t lowtag
:temp temp
)
57 (load-type temp value
(- lowtag
))
59 (do ((remaining headers
(cdr remaining
)))
61 (let ((header (car remaining
))
62 (last (null (cdr remaining
))))
65 (inst subq temp
(- header delta
) temp
)
69 (inst bne temp target
)
70 (inst beq temp target
))
71 (inst beq temp when-true
)))
73 (let ((start (car header
))
75 (unless (= start bignum-widetag
)
76 (inst subq temp
(- start delta
) temp
)
78 (inst blt temp when-false
))
79 (inst subq temp
(- end delta
) temp
)
83 (inst bgt temp target
)
84 (inst ble temp target
))
85 (inst ble temp when-true
))))))))
86 (emit-label drop-through
)))))
88 ;;;; Other integer ranges.
90 ;;; A (signed-byte 32) can be represented with either fixnum or a bignum with
91 ;;; exactly one digit.
92 (define-vop (signed-byte-32-p type-predicate
)
93 (:translate signed-byte-32-p
)
94 (:temporary
(:scs
(non-descriptor-reg)) temp1
)
99 (values not-target target
)
100 (values target not-target
))
102 (inst and value fixnum-tag-mask temp
)
104 (inst and value lowtag-mask temp
)
105 (inst xor temp other-pointer-lowtag temp
)
107 (loadw temp value
0 other-pointer-lowtag
)
108 (inst li
(+ (ash 1 n-widetag-bits
) bignum-widetag
) temp1
)
109 (inst xor temp temp1 temp
)
111 (inst bne temp target
)
112 (inst beq temp target
))))
115 ;;; An (unsigned-byte 32) can be represented with either a positive fixnum, a
116 ;;; bignum with exactly one positive digit, or a bignum with exactly two digits
117 ;;; and the second digit all zeros.
119 (define-vop (unsigned-byte-32-p type-predicate
)
120 (:translate unsigned-byte-32-p
)
121 (:temporary
(:scs
(non-descriptor-reg)) temp1
)
123 (multiple-value-bind (yep nope
)
125 (values not-target target
)
126 (values target not-target
))
129 (inst and value fixnum-tag-mask temp1
)
130 (inst move value temp
)
131 (inst beq temp1 fixnum
)
133 ;; If not, is it an other pointer?
134 (inst and value lowtag-mask temp
)
135 (inst xor temp other-pointer-lowtag temp
)
138 (loadw temp value
0 other-pointer-lowtag
)
140 (inst li
(+ (ash 1 n-widetag-bits
) bignum-widetag
) temp1
)
141 (inst xor temp temp1 temp
)
142 (inst beq temp single-word
)
143 ;; If it's other than two, we can't be an (unsigned-byte 32)
144 (inst li
(logxor (+ (ash 1 n-widetag-bits
) bignum-widetag
)
145 (+ (ash 2 n-widetag-bits
) bignum-widetag
))
147 (inst xor temp temp1 temp
)
149 ;; Get the second digit.
150 (loadw temp value
(1+ bignum-digits-offset
) other-pointer-lowtag
)
151 ;; All zeros, its an (unsigned-byte 32).
153 (inst br zero-tn nope
)
156 ;; Get the single digit.
157 (loadw temp value bignum-digits-offset other-pointer-lowtag
)
159 ;; positive implies (unsigned-byte 32).
162 (inst blt temp target
)
163 (inst bge temp target
))))
166 ;;;; List/symbol types:
168 ;;; symbolp (or symbol (eq nil))
169 ;;; consp (and list (not (eq nil)))
171 (define-vop (symbolp type-predicate
)
173 (:temporary
(:scs
(non-descriptor-reg)) temp
)
175 (inst cmpeq value null-tn temp
)
176 (inst bne temp
(if not-p drop-thru target
))
177 (test-type value target not-p
(symbol-widetag) :temp temp
)
180 (define-vop (consp type-predicate
)
182 (:temporary
(:scs
(non-descriptor-reg)) temp
)
184 (inst cmpeq value null-tn temp
)
185 (inst bne temp
(if not-p target drop-thru
))
186 (test-type value target not-p
(list-pointer-lowtag) :temp temp
)