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")
29 (!def-primitive-type unsigned-byte-31
(signed-reg unsigned-reg descriptor-reg
)
30 :type
(unsigned-byte 31))
31 (/show0
"primtype.lisp 31")
33 (!def-primitive-type unsigned-byte-32
(unsigned-reg descriptor-reg
)
34 :type
(unsigned-byte 32))
35 (/show0
"primtype.lisp 35")
37 (!def-primitive-type unsigned-byte-63
(signed-reg unsigned-reg descriptor-reg
)
38 :type
(unsigned-byte 63))
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+ n-positive-fixnum-bits
)))
45 (!def-primitive-type signed-byte-32
(signed-reg descriptor-reg
)
46 :type
(signed-byte 32))
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
))
55 (multiple-value-bind (unsigned signed
)
56 (case sb
!vm
::n-machine-word-bits
57 (64 (values '(unsigned-byte-64 unsigned-byte-63 positive-fixnum
)
58 '(signed-byte-64 fixnum unsigned-byte-63 positive-fixnum
)))
59 (32 (values '(unsigned-byte-32 unsigned-byte-31 positive-fixnum
)
60 '(signed-byte-32 fixnum unsigned-byte-31 positive-fixnum
))))
61 (!def-primitive-type-alias unsigned-num
`(:or
,@unsigned
))
62 (!def-primitive-type-alias signed-num
`(:or
,@signed
))
63 (!def-primitive-type-alias untagged-num
64 `(:or
,@(sort (copy-list (union unsigned signed
)) #'string
<))))
66 ;;; other primitive immediate types
67 (/show0
"primtype.lisp 68")
68 (!def-primitive-type character
(character-reg any-reg
))
70 ;;; primitive pointer types
71 (/show0
"primtype.lisp 73")
72 (!def-primitive-type function
(descriptor-reg))
73 (!def-primitive-type list
(descriptor-reg))
74 (!def-primitive-type instance
(descriptor-reg))
76 (/show0
"primtype.lisp 77")
77 (!def-primitive-type funcallable-instance
(descriptor-reg))
79 ;;; primitive other-pointer number types
80 (/show0
"primtype.lisp 81")
81 (!def-primitive-type bignum
(descriptor-reg))
82 (!def-primitive-type ratio
(descriptor-reg))
83 (!def-primitive-type complex
(descriptor-reg))
84 (/show0
"about to !DEF-PRIMITIVE-TYPE SINGLE-FLOAT")
85 (!def-primitive-type single-float
(single-reg descriptor-reg
))
86 (/show0
"about to !DEF-PRIMITIVE-TYPE DOUBLE-FLOAT")
87 (!def-primitive-type double-float
(double-reg descriptor-reg
))
89 (/show0
"about to !DEF-PRIMITIVE-TYPE COMPLEX-SINGLE-FLOAT")
90 (!def-primitive-type complex-single-float
(complex-single-reg descriptor-reg
)
91 :type
(complex single-float
))
92 (/show0
"about to !DEF-PRIMITIVE-TYPE COMPLEX-DOUBLE-FLOAT")
93 (!def-primitive-type complex-double-float
(complex-double-reg descriptor-reg
)
94 :type
(complex double-float
))
97 (/show0
"about to !DEF-PRIMITIVE-TYPE SIMD-PACK")
98 (!def-primitive-type simd-pack-single
(single-sse-reg descriptor-reg
)
99 :type
(simd-pack single-float
))
100 (!def-primitive-type simd-pack-double
(double-sse-reg descriptor-reg
)
101 :type
(simd-pack double-float
))
102 (!def-primitive-type simd-pack-int
(int-sse-reg descriptor-reg
)
103 :type
(simd-pack integer
))
104 (!def-primitive-type-alias simd-pack
105 '(:or simd-pack-single simd-pack-double simd-pack-int
)))
107 ;;; primitive other-pointer array types
108 (/show0
"primtype.lisp 96")
109 (macrolet ((define-simple-array-primitive-types ()
113 `(!def-primitive-type
114 ,(saetp-primitive-type-name saetp
)
116 :type
(simple-array ,(saetp-specifier saetp
) (*))))
117 *specialized-array-element-type-properties
*))))
118 (define-simple-array-primitive-types))
119 ;;; Note: The complex array types are not included, 'cause it is
120 ;;; pointless to restrict VOPs to them.
122 ;;; other primitive other-pointer types
123 (!def-primitive-type system-area-pointer
(sap-reg descriptor-reg
))
124 (!def-primitive-type weak-pointer
(descriptor-reg))
126 ;;; miscellaneous primitive types that don't exist at the LISP level
127 (!def-primitive-type catch-block
(catch-block) :type nil
)
128 (!def-primitive-type unwind-block
(unwind-block) :type nil
)
130 ;;;; PRIMITIVE-TYPE-OF and friends
132 ;;; Return the most restrictive primitive type that contains OBJECT.
133 (/show0
"primtype.lisp 147")
134 (defun primitive-type-of (object)
135 (let ((type (ctype-of object
)))
136 (cond ((not (member-type-p type
)) (primitive-type type
))
137 ((and (eql 1 (member-type-size type
))
138 (equal (member-type-members type
) '(nil)))
139 (primitive-type-or-lose 'list
))
141 *backend-t-primitive-type
*))))
143 ;;; Return the primitive type corresponding to a type descriptor
144 ;;; structure. The second value is true when the primitive type is
145 ;;; exactly equivalent to the argument Lisp type.
147 ;;; In a bootstrapping situation, we should be careful to use the
148 ;;; correct values for the system parameters.
150 ;;; Meta: the following comment is not true. Should remove the AUX fn.
151 ;;; We need an aux function because we need to use both
152 ;;; !DEF-VM-SUPPORT-ROUTINE and DEFUN-CACHED.
153 (/show0
"primtype.lisp 188")
154 (defun primitive-type (type)
155 (sb!kernel
::maybe-reparse-specifier
! type
)
156 (primitive-type-aux type
))
157 (/show0
"primtype.lisp 191")
158 (defun-cached (primitive-type-aux
159 :hash-function
#'type-hash-value
163 (declare (type ctype type
))
164 (macrolet ((any () '(values *backend-t-primitive-type
* nil
))
166 `(values (primitive-type-or-lose ',type
) t
))
168 `(values (primitive-type-or-lose ',type
) nil
)))
169 (flet ((maybe-numeric-type-union (t1 t2
)
170 (let ((t1-name (primitive-type-name t1
))
171 (t2-name (primitive-type-name t2
)))
174 (if (or (eq t2-name
'fixnum
)
176 (ecase n-machine-word-bits
178 (64 'signed-byte-64
)))
180 (ecase n-machine-word-bits
181 (32 'unsigned-byte-31
)
182 (64 'unsigned-byte-63
)))
184 (ecase n-machine-word-bits
185 (32 'unsigned-byte-32
)
186 (64 'unsigned-byte-64
))))
190 (#.
(ecase n-machine-word-bits
192 (64 'signed-byte-64
))
194 (#.
(ecase n-machine-word-bits
195 (32 'unsigned-byte-31
)
196 (64 'unsigned-byte-63
))
197 (primitive-type-or-lose
198 (ecase n-machine-word-bits
200 (64 'signed-byte-64
))))))
201 (#.
(ecase n-machine-word-bits
203 (64 'signed-byte-64
))
205 (ecase n-machine-word-bits
206 (32 'unsigned-byte-31
)
207 (64 'unsigned-byte-63
)))
209 (#.
(ecase n-machine-word-bits
210 (32 'unsigned-byte-31
)
211 (64 'unsigned-byte-63
))
213 (ecase n-machine-word-bits
214 (32 'unsigned-byte-32
)
215 (64 'unsigned-byte-64
)))
219 (let ((lo (numeric-type-low type
))
220 (hi (numeric-type-high type
)))
221 (case (numeric-type-complexp type
)
223 (case (numeric-type-class type
)
227 `((positive-fixnum 0 ,sb
!xc
:most-positive-fixnum
)
228 ,@(ecase n-machine-word-bits
233 0 ,(1- (ash 1 32)))))
238 0 ,(1- (ash 1 64))))))
239 (fixnum ,sb
!xc
:most-negative-fixnum
240 ,sb
!xc
:most-positive-fixnum
)
241 ,(ecase n-machine-word-bits
243 `(signed-byte-32 ,(ash -
1 31)
246 `(signed-byte-64 ,(ash -
1 63)
248 (if (or (< hi sb
!xc
:most-negative-fixnum
)
249 (> lo sb
!xc
:most-positive-fixnum
))
252 (let ((type (car spec
))
255 (when (<= min lo hi max
)
257 (primitive-type-or-lose type
)
258 (and (= lo min
) (= hi max
))))))))
259 ((or (and hi
(< hi sb
!xc
:most-negative-fixnum
))
260 (and lo
(> lo sb
!xc
:most-positive-fixnum
)))
265 (let ((exact (and (null lo
) (null hi
))))
266 (case (numeric-type-format type
)
267 ((short-float single-float
)
268 (values (primitive-type-or-lose 'single-float
)
271 (values (primitive-type-or-lose 'double-float
)
278 (if (eq (numeric-type-class type
) 'float
)
279 (let ((exact (and (null lo
) (null hi
))))
280 (case (numeric-type-format type
)
281 ((short-float single-float
)
282 (values (primitive-type-or-lose 'complex-single-float
)
284 ((double-float long-float
)
285 (values (primitive-type-or-lose 'complex-double-float
)
293 (if (or (array-type-complexp type
)
294 (not (singleton-p (array-type-dimensions type
))))
296 ;; EQ is ok to compare by because all CTYPEs representing
297 ;; array specializations are interned objects.
298 (let ((saetp (find (array-type-specialized-element-type type
)
299 *specialized-array-element-type-properties
*
300 :key
#'saetp-ctype
:test
#'eq
)))
302 (values (primitive-type-or-lose
303 (saetp-primitive-type-name saetp
))
304 (eq (first (array-type-dimensions type
)) '*))
307 (if (type= type
(specifier-type 'list
))
309 (let ((types (union-type-types type
)))
310 (multiple-value-bind (res exact
) (primitive-type (first types
))
311 (dolist (type (rest types
) (values res exact
))
312 (multiple-value-bind (ptype ptype-exact
)
313 (primitive-type type
)
314 (unless ptype-exact
(setq exact nil
))
315 (unless (eq ptype res
)
317 (or (maybe-numeric-type-union res ptype
)
318 (maybe-numeric-type-union ptype res
))))
321 (return (any)))))))))))
323 (let ((types (intersection-type-types type
))
325 ;; why NIL for the exact? Well, we assume that the
326 ;; intersection type is in fact doing something for us:
327 ;; that is, that each of the types in the intersection is
328 ;; in fact cutting off some of the type lattice. Since no
329 ;; intersection type is represented by a primitive type and
330 ;; primitive types are mutually exclusive, it follows that
331 ;; no intersection type can represent the entirety of the
332 ;; primitive type. (And NIL is the conservative answer,
333 ;; anyway). -- CSR, 2006-09-14
334 (dolist (type types
(values res nil
))
335 (multiple-value-bind (ptype)
336 (primitive-type type
)
338 ;; if the result so far is (any), any improvement on
339 ;; the specificity of the primitive type is valid.
342 ;; if the primitive type returned is (any), the
343 ;; result so far is valid. Likewise, if the
344 ;; primitive type is the same as the result so far,
345 ;; everything is fine.
346 ((or (eq ptype
(any)) (eq ptype res
)))
347 ;; otherwise, we have something hairy and confusing,
348 ;; such as (and condition funcallable-instance).
350 (t (return (any))))))))
354 (mapc-member-type-members
356 (let ((ptype (primitive-type-of member
)))
358 (unless (eq ptype res
)
359 (let ((new-ptype (or (maybe-numeric-type-union res ptype
)
360 (maybe-numeric-type-union ptype res
))))
368 (ecase (named-type-name type
)
369 ((t *) (values *backend-t-primitive-type
* t
))
370 ((instance) (exactly instance
))
371 ((funcallable-instance) (part-of function
))
372 ((extended-sequence) (any))
375 (if (eq type
(specifier-type 'character
))
377 (part-of character
)))
380 (let ((eltypes (simd-pack-type-element-type type
)))
381 (cond ((member 'integer eltypes
)
382 (exactly simd-pack-int
))
383 ((member 'single-float eltypes
)
384 (exactly simd-pack-single
))
385 ((member 'double-float eltypes
)
386 (exactly simd-pack-double
)))))
388 (case (classoid-name type
)
390 ;; Can't tell what specific type; assume integers.
392 (exactly simd-pack-int
))
393 ((complex function system-area-pointer weak-pointer
)
394 (values (primitive-type-or-lose (classoid-name type
)) t
))
402 (if (csubtypep type
(specifier-type 'function
))
406 (if (csubtypep type
(specifier-type 'function
))
410 (/show0
"primtype.lisp end of file")