0.7.13.21:
[sbcl.git] / src / compiler / generic / vm-type.lisp
1 ;;;; This file contains implementation-dependent parts of the type
2 ;;;; support code. This is stuff which deals with the mapping from
3 ;;;; types defined in Common Lisp to types actually supported by an
4 ;;;; implementation.
5
6 ;;;; This software is part of the SBCL system. See the README file for
7 ;;;; more information.
8 ;;;;
9 ;;;; This software is derived from the CMU CL system, which was
10 ;;;; written at Carnegie Mellon University and released into the
11 ;;;; public domain. The software is in the public domain and is
12 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
13 ;;;; files for more information.
14
15 (in-package "SB!KERNEL")
16
17 (/show0 "vm-type.lisp 17")
18
19 (!begin-collecting-cold-init-forms)
20 \f
21 ;;;; FIXME: I'm not sure where to put this. -- WHN 19990817
22
23 (deftype sb!vm:word () `(unsigned-byte ,sb!vm:n-word-bits))
24 \f
25 ;;;; implementation-dependent DEFTYPEs
26
27 ;;; Make DOUBLE-FLOAT a synonym for LONG-FLOAT, SINGLE-FLOAT for
28 ;;; SHORT-FLOAT. This is expanded before the translator gets a chance,
29 ;;; so we will get precedence.
30 #!-long-float
31 (setf (info :type :kind 'long-float) :defined)
32 #!-long-float
33 (sb!xc:deftype long-float (&optional low high)
34   `(double-float ,low ,high))
35 (setf (info :type :kind 'short-float) :defined)
36 (sb!xc:deftype short-float (&optional low high)
37   `(single-float ,low ,high))
38
39 ;;; an index into an integer
40 (sb!xc:deftype bit-index () `(integer 0 ,most-positive-fixnum))
41
42 ;;; worst-case values for float attributes
43 (sb!xc:deftype float-exponent ()
44   #!-long-float 'double-float-exponent
45   #!+long-float 'long-float-exponent)
46 (sb!xc:deftype float-digits ()
47   #!-long-float `(integer 0 ,sb!vm:double-float-digits)
48   #!+long-float `(integer 0 ,sb!vm:long-float-digits))
49 (sb!xc:deftype float-radix () '(integer 2 2))
50
51 ;;; a code for BOOLE
52 (sb!xc:deftype boole-code () '(unsigned-byte 4))
53
54 ;;; a byte specifier (as generated by BYTE)
55 (sb!xc:deftype byte-specifier () 'cons)
56
57 ;;; result of CHAR-INT
58 (sb!xc:deftype char-int () 'char-code)
59
60 ;;; PATHNAME pieces, as returned by the PATHNAME-xxx functions
61 (sb!xc:deftype pathname-host () '(or sb!impl::host null))
62 (sb!xc:deftype pathname-device ()
63   '(or simple-string (member nil :unspecific)))
64 (sb!xc:deftype pathname-directory () 'list)
65 (sb!xc:deftype pathname-name ()
66   '(or simple-string sb!impl::pattern (member nil :unspecific :wild)))
67 (sb!xc:deftype pathname-type ()
68   '(or simple-string sb!impl::pattern (member nil :unspecific :wild)))
69 (sb!xc:deftype pathname-version ()
70   '(or integer (member nil :newest :wild :unspecific)))
71
72 ;;; internal time format. (Note: not a FIXNUM, ouch..)
73 (sb!xc:deftype internal-time () 'unsigned-byte)
74
75 (sb!xc:deftype bignum-element-type () `(unsigned-byte ,sb!vm:n-word-bits))
76 (sb!xc:deftype bignum-type () 'bignum)
77 (sb!xc:deftype bignum-index () 'index)
78 \f
79 ;;;; hooks into the type system
80
81 ;;; the kinds of specialized array that actually exist in this implementation
82 (defvar *specialized-array-element-types*)
83 (!cold-init-forms
84   (setf *specialized-array-element-types*
85         '(nil
86           bit
87           (unsigned-byte 2)
88           (unsigned-byte 4)
89           (unsigned-byte 8)
90           (unsigned-byte 16)
91           (unsigned-byte 32)
92           (signed-byte 8)
93           (signed-byte 16)
94           (signed-byte 30)
95           (signed-byte 32)
96           (complex single-float)
97           (complex double-float)
98           #!+long-float (complex long-float)
99           base-char
100           single-float
101           double-float
102           #!+long-float long-float)))
103
104 (sb!xc:deftype unboxed-array (&optional dims)
105   (collect ((types (list 'or)))
106     (dolist (type *specialized-array-element-types*)
107       (when (subtypep type '(or integer character float (complex float)))
108         (types `(array ,type ,dims))))
109     (types)))
110
111 (sb!xc:deftype simple-unboxed-array (&optional dims)
112   (collect ((types (list 'or)))
113     (dolist (type *specialized-array-element-types*)
114       (when (subtypep type '(or integer character float (complex float)))
115         (types `(simple-array ,type ,dims))))
116     (types)))
117
118 ;;; Return the symbol that describes the format of FLOAT.
119 (declaim (ftype (function (float) symbol) float-format-name))
120 (defun float-format-name (x)
121   (etypecase x
122     (single-float 'single-float)
123     (double-float 'double-float)
124     #!+long-float (long-float 'long-float)))
125
126 ;;; This function is called when the type code wants to find out how
127 ;;; an array will actually be implemented. We set the
128 ;;; SPECIALIZED-ELEMENT-TYPE to correspond to the actual
129 ;;; specialization used in this implementation.
130 (declaim (ftype (function (array-type) array-type) specialize-array-type))
131 (defun specialize-array-type (type)
132   (let ((eltype (array-type-element-type type)))
133     (setf (array-type-specialized-element-type type)
134           (if (or (eq eltype *wild-type*)
135                   ;; This is slightly dubious, but not as dubious as
136                   ;; assuming that the upgraded-element-type should be
137                   ;; equal to T, given the way that the AREF
138                   ;; DERIVE-TYPE optimizer works.  -- CSR, 2002-08-19
139                   (unknown-type-p eltype))
140               *wild-type*
141               (dolist (stype-name *specialized-array-element-types*
142                                   *universal-type*)
143                 ;; FIXME: Mightn't it be better to have
144                 ;; *SPECIALIZED-ARRAY-ELEMENT-TYPES* be stored as precalculated
145                 ;; SPECIFIER-TYPE results, instead of having to calculate
146                 ;; them on the fly this way? (Call the new array
147                 ;; *SPECIALIZED-ARRAY-ELEMENT-SPECIFIER-TYPES* or something..)
148                 (let ((stype (specifier-type stype-name)))
149                   (when (csubtypep eltype stype)
150                     (return stype))))))
151     type))
152
153 ;;; Return the most specific integer type that can be quickly checked that
154 ;;; includes the given type.
155 (defun containing-integer-type (subtype)
156   (dolist (type '(fixnum
157                   (signed-byte 32)
158                   (unsigned-byte 32)
159                   integer)
160                 (error "~S isn't an integer type?" subtype))
161     (when (csubtypep subtype (specifier-type type))
162       (return type))))
163
164 ;;; If TYPE has a CHECK-xxx template, but doesn't have a corresponding
165 ;;; PRIMITIVE-TYPE, then return the template's name. Otherwise, return NIL.
166 (defun hairy-type-check-template-name (type)
167   (declare (type ctype type))
168   (typecase type
169     (cons-type
170      (if (type= type (specifier-type 'cons))
171          'sb!c:check-cons
172          nil))
173     (built-in-class
174      (if (type= type (specifier-type 'symbol))
175          'sb!c:check-symbol
176          nil))
177     (numeric-type
178      (cond ((type= type (specifier-type 'fixnum))
179             'sb!c:check-fixnum)
180            ((type= type (specifier-type '(signed-byte 32)))
181             'sb!c:check-signed-byte-32)
182            ((type= type (specifier-type '(unsigned-byte 32)))
183             'sb!c:check-unsigned-byte-32)
184            (t nil)))
185     (fun-type
186      'sb!c:check-fun)
187     (t
188      nil)))
189 \f
190 (!defun-from-collected-cold-init-forms !vm-type-cold-init)
191
192 (/show0 "vm-type.lisp end of file")