source: branches/1.1/ccl/compiler/X86/x86-lapmacros.lisp

Last change on this file was 6469, checked in by Gary Byers, 18 years ago

Support the new (call/ret) calling sequence, new tra/talign scheme.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.1 KB
Line 
1;;;-*- Mode: Lisp; Package: CCL -*-
2;;;
3;;; Copyright (C) 2005, Clozure Associates and contributors.
4;;; This file is part of OpenMCL.
5;;;
6;;; OpenMCL is licensed under the terms of the Lisp Lesser GNU Public
7;;; License , known as the LLGPL and distributed with OpenMCL as the
8;;; file "LICENSE". The LLGPL consists of a preamble and the LGPL,
9;;; which is distributed with OpenMCL as the file "LGPL". Where these
10;;; conflict, the preamble takes precedence.
11;;;
12;;; OpenMCL is referenced in the preamble as the "LIBRARY."
13;;;
14;;; The LLGPL is also available online at
15;;; http://opensource.franz.com/preamble.html
16
17(in-package "CCL")
18
19;;; Comparisons make more sense if arg order is "dest, src", instead
20;;; of the gas/ATT arg order.
21
22(defx86lapmacro rcmp (src dest)
23 `(cmp ,dest ,src))
24
25(defx86lapmacro clrq (reg)
26 `(xorq (% ,reg) (% ,reg)))
27
28(defx86lapmacro set-nargs (n)
29 (if (eql n 0)
30 `(xorw (% nargs) (% nargs))
31 `(movw ($ ',n) (% nargs))))
32
33(defx86lapmacro check-nargs (min &optional (max min))
34 (let* ((ok (gensym)))
35 (if (and max (= max min))
36 `(progn
37 (rcmp (% nargs) ($ ',min))
38 (je.pt ,ok)
39 (uuo-error-wrong-number-of-args)
40 ,ok)
41 (if (null max)
42 (unless (zerop min)
43 `(progn
44 (rcmp (% nargs) ($ ',min))
45 (jae.pt ,ok)
46 (uuo-error-too-few-args)
47 ,ok))
48 (if (zerop min)
49 `(progn
50 (rcmp (% nargs) ($ ',max))
51 (jb.pt ,ok)
52 (uuo-error-too-many-args)
53 ,ok)
54 (let* ((sofar (gensym)))
55 `(progn
56 (rcmp (% nargs) ($ ',min))
57 (jae.pt ,sofar)
58 (uuo-error-too-few-args)
59 ,sofar
60 (rcmp (% nargs) ($ ',max))
61 (jbe.pt ,ok)
62 (uuo-error-too-many-args)
63 ,ok)))))))
64
65
66
67(defx86lapmacro extract-lisptag (node dest)
68 `(progn
69 (movb ($ x8664::tagmask) (%b ,dest))
70 (andb (%b ,node) (%b ,dest))))
71
72(defx86lapmacro extract-fulltag (node dest)
73 `(progn
74 (movb ($ x8664::fulltagmask) (%b ,dest))
75 (andb (%b ,node) (%b ,dest))))
76
77(defx86lapmacro extract-subtag (node dest)
78 `(movb (@ x8664::misc-subtag-offset (% ,node)) (%b ,dest)))
79
80(defx86lapmacro extract-typecode (node dest)
81 ;;; In general, these things are only defined to affect the low
82 ;;; byte of the destination register. This can also affect
83 ;;; the #xff00 byte.
84 (let* ((done (gensym)))
85 `(progn
86 (extract-lisptag ,node ,dest)
87 (rcmp (%b ,dest) ($ x8664::tag-misc))
88 (jne ,done)
89 (movb (@ x8664::misc-subtag-offset (% ,node)) (%b ,dest))
90 ,done)))
91
92(defx86lapmacro trap-unless-typecode= (node tag &optional (immreg 'imm0))
93 (let* ((ok (gensym)))
94 `(progn
95 (extract-typecode ,node ,immreg)
96 (cmpb ($ ,tag) (%b ,immreg))
97 (je.pt ,ok)
98 (uuo-error-reg-not-tag (% ,node) ($ ,tag))
99 ,ok)))
100
101(defx86lapmacro trap-unless-fulltag= (node tag &optional (immreg 'imm0))
102 (let* ((ok (gensym)))
103 `(progn
104 (extract-fulltag ,node ,immreg)
105 (cmpb ($ ,tag) (%b ,immreg))
106 (je.pt ,ok)
107 (uuo-error-reg-not-tag (% ,node) ($ ,tag))
108 ,ok)))
109
110(defx86lapmacro trap-unless-lisptag= (node tag &optional (immreg 'imm0))
111 (let* ((ok (gensym)))
112 `(progn
113 (extract-lisptag ,node ,immreg)
114 (cmpb ($ ,tag) (%b ,immreg))
115 (je.pt ,ok)
116 (uuo-error-reg-not-tag (% ,node) ($ ,tag))
117 ,ok)))
118
119(defx86lapmacro trap-unless-fixnum (node)
120 (let* ((ok (gensym)))
121 `(progn
122 (testb ($ x8664::tagmask) (%b ,node))
123 (je.pt ,ok)
124 (uuo-error-reg-not-fixnum (% ,node))
125 ,ok)))
126
127;;; On x8664, NIL has its own tag, so no other lisp object can
128;;; have the same low byte as NIL. (That probably won't be
129;;; true on x8632.)
130(defx86lapmacro cmp-reg-to-nil (reg)
131 `(cmpb ($ (logand #xff x8664::nil-value)) (%b ,reg)))
132
133
134(defx86lapmacro unbox-fixnum (src dest)
135 `(progn
136 (mov (% ,src) (% ,dest))
137 (sar ($ x8664::fixnumshift) (% ,dest))))
138
139(defx86lapmacro box-fixnum (src dest)
140 `(imulq ($ x8664::fixnumone) (% ,src) (% ,dest)))
141
142
143(defx86lapmacro get-single-float (node dest)
144 `(progn
145 (movd (% ,node) (% ,dest))
146 (psrlq ($ 32) (% ,dest))))
147
148
149;;; Note that this modifies the src argument.
150(defx86lapmacro put-single-float (src node)
151 `(progn
152 (psllq ($ 32) (% ,src))
153 (movd (% ,src) (% ,node))
154 (movb ($ x8664::tag-single-float) (%b ,node))))
155
156(defx86lapmacro get-double-float (src fpreg)
157 `(movsd (@ x8664::double-float.value (% ,src)) (% ,fpreg)))
158
159(defx86lapmacro put-double-float (fpreg dest)
160 `(movsd (% ,fpreg) (@ x8664::double-float.value (% ,dest))))
161
162
163
164(defx86lapmacro getvheader (src dest)
165 `(movq (@ x8664::misc-header-offset (% ,src)) (% ,dest)))
166
167;;; "Size" is unboxed element-count. vheader and dest should
168;;; both be immediate registers
169(defx86lapmacro header-size (vheader dest)
170 `(progn
171 (mov (% ,vheader) (% ,dest))
172 (shr ($ x8664::num-subtag-bits) (% ,dest))))
173
174
175;;; "Length" is fixnum element-count.
176(defx86lapmacro header-length (vheader dest)
177 `(progn
178 (movq ($ (lognot 255)) (% ,dest))
179 (andq (% ,vheader) (% ,dest))
180 (shr ($ (- x8664::num-subtag-bits x8664::fixnumshift)) (% ,dest))))
181
182(defx86lapmacro header-subtag[fixnum] (vheader dest)
183 `(progn
184 (lea (@ (% ,vheader) 8) (% ,dest))
185 (andl ($ '255) (%l ,dest))))
186
187(defx86lapmacro vector-size (vector vheader dest)
188 `(progn
189 (getvheader ,vector ,vheader)
190 (header-size ,vheader ,dest)))
191
192(defx86lapmacro vector-length (vector dest)
193 `(progn
194 (movq ($ (lognot 255)) (% ,dest))
195 (andq (@ x8664::misc-header-offset (% ,vector)) (% ,dest))
196 (shr ($ (- x8664::num-subtag-bits x8664::fixnumshift)) (% ,dest))))
197
198
199(defx86lapmacro int-to-double (int temp double)
200 `(progn
201 (unbox-fixnum ,int ,temp)
202 (cvtsi2sdq (% ,temp) (% ,double))))
203
204(defx86lapmacro int-to-single (int temp single)
205 `(progn
206 (unbox-fixnum ,int ,temp)
207 (cvtsi2ssq (% ,temp) (% ,single))))
208
209(defx86lapmacro ref-global (global reg)
210 `(movq (@ (+ x8664::nil-value ,(x8664::%kernel-global global))) (% ,reg)))
211
212(defx86lapmacro ref-global.l (global reg)
213 `(movl (@ (+ x8664::nil-value ,(x8664::%kernel-global global))) (%l ,reg)))
214
215(defx86lapmacro set-global (reg global)
216 `(movq (% ,reg) (@ (+ x8664::nil-value ,(x8664::%kernel-global global)))))
217
218(defx86lapmacro macptr-ptr (src dest)
219 `(movq (@ x8664::macptr.address (% ,src)) (% ,dest)))
220
221;;; CODE is unboxed char-code (in low 8 bits); CHAR needs to be boxed.
222(defx86lapmacro box-character (code char)
223 `(progn
224 (box-fixnum ,code ,char)
225 (shl ($ (- x8664::charcode-shift x8664::fixnumshift)) (% ,char))
226 (movb ($ x8664::subtag-character) (%b ,char))))
227
228
229;;; index is a constant
230(defx86lapmacro svref (vector index dest)
231 `(movq (@ (+ x8664::misc-data-offset (* ,index 8)) (% ,vector)) (% ,dest)))
232
233;;; Index is still a constant
234(defx86lapmacro svset (vector index new)
235 `(movq (% ,new) (@ (+ x8664::misc-data-offset (* ,index 8)) (% ,vector))))
236
237
238
239;;; Frames, function entry and exit.
240
241
242;;; Simple frame, since the caller didn't reserve space for it.
243(defx86lapmacro save-simple-frame ()
244 `(progn
245 (pushq (% rbp))
246 (movq (% rsp) (% rbp))))
247
248(defx86lapmacro save-frame-variable-arg-count ()
249 (let* ((push (gensym))
250 (done (gensym)))
251 `(progn
252 (movzwl (% nargs) (%l imm0))
253 (subq ($ (* $numx8664argregs x8664::node-size)) (% imm0))
254 (jle ,push)
255 (movq (% rbp) (@ 8 (% rsp) (% imm0)))
256 (leaq (@ 8 (% rsp) (% imm0)) (% rbp))
257 (popq (@ 8 (% rbp)))
258 (jmp ,done)
259 ,push
260 (save-simple-frame)
261 ,done)))
262
263
264(defx86lapmacro restore-simple-frame ()
265 `(progn
266 (leave)))
267
268
269
270(defx86lapmacro discard-reserved-frame ()
271 `(add ($ '2) (% rsp)))
272
273;;; Return to caller.
274(defx86lapmacro single-value-return (&optional (words-to-discard 0))
275 (if (zerop words-to-discard)
276 `(ret)
277 `(ret ($ ,(* x8664::node-size words-to-discard)))))
278
279;;; Using *x8664-backend* here is wrong but expedient.
280(defun x86-subprim-offset (name)
281 (let* ((info (find name (arch::target-subprims-table (backend-target-arch *x8664-backend*)) :test #'string-equal :key #'subprimitive-info-name))
282 (offset (when info
283 (subprimitive-info-offset info))))
284 (or offset
285 (error "Unknown subprim: ~s" name))))
286
287(defx86lapmacro jmp-subprim (name)
288 `(jmp (@ ,(x86-subprim-offset name))))
289
290(defx86lapmacro call-subprim (name)
291 `(progn
292 (:talign 4)
293 (call (@ ,(x86-subprim-offset name)))
294 (recover-fn-from-rip)))
295
296
297(defx86lapmacro %car (src dest)
298 `(movq (@ x8664::cons.car (% ,src)) (% ,dest)))
299
300(defx86lapmacro %cdr (src dest)
301 `(movq (@ x8664::cons.cdr (% ,src)) (% ,dest)))
302
303(defx86lapmacro stack-probe ()
304 (let* ((ok (gensym)))
305 `(progn
306 (rcmp (% rsp) (@ (% rcontext) x8664::tcr.cs-limit))
307 (jae.pt ,ok)
308 (uuo-stack-overflow)
309 ,ok)))
310
311(defx86lapmacro load-constant (constant dest &optional (fn 'fn))
312 `(movq (@ ',constant (% ,fn)) (% ,dest)))
313
314(defx86lapmacro recover-fn-from-rip ()
315 (let* ((next (gensym)))
316 `(progn
317 (lea (@ (- (:^ ,next)) (% rip)) (% fn))
318 ,next)))
319
320;;; call symbol named NAME, setting nargs to NARGS. Do the TRA
321;;; hair. Args should already be in arg regs, and we expect
322;;; to return a single value.
323(defx86lapmacro call-symbol (name nargs)
324 `(progn
325 (load-constant ,name fname)
326 (set-nargs ,nargs)
327 (:talign 4)
328 (call (@ x8664::symbol.fcell (% fname)))
329 (recover-fn-from-rip)))
330
331
332;;; tail call the function named by NAME with nargs NARGS. %FN is
333;;; the caller, which will be in %FN on entry to the callee. For the
334;;; couple of instructions where neither %RA0 or %FN point to the
335;;; current function, ensure that %XFN does; this is necessary to
336;;; prevent the current function from being GCed halfway through
337;;; those couple of instructions.
338(defx86lapmacro jump-symbol (name nargs)
339 `(progn
340 (load-constant ,name fname)
341 (set-nargs ,nargs)
342 (jmp (@ x8664::symbol.fcell (% fname)))))
343
344(defx86lapmacro push-argregs ()
345 (let* ((done (gensym))
346 (yz (gensym))
347 (z (gensym)))
348 `(progn
349 (testw (% nargs) (% nargs))
350 (je ,done)
351 (cmpw ($ '2) (% nargs))
352 (je ,yz)
353 (jb ,z)
354 (push (% arg_x))
355 ,yz
356 (push (% arg_y))
357 ,z
358 (push (% arg_z))
359 ,done)))
360
Note: See TracBrowser for help on using the repository browser.