1 ;;;; machine-independent aspects of the object representation and
4 ;;;; This software is part of the SBCL system. See the README file for
7 ;;;; This software is derived from the CMU CL system, which was
8 ;;;; written at Carnegie Mellon University and released into the
9 ;;;; public domain. The software is in the public domain and is
10 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
11 ;;;; files for more information.
15 ;;;; primitive type definitions
17 (/show0
"primtype.lisp 17")
19 (!def-primitive-type t
(descriptor-reg))
20 (/show0
"primtype.lisp 20")
21 (setf *backend-t-primitive-type
* (primitive-type-or-lose t
))
23 ;;; primitive integer types that fit in registers
24 (/show0
"primtype.lisp 24")
25 (!def-primitive-type positive-fixnum
(any-reg signed-reg unsigned-reg
)
26 :type
(unsigned-byte #.sb
!vm
:n-positive-fixnum-bits
))
27 (/show0
"primtype.lisp 27")
28 #!+#.
(cl:if
(cl:= sb
!vm
::n-machine-word-bits
32) '(and) '(or))
29 (!def-primitive-type unsigned-byte-31
(signed-reg unsigned-reg descriptor-reg
)
30 :type
(unsigned-byte 31))
31 (/show0
"primtype.lisp 31")
32 #!+#.
(cl:if
(cl:= sb
!vm
::n-machine-word-bits
32) '(and) '(or))
33 (!def-primitive-type unsigned-byte-32
(unsigned-reg descriptor-reg
)
34 :type
(unsigned-byte 32))
35 (/show0
"primtype.lisp 35")
36 #!+#.
(cl:if
(cl:= sb
!vm
::n-machine-word-bits
64) '(and) '(or))
37 (!def-primitive-type unsigned-byte-63
(signed-reg unsigned-reg descriptor-reg
)
38 :type
(unsigned-byte 63))
39 #!+#.
(cl:if
(cl:= sb
!vm
::n-machine-word-bits
64) '(and) '(or))
40 (!def-primitive-type unsigned-byte-64
(unsigned-reg descriptor-reg
)
41 :type
(unsigned-byte 64))
42 (!def-primitive-type fixnum
(any-reg signed-reg
)
43 :type
(signed-byte #.
(1+ sb
!vm
:n-positive-fixnum-bits
)))
44 #!+#.
(cl:if
(cl:= sb
!vm
::n-machine-word-bits
32) '(and) '(or))
45 (!def-primitive-type signed-byte-32
(signed-reg descriptor-reg
)
46 :type
(signed-byte 32))
47 #!+#.
(cl:if
(cl:= sb
!vm
::n-machine-word-bits
64) '(and) '(or))
48 (!def-primitive-type signed-byte-64
(signed-reg descriptor-reg
)
49 :type
(signed-byte 64))
51 (defvar *fixnum-primitive-type
* (primitive-type-or-lose 'fixnum
))
53 (/show0
"primtype.lisp 53")
54 (!def-primitive-type-alias tagged-num
(:or positive-fixnum fixnum
))
56 (!def-primitive-type-alias unsigned-num
#1=
57 #!+#.
(cl:if
(cl:= sb
!vm
::n-machine-word-bits
64) '(and) '(or))
58 (:or unsigned-byte-64 unsigned-byte-63 positive-fixnum
)
59 #!-
#.
(cl:if
(cl:= sb
!vm
::n-machine-word-bits
64) '(and) '(or))
60 (:or unsigned-byte-32 unsigned-byte-31 positive-fixnum
))
61 (!def-primitive-type-alias signed-num
#2=
62 #!+#.
(cl:if
(cl:= sb
!vm
::n-machine-word-bits
64) '(and) '(or))
63 (:or signed-byte-64 fixnum unsigned-byte-63 positive-fixnum
)
64 #!-
#.
(cl:if
(cl:= sb
!vm
::n-machine-word-bits
64) '(and) '(or))
65 (:or signed-byte-32 fixnum unsigned-byte-31 positive-fixnum
))
66 (!def-primitive-type-alias untagged-num
67 (:or .
#.
(sort (copy-list (union (cdr '#1#) (cdr '#2#))) #'string
<))))
69 ;;; other primitive immediate types
70 (/show0
"primtype.lisp 68")
71 (!def-primitive-type character
(character-reg any-reg
))
73 ;;; primitive pointer types
74 (/show0
"primtype.lisp 73")
75 (!def-primitive-type function
(descriptor-reg))
76 (!def-primitive-type list
(descriptor-reg))
77 (!def-primitive-type instance
(descriptor-reg))
79 (/show0
"primtype.lisp 77")
80 (!def-primitive-type funcallable-instance
(descriptor-reg))
82 ;;; primitive other-pointer number types
83 (/show0
"primtype.lisp 81")
84 (!def-primitive-type bignum
(descriptor-reg))
85 (!def-primitive-type ratio
(descriptor-reg))
86 (!def-primitive-type complex
(descriptor-reg))
87 (/show0
"about to !DEF-PRIMITIVE-TYPE SINGLE-FLOAT")
88 (!def-primitive-type single-float
(single-reg descriptor-reg
))
89 (/show0
"about to !DEF-PRIMITIVE-TYPE DOUBLE-FLOAT")
90 (!def-primitive-type double-float
(double-reg descriptor-reg
))
92 (/show0
"about to !DEF-PRIMITIVE-TYPE COMPLEX-SINGLE-FLOAT")
93 (!def-primitive-type complex-single-float
(complex-single-reg descriptor-reg
)
94 :type
(complex single-float
))
95 (/show0
"about to !DEF-PRIMITIVE-TYPE COMPLEX-DOUBLE-FLOAT")
96 (!def-primitive-type complex-double-float
(complex-double-reg descriptor-reg
)
97 :type
(complex double-float
))
100 (/show0
"about to !DEF-PRIMITIVE-TYPE SSE-PACK")
101 (!def-primitive-type sse-pack
(sse-reg descriptor-reg
)))
103 ;;; primitive other-pointer array types
104 (/show0
"primtype.lisp 96")
105 (macrolet ((define-simple-array-primitive-types ()
109 `(!def-primitive-type
110 ,(saetp-primitive-type-name saetp
)
112 :type
(simple-array ,(saetp-specifier saetp
) (*))))
113 *specialized-array-element-type-properties
*))))
114 (define-simple-array-primitive-types))
115 ;;; Note: The complex array types are not included, 'cause it is
116 ;;; pointless to restrict VOPs to them.
118 ;;; other primitive other-pointer types
119 (!def-primitive-type system-area-pointer
(sap-reg descriptor-reg
))
120 (!def-primitive-type weak-pointer
(descriptor-reg))
122 ;;; miscellaneous primitive types that don't exist at the LISP level
123 (!def-primitive-type catch-block
(catch-block) :type nil
)
125 ;;;; PRIMITIVE-TYPE-OF and friends
127 ;;; Return the most restrictive primitive type that contains OBJECT.
128 (/show0
"primtype.lisp 147")
129 (!def-vm-support-routine primitive-type-of
(object)
130 (let ((type (ctype-of object
)))
131 (cond ((not (member-type-p type
)) (primitive-type type
))
132 ((and (eql 1 (member-type-size type
))
133 (equal (member-type-members type
) '(nil)))
134 (primitive-type-or-lose 'list
))
136 *backend-t-primitive-type
*))))
138 ;;; Return the primitive type corresponding to a type descriptor
139 ;;; structure. The second value is true when the primitive type is
140 ;;; exactly equivalent to the argument Lisp type.
142 ;;; In a bootstrapping situation, we should be careful to use the
143 ;;; correct values for the system parameters.
145 ;;; We need an aux function because we need to use both
146 ;;; !DEF-VM-SUPPORT-ROUTINE and DEFUN-CACHED.
147 (/show0
"primtype.lisp 188")
148 (!def-vm-support-routine primitive-type
(type)
149 (primitive-type-aux type
))
150 (/show0
"primtype.lisp 191")
151 (defun-cached (primitive-type-aux
152 :hash-function
(lambda (x)
153 (logand (type-hash-value x
) #x1FF
))
156 :default
(values nil
:empty
))
158 (declare (type ctype type
))
159 (macrolet ((any () '(values *backend-t-primitive-type
* nil
))
161 `(values (primitive-type-or-lose ',type
) t
))
163 `(values (primitive-type-or-lose ',type
) nil
)))
164 (flet ((maybe-numeric-type-union (t1 t2
)
165 (let ((t1-name (primitive-type-name t1
))
166 (t2-name (primitive-type-name t2
)))
169 (if (or (eq t2-name
'fixnum
)
171 (ecase sb
!vm
::n-machine-word-bits
173 (64 'signed-byte-64
)))
175 (ecase sb
!vm
::n-machine-word-bits
176 (32 'unsigned-byte-31
)
177 (64 'unsigned-byte-63
)))
179 (ecase sb
!vm
::n-machine-word-bits
180 (32 'unsigned-byte-32
)
181 (64 'unsigned-byte-64
))))
185 (#.
(ecase sb
!vm
::n-machine-word-bits
187 (64 'signed-byte-64
))
189 (#.
(ecase sb
!vm
::n-machine-word-bits
190 (32 'unsigned-byte-31
)
191 (64 'unsigned-byte-63
))
192 (primitive-type-or-lose
193 (ecase sb
!vm
::n-machine-word-bits
195 (64 'signed-byte-64
))))))
196 (#.
(ecase sb
!vm
::n-machine-word-bits
198 (64 'signed-byte-64
))
200 (ecase sb
!vm
::n-machine-word-bits
201 (32 'unsigned-byte-31
)
202 (64 'unsigned-byte-63
)))
204 (#.
(ecase sb
!vm
::n-machine-word-bits
205 (32 'unsigned-byte-31
)
206 (64 'unsigned-byte-63
))
208 (ecase sb
!vm
::n-machine-word-bits
209 (32 'unsigned-byte-32
)
210 (64 'unsigned-byte-64
)))
214 (let ((lo (numeric-type-low type
))
215 (hi (numeric-type-high type
)))
216 (case (numeric-type-complexp type
)
218 (case (numeric-type-class type
)
222 `((positive-fixnum 0 ,sb
!xc
:most-positive-fixnum
)
223 ,@(ecase sb
!vm
::n-machine-word-bits
228 0 ,(1- (ash 1 32)))))
233 0 ,(1- (ash 1 64))))))
234 (fixnum ,sb
!xc
:most-negative-fixnum
235 ,sb
!xc
:most-positive-fixnum
)
236 ,(ecase sb
!vm
::n-machine-word-bits
238 `(signed-byte-32 ,(ash -
1 31)
241 `(signed-byte-64 ,(ash -
1 63)
243 (if (or (< hi sb
!xc
:most-negative-fixnum
)
244 (> lo sb
!xc
:most-positive-fixnum
))
247 (let ((type (car spec
))
250 (when (<= min lo hi max
)
252 (primitive-type-or-lose type
)
253 (and (= lo min
) (= hi max
))))))))
254 ((or (and hi
(< hi sb
!xc
:most-negative-fixnum
))
255 (and lo
(> lo sb
!xc
:most-positive-fixnum
)))
260 (let ((exact (and (null lo
) (null hi
))))
261 (case (numeric-type-format type
)
262 ((short-float single-float
)
263 (values (primitive-type-or-lose 'single-float
)
266 (values (primitive-type-or-lose 'double-float
)
273 (if (eq (numeric-type-class type
) 'float
)
274 (let ((exact (and (null lo
) (null hi
))))
275 (case (numeric-type-format type
)
276 ((short-float single-float
)
277 (values (primitive-type-or-lose 'complex-single-float
)
279 ((double-float long-float
)
280 (values (primitive-type-or-lose 'complex-double-float
)
288 (if (array-type-complexp type
)
290 (let* ((dims (array-type-dimensions type
))
291 (etype (array-type-specialized-element-type type
))
292 (type-spec (type-specifier etype
))
293 ;; FIXME: We're _WHAT_? Testing for type equality
294 ;; with a specifier and #'EQUAL? *BOGGLE*. --
296 (ptype (cdr (assoc type-spec
*simple-array-primitive-types
*
298 (if (and (consp dims
) (null (rest dims
)) ptype
)
299 (values (primitive-type-or-lose ptype
)
300 (eq (first dims
) '*))
303 (if (type= type
(specifier-type 'list
))
305 (let ((types (union-type-types type
)))
306 (multiple-value-bind (res exact
) (primitive-type (first types
))
307 (dolist (type (rest types
) (values res exact
))
308 (multiple-value-bind (ptype ptype-exact
)
309 (primitive-type type
)
310 (unless ptype-exact
(setq exact nil
))
311 (unless (eq ptype res
)
313 (or (maybe-numeric-type-union res ptype
)
314 (maybe-numeric-type-union ptype res
))))
317 (return (any)))))))))))
319 (let ((types (intersection-type-types type
))
321 ;; why NIL for the exact? Well, we assume that the
322 ;; intersection type is in fact doing something for us:
323 ;; that is, that each of the types in the intersection is
324 ;; in fact cutting off some of the type lattice. Since no
325 ;; intersection type is represented by a primitive type and
326 ;; primitive types are mutually exclusive, it follows that
327 ;; no intersection type can represent the entirety of the
328 ;; primitive type. (And NIL is the conservative answer,
329 ;; anyway). -- CSR, 2006-09-14
330 (dolist (type types
(values res nil
))
331 (multiple-value-bind (ptype)
332 (primitive-type type
)
334 ;; if the result so far is (any), any improvement on
335 ;; the specificity of the primitive type is valid.
338 ;; if the primitive type returned is (any), the
339 ;; result so far is valid. Likewise, if the
340 ;; primitive type is the same as the result so far,
341 ;; everything is fine.
342 ((or (eq ptype
(any)) (eq ptype res
)))
343 ;; otherwise, we have something hairy and confusing,
344 ;; such as (and condition funcallable-instance).
346 (t (return (any))))))))
350 (mapc-member-type-members
352 (let ((ptype (primitive-type-of member
)))
354 (unless (eq ptype res
)
355 (let ((new-ptype (or (maybe-numeric-type-union res ptype
)
356 (maybe-numeric-type-union ptype res
))))
364 (ecase (named-type-name type
)
365 ((t *) (values *backend-t-primitive-type
* t
))
366 ((instance) (exactly instance
))
367 ((funcallable-instance) (part-of function
))
368 ((extended-sequence) (any))
371 (let ((pairs (character-set-type-pairs type
)))
372 (if (and (= (length pairs
) 1)
374 (= (cdar pairs
) (1- sb
!xc
:char-code-limit
)))
376 (part-of character
))))
378 (case (classoid-name type
)
379 ((complex function sse-pack system-area-pointer weak-pointer
)
380 (values (primitive-type-or-lose (classoid-name type
)) t
))
388 (if (csubtypep type
(specifier-type 'function
))
392 (if (csubtypep type
(specifier-type 'function
))
396 (/show0
"primtype.lisp end of file")