source: release/1.8/source/level-0/X86/X8632/x8632-misc.lisp

Last change on this file was 15241, checked in by R. Matthew Emerson, 13 years ago

Merge from trunk:

File size: 29.2 KB
RevLine 
[13067]1;;; Copyright 2009 Clozure Associates
2;;; This file is part of Clozure CL.
3;;;
4;;; Clozure CL is licensed under the terms of the Lisp Lesser GNU
5;;; Public License , known as the LLGPL and distributed with Clozure
6;;; CL as the file "LICENSE". The LLGPL consists of a preamble and
7;;; the LGPL, which is distributed with Clozure CL as the file "LGPL".
8;;; Where these conflict, the preamble takes precedence.
9;;;
10;;; Clozure CL is referenced in the preamble as the "LIBRARY."
11;;;
12;;; The LLGPL is also available online at
13;;; http://opensource.franz.com/preamble.html
14
[7997]15(in-package "CCL")
16
17;;; Copy N bytes from pointer src, starting at byte offset src-offset,
18;;; to ivector dest, starting at offset dest-offset.
19;;; It's fine to leave this in lap.
20;;; Depending on alignment, it might make sense to move more than
21;;; a byte at a time.
22;;; Does no arg checking of any kind. Really.
[15156]23(defun %copy-ptr-to-ivector (src src-byte-offset dest dest-byte-offset nbytes)
24 (declare (fixnum src-byte-offset dest-byte-offset nbytes)
25 (optimize (speed 3) (safety 0)))
26 (let* ((ptr-align (logand 7 (%ptr-to-int src))))
27 (declare (type (mod 8) ptr-align))
28 (if (and (= 0 (logand nbytes 3))
29 (= 0 (logand dest-byte-offset 3))
30 (= 0 (logand (the fixnum (+ ptr-align src-byte-offset)) 3)))
31 (%copy-ptr-to-ivector-32bit src src-byte-offset dest dest-byte-offset nbytes)
32 (%copy-ptr-to-ivector-8bit src src-byte-offset dest dest-byte-offset nbytes))
33 dest))
[7997]34
[15156]35;;; We can exploit the fact that SRC-BYTE-OFFSET and DEST-BYTE-OFFSET
36;;; are both multiples of 4 (and therefore still fixnums when unboxed).
37(defx8632lapfunction %copy-ptr-to-ivector-32bit ((psrc 12)
38 (psrc-byte-offset 8)
39 (pdest 4)
40 #|(ra 0)|#
41 (dest-byte-offset arg_y)
42 (nbytes arg_z))
43
44 (let ((foreign-ptr imm0) ;raw foreign pointer
45 (ivector temp1)) ;destination ivector
46 (movl (@ psrc (% esp)) (% temp1))
47 (movl (@ psrc-byte-offset (% esp)) (% foreign-ptr))
48 (sarl ($ x8632::word-shift)(% foreign-ptr))
49 (addl (@ x8632::macptr.address (% temp1)) (% foreign-ptr))
50 (movl (@ pdest (% esp)) (% ivector))
51 (sarl ($ x8632::word-shift) (% dest-byte-offset))
52 (jmp @test16)
53 @loop16
54 (movdqu (@ (% foreign-ptr)) (% xmm0))
55 (movdqu (% xmm0) (@ x8632::misc-data-offset (% ivector) (% dest-byte-offset)))
56 (addl ($ 16) (% foreign-ptr))
57 (addl ($ 16) (% dest-byte-offset))
58 (subl ($ '16) (% nbytes))
59 @test16
60 (cmpl ($ '16) (% nbytes))
61 (jge @loop16)
62 (testl (% nbytes) (% nbytes))
63 (je @done)
64 @loop4
65 (movd (@ (% foreign-ptr)) (% mm0))
66 (movd (% mm0) (@ x8632::misc-data-offset (% ivector) (% dest-byte-offset)))
67 (addl ($ 4) (% foreign-ptr))
68 (addl ($ 4) (% dest-byte-offset))
69 (subl ($ '4) (% nbytes))
70 (jne @loop4)
71 @done
72 (movl (% ivector) (% arg_z))
73 (single-value-return 5)))
74
[7997]75;;; I went ahead and used the INC and DEC instructions here, since
76;;; they're shorter than the equivalent ADD/SUB. Intel's optimization
77;;; manual advises avoiding INC and DEC because they might cause
78;;; dependencies on earlier instructions that set the flags. So, if
79;;; these functions end up being hot, replacing the inc/dec insns
80;;; might be worth a try.
81
[15156]82(defx8632lapfunction %copy-ptr-to-ivector-8bit ((src 12)
83 (src-byte-offset 8)
84 (dest 4)
85 #|(ra 0)|#
86 (dest-byte-offset arg_y)
87 (nbytes arg_z))
[7997]88 (mark-as-imm temp0)
89 (mark-as-imm arg_y)
90 (let ((foreign-ptr temp0) ;raw foreign pointer
91 (ivector temp1) ;destination ivector
92 (j arg_y)) ;unboxed index into ivector
93 (movl (@ src (% esp)) (% temp1))
94 (macptr-ptr temp1 foreign-ptr)
95 (movl (@ src-byte-offset (% esp)) (% temp1))
96 (unbox-fixnum temp1 imm0)
97 (addl (% imm0) (% foreign-ptr)) ;point to starting byte in src
98 (movl (@ dest (% esp)) (% ivector))
99 (sarl ($ x8632::fixnumshift) (% j)) ;unbox dest-byte-offset
100 (testl (% nbytes) (% nbytes))
101 (jmp @test)
102 @loop
103 (movb (@ (% foreign-ptr)) (%b imm0))
104 (incl (% foreign-ptr))
105 (movb (%b imm0) (@ x8632::misc-data-offset (% ivector) (% j)))
106 (incl (% j))
107 (subl ($ '1) (% nbytes))
108 @test
109 (jne @loop)
110 (movl (% ivector) (% arg_z)))
111 (mark-as-node temp0)
112 (mark-as-node arg_y)
113 (single-value-return 5))
114
115(defx8632lapfunction %copy-ivector-to-ptr ((src 12)
116 (src-byte-offset 8)
117 (dest 4)
118 #|(ra 0)|#
119 (dest-byte-offset arg_y)
120 (nbytes arg_z))
121 (mark-as-imm temp0)
122 (mark-as-imm arg_y)
123 (let ((foreign-ptr temp0) ;raw foreign pointer
124 (ivector temp1) ;source ivector
125 (j arg_y)) ;unboxed index into ivector
126 (movl (@ dest (% esp)) (% temp1))
127 (macptr-ptr temp1 foreign-ptr)
128 (unbox-fixnum dest-byte-offset imm0)
129 (addl (% imm0) (% foreign-ptr)) ;point to starting byte in dest
130 (movl (@ src (% esp)) (% ivector))
131 (movl (@ src-byte-offset (% esp)) (% j))
132 (sarl ($ x8632::fixnumshift) (% j)) ;unbox src-byte-offset
133 (test (% nbytes) (% nbytes))
134 (jmp @test)
135 @loop
136 (movb (@ x8632::misc-data-offset (% ivector) (% j)) (%b imm0))
137 (incl (% j))
138 (movb (%b imm0) (@ (% foreign-ptr)))
139 (incl (% foreign-ptr))
140 (subl ($ '1) (% nbytes))
141 @test
142 (jne @loop)
143 (movl (@ dest (% esp)) (% arg_z)))
144 (mark-as-node temp0)
145 (mark-as-node arg_y)
146 (single-value-return 5))
147
148(defx8632lapfunction %copy-ivector-to-ivector ((src 12)
149 (src-byte-offset 8)
150 (dest 4)
151 #|(ra 0)|#
152 (dest-byte-offset arg_y)
153 (nbytes arg_z))
154 (movl (@ src (% esp)) (% temp0))
155 (movl (@ src-byte-offset (% esp)) (% temp1))
156 (unbox-fixnum nbytes imm0) ;will be used below
157 (push (% nbytes)) ;put loop counter on stack
[8906]158 (movl (@ (+ 4 dest) (% esp)) (% arg_z))
[7997]159 (mark-as-imm temp1)
160 (mark-as-imm arg_y)
161 (sarl ($ x8632::fixnumshift) (% temp1)) ;unboxed src index
162 (sarl ($ x8632::fixnumshift) (% arg_y)) ;unboxed dest index
163 (let ((a temp0)
164 (i temp1)
165 (b arg_z)
166 (j arg_y))
167 ;; copy nbytes starting at a[i] to b[j]
168 (cmpl (% b) (% a))
169 (jne @front)
170 (cmpl (% i) (% j))
171 (jg @back)
172 @front
173 (testl (% imm0) (% imm0)) ;test nbytes
174 (jmp @front-test)
175 @front-loop
176 (movb (@ x8632::misc-data-offset (% a) (% i)) (%b imm0))
177 (movb (%b imm0) (@ x8632::misc-data-offset (% b) (% j)))
178 (incl (% i))
179 (incl (% j))
180 (subl ($ '1) (@ (% esp)))
181 @front-test
182 (jne @front-loop)
183 (jmp @done)
184 @back
185 ;; unboxed nbytes in imm0
186 (addl (% imm0) (% i))
187 (addl (% imm0) (% j))
188 (testl (% imm0) (% imm0))
189 (jmp @back-test)
190 @back-loop
191 (decl (% i))
192 (decl (% j))
193 (movb (@ x8632::misc-data-offset (% a) (% i)) (%b imm0))
194 (movb (%b imm0) (@ x8632::misc-data-offset (% b) (% j)))
195 (subl ($ '1) (@ (% esp)))
196 @back-test
197 (jne @back-loop)
198 @done
199 ;; dest already in arg_z
200 (addl ($ 4) (% esp)) ;pop nbytes
[8006]201 (mark-as-node temp1)
202 (mark-as-node arg_y)
[7997]203 (single-value-return 5)))
204
205(defx8632lapfunction %copy-gvector-to-gvector ((src 12)
206 (src-element 8)
207 (dest 4)
208 #|(ra 0)|#
209 (dest-element arg_y)
210 (nelements arg_z))
211 (let ((a temp0)
212 (i imm0)
213 (b arg_z)
214 (j arg_y)
215 (val temp1))
216 (movl (% nelements) (% val)) ;will be used below
217 (push (% nelements)) ;loop counter on stack (use ebp?)
[8906]218 (movl (@ (+ 4 src) (% esp)) (% a))
219 (movl (@ (+ 4 src-element) (% esp)) (% i))
220 (movl (@ (+ 4 dest) (% esp)) (% b))
[7997]221 ;; j/arg_y already set
222 (cmpl (% a) (% b))
223 (jne @front)
224 (rcmp (% i) (% j))
225 (jl @back)
226 @front
227 (testl (% val) (% val)) ;test nelements
228 (jmp @front-test)
229 @front-loop
230 (movl (@ x8632::misc-data-offset (% a) (% i)) (% val))
231 (movl (% val) (@ x8632::misc-data-offset (% b) (% j)))
232 (addl ($ '1) (% i))
233 (addl ($ '1) (% j))
234 (subl ($ '1) (@ (% esp)))
235 @front-test
236 (jne @front-loop)
237 (jmp @done)
238 @back
239 ;; nelements in val (from above)
240 (addl (% val) (% i))
241 (addl (% val) (% j))
242 (testl (% val) (% val))
243 (jmp @back-test)
244 @back-loop
245 (subl ($ '1) (% i))
246 (subl ($ '1) (% j))
247 (movl (@ x8632::misc-data-offset (% a) (% i)) (% val))
248 (movl (% val) (@ x8632::misc-data-offset (% b) (% j)))
249 (subl ($ '1) (@ (% esp)))
250 @back-test
251 (jne @back-loop)
252 @done
253 ;; dest already in arg_z
254 (addl ($ 4) (% esp)) ;pop loop counter
255 (single-value-return 5)))
256
257(defx8632lapfunction %heap-bytes-allocated ()
258 (movl (@ (% :rcontext) x8632::tcr.save-allocptr) (% temp1))
259 (movl (@ (% :rcontext) x8632::tcr.last-allocptr) (% temp0))
260 (cmpl ($ -8) (% temp1)) ;void_allocptr
[14619]261 (jz @go)
262 #+windows-target
263 (progn
264 (movl (:rcontext x8632::tcr.aux) (% imm0))
265 (movq (@ x8632::tcr-aux.total-bytes-allocated-low (% imm0)) (% mm0)))
266 #-windows-target
[7997]267 (movq (@ (% :rcontext) x8632::tcr.total-bytes-allocated-low) (% mm0))
268 (movl (% temp0) (% arg_y))
269 (subl (% temp1) (% temp0))
270 (testl (% arg_y) (% arg_y))
271 (jz @go)
272 (movd (% temp0) (% mm1))
273 (paddq (% mm1) (% mm0))
274 @go
275 (jmp-subprim .SPmakeu64))
276
277(defx8632lapfunction values ()
278 (:arglist (&rest values))
279 (save-frame-variable-arg-count)
280 (push-argregs)
281 (jmp-subprim .SPnvalret))
282
283(defx8632lapfunction rdtsc ()
284 (mark-as-imm temp1) ;aka edx
285 (:byte #x0f) ;two-byte rdtsc opcode
286 (:byte #x31) ;is #x0f #x31
287 (box-fixnum imm0 arg_z)
288 (mark-as-node temp1)
289 (single-value-return))
290
291;;; Return all 64 bits of the time-stamp counter as an unsigned integer.
292(defx8632lapfunction rdtsc64 ()
293 (mark-as-imm temp1) ;aka edx
294 (:byte #x0f) ;two-byte rdtsc opcode
295 (:byte #x31) ;is #x0f #x31
296 (movd (% eax) (% mm0))
297 (movd (% edx) (% mm1))
298 (psllq ($ 32) (% mm1))
299 (por (% mm1) (% mm0))
300 (mark-as-node temp1)
301 (jmp-subprim .SPmakeu64))
302
303;;; It would be nice if (%setf-macptr macptr (ash (the fixnum value)
304;;; ash::fixnumshift)) would do this inline.
305
306(defx8632lapfunction %setf-macptr-to-object ((macptr arg_y) (object arg_z))
307 (check-nargs 2)
308 (trap-unless-typecode= macptr x8632::subtag-macptr)
309 (movl (% object) (@ x8632::macptr.address (% macptr)))
310 (single-value-return))
311
312(defx8632lapfunction %fixnum-from-macptr ((macptr arg_z))
313 (check-nargs 1)
314 (trap-unless-typecode= arg_z x8632::subtag-macptr)
315 (movl (@ x8632::macptr.address (% arg_z)) (% imm0))
316 (mark-as-imm temp0)
317 (let ((imm1 temp0))
318 (trap-unless-lisptag= imm0 x8632::tag-fixnum imm1))
319 (mark-as-node temp0)
320 (movl (% imm0) (% arg_z))
321 (single-value-return))
322
323(defx8632lapfunction %%get-unsigned-longlong ((ptr arg_y) (offset arg_z))
324 (trap-unless-typecode= ptr x8632::subtag-macptr)
325 (mark-as-imm temp0)
326 (let ((imm1 temp0))
327 (macptr-ptr ptr imm1)
328 (unbox-fixnum offset imm0)
329 (movq (@ (% imm1) (% imm0)) (% mm0)))
330 (mark-as-node temp0)
331 (jmp-subprim .SPmakeu64))
332
333(defx8632lapfunction %%get-signed-longlong ((ptr arg_y) (offset arg_z))
334 (trap-unless-typecode= ptr x8632::subtag-macptr)
335 (mark-as-imm temp0)
336 (let ((imm1 temp0))
337 (macptr-ptr ptr imm1)
338 (unbox-fixnum offset imm0)
339 (movq (@ (% imm1) (% imm0)) (% mm0)))
340 (mark-as-node temp0)
341 (jmp-subprim .SPmakes64))
342
343(defx8632lapfunction %%set-unsigned-longlong ((ptr 4)
344 #|(ra 0)|#
345 (offset arg_y)
346 (val arg_z))
347 (let ((rptr temp0)
[11057]348 (imm1 temp1)
349 (ptr-in-frame -4))
350 (save-stackargs-frame 1)
351 (movl (@ ptr-in-frame (% ebp)) (% rptr))
[7997]352 (trap-unless-typecode= rptr x8632::subtag-macptr)
353 (call-subprim .SPgetu64)
354 (macptr-ptr rptr imm0)
[11057]355 (mark-as-imm temp1)
[7997]356 (unbox-fixnum offset imm1)
357 (movq (% mm0) (@ (% imm0) (% imm1)))
[11057]358 (mark-as-node temp1)
359 (restore-simple-frame)
360 (single-value-return)))
[7997]361
362(defx8632lapfunction %%set-signed-longlong ((ptr 4)
363 #|(ra 0)|#
364 (offset arg_y)
365 (val arg_z))
366 (let ((rptr temp0)
[11057]367 (imm1 temp1)
368 (ptr-in-frame -4))
369 (save-stackargs-frame 1)
370 (movl (@ ptr-in-frame (% ebp)) (% rptr))
[7997]371 (trap-unless-typecode= rptr x8632::subtag-macptr)
372 (call-subprim .SPgets64)
373 (macptr-ptr rptr imm0)
[11057]374 (mark-as-imm temp1)
[7997]375 (unbox-fixnum offset imm1)
376 (movq (% mm0) (@ (% imm0) (% imm1)))
[11057]377 (mark-as-node temp1)
378 (restore-simple-frame)
379 (single-value-return)))
[7997]380
381(defx8632lapfunction interrupt-level ()
382 (movl (@ (% :rcontext) x8632::tcr.tlb-pointer) (% imm0))
383 (movl (@ x8632::interrupt-level-binding-index (% imm0)) (% arg_z))
384 (single-value-return))
385
386(defx8632lapfunction set-interrupt-level ((new arg_z))
387 (movl (@ (% :rcontext) x8632::tcr.tlb-pointer) (% imm0))
388 (trap-unless-fixnum new)
389 (movl (% new) (@ x8632::interrupt-level-binding-index (% imm0)))
390 (single-value-return))
391
392(defx8632lapfunction %current-tcr ()
393 (movl (@ (% :rcontext) x8632::tcr.linear) (% arg_z))
394 (single-value-return))
395
396(defx8632lapfunction %tcr-toplevel-function ((tcr arg_z))
397 (check-nargs 1)
[14619]398 (movl (@ (- x8632::tcr.vs-area x8632::tcr-bias) (% tcr)) (% temp0))
[8216]399 (movl (@ x8632::area.high (% temp0)) (% imm0)) ;bottom of vstack
400 (cmpl (% tcr) (@ (% :rcontext) x8632::tcr.linear))
401 (jz @myself)
402 (cmpl (% imm0) (@ x8632::area.active (% temp0)))
403 (jmp @finish)
404 @myself
405 (cmpl (% imm0) (% esp))
406 @finish
[10959]407 (movl ($ (target-nil-value)) (% arg_z))
[8216]408 (cmovnel (@ (- x8632::node-size) (% imm0)) (% arg_z))
[7997]409 (single-value-return))
[8216]410
[7997]411(defx8632lapfunction %set-tcr-toplevel-function ((tcr arg_y) (fun arg_z))
412 (check-nargs 2)
[14619]413 (movl (@ (- x8632::tcr.vs-area x8632::tcr-bias) (% tcr)) (% temp0))
[8216]414 (movl (@ x8632::area.high (% temp0)) (% imm0))
415 (cmpl (% tcr) (@ (% :rcontext) x8632::tcr.linear))
416 (jz @myself)
417 (cmpl (% imm0) (@ x8632::area.active (% temp0))) ;vstack empty?
418 (jmp @room)
419 @myself
420 (cmpl (% imm0) (% esp))
421 @room
422 (leal (@ (- x8632::node-size) (% imm0)) (% imm0))
423 (movl ($ 0) (@ (% imm0)))
424 (jne @have-room)
425 (movl (% imm0) (@ x8632::area.active (% temp0)))
[14619]426 (movl (% imm0) (@ (- x8632::tcr.save-vsp x8632::tcr-bias) (% tcr)))
[8216]427 (jmp @have-room)
428 @have-room
429 (movl (% fun) (@ (% imm0)))
[7997]430 (single-value-return))
431
432;;; This needs to be done out-of-line, to handle EGC memoization.
433(defx8632lapfunction %store-node-conditional ((offset 8)
434 (object 4)
435 #|(ra 0)|#
436 (old arg_y)
437 (new arg_z))
438 (movl (@ offset (% esp)) (% temp0))
439 (movl (@ object (% esp)) (% temp1))
440 (save-simple-frame)
441 (call-subprim .SPstore-node-conditional)
442 (restore-simple-frame)
[8690]443 (single-value-return 4))
[7997]444
445(defx8632lapfunction %store-immediate-conditional ((offset 8)
446 (object 4)
447 #|(ra 0)|#
448 (old arg_y)
449 (new arg_z))
450 (mark-as-imm temp0)
451 (let ((imm1 temp0)
452 (robject temp1))
453 (movl (@ offset (% esp)) (% imm1))
454 (sarl ($ x8632::fixnumshift) (% imm1))
455 (movl (@ object (% esp)) (% robject))
456 @again
457 (movl (@ (% robject) (% imm1)) (% eax))
458 (cmpl (% eax) (% old))
459 (jne @lose)
460 (lock)
461 (cmpxchgl (% new) (@ (% robject) (% imm1)))
462 (jne @again)
[10959]463 (movl ($ (target-t-value)) (% arg_z))
[7997]464 (mark-as-node temp0)
465 (single-value-return 4)
466 @lose
[10959]467 (movl ($ (target-nil-value)) (% arg_z))
[7997]468 (mark-as-node temp0)
469 (single-value-return 4)))
470
471(defx8632lapfunction set-%gcable-macptrs% ((ptr arg_z))
472 @again
[10959]473 (movl (@ (+ (target-nil-value) (x8632::kernel-global gcable-pointers))) (% eax))
[7997]474 (movl (% eax) (@ x8632::xmacptr.link (% ptr)))
475 (lock)
[10959]476 (cmpxchgl (% ptr) (@ (+ (target-nil-value) (x8632::kernel-global gcable-pointers))))
[7997]477 (jne @again)
478 (single-value-return))
479
480;;; Atomically increment or decrement the gc-inhibit-count kernel-global
481;;; (It's decremented if it's currently negative, incremented otherwise.)
482(defx8632lapfunction %lock-gc-lock ()
483 @again
[10959]484 (movl (@ (+ (target-nil-value) (x8632::kernel-global gc-inhibit-count))) (% eax))
[7997]485 (lea (@ '-1 (% eax)) (% temp0))
486 (lea (@ '1 (% eax)) (% arg_z))
487 (test (% eax) (% eax))
488 (cmovsl (% temp0) (% arg_z))
489 (lock)
[10959]490 (cmpxchgl (% arg_z) (@ (+ (target-nil-value) (x8632::kernel-global gc-inhibit-count))))
[7997]491 (jnz @again)
492 (single-value-return))
493
494;;; Atomically decrement or increment the gc-inhibit-count kernel-global
495;;; (It's incremented if it's currently negative, incremented otherwise.)
496;;; If it's incremented from -1 to 0, try to GC (maybe just a little.)
497(defx8632lapfunction %unlock-gc-lock ()
498 @again
[10959]499 (movl (@ (+ (target-nil-value) (x8632::kernel-global gc-inhibit-count)))
[7997]500 (% eax))
501 (lea (@ '1 (% eax)) (% temp0))
502 (cmpl ($ -1) (% eax))
503 (lea (@ '-1 (% eax)) (% arg_z))
504 (cmovlel (% temp0) (% arg_z))
505 (lock)
[10959]506 (cmpxchgl (% arg_z) (@ (+ (target-nil-value) (x8632::kernel-global gc-inhibit-count))))
[7997]507 (jne @again)
508 (cmpl ($ '-1) (% eax))
509 (jne @done)
510 ;; The GC tried to run while it was inhibited. Unless something else
511 ;; has just inhibited it, it should be possible to GC now.
512 (mov ($ arch::gc-trap-function-immediate-gc) (% imm0))
513 (uuo-gc-trap)
514 @done
515 (single-value-return))
516
517(defx8632lapfunction %atomic-incf-node ((by 4) #|(ra 0)|# (node arg_y) (disp arg_z))
518 (check-nargs 3)
519 (mark-as-imm temp0)
520 (let ((imm1 temp0)
521 (rby temp1))
522 (movl (@ by (% esp)) (% rby))
523 (unbox-fixnum disp imm1)
524 @again
525 (movl (@ (% node) (% imm1)) (% eax))
526 (lea (@ (% eax) (% rby)) (% arg_z))
527 (lock)
528 (cmpxchgl (% arg_z) (@ (% node) (% imm1)))
529 (jne @again))
530 (mark-as-node temp0)
[8690]531 (single-value-return 3))
[7997]532
533(defx8632lapfunction %atomic-incf-ptr ((ptr arg_z))
534 (mark-as-imm temp0)
535 (mark-as-imm temp1)
536 (let ((imm1 temp0)
537 (imm2 temp1))
538 (macptr-ptr ptr imm2)
539 @again
540 (movl (@ (% imm2)) (% eax))
541 (lea (@ 1 (% eax)) (% imm1))
542 (lock)
543 (cmpxchgl (% imm1) (@ (% imm2)))
544 (jne @again)
545 (box-fixnum imm1 arg_z))
546 (mark-as-node temp0)
547 (mark-as-node temp1)
548 (single-value-return))
549
550(defx8632lapfunction %atomic-incf-ptr-by ((ptr arg_y) (by arg_z))
551 (mark-as-imm temp0)
552 (mark-as-imm temp1)
553 (let ((imm1 temp0)
554 (imm2 temp1))
555 (macptr-ptr ptr imm2)
556 @again
557 (movl (@ (% imm2)) (% eax))
558 (unbox-fixnum by imm1)
559 (add (% eax) (% imm1))
560 (lock)
561 (cmpxchgl (% imm1) (@ (% imm2)))
562 (jnz @again)
563 (box-fixnum imm1 arg_z))
564 (mark-as-node temp0)
565 (mark-as-node temp1)
566 (single-value-return))
567
568(defx8632lapfunction %atomic-decf-ptr ((ptr arg_z))
569 (mark-as-imm temp0)
570 (mark-as-imm temp1)
571 (let ((imm1 temp0)
572 (imm2 temp1))
573 (macptr-ptr ptr imm2)
574 @again
575 (movl (@ (% imm2)) (% eax))
576 (lea (@ -1 (% eax)) (% imm1))
577 (lock)
578 (cmpxchgl (% imm1) (@ (% imm2)))
579 (jne @again)
580 (box-fixnum imm1 arg_z))
581 (mark-as-node temp0)
582 (mark-as-node temp1)
583 (single-value-return))
584
585(defx8632lapfunction %atomic-decf-ptr-if-positive ((ptr arg_z))
586 (mark-as-imm temp0)
587 (mark-as-imm temp1)
588 (let ((imm1 temp0)
589 (imm2 temp1))
590 (macptr-ptr ptr imm2)
591 @again
592 (movl (@ (% imm2)) (% eax))
593 (testl (% eax) (% eax))
594 (lea (@ -1 (% eax)) (% imm1))
595 (jz @done)
596 (lock)
597 (cmpxchgl (% imm1) (@ (% imm2)))
598 (jnz @again)
599 @done
600 (box-fixnum imm1 arg_z))
601 (mark-as-node temp0)
602 (mark-as-node temp1)
603 (single-value-return))
604
605(defx8632lapfunction %atomic-swap-ptr ((ptr arg_y) (newval arg_z))
606 (mark-as-imm temp0)
607 (let ((imm1 temp0))
608 (macptr-ptr arg_y imm1)
609 (unbox-fixnum newval imm0)
610 (lock)
611 (xchgl (% imm0) (@ (% imm1)))
612 (box-fixnum imm0 arg_z))
613 (mark-as-node temp0)
614 (single-value-return))
615
616;;; Try to store the fixnum NEWVAL at PTR, if and only if the old value
617;;; was equal to OLDVAL. Return the old value
618(defx8632lapfunction %ptr-store-conditional ((ptr 4) #|(ra 0)|# (expected-oldval arg_y) (newval arg_z))
619 (mark-as-imm temp1)
620 (let ((imm2 temp1))
621 (movl (@ ptr (% esp)) (% temp0))
622 (macptr-ptr temp0 imm2)
623 (mark-as-imm temp0)
624 (let ((imm1 temp0))
625 @again
626 (movl (@ (% imm2)) (% imm0))
627 (box-fixnum imm0 imm0)
628 (cmpl (% imm0) (% expected-oldval))
629 (jne @done)
630 (unbox-fixnum newval imm1)
631 (lock)
632 (cmpxchgl (% imm1) (@ (% imm2)))
633 (jne @again)
634 @done
635 (movl (% imm0) (% arg_z)))
636 (mark-as-node temp0))
637 (mark-as-node temp1)
[8690]638 (single-value-return 3))
[7997]639
[10266]640(defx8632lapfunction %ptr-store-fixnum-conditional ((ptr 4) #|(ra 0)|# (expected-oldval arg_y) (newval arg_z))
[7997]641 (mark-as-imm temp0)
642 (let ((address temp0))
[8690]643 (movl (@ ptr (% esp)) (% temp1))
644 (macptr-ptr temp1 address)
[7997]645 @again
646 (movl (@ (% address)) (% imm0))
647 (cmpl (% imm0) (% expected-oldval))
648 (jne @done)
649 (lock)
650 (cmpxchgl (% newval) (@ (% address)))
651 (jne @again)
652 @done
653 (movl (% imm0) (% arg_z)))
654 (mark-as-node temp0)
[8690]655 (single-value-return 3))
[7997]656
[10266]657(defx8632lapfunction xchgl ((newval arg_y) (ptr arg_z))
658 (unbox-fixnum newval imm0)
659 (macptr-ptr ptr arg_y) ;better be aligned
660 (xchgl (% imm0) (@ (% arg_y)))
661 (box-fixnum imm0 arg_z)
662 (single-value-return))
663
[7997]664(defx8632lapfunction %macptr->dead-macptr ((macptr arg_z))
665 (check-nargs 1)
666 (movb ($ x8632::subtag-dead-macptr) (@ x8632::misc-subtag-offset (% macptr)))
667 (single-value-return))
668
669;;; %%apply-in-frame
670
671(defx8632lapfunction %%save-application ((flags arg_y) (fd arg_z))
[9475]672 (unbox-fixnum fd imm0)
673 (movd (% imm0) (% mm0))
[7997]674 (unbox-fixnum flags imm0)
675 (orl ($ arch::gc-trap-function-save-application) (% imm0))
676 (uuo-gc-trap)
677 (single-value-return))
678
679(defx8632lapfunction %misc-address-fixnum ((misc-object arg_z))
680 (check-nargs 1)
681 (lea (@ x8632::misc-data-offset (% misc-object)) (% arg_z))
682 (single-value-return))
683
684(defx8632lapfunction fudge-heap-pointer ((ptr 4) #|(ra 0)|# (subtype arg_y) (len arg_z))
685 (check-nargs 3)
686 (mark-as-imm temp0)
687 (let ((imm1 temp0))
688 (movl (@ ptr (% esp)) (% temp1))
689 (macptr-ptr temp1 imm1) ; address in macptr
690 (lea (@ 9 (% imm1)) (% imm0)) ; 2 for delta + 7 for alignment
691 (andb ($ -8) (%b imm0)) ; Clear low three bits to align
692 (subl (% imm0) (% imm1)) ; imm1 = -delta
693 (negw (%w imm1))
694 (movw (%w imm1) (@ -2 (% imm0))) ; save delta halfword
695 (unbox-fixnum subtype imm1) ; subtype at low end of imm1
696 (shll ($ (- x8632::num-subtag-bits x8632::fixnum-shift)) (% len))
697 (orl (% len) (% imm1))
698 (movl (% imm1) (@ (% imm0))) ; store subtype & length
699 (lea (@ x8632::fulltag-misc (% imm0)) (% arg_z))) ; tag it, return it
700 (mark-as-node temp0)
[8690]701 (single-value-return 3))
[7997]702
703(defx8632lapfunction %%make-disposable ((ptr arg_y) (vector arg_z))
704 (check-nargs 2)
705 (mark-as-imm temp0)
706 (let ((imm1 temp0))
707 (lea (@ (- x8632::fulltag-misc) (% vector)) (% imm0)) ; imm0 is addr = vect less tag
708 (movzwl (@ -2 (% imm0)) (% imm1)) ; get delta
709 (subl (% imm1) (% imm0)) ; vector addr (less tag) - delta is orig addr
710 (movl (% imm0) (@ x8632::macptr.address (% ptr))))
711 (mark-as-node temp0)
712 (single-value-return))
713
714(defx8632lapfunction %vect-data-to-macptr ((vect arg_y) (ptr arg_z))
[15241]715 (cmpb ($ x8632::subtag-double-float-vector) (@ x8632::misc-subtag-offset (% vect)))
716 (je @dfloat)
717 (cmpb ($ x8632::subtag-double-float) (@ x8632::misc-subtag-offset (% vect)))
718 (je @dfloat)
[7997]719 (lea (@ x8632::misc-data-offset (% vect)) (% imm0))
[15241]720 (jmp @common)
721 @dfloat
722 (lea (@ x8632::misc-dfloat-offset (% vect)) (% imm0))
723 @common
[7997]724 (movl (% imm0) (@ x8632::macptr.address (% ptr)))
725 (single-value-return))
[9270]726
[14710]727(defx8632lapfunction %ivector-from-macptr ((ptr arg_z))
728 (macptr-ptr ptr imm0)
729 (mark-as-imm temp0)
730 (let ((imm1 temp0))
731 (movl (% imm0) (% imm1))
732 (andl ($ target::node-size) (% imm1))
733 (xorl ($ target::node-size) (% imm1))
734 (addl ($ (- target::fulltag-misc target::node-size)) (% imm0))
735 (subl (% imm1) (% imm0))
[14711]736 (mark-as-node temp0))
[14710]737 (movl (% imm0) (% arg_z))
738 (single-value-return))
739
[9270]740;;; Sadly, we have no NVRs on x8632.
741(defun get-saved-register-values ()
742 (values))
[9300]743
744(defx8632lapfunction %current-db-link ()
745 (movl (@ (% :rcontext) x8632::tcr.db-link) (% arg_z))
746 (single-value-return))
747
748(defx8632lapfunction %no-thread-local-binding-marker ()
749 (movl ($ x8632::subtag-no-thread-local-binding) (% arg_z))
750 (single-value-return))
[9475]751
[11450]752(defx8632lapfunction pending-user-interrupt ()
[9475]753 (xorl (% temp0) (% temp0))
[11450]754 (ref-global x8632::intflag arg_z)
755 ;; If another signal happens now, it will get ignored, same as if it happened
756 ;; before whatever signal is in arg_z. But then these are async signals, so
757 ;; who can be sure it didn't actually happen just before...
[9475]758 (set-global temp0 x8632::intflag)
759 (single-value-return))
[10266]760
761(defx8632lapfunction debug-trap-with-string ((arg arg_z))
762 (check-nargs 1)
763 (uuo-error-debug-trap-with-string)
764 (single-value-return))
765
[10449]766(defx8632lapfunction %safe-get-ptr ((src arg_y) (dest arg_z))
767 (check-nargs 2)
768 (save-simple-frame)
769 (macptr-ptr src imm0)
770 (leal (@ (:^ done) (% fn)) (% ra0))
771 (movl (% imm0) (@ (% :rcontext) x8632::tcr.safe-ref-address))
772 (movl (@ (% imm0)) (% imm0))
773 (jmp done)
774 (:tra done)
775 (recover-fn)
776 (movl ($ 0) (@ (% :rcontext) x8632::tcr.safe-ref-address))
777 (movl (% imm0) (@ x8632::macptr.address (% dest)))
778 (restore-simple-frame)
779 (single-value-return))
780
[10266]781(defx8632lapfunction %%tcr-interrupt ((target arg_z))
782 (check-nargs 1)
783 (ud2a)
784 (:byte 4)
785 (box-fixnum imm0 arg_z)
786 (single-value-return))
787
788(defx8632lapfunction %suspend-tcr ((target arg_z))
789 (check-nargs 1)
790 (ud2a)
791 (:byte 5)
[10407]792 (movzbl (%b imm0) (%l imm0))
[10266]793 (testl (%l imm0) (%l imm0))
[10959]794 (movl ($ (target-nil-value)) (%l arg_z))
[10407]795 (cmovnel (@ (+ target::t-offset target::symbol.vcell) (% arg_z)) (%l arg_z))
[10266]796 (single-value-return))
797
798(defx8632lapfunction %suspend-other-threads ()
799 (check-nargs 0)
800 (ud2a)
801 (:byte 6)
[10959]802 (movl ($ (target-nil-value)) (%l arg_z))
[10266]803 (single-value-return))
804
805(defx8632lapfunction %resume-tcr ((target arg_z))
806 (check-nargs 1)
807 (ud2a)
808 (:byte 7)
[10407]809 (movzbl (%b imm0) (%l imm0))
[10266]810 (testl (%l imm0) (%l imm0))
[10959]811 (movl ($ (target-nil-value)) (%l arg_z))
[10407]812 (cmovnel (@ (+ target::t-offset target::symbol.vcell) (% arg_z)) (%l arg_z))
[10266]813 (single-value-return))
814
815(defx8632lapfunction %resume-other-threads ()
816 (check-nargs 0)
817 (ud2a)
818 (:byte 8)
[10959]819 (movl ($ (target-nil-value)) (%l arg_z))
[10266]820 (single-value-return))
821
[11150]822
823(defx8632lapfunction %kill-tcr ((target arg_z))
824 (check-nargs 1)
825 (ud2a)
826 (:byte 9)
827 (testb (%b imm0) (%b imm0))
828 (movl ($ (target-nil-value)) (%l arg_z))
829 (cmovnel (@ (+ target::t-offset target::symbol.vcell) (% arg_z)) (%l arg_z))
830 (single-value-return))
831
[10266]832(defx8632lapfunction %get-spin-lock ((p arg_z))
833 (check-nargs 1)
834 (save-simple-frame)
835 (push (% arg_z))
836 @again
837 (mark-as-imm temp1)
838 (movl (@ -4 (% ebp)) (% arg_z))
839 (macptr-ptr arg_z temp1)
840 (movl (@ '*spin-lock-tries* (% fn)) (% arg_y))
841 (movl (@ '*spin-lock-timeouts* (% fn)) (% arg_z))
842 (movl (@ target::symbol.vcell (% arg_y)) (% arg_y))
[10270]843 (movl (@ (% :rcontext) x8632::tcr.linear) (% temp0))
[10266]844 @try-swap
845 (xorl (% eax) (% eax))
846 (lock)
847 (cmpxchgl (% temp0) (@ (% temp1)))
848 (je @done)
849 @spin
850 (pause)
851 (cmpl ($ 0) (@ (% temp1)))
852 (je @try-swap)
853 (subl ($ '1) (% arg_y))
854 (jne @spin)
855 @wait
856 (addl ($ x8632::fixnumone) (@ x8632::symbol.vcell (% arg_z)))
857 (mark-as-node temp1)
858 (call-symbol yield 0)
859 (jmp @again)
860 @done
861 (mark-as-node temp1)
862 (movl (@ -4 (% ebp)) (% arg_z))
863 (restore-simple-frame)
864 (single-value-return))
865
[11422]866;; tbd
867(defx8632lapfunction %%apply-in-frame-proto ()
868 (hlt))
[10266]869
870(defx8632lapfunction %atomic-pop-static-cons ()
871 @again
[10959]872 (movl (@ (+ (target-nil-value) (x8632::kernel-global static-conses))) (% eax))
[11526]873 (cmpl ($ (target-nil-value)) (% eax))
[10266]874 (jz @lose)
875 (%cdr eax temp0)
876 (lock)
[10959]877 (cmpxchgl (% temp0) (@ (+ (target-nil-value) (x8632::kernel-global static-conses))))
[10266]878 (jnz @again)
[13279]879 (lock)
880 (subl ($ '1) (@ (+ (target-nil-value) (x8632::kernel-global free-static-conses))))
[10266]881 @lose
882 (movl (% eax) (% arg_z))
883 (single-value-return))
884
[11526]885
[13279]886
[10266]887(defx8632lapfunction %staticp ((x arg_z))
888 (check-nargs 1)
[13279]889 (ref-global static-cons-area temp0)
[10266]890 (movl (% x) (% imm0))
[13279]891 (movl ($ (target-nil-value)) (% arg_z))
[10266]892 (subl (@ target::area.low (% temp0)) (% imm0))
893 (shrl ($ target::dnode-shift) (% imm0))
[13279]894 (mark-as-imm temp1)
895 (movl (@ target::area.ndnodes (% temp0)) (% temp1))
896 (subl (% imm0) (% temp1))
897 (lea (@ 128 (% temp1)) (% temp1))
898 (leal (@ (% temp1) target::fixnumone) (% temp1))
899 (cmoval (% temp1) (% arg_z))
900 (mark-as-node temp1)
[10266]901 (single-value-return))
902
903(defx8632lapfunction %static-inverse-cons ((n arg_z))
904 (check-nargs 1)
[13352]905 (testl ($ target::tagmask) (% arg_z))
906 (jne @fail)
[13279]907 (subl ($ '128) (% arg_z))
908 (ref-global static-cons-area temp0)
[13352]909 (movl (@ target::area.ndnodes (% temp0)) (% imm0))
910 (box-fixnum imm0 arg_y)
911 (rcmpl (% arg_z) (% arg_y))
912 (ja @fail)
[13279]913 (movl (@ target::area.high (% temp0)) (% imm0))
914 (subl (% arg_z) (% imm0))
915 (subl (% arg_z) (% imm0))
916 (lea (@ x8632::fulltag-cons (% imm0)) (% arg_z))
[13365]917 (cmpl ($ x8632::subtag-unbound) (@ x8632::cons.car (% arg_z)))
[13352]918 (je @fail)
919 (single-value-return)
920 @fail
921 (movl ($ (target-nil-value)) (% arg_z))
[10266]922 (single-value-return))
[10559]923
924;;; Get the thread-specific value of %fs.
925(defx8632lapfunction %get-fs-register ()
926 (xorl (% imm0) (% imm0))
927 (:byte #x66) ;movw %fs,%ax
928 (:byte #x8c)
929 (:byte #xe0)
930 (box-fixnum imm0 arg_z)
931 (single-value-return))
932
[10575]933(defx8632lapfunction %get-gs-register ()
[10559]934 (xorl (% imm0) (% imm0))
935 (:byte #x66) ;movw %gs,%ax
936 (:byte #x8c)
937 (:byte #xe8)
938 (box-fixnum imm0 arg_z)
939 (single-value-return))
940
Note: See TracBrowser for help on using the repository browser.