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