source: trunk/source/level-0/X86/x86-utils.lisp @ 8356

Last change on this file since 8356 was 8356, checked in by gb, 12 years ago

Change some LAP code to recogize that %nargs is 32 bits wide now.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.4 KB
Line 
1; -*- Mode: Lisp; Package: CCL; -*-
2;;;
3;;;   Copyright (C) 1994-2001 Digitool, Inc
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
18(in-package "CCL")
19
20(defx86lapfunction %address-of ((arg arg_z))
21  ;; %address-of a fixnum is a fixnum, just for spite.
22  ;; %address-of anything else is the address of that thing as an integer.
23  (testb ($ x8664::fixnummask) (%b arg))
24  (je @done)
25  (movq (% arg) (% imm0))
26  (jmp-subprim .SPmakeu64)
27  @done
28  (single-value-return))
29
30;;; "areas" are fixnum-tagged and, for the most part, so are their
31;;; contents.
32
33;;; The nilreg-relative global all-areas is a doubly-linked-list header
34;;; that describes nothing.  Its successor describes the current/active
35;;; dynamic heap.  Return a fixnum which "points to" that area, after
36;;; ensuring that the "active" pointers associated with the current thread's
37;;; stacks are correct.
38
39
40
41(defx86lapfunction %normalize-areas ()
42  (let ((address temp0)
43        (temp temp1))
44
45    ; update active pointer for tsp area.
46    (movq (@ (% :rcontext) x8664::tcr.ts-area) (% address))
47    (movq (@ (% :rcontext) x8664::tcr.save-tsp) (% temp))
48    (movq (% temp) (@ x8664::area.active (% address)))
49   
50    ;; Update active pointer for vsp area.
51    (movq (@ (% :rcontext) x8664::tcr.vs-area) (% address))
52    (movq (% rsp) (@ x8664::area.active (% address)))
53
54    (ref-global all-areas arg_z)
55    (movq (@ x8664::area.succ (% arg_z)) (% arg_z))
56
57    (single-value-return)))
58
59(defx86lapfunction %active-dynamic-area ()
60  (ref-global all-areas arg_z)
61  (movq (@ x8664::area.succ (% arg_z)) (% arg_z))
62  (single-value-return))
63
64 
65(defx86lapfunction %object-in-stack-area-p ((object arg_y) (area arg_z))
66  (movq (@ x8664::area.active (% area)) (% imm0))
67  (movq (@ x8664::area.high (% area)) (% imm1))
68  (rcmp (% object) (% imm0))
69  (movq ($ nil) (% arg_z))
70  (movq ($ t) (% imm0))
71  (jb @done)
72  (rcmp (% object) (% imm1))
73  (cmovbq (% imm0) (% arg_z))
74  @done
75  (single-value-return))
76
77(defx86lapfunction %object-in-heap-area-p ((object arg_y) (area arg_z))
78  (rcmp (% object) (@ x8664::area.low (% area)))
79  (setae (%b imm0))
80  (rcmp (% object) (@ x8664::area.low (% area)))
81  (setb (%b imm1))
82  (andb (% imm1.b) (% imm0.b))
83  (andl ($ x8664::t-offset) (%l imm0))
84  (lea (@ x8664::nil-value (% imm0)) (% arg_z))
85  (single-value-return))
86
87
88
89
90(defx86lapfunction walk-static-area ((a arg_y) (f arg_z))
91  (let ((fun save0)
92        (obj save1)
93        (limit save2)
94        (prev save3))
95    (save-simple-frame)
96    (push (% fun))
97    (push (% obj))
98    (push (% limit))
99    (push (% prev))
100    (xorl (%l prev) (%l prev))
101    (movq (% f) (% fun))
102    (movq (@ x8664::area.active (% a)) (% limit))
103    (movq (@ x8664::area.low (% a)) (% obj))
104    (jmp @test)
105    @loop
106    (movb (@ (% obj)) (% imm0.b))
107    (andb ($ x8664::fulltagmask) (% imm0.b))
108    (cmpb ($ x8664::fulltag-nodeheader-0) (% imm0.b))
109    (je @misc)
110    (cmpb ($ x8664::fulltag-nodeheader-1) (% imm0.b))
111    (je @misc)
112    (cmpb ($ x8664::fulltag-immheader-0) (% imm0.b))
113    (je @misc)
114    (cmpb ($ x8664::fulltag-immheader-2) (% imm0.b))
115    (je @misc)
116    (cmpb ($ x8664::fulltag-immheader-1) (% imm0.b))
117    (jne @cons)
118    @misc
119    (lea (@ x8664::fulltag-misc (% obj)) (% obj))
120    (movq (% obj) (% prev))
121    (movq (% obj) (% arg_z))
122    (set-nargs 1)
123    (:talign 4)
124    (call (% fun))
125    (recover-fn-from-rip)
126    (getvheader obj imm1)
127    (movb (% imm1.b) (% imm0.b))
128    (andb ($ x8664::fulltagmask) (% imm0.b))
129    (cmpb ($ x8664::fulltag-nodeheader-0) (% imm0.b))
130    (je @64)
131    (cmpb ($ x8664::fulltag-nodeheader-1) (% imm0.b))
132    (je @64)
133    (cmpb ($ x8664::ivector-class-64-bit) (% imm0.b))
134    (jne @not64)
135    @64
136    (shrq ($ x8664::num-subtag-bits) (% imm1))
137    (shlq ($ x8664::word-shift) (% imm1))
138    (jmp @uvector-next)
139    @not64
140    (cmpb ($ x8664::ivector-class-32-bit) (% imm0.b))
141    (jne @not32)
142    (shrq ($ x8664::num-subtag-bits) (% imm1))
143    (shlq ($ 2) (% imm1))
144    (jmp @uvector-next)
145    @not32
146    (cmpb ($ (- x8664::subtag-bit-vector 256)) (% imm1.b))
147    (jne @not-bit)
148    (shrq ($ x8664::num-subtag-bits) (% imm1))
149    (addq ($ 7) (% imm1))
150    (shrq ($ 3) (% imm1))
151    (jmp @uvector-next)
152    @not-bit
153    (rcmpb (% imm1.b) ($ (- x8664::min-8-bit-ivector-subtag 256)))
154    (jb @16)
155    (shrq ($ x8664::num-subtag-bits) (% imm1))
156    (jmp @uvector-next)
157    @16
158    (shrq ($ x8664::num-subtag-bits) (% imm1))
159    (shlq ($ 1) (% imm1))
160    (jmp @uvector-next)
161    @cons
162    (addq ($ x8664::fulltag-cons) (% obj))
163    (movq (% obj) (% prev))
164    (movq (% obj) (% arg_z))
165    (set-nargs 1)
166    (:talign 4)
167    (call (% fun))
168    (recover-fn-from-rip)
169    (addq ($ (- x8664::cons.size x8664::fulltag-cons)) (% obj))
170    (jmp @test)
171    ;; size of OBJ in bytes (without header or alignment padding)
172    ;; in imm1.
173    @uvector-next
174    (addq ($ (+ x8664::node-size (1- x8664::dnode-size))) (% imm1))
175    (andb ($ (lognot (1- x8664::dnode-size))) (% imm1.b))
176    (lea (@ (- x8664::fulltag-misc) (% obj) (% imm1)) (% obj))
177    @test
178    (cmpq (% limit) (% obj))
179    (jb @loop)
180    (pop (% prev))
181    (pop (% limit))
182    (pop (% obj))
183    (pop (% fun))
184    (movl ($ x8664::nil-value) (% arg_z.l))
185    (restore-simple-frame)
186    (single-value-return)))
187
188
189
190;;; This walks the active "dynamic" area.  Objects might be moving around
191;;; while we're doing this, so we have to be a lot more careful than we
192;;; are when walking a static area.
193;;; There are a couple of approaches to termination:
194;;;  a) Allocate a "sentinel" cons, and terminate when we run into it.
195;;;  b) Check the area limit (which is changing if we're consing) and
196;;;     terminate when we hit it.
197;;; (b) loses if the function conses.  (a) conses.  I can't think of anything
198;;; better than (a).
199;;; This, of course, assumes that any GC we're doing does in-place compaction
200;;; (or at least preserves the relative order of objects in the heap.)
201
202(defx86lapfunction %walk-dynamic-area ((a arg_y) (f arg_z))
203  (let ((fun save0)
204        (obj save1)
205        (limit save2)
206        (prev save3))
207    (save-simple-frame)
208    (push (% fun))
209    (push (% obj))
210    (push (% limit))
211    (push (% prev))
212    (movq (% f) (% fun))
213    (xorl (%l prev) (%l prev))
214    (ref-global tenured-area a)
215    (movq (@ x8664::area.low (% a)) (% obj))
216    (subq ($ (- x8664::cons.size x8664::fulltag-cons))
217          (@ (% :rcontext) x8664::tcr.save-allocptr))
218    (movq (@ (% :rcontext) x8664::tcr.save-allocptr) (% allocptr))
219    (cmpq (@ (% :rcontext) x8664::tcr.save-allocbase) (% allocptr))
220    (jg @ok)
221    (uuo-alloc)
222    @ok
223    (andb ($ (lognot x8664::fulltagmask))
224          (@ (% :rcontext) x8664::tcr.save-allocptr))
225    (movq (% allocptr) (% limit))
226    (jmp @test)
227    @loop
228    (movb (@ (% obj)) (% imm0.b))
229    (andb ($ x8664::fulltagmask) (% imm0.b))
230    (cmpb ($ x8664::fulltag-nodeheader-0) (% imm0.b))
231    (je @misc)
232    (cmpb ($ x8664::fulltag-nodeheader-1) (% imm0.b))
233    (je @misc)
234    (cmpb ($ x8664::fulltag-immheader-0) (% imm0.b))
235    (je @misc)
236    (cmpb ($ x8664::fulltag-immheader-2) (% imm0.b))
237    (je @misc)
238    (cmpb ($ x8664::fulltag-immheader-1) (% imm0.b))
239    (jne @cons)
240    @misc
241    (lea (@ x8664::fulltag-misc (% obj)) (% obj))
242    (movq (% obj) (% arg_z))
243    (movq (% obj) (% prev))
244    (set-nargs 1)
245    (:talign 4)
246    (call (% fun))
247    (recover-fn-from-rip)
248    (getvheader obj imm1)
249    (movb (% imm1.b) (% imm0.b))
250    (andb ($ x8664::fulltagmask) (% imm0.b))
251    (cmpb ($ x8664::fulltag-nodeheader-0) (% imm0.b))
252    (je @64)
253    (cmpb ($ x8664::fulltag-nodeheader-1) (% imm0.b))
254    (je @64)
255    (cmpb ($ x8664::ivector-class-64-bit) (% imm0.b))
256    (jne @not64)
257    @64
258    (shrq ($ x8664::num-subtag-bits) (% imm1))
259    (shlq ($ x8664::word-shift) (% imm1))
260    (jmp @uvector-next)
261    @not64
262    (cmpb ($ x8664::ivector-class-32-bit) (% imm0.b))
263    (jne @not32)
264    (shrq ($ x8664::num-subtag-bits) (% imm1))
265    (shlq ($ 2) (% imm1))
266    (jmp @uvector-next)
267    @not32
268    (cmpb ($ (- x8664::subtag-bit-vector 256)) (% imm1.b))
269    (jne @not-bit)
270    (shrq ($ x8664::num-subtag-bits) (% imm1))
271    (addq ($ 7) (% imm1))
272    (shrq ($ 3) (% imm1))
273    (jmp @uvector-next)
274    @not-bit
275    (rcmpb (% imm1.b) ($ (- x8664::min-8-bit-ivector-subtag 256)))
276    (jb @16)
277    (shrq ($ x8664::num-subtag-bits) (% imm1))
278    (jmp @uvector-next)
279    @16
280    (shrq ($ x8664::num-subtag-bits) (% imm1))
281    (shlq ($ 1) (% imm1))
282    (jmp @uvector-next)
283    @cons
284    (addq ($ x8664::fulltag-cons) (% obj))
285    (cmpq (% obj) (% limit))
286    (movq (% obj) (% arg_z))
287    (je @done)
288    (movq (% obj) (% prev))
289    (set-nargs 1)
290    (:talign 4)
291    (call (% fun))
292    (recover-fn-from-rip)
293    (addq ($ (- x8664::cons.size x8664::fulltag-cons)) (% obj))
294    (jmp @test)
295    ;; size of OBJ in bytes (without header or alignment padding)
296    ;; in imm1.
297    @uvector-next
298    (addq ($ (+ x8664::node-size (1- x8664::dnode-size))) (% imm1))
299    (andb ($ (lognot (1- x8664::dnode-size))) (% imm1.b))
300    (lea (@ (- x8664::fulltag-misc) (% obj) (% imm1)) (% obj))
301    @test
302    (cmpq (% limit) (% obj))
303    (jb @loop)
304    @done
305    (pop (% prev))
306    (pop (% limit))
307    (pop (% obj))
308    (pop (% fun))
309    (movl ($ x8664::nil-value) (% arg_z.l))
310    (restore-simple-frame)
311    (single-value-return)))
312
313(defun walk-dynamic-area (area func)
314  (with-other-threads-suspended
315      (%walk-dynamic-area area func)))
316
317
318
319(defx86lapfunction %class-of-instance ((i arg_z))
320  (svref i instance.class-wrapper arg_z)
321  (svref arg_z %wrapper-class arg_z)
322  (single-value-return))
323
324(defx86lapfunction class-of ((x arg_z))
325  (check-nargs 1)
326  (movw ($ (logior (ash 1 x8664::tag-list)
327                   (ash 1 x8664::tag-imm-1)))
328        (%w imm1))
329  (extract-lisptag x imm0)
330  (btw (% imm0.w) (% imm1.w))
331  (cmovbl (% arg_z.l) (% imm0.l))
332  (movq (@ '*class-table* (% fn)) (% temp1))
333  (cmpb ($ x8664::tag-misc) (% imm0.b))
334  (jne @have-tag)
335  (extract-subtag x imm0)
336  @have-tag
337  (movq (@ x8664::symbol.vcell (% temp1)) (% temp1))
338  (movzbl (% imm0.b) (% imm0.l))
339  (movq (@ x8664::misc-data-offset (% temp1) (% imm0) 8) (% temp0))
340  (cmpb ($ x8664::fulltag-nil) (%b temp0))
341  (je @bad)
342  (extract-fulltag temp0 imm0)
343  (cmpb ($ x8664::fulltag-function) (%b imm0))
344  (jne @ret)
345  (set-nargs 1)
346  (jmp (% temp0))
347  @bad
348  (load-constant no-class-error fname)
349  (set-nargs 1)
350  (jmp  (@ x8664::symbol.fcell (% fname)))
351  @ret
352  (movq (% temp0) (% arg_z))  ; return frob from table
353  (single-value-return))
354
355(defx86lapfunction full-gccount ()
356  (ref-global tenured-area arg_z)
357  (testq (% arg_z) (% arg_z))
358  (cmoveq (@ (+ x8664::nil-value (x8664::%kernel-global 'gc-count))) (% arg_z))
359  (cmovneq (@ x8664::area.gc-count (% arg_z)) (% arg_z))
360  (single-value-return))
361
362
363(defx86lapfunction gc ()
364  (check-nargs 0)
365  (movq ($ arch::gc-trap-function-gc) (% imm0))
366  (uuo-gc-trap)
367  (movq ($ nil) (% arg_z))
368  (single-value-return))
369
370
371(defx86lapfunction egc ((arg arg_z))
372  "Enable the EGC if arg is non-nil, disables the EGC otherwise. Return
373the previous enabled status. Although this function is thread-safe (in
374the sense that calls to it are serialized), it doesn't make a whole lot
375of sense to be turning the EGC on and off from multiple threads ..."
376  (check-nargs 1)
377  (clrq imm1)
378  (cmp-reg-to-nil arg)
379  (setne (% imm1.b))
380  (movq ($ arch::gc-trap-function-egc-control) (% imm0))
381  (uuo-gc-trap)
382  (single-value-return))
383
384
385
386
387(defx86lapfunction %configure-egc ((e0size arg_x)
388                                   (e1size arg_y)
389                                   (e2size arg_z))
390  (check-nargs 3)
391  (movq ($ arch::gc-trap-function-configure-egc) (% imm0))
392  (uuo-gc-trap)
393  (single-value-return))
394
395(defx86lapfunction purify ()
396  (check-nargs 0)
397  (movq ($ arch::gc-trap-function-purify) (% imm0))
398  (uuo-gc-trap)
399  (movq ($ nil) (% arg_z))
400  (single-value-return))
401
402
403(defx86lapfunction impurify ()
404  (check-nargs 0)
405  (movq ($ arch::gc-trap-function-impurify) (% imm0))
406  (uuo-gc-trap)
407  (movq ($ nil) (% arg_z))
408  (single-value-return))
409
410
411(defx86lapfunction lisp-heap-gc-threshold ()
412  "Return the value of the kernel variable that specifies the amount
413of free space to leave in the heap after full GC."
414  (check-nargs 0)
415  (movq ($ arch::gc-trap-function-get-lisp-heap-threshold) (% imm0))
416  (uuo-gc-trap)
417  #+x8632-target
418  (jmp-subprim .SPmakeu32)
419  #+x8664-target
420  (jmp-subprim .SPmakeu64))
421
422(defx86lapfunction set-lisp-heap-gc-threshold ((new arg_z))
423  "Set the value of the kernel variable that specifies the amount of free
424space to leave in the heap after full GC to new-value, which should be a
425non-negative fixnum. Returns the value of that kernel variable (which may
426be somewhat larger than what was specified)."
427  (check-nargs 1)
428  (save-simple-frame)
429  (call-subprim .SPgetu64)
430  (movq (% imm0) (% imm1))
431  (movq ($ arch::gc-trap-function-set-lisp-heap-threshold) (% imm0))
432  (uuo-gc-trap)
433  (restore-simple-frame)
434  (jmp-subprim .SPmakeu64))
435
436
437(defx86lapfunction use-lisp-heap-gc-threshold ()
438  "Try to grow or shrink lisp's heap space, so that the free space is (approximately) equal to the current heap threshold. Return NIL"
439  (check-nargs 0) 
440  (movq ($ arch::gc-trap-function-use-lisp-heap-threshold) (% imm0))
441  (uuo-gc-trap)
442  (movl ($ x8664::nil-value) (%l arg_z))
443  (single-value-return))
444
445(defx86lapfunction freeze ()
446  "Do a full GC, then consider all heap-allocated objects which survive to be non-relocatable."
447  (movq ($ arch::gc-trap-function-freeze) (% imm0))
448  (uuo-gc-trap)
449  (jmp-subprim .SPmakeu64))
450
451 
452 
453
454
455;;; offset is a fixnum, one of the x8664::kernel-import-xxx constants.
456;;; Returns that kernel import, a fixnum.
457(defx86lapfunction %kernel-import ((offset arg_z))
458  (ref-global kernel-imports imm0)
459  (unbox-fixnum arg_z imm1)
460  (movq (@ (% imm0) (% imm1)) (% imm0))
461  (box-fixnum imm0 arg_z)
462  (single-value-return))
463
464(defx86lapfunction %get-unboxed-ptr ((macptr arg_z))
465  (macptr-ptr arg_z imm0)
466  (movq (@ (% imm0)) (% arg_z))
467  (single-value-return))
468
469
470(defx86lapfunction %revive-macptr ((p arg_z))
471  (movb ($ x8664::subtag-macptr) (@ x8664::misc-subtag-offset (% p)))
472  (single-value-return))
473
474(defx86lapfunction %macptr-type ((p arg_z))
475  (check-nargs 1)
476  (trap-unless-typecode= p x8664::subtag-macptr)
477  (svref p x8664::macptr.type-cell imm0)
478  (box-fixnum imm0 arg_z)
479  (single-value-return))
480 
481(defx86lapfunction %macptr-domain ((p arg_z))
482  (check-nargs 1)
483  (trap-unless-typecode= p x8664::subtag-macptr)
484  (svref p x8664::macptr.domain-cell imm0)
485  (box-fixnum imm0 arg_z)
486  (single-value-return))
487
488(defx86lapfunction %set-macptr-type ((p arg_y) (new arg_z))
489  (check-nargs 2)
490  (unbox-fixnum new imm1)
491  (trap-unless-typecode= p x8664::subtag-macptr)
492  (svset p x8664::macptr.type-cell imm1)
493  (single-value-return))
494
495(defx86lapfunction %set-macptr-domain ((p arg_y) (new arg_z))
496  (check-nargs 2)
497  (unbox-fixnum new imm1)
498  (trap-unless-typecode= p x8664::subtag-macptr)
499  (svset p x8664::macptr.domain-cell imm1)
500  (single-value-return))
501
502(defx86lapfunction true ()
503  (subq ($ '3) (% nargs.q))
504  (leaq (@ '2 (% rsp) (% nargs.q)) (% imm0))
505  (cmovaq (% imm0) (% rsp))
506  (movl ($ x8664::t-value) (%l arg_z))
507  (single-value-return))
508
509(defx86lapfunction false ()
510  (subq ($ '3) (% nargs.q))
511  (leaq (@ '2 (% rsp) (% nargs.q)) (% imm0))
512  (cmovaq (% imm0) (% rsp))
513  (movl ($ x8664::nil) (%l arg_z))
514  (single-value-return))
515
516
517
518;;; end
Note: See TracBrowser for help on using the repository browser.