0.8.12.16:
[sbcl.git] / src / compiler / x86-64 / vm.lisp
1 ;;;; miscellaneous VM definition noise for the x86-64
2
3 ;;;; This software is part of the SBCL system. See the README file for
4 ;;;; more information.
5 ;;;;
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.
11
12 (in-package "SB!VM")
13
14 ;;; the size of an INTEGER representation of a SYSTEM-AREA-POINTER, i.e.
15 ;;; size of a native memory address
16 (deftype sap-int () '(unsigned-byte 64))
17 \f
18 ;;;; register specs
19
20 (eval-when (:compile-toplevel :load-toplevel :execute)
21   (defvar *byte-register-names* (make-array 8 :initial-element nil))
22   (defvar *word-register-names* (make-array 16 :initial-element nil))
23   (defvar *dword-register-names* (make-array 16 :initial-element nil))
24   (defvar *qword-register-names* (make-array 32 :initial-element nil))
25   (defvar *xmm-register-names* (make-array 16 :initial-element nil)))
26
27 (macrolet ((defreg (name offset size)
28              (let ((offset-sym (symbolicate name "-OFFSET"))
29                    (names-vector (symbolicate "*" size "-REGISTER-NAMES*")))
30                `(progn
31                   (eval-when (:compile-toplevel :load-toplevel :execute)
32                     ;; EVAL-WHEN is necessary because stuff like #.EAX-OFFSET
33                     ;; (in the same file) depends on compile-time evaluation
34                     ;; of the DEFCONSTANT. -- AL 20010224
35                     (def!constant ,offset-sym ,offset))
36                   (setf (svref ,names-vector ,offset-sym)
37                         ,(symbol-name name)))))
38            ;; FIXME: It looks to me as though DEFREGSET should also
39            ;; define the related *FOO-REGISTER-NAMES* variable.
40            (defregset (name &rest regs)
41              `(eval-when (:compile-toplevel :load-toplevel :execute)
42                 (defparameter ,name
43                   (list ,@(mapcar (lambda (name)
44                                     (symbolicate name "-OFFSET"))
45                                   regs))))))
46
47   ;; byte registers
48   ;;
49   ;; Note: the encoding here is different than that used by the chip.
50   ;; We use this encoding so that the compiler thinks that AX (and
51   ;; EAX) overlap AL and AH instead of AL and CL.
52   (defreg al 0 :byte)
53   (defreg ah 1 :byte)
54   (defreg cl 2 :byte)
55   (defreg ch 3 :byte)
56   (defreg dl 4 :byte)
57   (defreg dh 5 :byte)
58   (defreg bl 6 :byte)
59   (defreg bh 7 :byte)
60   (defregset *byte-regs* al ah cl ch dl dh bl bh)
61
62   ;; word registers
63   (defreg ax 0 :word)
64   (defreg cx 2 :word)
65   (defreg dx 4 :word)
66   (defreg bx 6 :word)
67   (defreg sp 8 :word)
68   (defreg bp 10 :word)
69   (defreg si 12 :word)
70   (defreg di 14 :word)
71   (defregset *word-regs* ax cx dx bx si di)
72
73   ;; double word registers
74   (defreg eax 0 :dword)
75   (defreg ecx 2 :dword)
76   (defreg edx 4 :dword)
77   (defreg ebx 6 :dword)
78   (defreg esp 8 :dword)
79   (defreg ebp 10 :dword)
80   (defreg esi 12 :dword)
81   (defreg edi 14 :dword)
82   (defregset *dword-regs* eax ecx edx ebx esi edi)
83
84   ;; quadword registers
85   (defreg rax 0 :qword)
86   (defreg rcx 2 :qword)
87   (defreg rdx 4 :qword)
88   (defreg rbx 6 :qword)
89   (defreg rsp 8 :qword)
90   (defreg rbp 10 :qword)
91   (defreg rsi 12 :qword)
92   (defreg rdi 14 :qword)
93   (defreg r8  16 :qword)
94   (defreg r9  18 :qword)
95   (defreg r10 20 :qword)
96   (defreg r11 22 :qword)
97   (defreg r12 24 :qword)
98   (defreg r13 26 :qword)
99   (defreg r14 28 :qword)
100   (defreg r15 30 :qword)
101   (defregset *qword-regs* rax rcx rdx rbx rsi rdi 
102              r8 r9 r10 r11 #+nil r12 #+nil r13 r14 r15)
103
104   ;; floating point registers
105   (defreg xmm0 0 :float)
106   (defreg xmm1 1 :float)
107   (defreg xmm2 2 :float)
108   (defreg xmm3 3 :float)
109   (defreg xmm4 4 :float)
110   (defreg xmm5 5 :float)
111   (defreg xmm6 6 :float)
112   (defreg xmm7 7 :float)
113   (defreg xmm8 8 :float)
114   (defreg xmm9 9 :float)
115   (defreg xmm10 10 :float)
116   (defreg xmm11 11 :float)
117   (defreg xmm12 12 :float)
118   (defreg xmm13 13 :float)
119   (defreg xmm14 14 :float)
120   (defreg xmm15 15 :float)
121   (defregset *xmm-regs* xmm0 xmm1 xmm2 xmm3 xmm4 xmm5 xmm6 xmm7
122              xmm8 xmm9 xmm10 xmm11 xmm12 xmm13 xmm14 xmm15)
123
124   ;; registers used to pass arguments
125   ;;
126   ;; the number of arguments/return values passed in registers
127   (def!constant  register-arg-count 3)
128   ;; names and offsets for registers used to pass arguments
129   (eval-when (:compile-toplevel :load-toplevel :execute)
130     (defparameter *register-arg-names* '(rdx rdi rsi)))
131   (defregset    *register-arg-offsets* rdx rdi rsi))
132 \f
133 ;;;; SB definitions
134
135 ;;; There are 16 registers really, but we consider them 32 in order to
136 ;;; describe the overlap of byte registers. The only thing we need to
137 ;;; represent is what registers overlap. Therefore, we consider bytes
138 ;;; to take one unit, and [dq]?words to take two. We don't need to
139 ;;; tell the difference between [dq]?words, because you can't put two
140 ;;; words in a dword register.
141 (define-storage-base registers :finite :size 32)
142
143 (define-storage-base xmm-registers :finite :size 16)
144
145 (define-storage-base stack :unbounded :size 8)
146 (define-storage-base constant :non-packed)
147 (define-storage-base immediate-constant :non-packed)
148 (define-storage-base noise :unbounded :size 2)
149 \f
150 ;;;; SC definitions
151
152 ;;; a handy macro so we don't have to keep changing all the numbers whenever
153 ;;; we insert a new storage class
154 ;;;
155 (defmacro !define-storage-classes (&rest classes)
156   (collect ((forms))
157     (let ((index 0))
158       (dolist (class classes)
159         (let* ((sc-name (car class))
160                (constant-name (symbolicate sc-name "-SC-NUMBER")))
161           (forms `(define-storage-class ,sc-name ,index
162                     ,@(cdr class)))
163           (forms `(def!constant ,constant-name ,index))
164           (incf index))))
165     `(progn
166        ,@(forms))))
167
168 ;;; The DEFINE-STORAGE-CLASS call for CATCH-BLOCK refers to the size
169 ;;; of CATCH-BLOCK. The size of CATCH-BLOCK isn't calculated until
170 ;;; later in the build process, and the calculation is entangled with
171 ;;; code which has lots of predependencies, including dependencies on
172 ;;; the prior call of DEFINE-STORAGE-CLASS. The proper way to
173 ;;; unscramble this would be to untangle the code, so that the code
174 ;;; which calculates the size of CATCH-BLOCK can be separated from the
175 ;;; other lots-of-dependencies code, so that the code which calculates
176 ;;; the size of CATCH-BLOCK can be executed early, so that this value
177 ;;; is known properly at this point in compilation. However, that
178 ;;; would be a lot of editing of code that I (WHN 19990131) can't test
179 ;;; until the project is complete. So instead, I set the correct value
180 ;;; by hand here (a sort of nondeterministic guess of the right
181 ;;; answer:-) and add an assertion later, after the value is
182 ;;; calculated, that the original guess was correct.
183 ;;;
184 ;;; (What a KLUDGE! Anyone who wants to come in and clean up this mess
185 ;;; has my gratitude.) (FIXME: Maybe this should be me..)
186 (eval-when (:compile-toplevel :load-toplevel :execute)
187   (def!constant kludge-nondeterministic-catch-block-size 6))
188
189 (!define-storage-classes
190
191   ;; non-immediate constants in the constant pool
192   (constant constant)
193
194   (immediate immediate-constant)
195
196   ;;
197   ;; the stacks
198   ;;
199   
200   ;; the control stack
201   (control-stack stack)                 ; may be pointers, scanned by GC
202
203   ;; the non-descriptor stacks
204   ;; XXX alpha backend has :element-size 2 :alignment 2 in these entries
205   (signed-stack stack)                  ; (signed-byte 32)
206   (unsigned-stack stack)                ; (unsigned-byte 32)
207   (base-char-stack stack)               ; non-descriptor characters.
208   (sap-stack stack)                     ; System area pointers.
209   (single-stack stack)                  ; single-floats
210   (double-stack stack)
211   (complex-single-stack stack :element-size 2)  ; complex-single-floats
212   (complex-double-stack stack :element-size 2)  ; complex-double-floats
213
214
215   ;;
216   ;; magic SCs
217   ;;
218
219   (ignore-me noise)
220
221   ;;
222   ;; things that can go in the integer registers
223   ;;
224
225   ;; On the X86, we don't have to distinguish between descriptor and
226   ;; non-descriptor registers, because of the conservative GC.
227   ;; Therefore, we use different scs only to distinguish between
228   ;; descriptor and non-descriptor values and to specify size.
229
230   ;; immediate descriptor objects. Don't have to be seen by GC, but nothing
231   ;; bad will happen if they are. (fixnums, characters, header values, etc).
232   (any-reg registers
233            :locations #.*qword-regs*
234            :element-size 2 ; I think this is for the al/ah overlap thing
235            :constant-scs (immediate)
236            :save-p t
237            :alternate-scs (control-stack))
238
239   ;; pointer descriptor objects -- must be seen by GC
240   (descriptor-reg registers
241                   :locations #.*qword-regs*
242                   :element-size 2
243 ;                 :reserve-locations (#.eax-offset)
244                   :constant-scs (constant immediate)
245                   :save-p t
246                   :alternate-scs (control-stack))
247
248   ;; non-descriptor characters
249   (base-char-reg registers
250                  :locations #.*byte-regs*
251                  :reserve-locations (#.ah-offset #.al-offset)
252                  :constant-scs (immediate)
253                  :save-p t
254                  :alternate-scs (base-char-stack))
255
256   ;; non-descriptor SAPs (arbitrary pointers into address space)
257   (sap-reg registers
258            :locations #.*qword-regs*
259            :element-size 2
260 ;          :reserve-locations (#.eax-offset)
261            :constant-scs (immediate)
262            :save-p t
263            :alternate-scs (sap-stack))
264
265   ;; non-descriptor (signed or unsigned) numbers
266   (signed-reg registers
267               :locations #.*qword-regs*
268               :element-size 2
269               :constant-scs (immediate)
270               :save-p t
271               :alternate-scs (signed-stack))
272   (unsigned-reg registers
273                 :locations #.*qword-regs*
274                 :element-size 2
275                 :constant-scs (immediate)
276                 :save-p t
277                 :alternate-scs (unsigned-stack))
278
279   ;; miscellaneous objects that must not be seen by GC. Used only as
280   ;; temporaries.
281   (word-reg registers
282             :locations #.*word-regs*
283             :element-size 2
284             )
285   (dword-reg registers
286             :locations #.*dword-regs*
287             :element-size 2
288             )
289   (byte-reg registers
290             :locations #.*byte-regs*
291             )
292
293   ;; that can go in the floating point registers
294
295   ;; non-descriptor SINGLE-FLOATs
296   (single-reg xmm-registers
297               :locations #.(loop for i from 0 to 15 collect i)
298               :constant-scs (fp-constant)
299               :save-p t
300               :alternate-scs (single-stack))
301
302   ;; non-descriptor DOUBLE-FLOATs
303   (double-reg xmm-registers
304               :locations #.(loop for i from 0 to 15 collect i)
305               :constant-scs (fp-constant)
306               :save-p t
307               :alternate-scs (double-stack))
308
309   (complex-single-reg xmm-registers
310                       :locations #.(loop for i from 0 to 14 by 2 collect i)
311                       :element-size 2
312                       :constant-scs ()
313                       :save-p t
314                       :alternate-scs (complex-single-stack))
315
316   (complex-double-reg xmm-registers
317                       :locations #.(loop for i from 0 to 14 by 2 collect i)
318                       :element-size 2
319                       :constant-scs ()
320                       :save-p t
321                       :alternate-scs (complex-double-stack))
322
323   ;; a catch or unwind block
324   (catch-block stack :element-size kludge-nondeterministic-catch-block-size))
325
326 (eval-when (:compile-toplevel :load-toplevel :execute)
327 (defparameter *byte-sc-names* '(base-char-reg byte-reg base-char-stack))
328 (defparameter *word-sc-names* '(word-reg))
329 (defparameter *dword-sc-names* '(dword-reg))
330 (defparameter *qword-sc-names* 
331   '(any-reg descriptor-reg sap-reg signed-reg unsigned-reg control-stack
332     signed-stack unsigned-stack sap-stack single-stack constant))
333 ;;; added by jrd. I guess the right thing to do is to treat floats
334 ;;; as a separate size...
335 ;;;
336 ;;; These are used to (at least) determine operand size.
337 (defparameter *float-sc-names* '(single-reg))
338 (defparameter *double-sc-names* '(double-reg double-stack))
339 ) ; EVAL-WHEN
340 \f
341 ;;;; miscellaneous TNs for the various registers
342
343 (macrolet ((def-misc-reg-tns (sc-name &rest reg-names)
344              (collect ((forms))
345                       (dolist (reg-name reg-names)
346                         (let ((tn-name (symbolicate reg-name "-TN"))
347                               (offset-name (symbolicate reg-name "-OFFSET")))
348                           ;; FIXME: It'd be good to have the special
349                           ;; variables here be named with the *FOO*
350                           ;; convention.
351                           (forms `(defparameter ,tn-name
352                                     (make-random-tn :kind :normal
353                                                     :sc (sc-or-lose ',sc-name)
354                                                     :offset
355                                                     ,offset-name)))))
356                       `(progn ,@(forms)))))
357
358   (def-misc-reg-tns unsigned-reg rax rbx rcx rdx rbp rsp rdi rsi
359                     r8 r9 r10 r11  r12 r13 r14 r15)
360   (def-misc-reg-tns dword-reg eax ebx ecx edx ebp esp edi esi)
361   (def-misc-reg-tns word-reg ax bx cx dx bp sp di si)
362   (def-misc-reg-tns byte-reg al ah bl bh cl ch dl dh)
363   (def-misc-reg-tns single-reg 
364       xmm0 xmm1 xmm2 xmm3 xmm4 xmm5 xmm6 xmm7
365       xmm8 xmm9 xmm10 xmm11 xmm12 xmm13 xmm14 xmm15))
366
367 ;;; TNs for registers used to pass arguments
368 (defparameter *register-arg-tns*
369   (mapcar (lambda (register-arg-name)
370             (symbol-value (symbolicate register-arg-name "-TN")))
371           *register-arg-names*))
372
373
374 (defparameter fp-single-zero-tn
375   (make-random-tn :kind :normal
376                   :sc (sc-or-lose 'single-reg)
377                   :offset 15))
378
379 (defparameter fp-double-zero-tn
380   (make-random-tn :kind :normal
381                   :sc (sc-or-lose 'double-reg)
382                   :offset 15))
383
384 ;;; If value can be represented as an immediate constant, then return
385 ;;; the appropriate SC number, otherwise return NIL.
386 (!def-vm-support-routine immediate-constant-sc (value)
387   (typecase value
388     ((or (integer #.sb!xc:most-negative-fixnum #.sb!xc:most-positive-fixnum)
389          #-sb-xc-host system-area-pointer character)
390      (sc-number-or-lose 'immediate))
391     (symbol
392      (when (static-symbol-p value)
393        (sc-number-or-lose 'immediate)))
394     (single-float
395      (if (eql value 0f0)
396          (sc-number-or-lose 'fp-single-zero )
397          nil))
398     (double-float
399      (if (eql value 0d0)
400          (sc-number-or-lose 'fp-double-zero )
401          nil))))
402
403 \f
404 ;;;; miscellaneous function call parameters
405
406 ;;; offsets of special stack frame locations
407 (def!constant ocfp-save-offset 0)
408 (def!constant return-pc-save-offset 1)
409 (def!constant code-save-offset 2)
410
411 (def!constant lra-save-offset return-pc-save-offset) ; ?
412
413 ;;; This is used by the debugger.
414 (def!constant single-value-return-byte-offset 3)
415 \f
416 ;;; This function is called by debug output routines that want a pretty name
417 ;;; for a TN's location. It returns a thing that can be printed with PRINC.
418 (!def-vm-support-routine location-print-name (tn)
419   (declare (type tn tn))
420   (let* ((sc (tn-sc tn))
421          (sb (sb-name (sc-sb sc)))
422          (offset (tn-offset tn)))
423     (ecase sb
424       (registers
425        (let* ((sc-name (sc-name sc))
426               (name-vec (cond ((member sc-name *byte-sc-names*)
427                                *byte-register-names*)
428                               ((member sc-name *word-sc-names*)
429                                *word-register-names*)
430                               ((member sc-name *dword-sc-names*)
431                                *dword-register-names*)
432                               ((member sc-name *qword-sc-names*)
433                                *qword-register-names*))))
434          (or (and name-vec
435                   (< -1 offset (length name-vec))
436                   (svref name-vec offset))
437              ;; FIXME: Shouldn't this be an ERROR?
438              (format nil "<unknown reg: off=~W, sc=~A>" offset sc-name))))
439       (float-registers (format nil "FR~D" offset))
440       (stack (format nil "S~D" offset))
441       (constant (format nil "Const~D" offset))
442       (immediate-constant "Immed")
443       (noise (symbol-name (sc-name sc))))))
444 ;;; FIXME: Could this, and everything that uses it, be made #!+SB-SHOW?
445
446 \f
447 ;;; The loader uses this to convert alien names to the form they need in
448 ;;; the symbol table (for example, prepending an underscore).
449 (defun extern-alien-name (name)
450   (declare (type simple-base-string name))
451   ;; OpenBSD is non-ELF, and needs a _ prefix
452   #!+openbsd (concatenate 'string "_" name)
453   ;; The other (ELF) ports currently don't need any prefix
454   #!-openbsd name)
455
456 (defun dwords-for-quad (value)
457   (let* ((lo (logand value (1- (ash 1 32))))
458          (hi (ash (- value lo) -32)))
459     (values lo hi)))