source: release/1.8/source/compiler/X86/X8632/x8632-vinsns.lisp

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

GC safety fix to x8632 init-closure vinsn from trunk.

File size: 154.9 KB
RevLine 
[7009]1;;;-*- Mode: Lisp; Package: (CCL :use CL) -*-
2
[13067]3;;; Copyright 2009 Clozure Associates
4;;; This file is part of Clozure CL.
5;;;
6;;; Clozure CL is licensed under the terms of the Lisp Lesser GNU
7;;; Public License , known as the LLGPL and distributed with Clozure
8;;; CL as the file "LICENSE". The LLGPL consists of a preamble and
9;;; the LGPL, which is distributed with Clozure CL as the file "LGPL".
10;;; Where these conflict, the preamble takes precedence.
11;;;
12;;; Clozure CL 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
[7009]17(in-package "CCL")
18
[10497]19
[7009]20(eval-when (:compile-toplevel :load-toplevel :execute)
21 (require "VINSN")
22 (require "X8632-BACKEND"))
23
24(eval-when (:compile-toplevel :execute)
25 (require "X8632ENV"))
26
[9802]27(defun unsigned-to-signed (u nbits)
28 (if (logbitp (1- nbits) u)
29 (- u (ash 1 nbits))
30 u))
31
[7009]32(defmacro define-x8632-vinsn (vinsn-name (results args &optional temps) &body body)
33 (%define-vinsn *x8632-backend* vinsn-name results args temps body))
34
[7428]35(define-x8632-vinsn scale-32bit-misc-index (((dest :u32))
36 ((idx :imm) ; A fixnum
37 )
38 ())
39 (movl (:%l idx) (:%l dest)))
[7009]40
41(define-x8632-vinsn scale-16bit-misc-index (((dest :u32))
42 ((idx :imm))) ; A fixnum
43 (movl (:%l idx) (:%l dest))
44 (shrl (:$ub 1) (:%l dest)))
45
46(define-x8632-vinsn scale-8bit-misc-index (((dest :u32))
47 ((idx :imm))) ; A fixnum
48 (movl (:%l idx) (:%l dest))
49 (shrl (:$ub 2) (:%l dest)))
50
[8629]51;;; same as above, but looks better in bit vector contexts
52(define-x8632-vinsn scale-1bit-misc-index (((dest :u32))
53 ((idx :imm))) ; A fixnum
54 (movl (:%l idx) (:%l dest))
55 (shrl (:$ub 2) (:%l dest)))
56
[7009]57(define-x8632-vinsn misc-ref-u32 (((dest :u32))
58 ((v :lisp)
59 (scaled-idx :u32)))
[7037]60 (movl (:@ x8632::misc-data-offset (:%l v) (:%l scaled-idx)) (:%l dest)))
[7009]61
62(define-x8632-vinsn misc-ref-double-float (((dest :double-float))
63 ((v :lisp)
64 (scaled-idx :imm)))
[11290]65 (movsd (:@ x8632::misc-dfloat-offset (:%l v) (:%l scaled-idx) 2) (:%xmm dest)))
[7009]66
[7112]67(define-x8632-vinsn misc-ref-c-double-float (((dest :double-float))
68 ((v :lisp)
69 (idx :s32const)))
[11861]70 (movsd (:@ (:apply + x8632::misc-dfloat-offset (:apply ash idx 3)) (:%l v)) (:%xmm dest)))
[7112]71
[7009]72(define-x8632-vinsn misc-ref-node (((dest :lisp))
73 ((v :lisp)
74 (scaled-idx :imm)))
[7037]75 (movl (:@ x8632::misc-data-offset (:%l v) (:%l scaled-idx)) (:%l dest)))
[7009]76
[7114]77(define-x8632-vinsn (push-misc-ref-node :push :node :vsp) (()
78 ((v :lisp)
79 (scaled-idx :imm)))
[7112]80 (pushl (:@ x8632::misc-data-offset (:%l v) (:%l scaled-idx))))
[7009]81
[7112]82(define-x8632-vinsn misc-set-node (()
83 ((val :lisp)
84 (v :lisp)
85 (unscaled-idx :imm))
86 ())
[7659]87 (movl (:%l val) (:@ x8632::misc-data-offset (:%l v) (:%l unscaled-idx))))
[7112]88
89(define-x8632-vinsn misc-set-immediate-node (()
90 ((val :s32const)
91 (v :lisp)
92 (unscaled-idx :imm))
93 ())
94 (movl (:$l val) (:@ x8632::misc-data-offset (:%l v) (:%l unscaled-idx))))
95
[11072]96(define-x8632-vinsn misc-set-single-float (()
97 ((val :single-float)
98 (v :lisp)
99 (scaled-idx :u32))
100 ())
101 (movss (:%xmm val) (:@ x8632::misc-data-offset (:%l v) (:%l scaled-idx))))
102
[7112]103(define-x8632-vinsn misc-set-double-float (()
104 ((val :double-float)
105 (v :lisp)
106 (unscaled-idx :imm))
107 ())
[11290]108 (movsd (:%xmm val) (:@ x8632::misc-dfloat-offset (:%l v) (:%l unscaled-idx) 2)))
[7112]109
110(define-x8632-vinsn misc-ref-u8 (((dest :u8))
111 ((v :lisp)
112 (scaled-idx :s32)))
113 (movzbl (:@ x8632::misc-data-offset (:%l v) (:%l scaled-idx)) (:%l dest)))
114
115(define-x8632-vinsn misc-ref-s8 (((dest :s8))
116 ((v :lisp)
117 (scaled-idx :s32)))
118 (movsbl (:@ x8632::misc-data-offset (:%l v) (:%l scaled-idx)) (:%l dest)))
119
[9802]120(define-x8632-vinsn misc-ref-c-u16 (((dest :u16))
121 ((v :lisp)
122 (idx :u32const)))
123 (movzwl (:@ (:apply + x8632::misc-data-offset (:apply ash idx 1)) (:%l v)) (:%l dest)))
124
125(define-x8632-vinsn misc-ref-c-s16 (((dest :s16))
126 ((v :lisp)
127 (idx :u32const)))
128 (movswl (:@ (:apply + x8632::misc-data-offset (:apply ash idx 1)) (:%l v)) (:%l dest)))
129
[7112]130(define-x8632-vinsn misc-ref-u16 (((dest :u16))
131 ((v :lisp)
132 (scaled-idx :s32)))
133 (movzwl (:@ x8632::misc-data-offset (:%l v) (:%l scaled-idx)) (:%l dest)))
134
135(define-x8632-vinsn misc-ref-u32 (((dest :u32))
136 ((v :lisp)
137 (scaled-idx :s32)))
138 (movl (:@ x8632::misc-data-offset (:%l v) (:%l scaled-idx)) (:%l dest)))
139
140(define-x8632-vinsn misc-ref-single-float (((dest :single-float))
141 ((v :lisp)
142 (scaled-idx :s32)))
143 (movss (:@ x8632::misc-data-offset (:%l v) (:%l scaled-idx)) (:%xmm dest)))
144
145(define-x8632-vinsn misc-ref-s32 (((dest :s32))
146 ((v :lisp)
147 (scaled-idx :s32)))
148 (movl (:@ x8632::misc-data-offset (:%l v) (:%l scaled-idx)) (:%l dest)))
149
150(define-x8632-vinsn misc-ref-s16 (((dest :s16))
151 ((v :lisp)
152 (scaled-idx :s32)))
153 (movswl (:@ x8632::misc-data-offset (:%l v) (:%l scaled-idx)) (:%l dest)))
154
155(define-x8632-vinsn misc-ref-c-node (((dest :lisp))
156 ((v :lisp)
157 (idx :u32const)) ; sic
158 ())
159 (movl (:@ (:apply + x8632::misc-data-offset (:apply ash idx x8632::word-shift)) (:%l v)) (:%l dest)))
160
161(define-x8632-vinsn (push-misc-ref-c-node :push :node :vsp)
162 (()
163 ((v :lisp)
164 (idx :u32const)) ; sic
165 ())
166 (pushl (:@ (:apply + x8632::misc-data-offset (:apply ash idx x8632::word-shift)) (:%l v))))
167
168(define-x8632-vinsn misc-ref-c-u32 (((dest :u32))
169 ((v :lisp)
170 (idx :u32const)) ; sic
171 ())
172 ;; xxx - should the 2 be x8632::word-shift?
173 (movl (:@ (:apply + x8632::misc-data-offset (:apply ash idx 2)) (:%l v)) (:%l dest)))
174
175(define-x8632-vinsn misc-ref-c-s32 (((dest :s32))
176 ((v :lisp)
177 (idx :s32const)) ; sic
178 ())
179 (movl (:@ (:apply + x8632::misc-data-offset (:apply ash idx x8632::word-shift)) (:%l v)) (:%l dest)))
180
181(define-x8632-vinsn misc-ref-c-single-float (((dest :single-float))
182 ((v :lisp)
183 (idx :s32const)) ; sic
184 ())
185 (movss (:@ (:apply + x8632::misc-data-offset (:apply ash idx x8632::word-shift)) (:%l v)) (:%xmm dest)))
186
187(define-x8632-vinsn misc-ref-c-u8 (((dest :u32))
188 ((v :lisp)
189 (idx :s32const)) ; sic
190 ())
191 (movzbl (:@ (:apply + x8632::misc-data-offset idx) (:%l v)) (:%l dest)))
192
193(define-x8632-vinsn misc-ref-c-s8 (((dest :s32))
194 ((v :lisp)
195 (idx :s32const)) ; sic
196 ())
197 (movsbl (:@ (:apply + x8632::misc-data-offset idx) (:%l v)) (:%l dest)))
198
[7765]199(define-x8632-vinsn misc-set-c-s8 (((val :s8))
200 ((v :lisp)
201 (idx :u32const))
202 ())
203 (movb (:%b val) (:@ (:apply + x8632::misc-data-offset idx) (:%l v))))
204
205(define-x8632-vinsn misc-set-s8 (((val :s8))
206 ((v :lisp)
207 (scaled-idx :s32))
208 ())
209 (movb (:%b val) (:@ x8632::misc-data-offset (:%l v) (:%l scaled-idx))))
210
211(define-x8632-vinsn mem-ref-s8 (((dest :s8))
212 ((src :address)
213 (index :s32)))
214 (movsbl (:@ (:%l src) (:%l index)) (:%l dest)))
215
[7112]216(define-x8632-vinsn misc-set-c-node (()
217 ((val :lisp)
218 (v :lisp)
219 (idx :s32const)))
220 (movl (:%l val) (:@ (:apply + x8632::misc-data-offset (:apply ash idx 2)) (:%l v))))
221
222(define-x8632-vinsn misc-set-immediate-c-node (()
223 ((val :s32const)
224 (v :lisp)
225 (idx :s32const)))
226 (movl (:$l val) (:@ (:apply + x8632::misc-data-offset (:apply ash idx 2)) (:%l v))))
227
228;;; xxx don't know if this is right
229(define-x8632-vinsn set-closure-forward-reference (()
230 ((val :lisp)
231 (closure :lisp)
232 (idx :s32const)))
233 (movl (:%l val) (:@ (:apply + x8632::misc-data-offset (:apply ash idx x8632::word-shift)) (:%l closure))))
234
235(define-x8632-vinsn misc-set-c-double-float (()
236 ((val :double-float)
237 (v :lisp)
238 (idx :s32const)))
239 (movsd (:%xmm val) (:@ (:apply + x8632::misc-dfloat-offset (:apply ash idx 3)) (:%l v))))
240
241(define-x8632-vinsn (call-known-symbol :call) (((result (:lisp x8632::arg_z)))
242 ()
243 ((entry (:label 1))))
244 (:talign x8632::fulltag-tra)
245 (call (:@ x8632::symbol.fcell (:% x8632::fname)))
[7222]246 (movl (:$self 0) (:%l x8632::fn)))
[7112]247
[7222]248(define-x8632-vinsn (jump-known-symbol :jumplr) (()
249 ())
250
251 (jmp (:@ x8632::symbol.fcell (:% x8632::fname))))
252
[7009]253(define-x8632-vinsn set-nargs (()
[15022]254 ((n :u16const))
255 ((casualty (:lisp #.x8632::nargs))))
[10363]256 ((:pred = n 0)
257 (xorl (:%l x8632::nargs) (:%l x8632::nargs)))
258 ((:not (:pred = n 0))
[8367]259 (movl (:$l (:apply ash n x8632::fixnumshift)) (:%l x8632::nargs))))
[7009]260
261(define-x8632-vinsn check-exact-nargs (()
262 ((n :u16const)))
[10495]263 :resume
[7009]264 ((:pred = n 0)
[8367]265 (testl (:%l x8632::nargs) (:%l x8632::nargs)))
266 ((:and (:pred > n 0) (:pred < n 32))
267 (cmpl (:$b (:apply ash n x8632::fixnumshift)) (:%l x8632::nargs)))
[8629]268 ((:pred >= n 32)
269 (cmpl (:$l (:apply ash n x8632::fixnumshift)) (:%l x8632::nargs)))
[10495]270 (jne :bad)
271 (:anchored-uuo-section :resume)
272 :bad
273 (:anchored-uuo (uuo-error-wrong-number-of-args)))
[7009]274
275(define-x8632-vinsn check-min-nargs (()
[8367]276 ((min :u16const)))
[10495]277 :resume
[8367]278 ((:pred = min 1)
279 (testl (:%l x8632::nargs) (:%l x8632::nargs))
[10495]280 (je :toofew))
[8629]281 ((:not (:pred = min 1))
282 ((:and (:pred > min 1) (:pred < min 32))
283 (rcmpl (:%l x8632::nargs) (:$b (:apply ash min x8632::fixnumshift))))
284 ((:pred >= min 32)
285 (rcmpl (:%l x8632::nargs) (:$l (:apply ash min x8632::fixnumshift))))
[10495]286 (jb :toofew))
287 (:anchored-uuo-section :resume)
288 :toofew
289 (:anchored-uuo (uuo-error-too-few-args)))
[7009]290
291(define-x8632-vinsn check-max-nargs (()
[8367]292 ((n :u16const)))
[10495]293 :resume
[8367]294 ((:pred < n 32)
295 (rcmpl (:%l x8632::nargs) (:$b (:apply ash n x8632::fixnumshift))))
296 ((:pred >= n 32)
297 (rcmpl (:%l x8632::nargs) (:$l (:apply ash n x8632::fixnumshift))))
[10495]298 (ja :bad)
299 (:anchored-uuo-section :resume)
300 :bad
301 (:anchored-uuo (uuo-error-too-many-args)))
[7009]302
[10234]303(define-x8632-vinsn check-min-max-nargs (()
304 ((min :u16const)
[14959]305 (max :u16const)))
[10234]306 :resume
307 ((:pred = min 1)
308 (testl (:%l x8632::nargs) (:%l x8632::nargs))
309 (je :toofew))
310 ((:not (:pred = min 1))
311 ((:pred < min 32)
312 (rcmpl (:%l x8632::nargs) (:$b (:apply ash min x8632::word-shift))))
313 ((:pred >= min 32)
314 (rcmpl (:%l x8632::nargs) (:$l (:apply ash min x8632::word-shift))))
315 (jb :toofew))
316 ((:pred < max 32)
317 (rcmpl (:%l x8632::nargs) (:$b (:apply ash max x8632::word-shift))))
318 ((:pred >= max 32)
319 (rcmpl (:%l x8632::nargs) (:$l (:apply ash max x8632::word-shift))))
320 (ja :toomany)
321
322 (:anchored-uuo-section :resume)
323 :toofew
324 (:anchored-uuo (uuo-error-too-few-args))
325 (:anchored-uuo-section :resume)
326 :toomany
327 (:anchored-uuo (uuo-error-too-many-args)))
328
[7112]329(define-x8632-vinsn default-1-arg (()
330 ((min :u16const)))
[8367]331 ((:pred < min 32)
332 (rcmpl (:%l x8632::nargs) (:$b (:apply ash min x8632::fixnumshift))))
333 ((:pred >= min 32)
334 (rcmpl (:%l x8632::nargs) (:$l (:apply ash min x8632::fixnumshift))))
[7112]335 (jne :done)
336 ((:pred >= min 2)
337 (pushl (:%l x8632::arg_y)))
338 ((:pred >= min 1)
339 (movl (:%l x8632::arg_z) (:%l x8632::arg_y)))
[10984]340 (movl (:$l (:apply target-nil-value)) (:%l x8632::arg_z))
[7112]341 :done)
[7009]342
[7112]343(define-x8632-vinsn default-2-args (()
344 ((min :u16const)))
[8367]345 ((:pred < (:apply 1+ min) 32)
346 (rcmpl (:%l x8632::nargs) (:$b (:apply ash (:apply 1+ min) x8632::fixnumshift))))
347 ((:pred >= (:apply 1+ min) 32)
348 (rcmpl (:%l x8632::nargs) (:$l (:apply ash (:apply 1+ min) x8632::fixnumshift))))
[7112]349 (ja :done)
350 (je :one)
351 ;; We got "min" args; arg_y & arg_z default to nil
352 ((:pred >= min 2)
353 (pushl (:%l x8632::arg_y)))
354 ((:pred >= min 1)
[7114]355 (pushl (:%l x8632::arg_z)))
[10984]356 (movl (:$l (:apply target-nil-value)) (:%l x8632::arg_y))
[7112]357 (jmp :last)
358 :one
359 ;; We got min+1 args: arg_y was supplied, arg_z defaults to nil.
360 ((:pred >= min 1)
361 (pushl (:%l x8632::arg_y)))
362 (movl (:%l x8632::arg_z) (:%l x8632::arg_y))
363 :last
[10984]364 (movl (:$l (:apply target-nil-value)) (:%l x8632::arg_z))
[7112]365 :done)
366
367(define-x8632-vinsn default-optionals (()
368 ((n :u16const))
[8629]369 ((temp :u32)
370 (nargs (:lisp #.x8632::nargs))))
371 (movl (:%l x8632::nargs) (:%l temp))
[8367]372 ((:pred < n 32)
373 (rcmpl (:%l x8632::nargs) (:$b (:apply ash n x8632::fixnumshift))))
374 ((:pred >= n 32)
375 (rcmpl (:%l x8632::nargs) (:$l (:apply ash n x8632::fixnumshift))))
[7112]376 (jae :done)
377 :loop
[8367]378 (addl (:$b x8632::fixnumone) (:%l temp))
[10984]379 (pushl (:$l (:apply target-nil-value)))
[8367]380 ((:pred < n 32)
381 (cmpl (:$b (:apply ash n x8632::fixnumshift)) (:%l temp)))
382 ((:pred >= n 32)
383 (cmpl (:$l (:apply ash n x8632::fixnumshift)) (:%l temp)))
[7112]384 (jne :loop)
[8256]385 :done)
[7112]386
387(define-x8632-vinsn save-lisp-context-no-stack-args (()
388 ())
389 (pushl (:%l x8632::ebp))
390 (movl (:%l x8632::esp) (:%l x8632::ebp)))
391
392(define-x8632-vinsn save-lisp-context-offset (()
393 ((nbytes-pushed :s32const)))
394 (movl (:%l x8632::ebp) (:@ (:apply + nbytes-pushed x8632::node-size) (:%l x8632::esp)))
[7114]395 (leal (:@ (:apply + nbytes-pushed x8632::node-size) (:%l x8632::esp)) (:%l x8632::ebp))
396 (popl (:@ x8632::node-size (:%l x8632::ebp))))
[7112]397
398(define-x8632-vinsn save-lisp-context-variable-arg-count (()
399 ()
[8629]400 ((temp :u32)
401 (nargs (:lisp #.x8632::nargs))))
[8367]402 (movl (:%l x8632::nargs) (:%l temp))
[7112]403 (subl (:$b (* $numx8632argregs x8632::node-size)) (:%l temp))
404 (jle :push)
405 (movl (:%l x8632::ebp) (:@ x8632::node-size (:%l x8632::esp) (:%l temp)))
406 (leal (:@ x8632::node-size (:%l x8632::esp) (:%l temp)) (:%l x8632::ebp))
407 (popl (:@ x8632::node-size (:%l x8632::ebp)))
408 (jmp :done)
409 :push
410 (pushl (:%l x8632::ebp))
411 (movl (:%l x8632::esp) (:%l x8632::ebp))
412 :done)
413
414;;; We know that some args were pushed, but don't know how many were
415;;; passed.
416(define-x8632-vinsn save-lisp-context-in-frame (()
417 ()
[8629]418 ((temp :u32)
419 (nargs (:lisp #.x8632::nargs))))
[8367]420 (movl (:%l x8632::nargs) (:%l temp))
[7112]421 (subl (:$b (* $numx8632argregs x8632::node-size)) (:%l temp))
[7114]422 (movl (:%l x8632::ebp) (:@ x8632::node-size (:%l x8632::esp) (:%l temp)))
[7112]423 (leal (:@ x8632::node-size (:%l x8632::esp) (:%l temp)) (:%l x8632::ebp))
424 (popl (:@ x8632::node-size (:%l x8632::ebp))))
425
[7009]426(define-x8632-vinsn (vpush-register :push :node :vsp)
427 (()
428 ((reg :lisp)))
429 (pushl (:% reg)))
430
431(define-x8632-vinsn (vpush-fixnum :push :node :vsp)
432 (()
433 ((const :s32const)))
434 ((:and (:pred < const 128) (:pred >= const -128))
435 (pushl (:$b const)))
436 ((:not (:and (:pred < const 128) (:pred >= const -128)))
437 (pushl (:$l const))))
438
[7112]439(define-x8632-vinsn vframe-load (((dest :lisp))
440 ((frame-offset :u16const)
441 (cur-vsp :u16const)))
442 (movl (:@ (:apply - (:apply + frame-offset x8632::word-size-in-bytes)) (:%l x8632::ebp)) (:%l dest)))
443
444(define-x8632-vinsn compare-vframe-offset-to-nil (()
445 ((frame-offset :u16const)
446 (cur-vsp :u16const)))
[10984]447 (cmpl (:$l (:apply target-nil-value)) (:@ (:apply - (:apply + frame-offset x8632::word-size-in-bytes)) (:%l x8632::ebp))))
[7112]448
[15022]449
450(define-x8632-vinsn compare-vframe-offset-to-fixnum (()
451 ((frame-offset :u16const)
452 (fixval :s32const)))
453 ((:and (:pred < fixval 128) (:pred >= fixval -128))
454 (cmpl (:$b fixval) (:@ (:apply - (:apply + frame-offset x8632::word-size-in-bytes)) (:%l x8632::ebp))))
455 ((:not (:and (:pred < fixval 128) (:pred >= fixval -128)))
456 (cmpl (:$l fixval) (:@ (:apply - (:apply + frame-offset x8632::word-size-in-bytes)) (:%l x8632::ebp)))))
457
458(define-x8632-vinsn add-constant-to-vframe-offset (()
459 ((frame-offset :u16const)
460 (constant :s32const)))
461 ((:and (:pred < constant 128) (:pred >= constant -128))
462 (addl (:$b constant) (:@ (:apply - (:apply + frame-offset x8632::word-size-in-bytes)) (:%l x8632::ebp))))
463 ((:not (:and (:pred < constant 128) (:pred >= constant -128)))
464 (addl (:$l constant) (:@ (:apply - (:apply + frame-offset x8632::word-size-in-bytes)) (:%l x8632::ebp)))))
465
[7112]466(define-x8632-vinsn compare-value-cell-to-nil (()
467 ((vcell :lisp)))
[10984]468 (cmpl (:$l (:apply target-nil-value)) (:@ x8632::value-cell.value (:%l vcell))))
[7112]469
470(define-x8632-vinsn lcell-load (((dest :lisp))
471 ((cell :lcell)
472 (top :lcell)))
473 (movl (:@ (:apply - (:apply + (:apply calc-lcell-offset cell) x8632::word-size-in-bytes)) (:%l x8632::ebp)) (:%l dest)))
474
475(define-x8632-vinsn (vframe-push :push :node :vsp)
476 (()
477 ((frame-offset :u16const)
478 (cur-vsp :u16const)))
[7114]479 (pushl (:@ (:apply - (:apply + frame-offset x8632::word-size-in-bytes)) (:%l x8632::ebp))))
[7112]480
481(define-x8632-vinsn vframe-store (()
482 ((src :lisp)
483 (frame-offset :u16const)
484 (cur-vsp :u16const)))
485 (movl (:%l src) (:@ (:apply - (:apply + frame-offset x8632::word-size-in-bytes)) (:%l x8632::ebp))))
486
487(define-x8632-vinsn lcell-store (()
488 ((src :lisp)
489 (cell :lcell)
490 (top :lcell)))
491 (movl (:%l src) (:@ (:apply - (:apply + (:apply calc-lcell-offset cell) x8632::word-size-in-bytes)) (:%l x8632::ebp))))
492
493(define-x8632-vinsn (popj :lispcontext :pop :csp :lrRestore :jumpLR)
494 (()
495 ())
496 (leave)
497 (ret))
498
499(define-x8632-vinsn (restore-full-lisp-context :lispcontext :pop :vsp )
500 (()
501 ())
502 (leave))
503
504(define-x8632-vinsn compare-to-nil (()
505 ((arg0 t)))
[10984]506 (cmpl (:$l (:apply target-nil-value)) (:%l arg0)))
[7112]507
[10234]508(define-x8632-vinsn compare-to-t (()
509 ((arg0 t)))
[10984]510 (cmpl (:$l (:apply target-t-value)) (:%l arg0)))
[10234]511
[7009]512(define-x8632-vinsn ref-constant (((dest :lisp))
513 ((lab :label)))
514 (movl (:@ (:^ lab) (:%l x8632::fn)) (:%l dest)))
515
[10234]516(define-x8632-vinsn compare-constant-to-register (()
517 ((lab :label)
518 (reg :lisp)))
519 (cmpl (:@ (:^ lab) (:%l x8632::fn)) (:%l reg)))
520
[7009]521(define-x8632-vinsn (vpush-constant :push :node :vsp) (()
522 ((lab :label)))
[7112]523 (pushl (:@ (:^ lab) (:%l x8632::fn))))
[7009]524
525(define-x8632-vinsn (jump :jump)
526 (()
527 ((label :label)))
528 (jmp label))
529
530(define-x8632-vinsn (cbranch-true :branch) (()
531 ((label :label)
532 (crbit :u8const)))
533 (jcc (:$ub crbit) label))
534
535(define-x8632-vinsn (cbranch-false :branch) (()
536 ((label :label)
537 (crbit :u8const)))
538 (jcc (:$ub (:apply logxor 1 crbit)) label))
539
[7112]540(define-x8632-vinsn (lri :constant-ref) (((dest :imm))
541 ((intval :s32const))
542 ())
543 ((:pred = intval 0)
544 (xorl (:%l dest) (:%l dest)))
[7428]545 ((:not (:pred = intval 0))
[7112]546 (movl (:$l intval) (:%l dest))))
547
[7817]548(define-x8632-vinsn (lriu :constant-ref) (((dest :imm))
549 ((intval :u32const))
550 ())
551 ((:pred = intval 0)
552 (xorl (:%l dest) (:%l dest)))
553 ((:not (:pred = intval 0))
554 (movl (:$l intval) (:%l dest))))
555
[7112]556;;; In the following trap/branch-unless vinsns, it might be worth
557;;; trying to use byte instructions when the args are known to be
558;;; accessible as byte regs. It also might be possible to
559;;; special-case eax/ax/al.
560
561(define-x8632-vinsn trap-unless-bit (()
562 ((value :lisp)))
[10495]563 :resume
[7112]564 (testl (:$l (lognot x8632::fixnumone)) (:%l value))
[10495]565 (jne :bad)
[7112]566
[10495]567 (:anchored-uuo-section :resume)
568 :bad
569 (:anchored-uuo (uuo-error-reg-not-type (:%l value) (:$ub arch::error-object-not-bit))))
570
[7133]571;;; note that NIL is just a distinguished CONS.
[7112]572;;; the tag formerly known as fulltag-nil is now
573;;; for tagged return addresses.
574(define-x8632-vinsn trap-unless-list (()
575 ((object :lisp))
[8211]576 ((tag :u8)))
[10495]577 :resume
[8211]578 (movl (:% object) (:% tag))
579 (andl (:$b x8632::fulltagmask) (:% tag))
580 (cmpl (:$b x8632::fulltag-cons) (:% tag))
[10495]581 (jne :bad)
[7112]582
[10495]583 (:anchored-uuo-section :resume)
584 :bad
585 (:anchored-uuo (uuo-error-reg-not-list (:%l object))))
586
[7112]587(define-x8632-vinsn trap-unless-cons (()
588 ((object :lisp))
[8367]589 ((tag :u8)))
590 ;; special check for NIL (which is a distinguished CONS on x8632)
[10495]591 :resume
[10984]592 (cmpl (:$l (:apply target-nil-value)) (:%l object))
[9692]593 (je :bad)
[8367]594 (movl (:%l object) (:%l tag))
595 (andl (:$b x8632::fulltagmask) (:%l tag))
596 (cmpl (:$b x8632::fulltag-cons) (:%l tag))
[10495]597 (jne :bad)
598
599 (:anchored-uuo-section :resume)
[7112]600 :bad
[10495]601 (:anchored-uuo (uuo-error-reg-not-tag (:%l object) (:$ub x8632::fulltag-cons))))
[7112]602
[8629]603(define-x8632-vinsn set-z-flag-if-consp (()
604 ((object :lisp))
605 ((tag (:u32 #.x8632::imm0))))
606 (movl (:%l object) (:%accl tag))
[11030]607 (andl (:$b x8632::fulltagmask) (:%accl tag))
[8629]608 (cmpb (:$b x8632::fulltag-cons) (:%accb tag))
[8687]609 (setne (:%b x8632::ah))
[10984]610 (cmpl (:$l (:apply target-nil-value)) (:% object))
[8629]611 (sete (:%b x8632::al))
[8687]612 (orb (:%b x8632::ah) (:%b x8632::al)))
[8629]613
[7009]614(define-x8632-vinsn trap-unless-uvector (()
615 ((object :lisp))
[8367]616 ((tag :u8)))
[10495]617 :resume
[8367]618 (movl (:%l object) (:%l tag))
619 (andl (:$b x8632::tagmask) (:%l tag))
620 (cmpl (:$b x8632::tag-misc) (:%l tag))
[10495]621 (jne :bad)
[7009]622
[10495]623 (:anchored-uuo-section :resume)
624 :bad
625 (:anchored-uuo (uuo-error-reg-not-tag (:%l object) (:$ub x8632::tag-misc))))
626
[7112]627(define-x8632-vinsn trap-unless-character (()
[8367]628 ((object :lisp))
629 ((tag :u8)))
630 ;; xxx can't be sure that object will be in a byte-accessible register
[10495]631 :resume
[8367]632 (movl (:%l object) (:%l tag))
633 (cmpb (:$b x8632::subtag-character) (:%b tag))
[10495]634 (jne :bad)
[7112]635
[10495]636 (:anchored-uuo-section :resume)
637 :bad
638 (:anchored-uuo(uuo-error-reg-not-tag (:%l object) (:$ub x8632::subtag-character))))
639
[7112]640(define-x8632-vinsn trap-unless-fixnum (()
641 ((object :lisp))
642 ())
[10495]643 :resume
[8367]644 (testl (:$l x8632::tagmask) (:%l object))
[10495]645 (jne :bad)
[7112]646
[10495]647 (:anchored-uuo-section :resume)
648 :bad
649 (:anchored-uuo (uuo-error-reg-not-fixnum (:%l object))))
650
[7112]651(define-x8632-vinsn set-flags-from-lisptag (()
652 ((reg :lisp)))
[8367]653 (testl (:$l x8632::tagmask) (:%l reg)))
[7112]654
655(define-x8632-vinsn trap-unless-typecode= (()
656 ((object :lisp)
[7251]657 (tagval :u8const))
658 ((tag :u8)))
[10495]659 :resume
[7251]660 (movl (:%l object) (:%l tag))
661 ((:pred = (:apply %hard-regspec-value tag) x8632::eax)
662 ;; accumulator
[8231]663 (andl (:$b x8632::tagmask) (:%accl tag))
664 (cmpl (:$b x8632::tag-misc) (:%accl tag)))
665 ((:pred > (:apply %hard-regspec-value tag) x8632::eax)
666 (andl (:$b x8632::tagmask) (:%l tag))
[7251]667 (cmpl (:$b x8632::tag-misc) (:%l tag)))
[7112]668 (jne :have-tag)
[11029]669 ;; This needs to be a sign-extending mov, since the cmpl below
670 ;; will sign-extend the 8-bit constant operand.
671 (movsbl (:@ x8632::misc-subtag-offset (:%l object)) (:%l tag))
[7112]672 :have-tag
[11029]673 (cmpl (:$b tagval) (:%l tag))
[10495]674 (jne :bad)
[7112]675
[10495]676 (:anchored-uuo-section :resume)
677 :bad
678 (:anchored-uuo (uuo-error-reg-not-tag (:%l object) (:$ub tagval))))
679
[7112]680(define-x8632-vinsn trap-unless-single-float (()
681 ((object :lisp))
[8367]682 ((tag :u8)))
[10495]683 :resume
[8367]684 (movl (:%l object) (:%l tag))
685 (andl (:$b x8632::tagmask) (:%l tag))
686 (cmpl (:$b x8632::tag-misc) (:%l tag))
[8629]687 (jne :bad)
[11029]688 (movsbl (:@ x8632::misc-subtag-offset (:%l object)) (:%l tag))
689 (cmpl (:$b x8632::subtag-single-float) (:%l tag))
[10495]690 (jne :bad)
691
692 (:anchored-uuo-section :resume)
[8629]693 :bad
[10495]694 (:anchored-uuo (uuo-error-reg-not-tag (:%l object) (:$ub x8632::subtag-single-float))))
[7112]695
696(define-x8632-vinsn trap-unless-double-float (()
697 ((object :lisp))
[8367]698 ((tag :u8)))
[10495]699 :resume
[8367]700 (movl (:%l object) (:%l tag))
701 (andl (:$b x8632::tagmask) (:%l tag))
702 (cmpl (:$b x8632::tag-misc) (:%l tag))
[8629]703 (jne :bad)
[11029]704 (movsbl (:@ x8632::misc-subtag-offset (:%l object)) (:%l tag))
705 (cmpl (:$b x8632::subtag-double-float) (:%l tag))
[10495]706 (jne :bad)
707
708 (:anchored-uuo-section :resume)
[8629]709 :bad
[10495]710 (:anchored-uuo (uuo-error-reg-not-tag (:%l object) (:$ub x8632::subtag-double-float))))
[7112]711
712(define-x8632-vinsn trap-unless-macptr (()
713 ((object :lisp))
[8367]714 ((tag :u8)))
[10495]715 :resume
[8367]716 (movl (:%l object) (:%l tag))
717 (andl (:$b x8632::tagmask) (:%l tag))
718 (cmpl (:$b x8632::tag-misc) (:%l tag))
[7112]719 (jne :have-tag)
[11029]720 (movsbl (:@ x8632::misc-subtag-offset (:%l object)) (:%l tag))
[7112]721 :have-tag
[8367]722 (cmpl (:$b x8632::subtag-macptr) (:%l tag))
[10495]723 (jne :bad)
[7112]724
[10495]725 (:anchored-uuo-section :resume)
726 :bad
727 (:anchored-uuo (uuo-error-reg-not-tag (:%l object) (:$ub x8632::subtag-macptr))))
728
[7112]729(define-x8632-vinsn check-misc-bound (()
730 ((idx :imm)
731 (v :lisp))
732 ((temp :u32)))
[10495]733 :resume
[7112]734 (movl (:@ x8632::misc-header-offset (:%l v)) (:%l temp))
[7286]735 ((:and (:pred >= (:apply %hard-regspec-value temp) x8632::eax)
736 (:pred <= (:apply %hard-regspec-value temp) x8632::ebx))
737 (xorb (:%b temp) (:%b temp))
738 (shrl (:$ub (- x8632::num-subtag-bits x8632::fixnumshift)) (:%l temp)))
739 ((:pred > (:apply %hard-regspec-value temp) x8632::ebx)
740 (shrl (:$ub x8632::num-subtag-bits) (:%l temp))
741 (shll (:$ub x8632::fixnumshift) (:%l temp)))
[7114]742 (rcmpl (:%l idx) (:%l temp))
[10495]743 (jae :bad)
[7112]744
[10495]745 (:anchored-uuo-section :resume)
746 :bad
747 (:anchored-uuo (uuo-error-vector-bounds (:%l idx) (:%l v))))
748
[7112]749(define-x8632-vinsn %cdr (((dest :lisp))
750 ((src :lisp)))
751 (movl (:@ x8632::cons.cdr (:%l src)) (:%l dest)))
752
753(define-x8632-vinsn (%vpush-cdr :push :node :vsp)
754 (()
755 ((src :lisp)))
756 (pushl (:@ x8632::cons.cdr (:%l src))))
757
758(define-x8632-vinsn %car (((dest :lisp))
759 ((src :lisp)))
760 (movl (:@ x8632::cons.car (:%l src)) (:%l dest)))
761
762(define-x8632-vinsn (%vpush-car :push :node :vsp)
763 (()
764 ((src :lisp)))
765 (pushl (:@ x8632::cons.car (:%l src))))
766
767(define-x8632-vinsn u32->char (((dest :lisp)
768 (src :u8))
769 ((src :u8))
770 ())
771 (shll (:$ub x8632::charcode-shift) (:%l src))
[7114]772 (leal (:@ x8632::subtag-character (:%l src)) (:%l dest)))
[7112]773
774(define-x8632-vinsn (load-nil :constant-ref) (((dest t))
775 ())
[10984]776 (movl (:$l (:apply target-nil-value)) (:%l dest)))
[7112]777
778
779(define-x8632-vinsn (load-t :constant-ref) (((dest t))
780 ())
[10984]781 (movl (:$l (:apply target-t-value)) (:%l dest)))
[7112]782
783(define-x8632-vinsn extract-tag (((tag :u8))
784 ((object :lisp)))
785 (movl (:%l object) (:%l tag))
[11030]786 (andl (:$b x8632::tagmask) (:%l tag)))
[7112]787
788(define-x8632-vinsn extract-tag-fixnum (((tag :imm))
789 ((object :lisp)))
[8902]790 (leal (:@ (:%l object) 4) (:%l tag))
[8367]791 (andl (:$b (ash x8632::tagmask x8632::fixnumshift)) (:%l tag)))
[7112]792
793(define-x8632-vinsn extract-fulltag (((tag :u8))
794 ((object :lisp)))
795 (movl (:%l object) (:%l tag))
[8367]796 (andl (:$b x8632::fulltagmask) (:%l tag)))
[7112]797
798(define-x8632-vinsn extract-fulltag-fixnum (((tag :imm))
799 ((object :lisp)))
[8367]800 ((:pred =
801 (:apply %hard-regspec-value tag)
802 (:apply %hard-regspec-value object))
803 (shll (:$ub x8632::fixnumshift) (:%l object)))
804 ((:not (:pred =
805 (:apply %hard-regspec-value tag)
806 (:apply %hard-regspec-value object)))
807 (imull (:$b x8632::fixnumone) (:%l object) (:%l tag)))
808 (andl (:$b (ash x8632::fulltagmask x8632::fixnumshift)) (:%l tag)))
[7112]809
[11029]810(define-x8632-vinsn extract-typecode (((tag :u32))
[7112]811 ((object :lisp)))
812 (movl (:%l object) (:%l tag))
[11029]813 (andl (:$b x8632::tagmask) (:%l tag))
814 (cmpl (:$b x8632::tag-misc) (:%l tag))
[7112]815 (jne :have-tag)
[11029]816 (movzbl (:@ x8632::misc-subtag-offset (:%l object)) (:%l tag))
[7112]817 :have-tag)
818
819(define-x8632-vinsn extract-typecode-fixnum (((tag :imm))
820 ((object :lisp))
821 ((temp :u32)))
822 (movl (:%l object) (:%l temp))
[8232]823 (andl (:$b x8632::tagmask) (:%l temp))
824 (cmpl (:$b x8632::tag-misc) (:%l temp))
[7112]825 (jne :have-tag)
[11029]826 (movzbl (:@ x8632::misc-subtag-offset (:%l object)) (:%l temp))
[7112]827 :have-tag
828 (leal (:@ (:%l temp) 4) (:%l tag)))
829
830(define-x8632-vinsn compare-reg-to-zero (()
831 ((reg :imm)))
832 (testl (:%l reg) (:%l reg)))
833
834;;; life will be sad if reg isn't byte accessible
835(define-x8632-vinsn compare-u8-reg-to-zero (()
836 ((reg :u8)))
837 (testb (:%b reg) (:%b reg)))
838
839(define-x8632-vinsn cr-bit->boolean (((dest :lisp))
840 ((crbit :u8const))
841 ((temp :u32)))
[10984]842 (movl (:$l (:apply target-t-value)) (:%l temp))
[7114]843 (leal (:@ (- x8632::t-offset) (:%l temp)) (:%l dest))
[7112]844 (cmovccl (:$ub crbit) (:%l temp) (:%l dest)))
845
846(define-x8632-vinsn compare-s32-constant (()
847 ((val :imm)
848 (const :s32const)))
849 ((:or (:pred < const -128) (:pred > const 127))
850 (rcmpl (:%l val) (:$l const)))
851 ((:not (:or (:pred < const -128) (:pred > const 127)))
852 (rcmpl (:%l val) (:$b const))))
853
854(define-x8632-vinsn compare-u31-constant (()
855 ((val :u32)
856 (const :u32const)))
857 ((:pred > const 127)
858 (rcmpl (:%l val) (:$l const)))
859 ((:not (:pred > const 127))
860 (rcmpl (:%l val) (:$b const))))
861
862(define-x8632-vinsn compare-u8-constant (()
863 ((val :u8)
864 (const :u8const)))
[7286]865 ((:pred = (:apply %hard-regspec-value val) x8632::eax)
866 (rcmpb (:%accb val) (:$b const)))
867 ((:and (:pred > (:apply %hard-regspec-value val) x8632::eax)
868 (:pred <= (:apply %hard-regspec-value val) x8632::ebx))
869 (rcmpb (:%b val) (:$b const)))
870 ((:pred > (:apply %hard-regspec-value val) x8632::ebx)
871 (rcmpl (:%l val) (:$l const)))
[7112]872 )
873
874(define-x8632-vinsn cons (((dest :lisp))
875 ((car :lisp)
[7222]876 (cdr :lisp))
877 ((allocptr (:lisp #.x8632::allocptr))))
[7112]878 (subl (:$b (- x8632::cons.size x8632::fulltag-cons)) (:@ (:%seg :rcontext) x8632::tcr.save-allocptr))
879 (movl (:@ (:%seg :rcontext) x8632::tcr.save-allocptr) (:%l x8632::allocptr))
880 (rcmpl (:%l x8632::allocptr) (:@ (:%seg :rcontext) x8632::tcr.save-allocbase))
[11556]881 (ja :no-trap)
[7112]882 (uuo-alloc)
883 :no-trap
884 (andb (:$b (lognot x8632::fulltagmask)) (:@ (:%seg :rcontext) x8632::tcr.save-allocptr))
885 (movl (:%l car) (:@ x8632::cons.car (:%l x8632::allocptr)))
886 (movl (:%l cdr) (:@ x8632::cons.cdr (:%l x8632::allocptr)))
887 (movl (:%l x8632::allocptr) (:%l dest)))
888
889(define-x8632-vinsn unbox-u8 (((dest :u8))
890 ((src :lisp)))
[10495]891 :resume
[7112]892 (movl (:$l (lognot (ash #xff x8632::fixnumshift))) (:%l dest))
893 (andl (:% src) (:% dest))
[10495]894 (jne :bad)
[7114]895 (movl (:%l src) (:%l dest))
[10495]896 (shrl (:$ub x8632::fixnumshift) (:%l dest))
[7112]897
[10495]898 (:anchored-uuo-section :resume)
899 :bad
900 (:anchored-uuo (uuo-error-reg-not-type (:%l src) (:$ub arch::error-object-not-unsigned-byte-8))))
901
[7112]902(define-x8632-vinsn %unbox-u8 (((dest :u8))
903 ((src :lisp)))
904 (movl (:%l src) (:%l dest))
905 (shrl (:$ub x8632::fixnumshift) (:%l dest))
906 (andl (:$l #xff) (:%l dest)))
907
908(define-x8632-vinsn unbox-s8 (((dest :s8))
909 ((src :lisp)))
[10495]910 :resume
[7112]911 (movl (:%l src) (:%l dest))
912 (shll (:$ub (- x8632::nbits-in-word (+ 8 x8632::fixnumshift))) (:%l dest))
913 (sarl (:$ub (- x8632::nbits-in-word (+ 8 x8632::fixnumshift))) (:%l dest))
914 (cmpl (:%l src) (:%l dest))
[9692]915 (jne :bad)
[8367]916 (testl (:$l x8632::fixnummask) (:%l dest))
[9692]917 (jne :bad)
[7112]918 (sarl (:$ub x8632::fixnumshift) (:%l dest))
[10495]919
920 (:anchored-uuo-section :resume)
[7112]921 :bad
[10495]922 (:anchored-uuo (uuo-error-reg-not-type (:%l src) (:$ub arch::error-object-not-signed-byte-8))))
[7112]923
924(define-x8632-vinsn unbox-u16 (((dest :u16))
925 ((src :lisp)))
[10495]926 :resume
[7112]927 (testl (:$l (lognot (ash #xffff x8632::fixnumshift))) (:% src))
928 (movl (:%l src) (:%l dest))
[10495]929 (jne :bad)
930 (shrl (:$ub x8632::fixnumshift) (:%l dest))
931 (:anchored-uuo-section :resume)
932 :bad
933 (:anchored-uuo (uuo-error-reg-not-type (:%l src) (:$ub arch::error-object-not-unsigned-byte-16))))
[7112]934
935(define-x8632-vinsn %unbox-u16 (((dest :u16))
936 ((src :lisp)))
937 (movl (:%l src) (:%l dest))
938 (shrl (:$ub x8632::fixnumshift) (:%l dest)))
939
940(define-x8632-vinsn unbox-s16 (((dest :s16))
941 ((src :lisp)))
[10495]942 :resume
[7112]943 (movl (:%l src) (:%l dest))
944 (shll (:$ub (- x8632::nbits-in-word (+ 16 x8632::fixnumshift))) (:%l dest))
945 (sarl (:$ub (- x8632::nbits-in-word (+ 16 x8632::fixnumshift))) (:%l dest))
946 (cmpl (:%l src) (:%l dest))
[9692]947 (jne :bad)
[8367]948 (testl (:$l x8632::fixnummask) (:%l dest))
[10495]949 (jne :bad)
950 (sarl (:$ub x8632::fixnumshift) (:%l dest))
951
952 (:anchored-uuo-section :resume)
[7112]953 :bad
[10495]954 (:anchored-uuo (uuo-error-reg-not-type (:%l src) (:$ub arch::error-object-not-signed-byte-16))))
[7112]955
956(define-x8632-vinsn %unbox-s16 (((dest :s16))
957 ((src :lisp)))
958 (movl (:%l src) (:%l dest))
959 (sarl (:$ub x8632::fixnumshift) (:%l dest)))
960
[9584]961;;; An object is of type (UNSIGNED-BYTE 32) iff
962;;; a) it's of type (UNSIGNED-BYTE 30) (e.g., an unsigned fixnum)
963;;; b) it's a bignum of length 1 and the 0'th digit is positive
964;;; c) it's a bignum of length 2 and the sign-digit is 0.
[7112]965(define-x8632-vinsn unbox-u32 (((dest :u32))
966 ((src :lisp)))
[10495]967 :resume
[7112]968 (movl (:$l (lognot (ash x8632::target-most-positive-fixnum x8632::fixnumshift))) (:%l dest))
969 (testl (:%l dest) (:%l src))
970 (movl (:%l src) (:%l dest))
971 (jnz :maybe-bignum)
972 (sarl (:$ub x8632::fixnumshift) (:%l dest))
973 (jmp :done)
974 :maybe-bignum
[8367]975 (andl (:$b x8632::tagmask) (:%l dest))
976 (cmpl (:$b x8632::tag-misc) (:%l dest))
[7112]977 (jne :bad)
978 (movl (:@ x8632::misc-header-offset (:%l src)) (:%l dest))
979 (cmpl (:$l x8632::two-digit-bignum-header) (:%l dest))
[9233]980 (je :two)
981 (cmpl (:$l x8632::one-digit-bignum-header) (:%l dest))
[7112]982 (jne :bad)
[7114]983 (movl (:@ x8632::misc-data-offset (:%l src)) (:%l dest))
[7112]984 (testl (:%l dest) (:%l dest))
[10495]985 (js :bad)
986 (jmp :done)
[9233]987 :two
[7112]988 (movl (:@ (+ 4 x8632::misc-data-offset) (:%l src)) (:%l dest))
989 (testl (:%l dest) (:%l dest))
[9233]990 (jne :bad)
[7112]991 (movl (:@ x8632::misc-data-offset (:%l src)) (:%l dest))
[10495]992 :done
993
994 (:anchored-uuo-section :resume)
995 :bad
996 (:anchored-uuo (uuo-error-reg-not-type (:%l src) (:$ub arch::error-object-not-unsigned-byte-32))))
[7112]997
[10859]998;;; an object is of type (SIGNED-BYTE 32) iff
999;;; a) it's a fixnum
1000;;; b) it's a bignum with exactly one digit.
[7112]1001(define-x8632-vinsn unbox-s32 (((dest :s32))
1002 ((src :lisp)))
[10495]1003 :resume
[7112]1004 (movl (:%l src) (:%l dest))
1005 (sarl (:$ub x8632::fixnumshift) (:%l dest))
1006 ;; Was it a fixnum ?
[8367]1007 (testl (:$l x8632::fixnummask) (:%l src))
[7112]1008 (je :done)
[10859]1009 ;; May be a 1-digit bignum
[8367]1010 (movl (:%l src) (:%l dest))
1011 (andl (:$b x8632::tagmask) (:%l dest))
1012 (cmpl (:$b x8632::tag-misc) (:%l dest))
[7112]1013 (jne :bad)
[10859]1014 (cmpl (:$l x8632::one-digit-bignum-header) (:@ x8632::misc-header-offset (:%l src)))
[7112]1015 (movl (:@ x8632::misc-data-offset (:%l src)) (:%l dest))
[10495]1016 (jne :bad)
1017 :done
1018
1019 (:anchored-uuo-section :resume)
[7112]1020 :bad
[10495]1021 (:anchored-uuo (uuo-error-reg-not-type (:%l src) (:$ub arch::error-object-not-signed-byte-32))))
[7112]1022
1023(define-x8632-vinsn sign-extend-s8 (((dest :s32))
1024 ((src :s8)))
[11355]1025 (movsbl (:%b src) (:%l dest)))
[7112]1026
1027(define-x8632-vinsn sign-extend-s16 (((dest :s32))
1028 ((src :s16)))
[7114]1029 (movswl (:%w src) (:%l dest)))
[7112]1030
1031(define-x8632-vinsn zero-extend-u8 (((dest :s32))
1032 ((src :u8)))
[15022]1033 ((:pred < (:apply %hard-regspec-value src) 4)
1034 (movzbl (:%b src) (:%l dest)))
1035 ((:pred >= (:apply %hard-regspec-value src) 4)
1036 (movl (:%l src) (:%l dest))
1037 (movzbl (:%b dest) (:%l dest))))
1038
[7112]1039
1040(define-x8632-vinsn zero-extend-u16 (((dest :s32))
1041 ((src :u16)))
1042 (movzwl (:%w src) (:%l dest)))
1043
1044(define-x8632-vinsn (jump-subprim :jumpLR) (()
1045 ((spno :s32const)))
1046 (jmp (:@ spno)))
1047
1048;;; Call a subprimitive using a tail-aligned CALL instruction.
1049(define-x8632-vinsn (call-subprim :call) (()
1050 ((spno :s32const))
1051 ((entry (:label 1))))
1052 (:talign x8632::fulltag-tra)
1053 (call (:@ spno))
[7222]1054 (movl (:$self 0) (:% x8632::fn)))
[7112]1055
1056(define-x8632-vinsn fixnum-subtract-from (((dest t)
1057 (y t))
1058 ((y t)
1059 (x t)))
1060 (subl (:%l y) (:%l x)))
1061
[14338]1062(define-x8632-vinsn %ilognot (((dest :imm)
1063 (src :imm))
1064 ((src :imm)))
1065 (xorl (:$b (- x8632::fixnumone)) (:%l dest)))
1066
[7112]1067(define-x8632-vinsn %logand-c (((dest t)
1068 (val t))
1069 ((val t)
1070 (const :s32const)))
1071 ((:and (:pred >= const -128) (:pred <= const 127))
1072 (andl (:$b const) (:%l val)))
1073 ((:not (:and (:pred >= const -128) (:pred <= const 127)))
1074 (andl (:$l const) (:%l val))))
1075
1076(define-x8632-vinsn %logior-c (((dest t)
1077 (val t))
1078 ((val t)
1079 (const :s32const)))
1080 ((:and (:pred >= const -128) (:pred <= const 127))
1081 (orl (:$b const) (:%l val)))
1082 ((:not (:and (:pred >= const -128) (:pred <= const 127)))
1083 (orl (:$l const) (:%l val))))
1084
1085(define-x8632-vinsn %logxor-c (((dest t)
1086 (val t))
1087 ((val t)
1088 (const :s32const)))
1089 ((:and (:pred >= const -128) (:pred <= const 127))
1090 (xorl (:$b const) (:%l val)))
1091 ((:not (:and (:pred >= const -128) (:pred <= const 127)))
1092 (xorl (:$l const) (:%l val))))
1093
1094(define-x8632-vinsn character->fixnum (((dest :lisp))
1095 ((src :lisp))
1096 ())
1097 ((:not (:pred =
1098 (:apply %hard-regspec-value dest)
1099 (:apply %hard-regspec-value src)))
1100 (movl (:%l src) (:%l dest)))
[9233]1101
1102 ((:pred <= (:apply %hard-regspec-value dest) x8632::ebx)
1103 (xorb (:%b dest) (:%b dest)))
1104 ((:pred > (:apply %hard-regspec-value dest) x8632::ebx)
1105 (andl (:$l -256) (:%l dest)))
[7112]1106 (shrl (:$ub (- x8632::charcode-shift x8632::fixnumshift)) (:%l dest)))
1107
[7133]1108(define-x8632-vinsn compare (()
1109 ((x t)
1110 (y t)))
1111 (rcmpl (:%l x) (:%l y)))
1112
[7112]1113(define-x8632-vinsn negate-fixnum (((val :lisp))
1114 ((val :imm)))
1115 (negl (:% val)))
1116
[7428]1117;;; This handles the 1-bit overflow from addition/subtraction/unary negation
1118(define-x8632-vinsn set-bigits-and-header-for-fixnum-overflow
1119 (()
1120 ((val :lisp)
1121 (no-overflow
1122 :label))
1123 ((imm (:u32 #.x8632::imm0))))
[9692]1124 (jno no-overflow)
[7428]1125 (movl (:%l val) (:%l imm))
1126 (sarl (:$ub x8632::fixnumshift) (:%l imm))
1127 (xorl (:$l #xc0000000) (:%l imm))
1128 ;; stash bignum digit
1129 (movd (:%l imm) (:%mmx x8632::mm1))
1130 ;; set header
1131 (movl (:$l x8632::one-digit-bignum-header) (:%l imm))
1132 (movd (:%l imm) (:%mmx x8632::mm0))
1133 ;; need 8 bytes of aligned memory for 1 digit bignum
1134 (movl (:$l (- 8 x8632::fulltag-misc)) (:%l imm)))
[7222]1135
[13248]1136(define-x8632-vinsn handle-fixnum-overflow-inline
1137 (()
1138 ((val :lisp)
1139 (no-overflow
1140 :label))
1141 ((imm (:u32 #.x8632::imm0))
1142 (freeptr (:lisp #.x8632::allocptr))))
1143 (jo :overflow)
1144 (:uuo-section)
1145 :overflow
1146 (movl (:%l val) (:%l imm))
1147 (sarl (:$ub x8632::fixnumshift) (:%l imm))
1148 (xorl (:$l #xc0000000) (:%l imm))
1149 ;; stash bignum digit
1150 (movd (:%l imm) (:%mmx x8632::mm1))
1151 ;; set header
1152 (movl (:$l x8632::one-digit-bignum-header) (:%l imm))
1153 (movd (:%l imm) (:%mmx x8632::mm0))
1154 ;; need 8 bytes of aligned memory for 1 digit bignum
1155 (movl (:$l (- 8 x8632::fulltag-misc)) (:%l imm))
1156 (subl (:%l imm) (:@ (:%seg :rcontext) x8632::tcr.save-allocptr))
1157 (movl (:@ (:%seg :rcontext) x8632::tcr.save-allocptr) (:%l freeptr))
1158 (rcmpl (:%l freeptr) (:@ (:%seg :rcontext) x8632::tcr.save-allocbase))
1159 (ja :no-trap)
1160 (uuo-alloc)
1161 :no-trap
1162 (movd (:%mmx x8632::mm0) (:@ x8632::misc-header-offset (:%l freeptr)))
1163 (andb (:$b (lognot x8632::fulltagmask)) (:@ (:%seg :rcontext) x8632::tcr.save-allocptr))
1164 ((:not (:pred = freeptr
1165 (:apply %hard-regspec-value val)))
1166 (movl (:%l freeptr) (:%l val)))
1167 (movd (:%mmx x8632::mm1) (:@ x8632::misc-data-offset (:%l val)))
1168 (jmp no-overflow))
1169
1170
[7428]1171(define-x8632-vinsn set-bigits-after-fixnum-overflow (()
1172 ((bignum :lisp)))
1173 (movd (:%mmx x8632::mm1) (:@ x8632::misc-data-offset (:%l bignum))))
1174
1175
[7222]1176(define-x8632-vinsn %set-z-flag-if-s32-fits-in-fixnum (((dest :imm))
1177 ((src :s32))
1178 ((temp :s32)))
1179 (movl (:%l src) (:%l temp))
1180 (shll (:$ub x8632::fixnumshift) (:%l temp))
1181 (movl (:%l temp) (:%l dest)) ; tagged as a fixnum
1182 (sarl (:$ub x8632::fixnumshift) (:%l temp))
1183 (cmpl (:%l src) (:%l temp)))
1184
1185(define-x8632-vinsn %set-z-flag-if-u32-fits-in-fixnum (((dest :imm))
1186 ((src :u32))
1187 ((temp :u32)))
1188 (movl (:%l src) (:%l temp))
1189 (shll (:$ub (1+ x8632::fixnumshift)) (:%l temp))
1190 (movl (:%l temp) (:%l dest)) ; tagged as an even fixnum
1191 (shrl (:$ub (1+ x8632::fixnumshift)) (:%l temp))
1192 (shrl (:%l dest))
1193 (cmpl (:%l src) (:%l temp))
1194 :done)
1195
1196;;; setup-bignum-alloc-for-s32-overflow
1197;;; setup-bignum-alloc-for-u32-overflow
1198
[7286]1199(define-x8632-vinsn setup-uvector-allocation (()
1200 ((header :imm)))
1201 (movd (:%l header) (:%mmx x8632::mm0)))
1202
1203;;; The code that runs in response to the uuo-alloc
1204;;; expects a header in mm0, and a size in imm0.
1205;;; mm0 is an implicit arg (it contains the uvector header)
1206;;; size is actually an arg, not a temporary,
[7222]1207;;; but it appears that there's isn't a way to enforce
1208;;; register usage on vinsn args.
[7251]1209(define-x8632-vinsn %allocate-uvector (((dest :lisp))
[7286]1210 ()
1211 ((size (:u32 #.x8632::imm0))
1212 (freeptr (:lisp #.x8632::allocptr))))
[7251]1213 (subl (:%l size) (:@ (:%seg :rcontext) x8632::tcr.save-allocptr))
1214 (movl (:@ (:%seg :rcontext) x8632::tcr.save-allocptr) (:%l freeptr))
1215 (rcmpl (:%l freeptr) (:@ (:%seg :rcontext) x8632::tcr.save-allocbase))
[11556]1216 (ja :no-trap)
[7251]1217 (uuo-alloc)
1218 :no-trap
[7286]1219 (movd (:%mmx x8632::mm0) (:@ x8632::misc-header-offset (:%l freeptr)))
[7251]1220 (andb (:$b (lognot x8632::fulltagmask)) (:@ (:%seg :rcontext) x8632::tcr.save-allocptr))
1221 ((:not (:pred = freeptr
1222 (:apply %hard-regspec-value dest)))
1223 (movl (:%l freeptr) (:%l dest))))
[7222]1224
1225(define-x8632-vinsn box-fixnum (((dest :imm))
1226 ((src :s32)))
1227 ;;(imull (:$b x8632::fixnumone) (:%l src) (:%l dest))
1228 (leal (:@ (:%l src) x8632::fixnumone) (:%l dest)))
1229
[7251]1230(define-x8632-vinsn (fix-fixnum-overflow-ool :call)
1231 (((val :lisp))
1232 ((val :lisp))
[9376]1233 ((unboxed (:s32 #.x8632::imm0))
1234 ;; we use %mm0 for header in subprim
[7251]1235 (entry (:label 1))))
[9692]1236 (jno :done)
[7251]1237 ((:not (:pred = x8632::arg_z
1238 (:apply %hard-regspec-value val)))
1239 (movl (:%l val) (:%l x8632::arg_z)))
1240 (:talign 5)
1241 (call (:@ .SPfix-overflow))
1242 (movl (:$self 0) (:%l x8632::fn))
1243 ((:not (:pred = x8632::arg_z
1244 (:apply %hard-regspec-value val)))
1245 (movl (:%l x8632::arg_z) (:%l val)))
1246 :done)
[7222]1247
1248(define-x8632-vinsn (fix-fixnum-overflow-ool-and-branch :call)
1249 (((val :lisp))
1250 ((val :lisp)
1251 (lab :label))
[9376]1252 ((unboxed (:s32 #.x8632::imm0))
1253 ;; we use %mm0 for header in subprim
[7222]1254 (entry (:label 1))))
[9692]1255 (jno lab)
[7222]1256 ((:not (:pred = x8632::arg_z
1257 (:apply %hard-regspec-value val)))
1258 (movl (:%l val) (:%l x8632::arg_z)))
1259 (:talign 5)
1260 (call (:@ .SPfix-overflow))
1261 (movl (:$self 0) (:%l x8632::fn))
1262 ((:not (:pred = x8632::arg_z
1263 (:apply %hard-regspec-value val)))
1264 (movl (:%l x8632::arg_z) (:%l val)))
1265 (jmp lab))
1266
1267
1268(define-x8632-vinsn add-constant (((dest :imm))
1269 ((dest :imm)
1270 (const :s32const)))
1271 ((:and (:pred >= const -128) (:pred <= const 127))
1272 (addl (:$b const) (:%l dest)))
1273 ((:not (:and (:pred >= const -128) (:pred <= const 127)))
1274 (addl (:$l const) (:%l dest))))
1275
1276(define-x8632-vinsn add-constant3 (((dest :imm))
1277 ((src :imm)
1278 (const :s32const)))
1279 ((:pred = (:apply %hard-regspec-value dest)
1280 (:apply %hard-regspec-value src))
1281 ((:and (:pred >= const -128) (:pred <= const 127))
1282 (addl (:$b const) (:%l dest)))
1283 ((:not (:and (:pred >= const -128) (:pred <= const 127)))
1284 (addl (:$l const) (:%l dest))))
1285 ((:not (:pred = (:apply %hard-regspec-value dest)
1286 (:apply %hard-regspec-value src)))
1287 (leal (:@ const (:%l src)) (:%l dest))))
1288
1289(define-x8632-vinsn fixnum-add2 (((dest :imm))
1290 ((dest :imm)
1291 (other :imm)))
1292 (addl (:%l other) (:%l dest)))
1293
1294(define-x8632-vinsn fixnum-sub2 (((dest :imm))
1295 ((x :imm)
1296 (y :imm))
1297 ((temp :imm)))
1298 (movl (:%l x) (:%l temp))
1299 (subl (:%l y) (:%l temp))
1300 (movl (:%l temp) (:%l dest)))
1301
1302(define-x8632-vinsn fixnum-add3 (((dest :imm))
1303 ((x :imm)
1304 (y :imm)))
1305
1306 ((:pred =
1307 (:apply %hard-regspec-value x)
1308 (:apply %hard-regspec-value dest))
1309 (addl (:%l y) (:%l dest)))
1310 ((:not (:pred =
1311 (:apply %hard-regspec-value x)
1312 (:apply %hard-regspec-value dest)))
1313 ((:pred =
1314 (:apply %hard-regspec-value y)
1315 (:apply %hard-regspec-value dest))
1316 (addl (:%l x) (:%l dest)))
1317 ((:not (:pred =
1318 (:apply %hard-regspec-value y)
1319 (:apply %hard-regspec-value dest)))
1320 (leal (:@ (:%l x) (:%l y)) (:%l dest)))))
1321
1322(define-x8632-vinsn copy-gpr (((dest t))
1323 ((src t)))
1324 ((:not (:pred =
1325 (:apply %hard-regspec-value dest)
1326 (:apply %hard-regspec-value src)))
1327 (movl (:%l src) (:%l dest))))
1328
1329(define-x8632-vinsn (vpop-register :pop :node :vsp)
1330 (((dest :lisp))
1331 ())
1332 (popl (:%l dest)))
1333
1334(define-x8632-vinsn (push-argregs :push :node :vsp) (()
[8367]1335 ())
1336 (rcmpl (:%l x8632::nargs) (:$b (* 1 x8632::node-size)))
[7222]1337 (jb :done)
1338 (je :one)
1339 (pushl (:%l x8632::arg_y))
1340 :one
1341 (pushl (:%l x8632::arg_z))
1342 :done)
1343
1344(define-x8632-vinsn (push-max-argregs :push :node :vsp) (()
1345 ((max :u32const)))
1346 ((:pred >= max 2)
[8367]1347 (rcmpl (:%l x8632::nargs) (:$b (* 1 x8632::node-size)))
[7222]1348 (jb :done)
1349 (je :one)
1350 (pushl (:%l x8632::arg_y))
1351 :one
1352 (pushl (:%l x8632::arg_z))
1353 :done)
1354 ((:pred = max 1)
[8367]1355 (testl (:%l x8632::nargs) (:%l x8632::nargs))
[7222]1356 (je :done)
1357 (pushl (:%l x8632::arg_z))
1358 :done))
1359
1360(define-x8632-vinsn (call-label :call) (()
1361 ((label :label))
1362 ((entry (:label 1))))
1363 (:talign 5)
1364 (call label)
1365 (movl (:$self 0) (:%l x8632::fn)))
1366
1367(define-x8632-vinsn double-float-compare (()
1368 ((arg0 :double-float)
1369 (arg1 :double-float)))
1370 (comisd (:%xmm arg1) (:%xmm arg0)))
1371
1372(define-x8632-vinsn single-float-compare (()
1373 ((arg0 :single-float)
1374 (arg1 :single-float)))
1375 (comiss (:%xmm arg1) (:%xmm arg0)))
1376
1377(define-x8632-vinsn double-float+-2 (((result :double-float))
1378 ((x :double-float)
1379 (y :double-float)))
1380 ((:pred =
1381 (:apply %hard-regspec-value result)
1382 (:apply %hard-regspec-value x))
1383 (addsd (:%xmm y) (:%xmm result)))
1384 ((:and (:not (:pred =
1385 (:apply %hard-regspec-value result)
1386 (:apply %hard-regspec-value x)))
1387 (:pred =
1388 (:apply %hard-regspec-value result)
1389 (:apply %hard-regspec-value y)))
1390 (addsd (:%xmm x) (:%xmm result)))
1391 ((:and (:not (:pred =
1392 (:apply %hard-regspec-value result)
1393 (:apply %hard-regspec-value x)))
1394 (:not (:pred =
1395 (:apply %hard-regspec-value result)
1396 (:apply %hard-regspec-value y))))
1397 (movsd (:%xmm x) (:%xmm result))
1398 (addsd (:%xmm y) (:%xmm result))))
1399
1400;;; Caller guarantees (not (eq y result))
1401(define-x8632-vinsn double-float--2 (((result :double-float))
1402 ((x :double-float)
1403 (y :double-float)))
1404 ((:not (:pred = (:apply %hard-regspec-value result)
1405 (:apply %hard-regspec-value x)))
1406 (movsd (:%xmm x) (:%xmm result)))
1407 (subsd (:%xmm y) (:%xmm result)))
1408
1409(define-x8632-vinsn double-float*-2 (((result :double-float))
1410 ((x :double-float)
1411 (y :double-float)))
1412 ((:pred =
1413 (:apply %hard-regspec-value result)
1414 (:apply %hard-regspec-value x))
1415 (mulsd (:%xmm y) (:%xmm result)))
1416 ((:and (:not (:pred =
1417 (:apply %hard-regspec-value result)
1418 (:apply %hard-regspec-value x)))
1419 (:pred =
1420 (:apply %hard-regspec-value result)
1421 (:apply %hard-regspec-value y)))
1422 (mulsd (:%xmm x) (:%xmm result)))
1423 ((:and (:not (:pred =
1424 (:apply %hard-regspec-value result)
1425 (:apply %hard-regspec-value x)))
1426 (:not (:pred =
1427 (:apply %hard-regspec-value result)
1428 (:apply %hard-regspec-value y))))
1429 (movsd (:%xmm x) (:%xmm result))
1430 (mulsd (:%xmm y) (:%xmm result))))
1431
1432;;; Caller guarantees (not (eq y result))
1433(define-x8632-vinsn double-float/-2 (((result :double-float))
1434 ((x :double-float)
1435 (y :double-float)))
1436 ((:not (:pred = (:apply %hard-regspec-value result)
1437 (:apply %hard-regspec-value x)))
1438 (movsd (:%xmm x) (:%xmm result)))
1439 (divsd (:%xmm y) (:%xmm result)))
1440
1441(define-x8632-vinsn single-float+-2 (((result :single-float))
1442 ((x :single-float)
1443 (y :single-float)))
1444 ((:pred =
1445 (:apply %hard-regspec-value result)
1446 (:apply %hard-regspec-value x))
1447 (addss (:%xmm y) (:%xmm result)))
1448 ((:and (:not (:pred =
1449 (:apply %hard-regspec-value result)
1450 (:apply %hard-regspec-value x)))
1451 (:pred =
1452 (:apply %hard-regspec-value result)
1453 (:apply %hard-regspec-value y)))
1454 (addss (:%xmm x) (:%xmm result)))
1455 ((:and (:not (:pred =
1456 (:apply %hard-regspec-value result)
1457 (:apply %hard-regspec-value x)))
1458 (:not (:pred =
1459 (:apply %hard-regspec-value result)
1460 (:apply %hard-regspec-value y))))
1461 (movss (:%xmm x) (:%xmm result))
1462 (addss (:%xmm y) (:%xmm result))))
1463
1464;;; Caller guarantees (not (eq y result))
1465(define-x8632-vinsn single-float--2 (((result :single-float))
1466 ((x :single-float)
1467 (y :single-float)))
1468 ((:not (:pred = (:apply %hard-regspec-value result)
1469 (:apply %hard-regspec-value x)))
1470 (movss (:%xmm x) (:%xmm result)))
1471 (subss (:%xmm y) (:%xmm result)))
1472
1473(define-x8632-vinsn single-float*-2 (((result :single-float))
1474 ((x :single-float)
1475 (y :single-float)))
1476 ((:pred =
1477 (:apply %hard-regspec-value result)
1478 (:apply %hard-regspec-value x))
1479 (mulss (:%xmm y) (:%xmm result)))
1480 ((:and (:not (:pred =
1481 (:apply %hard-regspec-value result)
1482 (:apply %hard-regspec-value x)))
1483 (:pred =
1484 (:apply %hard-regspec-value result)
1485 (:apply %hard-regspec-value y)))
1486 (mulss (:%xmm x) (:%xmm result)))
1487 ((:and (:not (:pred =
1488 (:apply %hard-regspec-value result)
1489 (:apply %hard-regspec-value x)))
1490 (:not (:pred =
1491 (:apply %hard-regspec-value result)
1492 (:apply %hard-regspec-value y))))
1493 (movss (:%xmm x) (:%xmm result))
1494 (mulss (:%xmm y) (:%xmm result))))
1495
1496;;; Caller guarantees (not (eq y result))
1497(define-x8632-vinsn single-float/-2 (((result :single-float))
1498 ((x :single-float)
1499 (y :single-float)))
1500 ((:not (:pred = (:apply %hard-regspec-value result)
1501 (:apply %hard-regspec-value x)))
1502 (movss (:%xmm x) (:%xmm result)))
1503 (divss (:%xmm y) (:%xmm result)))
1504
1505(define-x8632-vinsn get-single (((result :single-float))
1506 ((source :lisp)))
1507 (movss (:@ x8632::single-float.value (:%l source)) (:%xmm result)))
1508
1509(define-x8632-vinsn get-double (((result :double-float))
1510 ((source :lisp)))
1511 (movsd (:@ x8632::double-float.value (:%l source)) (:%xmm result)))
1512
1513;;; Extract a double-float value, typechecking in the process.
1514;;; IWBNI we could simply call the "trap-unless-typecode=" vinsn here,
1515;;; instead of replicating it ..
[11862]1516(define-x8632-vinsn get-double? (((target :double-float))
1517 ((source :lisp))
1518 ((tag :u8)))
1519 :resume
1520 (movl (:%l source) (:%l tag))
1521 ((:pred = (:apply %hard-regspec-value tag) x8632::eax)
1522 (andl (:$b x8632::tagmask) (:%accl tag))
1523 (cmpl (:$b x8632::tag-misc) (:%accl tag)))
1524 ((:pred > (:apply %hard-regspec-value tag) x8632::eax)
1525 (andl (:$b x8632::tagmask) (:%l tag))
1526 (cmpl (:$b x8632::tag-misc) (:%l tag)))
1527 (jne :have-tag)
1528 (movsbl (:@ x8632::misc-subtag-offset (:%l source)) (:%l tag))
1529 :have-tag
1530 (cmpl (:$b x8632::subtag-double-float) (:%l tag))
1531 (jne :bad)
1532 (movsd (:@ x8632::double-float.value (:%l source)) (:%xmm target))
[7222]1533
[11862]1534 (:anchored-uuo-section :resume)
1535 :bad
1536 (:anchored-uuo (uuo-error-reg-not-tag (:%q source) (:$ub x8632::subtag-double-float))))
[7659]1537
1538(define-x8632-vinsn copy-double-float (((dest :double-float))
1539 ((src :double-float)))
1540 (movsd (:%xmm src) (:%xmm dest)))
1541
[7222]1542(define-x8632-vinsn copy-single-float (((dest :single-float))
1543 ((src :single-float)))
1544 (movss (:%xmm src) (:%xmm dest)))
1545
1546(define-x8632-vinsn copy-single-to-double (((dest :double-float))
1547 ((src :single-float)))
1548 (cvtss2sd (:%xmm src) (:%xmm dest)))
1549
1550(define-x8632-vinsn copy-double-to-single (((dest :single-float))
1551 ((src :double-float)))
1552 (cvtsd2ss (:%xmm src) (:%xmm dest)))
1553
[9587]1554;;; these two clobber unboxed0, unboxed1 in tcr
1555;;; (There's no way to move a value from the x87 stack to an xmm register,
1556;;; so we have to go through memory.)
1557(define-x8632-vinsn fp-stack-to-single (((dest :single-float))
1558 ())
1559 (fstps (:@ (:%seg :rcontext) x8632::tcr.unboxed0))
1560 (movss (:@ (:%seg :rcontext) x8632::tcr.unboxed0) (:%xmm dest)))
1561
1562(define-x8632-vinsn fp-stack-to-double (((dest :double-float))
1563 ())
1564 (fstpl (:@ (:%seg :rcontext) x8632::tcr.unboxed0))
1565 (movsd (:@ (:%seg :rcontext) x8632::tcr.unboxed0) (:%xmm dest)))
1566
[7222]1567(define-x8632-vinsn fitvals (()
1568 ((n :u16const))
[8367]1569 ((imm :u32)))
[7222]1570 ((:pred = n 0)
1571 (xorl (:%l imm) (:%l imm)))
1572 ((:not (:pred = n 0))
[8367]1573 (movl (:$l (:apply ash n x8632::fixnumshift)) (:%l imm)))
1574 (subl (:%l x8632::nargs) (:%l imm))
[7222]1575 (jae :push-more)
1576 (subl (:%l imm) (:%l x8632::esp))
1577 (jmp :done)
1578 :push-loop
[10984]1579 (pushl (:$l (:apply target-nil-value)))
[8367]1580 (addl (:$b x8632::node-size) (:%l x8632::nargs))
1581 (subl (:$b x8632::node-size) (:%l imm))
[7222]1582 :push-more
1583 (jne :push-loop)
1584 :done)
1585
1586(define-x8632-vinsn (nvalret :jumpLR) (()
1587 ())
1588 (jmp (:@ .SPnvalret)))
1589
1590(define-x8632-vinsn lisp-word-ref (((dest t))
1591 ((base t)
1592 (offset t)))
1593 (movl (:@ (:%l base) (:%l offset)) (:%l dest)))
1594
1595(define-x8632-vinsn lisp-word-ref-c (((dest t))
1596 ((base t)
1597 (offset :s32const)))
1598 ((:pred = offset 0)
1599 (movl (:@ (:%l base)) (:%l dest)))
1600 ((:not (:pred = offset 0))
1601 (movl (:@ offset (:%l base)) (:%l dest))))
1602
1603;; start-mv-call
1604
[7339]1605(define-x8632-vinsn (vpush-label :push :node :vsp) (()
[8629]1606 ((label :label))
1607 ((temp :lisp)))
1608 (leal (:@ (:^ label) (:%l x8632::fn)) (:%l temp))
1609 (pushl (:%l temp)))
[7339]1610
[7222]1611(define-x8632-vinsn emit-aligned-label (()
1612 ((label :label)))
[8233]1613 ;; We don't care about label.
1614 ;; We just want the label following this stuff to be tra-tagged.
[7222]1615 (:align 3)
[8629]1616 (nop) (nop) (nop) (nop) (nop))
[7222]1617
1618;; pass-multiple-values-symbol
[7339]1619;;; %ra0 is pointing into %fn, so no need to copy %fn here.
1620(define-x8632-vinsn pass-multiple-values-symbol (()
1621 ())
[10984]1622 (pushl (:@ (:apply + (:apply target-nil-value) (x8632::%kernel-global 'x86::ret1valaddr))))
[7339]1623 (jmp (:@ x8632::symbol.fcell (:% x8632::fname))))
1624
1625
[7428]1626;;; It'd be good to have a variant that deals with a known function
1627;;; as well as this.
1628(define-x8632-vinsn pass-multiple-values (()
1629 ()
1630 ((tag :u8)))
[10495]1631 :resume
[11030]1632 (movl (:%l x8632::temp0) (:%l tag))
1633 (andl (:$b x8632::tagmask) (:%l tag))
1634 (cmpl (:$b x8632::tag-misc) (:%l tag))
[7428]1635 (jne :bad)
[11030]1636 (movsbl (:@ x8632::misc-subtag-offset (:%l x8632::temp0)) (:%l tag))
1637 (cmpl (:$b x8632::subtag-function) (:%l tag))
[7428]1638 (cmovel (:%l x8632::temp0) (:%l x8632::fn))
1639 (je :go)
[11030]1640 (cmpl (:$b x8632::subtag-symbol) (:%l tag))
[7428]1641 (cmovel (:@ x8632::symbol.fcell (:%l x8632::fname)) (:%l x8632::fn))
1642 (jne :bad)
1643 :go
[10984]1644 (pushl (:@ (:apply + (:apply target-nil-value) (x8632::%kernel-global 'x86::ret1valaddr))))
[7428]1645 (jmp (:%l x8632::fn))
[10495]1646 (:anchored-uuo-section :resume)
[7428]1647 :bad
[10495]1648 (:anchored-uuo (uuo-error-not-callable))
[7428]1649)
[7222]1650
[14969]1651(define-x8632-vinsn (pass-multiple-values-known-function :jumplr) (((fnreg :lisp))
1652 ())
1653 (pushl (:@ (:apply + (:apply target-nil-value) (x8632::%kernel-global 'x86::ret1valaddr))))
1654 (jmp (:%l fnreg)))
[7428]1655
[14969]1656
[7222]1657(define-x8632-vinsn reserve-outgoing-frame (()
1658 ())
1659 (pushl (:$b x8632::reserved-frame-marker))
1660 (pushl (:$b x8632::reserved-frame-marker)))
1661
1662;; implicit temp0 arg
1663(define-x8632-vinsn (call-known-function :call) (()
1664 ()
1665 ((entry (:label 1))))
1666 (:talign 5)
1667 (call (:%l x8632::temp0))
1668 (movl (:$self 0) (:%l x8632::fn)))
1669
[7286]1670(define-x8632-vinsn (jump-known-function :jumplr) (()
1671 ())
[8902]1672 (jmp (:%l x8632::temp0)))
[7286]1673
1674(define-x8632-vinsn (list :call) (()
1675 ()
[8902]1676 ((entry (:label 1))
1677 (temp (:lisp #.x8632::temp0))))
1678 (leal (:@ (:^ :back) (:%l x8632::fn)) (:%l x8632::temp0))
[7286]1679 (:talign 5)
[8902]1680 (jmp (:@ .SPconslist))
[7286]1681 :back
1682 (movl (:$self 0) (:%l x8632::fn)))
1683
[7428]1684(define-x8632-vinsn make-fixed-stack-gvector (((dest :lisp))
1685 ((aligned-size :u32const)
1686 (header :s32const))
1687 ((tempa :imm)
1688 (tempb :imm)))
1689 ((:and (:pred >= (:apply + aligned-size x8632::dnode-size) -128)
1690 (:pred <= (:apply + aligned-size x8632::dnode-size) 127))
1691 (subl (:$b (:apply + aligned-size x8632::dnode-size))
1692 (:@ (:%seg :rcontext) x8632::tcr.next-tsp)))
1693 ((:not (:and (:pred >= (:apply + aligned-size x8632::dnode-size) -128)
1694 (:pred <= (:apply + aligned-size x8632::dnode-size) 127)))
1695 (subl (:$l (:apply + aligned-size x8632::dnode-size))
1696 (:@ (:%seg :rcontext) x8632::tcr.next-tsp)))
1697 (movl (:@ (:%seg :rcontext) x8632::tcr.save-tsp) (:%l tempb))
1698 (movl (:@ (:%seg :rcontext) x8632::tcr.next-tsp) (:%l tempa))
1699 (movd (:%l tempb) (:%mmx x8632::stack-temp))
1700 :loop
[9123]1701 (movsd (:%xmm x8632::fpzero) (:@ -8 (:%l tempb)))
[7428]1702 (subl (:$b x8632::dnode-size) (:%l tempb))
1703 (cmpl (:%l tempa) (:%l tempb))
1704 (jnz :loop)
1705 (movd (:%mmx x8632::stack-temp) (:@ (:%l tempa)))
1706 (movl (:%l tempa) (:@ (:%seg :rcontext) x8632::tcr.save-tsp))
1707 (movl (:$l header) (:@ x8632::dnode-size (:%l tempa)))
1708 (leal (:@ (+ x8632::dnode-size x8632::fulltag-misc) (:%l tempa)) (:%l dest)))
1709
1710
1711
[7431]1712
[7428]1713(define-x8632-vinsn make-tsp-vcell (((dest :lisp))
1714 ((closed :lisp))
1715 ((temp :imm)))
1716 (subl (:$b (+ x8632::value-cell.size x8632::dnode-size)) (:@ (:%seg :rcontext) x8632::tcr.next-tsp))
1717 (movd (:@ (:%seg :rcontext) x8632::tcr.save-tsp) (:%mmx x8632::stack-temp))
1718 (movl (:@ (:%seg :rcontext) x8632::tcr.next-tsp) (:%l temp))
[9123]1719 (movsd (:%xmm x8632::fpzero) (:@ (:%l temp)))
1720 (movsd (:%xmm x8632::fpzero) (:@ x8632::dnode-size (:%l temp)))
[7428]1721 (movd (:%mmx x8632::stack-temp) (:@ (:%l temp)))
1722 (movl (:%l temp) (:@ (:%seg :rcontext) x8632::tcr.save-tsp))
1723 (movl (:$l x8632::value-cell-header) (:@ x8632::dnode-size (:%l temp)))
1724 (movl (:%l closed) (:@ (+ x8632::dnode-size x8632::node-size) (:%l temp)))
1725 (leal (:@ (+ x8632::dnode-size x8632::fulltag-misc) (:%l temp)) (:%l dest)))
1726
[7286]1727(define-x8632-vinsn make-tsp-cons (((dest :lisp))
1728 ((car :lisp) (cdr :lisp))
1729 ((temp :imm)))
1730 (subl (:$b (+ x8632::cons.size x8632::dnode-size)) (:@ (:%seg :rcontext) x8632::tcr.next-tsp))
1731 (movl (:@ (:%seg :rcontext) x8632::tcr.next-tsp) (:%l temp))
1732 (movq (:%xmm x8632::fpzero) (:@ (:%l temp)))
1733 (movq (:%xmm x8632::fpzero) (:@ 8 (:%l temp)))
1734 (movd (:@ (:%seg :rcontext) x8632::tcr.save-tsp) (:%mmx x8632::stack-temp))
1735 (movd (:%mmx x8632::stack-temp) (:@ (:%l temp)))
1736 (movl (:%l temp) (:@ (:%seg :rcontext) x8632::tcr.save-tsp))
1737 (leal (:@ (+ x8632::dnode-size x8632::fulltag-cons) (:%l temp)) (:%l temp))
1738 (movl (:%l car) (:@ x8632::cons.car (:%l temp)))
1739 (movl (:%l cdr) (:@ x8632::cons.cdr (:%l temp)))
1740 (movl (:%l temp) (:%l dest)))
1741
1742
[7222]1743;; make-fixed-stack-gvector
1744
[11290]1745(define-x8632-vinsn (discard-temp-frame :tsp :pop :discard) (()
1746 ()
1747 ((temp :imm)))
[7222]1748 (movl (:@ (:%seg :rcontext) x8632::tcr.save-tsp) (:%l temp))
1749 (movl (:@ (:%l temp)) (:%l temp))
1750 (movl (:%l temp) (:@ (:%seg :rcontext) x8632::tcr.save-tsp))
1751 (movl (:%l temp) (:@ (:%seg :rcontext) x8632::tcr.next-tsp))
1752 )
1753
[11290]1754(define-x8632-vinsn (discard-c-frame :csp :pop :discard) (()
1755 ()
1756 ((temp :imm)))
[7222]1757 (movl (:@ (:%seg :rcontext) x8632::tcr.foreign-sp) (:%l temp))
1758 (movl (:@ (:%l temp)) (:%l temp))
1759 (movl (:%l temp) (:@ (:%seg :rcontext) x8632::tcr.foreign-sp)))
1760
1761
[11290]1762(define-x8632-vinsn (vstack-discard :vsp :pop :discard) (()
[7222]1763 ((nwords :u32const)))
1764 ((:not (:pred = nwords 0))
1765 ((:pred < nwords 16)
1766 (addl (:$b (:apply ash nwords x8632::word-shift)) (:%l x8632::esp)))
1767 ((:not (:pred < nwords 16))
1768 (addl (:$l (:apply ash nwords x8632::word-shift)) (:%l x8632::esp)))))
1769
[7286]1770(defmacro define-x8632-subprim-lea-jmp-vinsn ((name &rest other-attrs) spno)
[9678]1771 `(define-x8632-vinsn (,name :call :subprim-call ,@other-attrs) (()
1772 ()
1773 ((entry (:label 1))
1774 (ra (:lisp #.x8632::ra0))))
1775 (leal (:@ (:^ :back) (:%l x8632::fn)) (:%l ra))
[7286]1776 (:talign 5)
1777 (jmp (:@ ,spno))
1778 :back
1779 (movl (:$self 0) (:%l x8632::fn))))
1780
[7222]1781(defmacro define-x8632-subprim-call-vinsn ((name &rest other-attrs) spno)
1782 `(define-x8632-vinsn (,name :call :subprim-call ,@other-attrs) (() () ((entry (:label 1))))
1783 (:talign 5)
1784 (call (:@ ,spno))
1785 :back
1786 (movl (:$self 0) (:%l x8632::fn))))
1787
1788(defmacro define-x8632-subprim-jump-vinsn ((name &rest other-attrs) spno)
[10339]1789 `(define-x8632-vinsn (,name :jumpLR ,@other-attrs) (() ())
[7222]1790 (jmp (:@ ,spno))))
1791
[7286]1792(define-x8632-vinsn (nthrowvalues :call :subprim-call) (()
[9678]1793 ((lab :label))
1794 ((ra (:lisp #.x8632::ra0))))
1795 (leal (:@ (:^ lab) (:%l x8632::fn)) (:%l ra))
[7286]1796 (jmp (:@ .SPnthrowvalues)))
[7222]1797
[7286]1798(define-x8632-vinsn (nthrow1value :call :subprim-call) (()
[9678]1799 ((lab :label))
1800 ((ra (:lisp #.x8632::ra0))))
1801 (leal (:@ (:^ lab) (:%l x8632::fn)) (:%l ra))
[7286]1802 (jmp (:@ .SPnthrow1value)))
[7222]1803
[7659]1804(define-x8632-vinsn set-single-c-arg (()
1805 ((arg :single-float)
[9265]1806 (offset :u32const))
1807 ((temp :imm)))
1808 (movl (:@ (:%seg :rcontext) x8632::tcr.foreign-sp) (:%l temp))
[10561]1809 (movss (:%xmm arg) (:@ (:apply + 8 (:apply ash offset 2)) (:%l temp))))
[7659]1810
1811(define-x8632-vinsn reload-single-c-arg (((arg :single-float))
[9265]1812 ((offset :u32const))
1813 ((temp :imm)))
1814 (movl (:@ (:%seg :rcontext) x8632::tcr.foreign-sp) (:%l temp))
[10561]1815 (movss (:@ (:apply + 8 (:apply ash offset 2)) (:%l temp)) (:%xmm arg)))
[7659]1816
1817(define-x8632-vinsn set-double-c-arg (()
1818 ((arg :double-float)
[9265]1819 (offset :u32const))
1820 ((temp :imm)))
1821 (movl (:@ (:%seg :rcontext) x8632::tcr.foreign-sp) (:%l temp))
[10561]1822 (movsd (:%xmm arg) (:@ (:apply + 8 (:apply ash offset 2)) (:%l temp))))
[7659]1823
1824(define-x8632-vinsn reload-double-c-arg (((arg :double-float))
[9265]1825 ((offset :u32const))
1826 ((temp :imm)))
1827 (movl (:@ (:%seg :rcontext) x8632::tcr.foreign-sp) (:%l temp))
[10561]1828 (movsd (:@ (:apply + 8 (:apply ash offset 2)) (:%l temp)) (:%xmm arg)))
[7659]1829
[10739]1830;;; .SPffcall has stored %edx in tcr.unboxed1. Load %mm0 with a
1831;;; 64-bit value composed from %edx:%eax.
1832(define-x8632-vinsn get-64-bit-ffcall-result (()
1833 ())
1834 (movl (:%l x8632::eax) (:@ (:%seg :rcontext) x8632::tcr.unboxed0))
[11046]1835 (movq (:@ (:%seg :rcontext) x8632::tcr.unboxed0) (:%mmx x8632::mm0)))
[10739]1836
[7659]1837(define-x8632-subprim-call-vinsn (ff-call) .SPffcall)
1838
[8750]1839(define-x8632-subprim-call-vinsn (syscall) .SPsyscall)
1840
[8834]1841(define-x8632-subprim-call-vinsn (syscall2) .SPsyscall2)
1842
[9561]1843(define-x8632-subprim-call-vinsn (setqsym) .SPsetqsym)
1844
[8858]1845(define-x8632-subprim-call-vinsn (gets32) .SPgets32)
1846
1847(define-x8632-subprim-call-vinsn (getu32) .SPgetu32)
1848
[8629]1849(define-x8632-subprim-call-vinsn (gets64) .SPgets64)
1850
1851(define-x8632-subprim-call-vinsn (getu64) .SPgetu64)
1852
1853(define-x8632-subprim-call-vinsn (makes64) .SPmakes64)
1854
1855(define-x8632-subprim-call-vinsn (makeu64) .SPmakeu64)
1856
[7659]1857(define-x8632-subprim-lea-jmp-vinsn (stack-cons-list*) .SPstkconslist-star)
1858
[7431]1859(define-x8632-subprim-lea-jmp-vinsn (list*) .SPconslist-star)
1860
[7286]1861(define-x8632-subprim-lea-jmp-vinsn (bind-interrupt-level-0) .SPbind-interrupt-level-0)
[7222]1862
[7286]1863(define-x8632-vinsn bind-interrupt-level-0-inline (()
1864 ()
1865 ((temp :imm)))
1866 (movl (:@ (:%seg :rcontext) x8632::tcr.tlb-pointer) (:%l temp))
1867 (cmpl (:$b 0) (:@ x8632::interrupt-level-binding-index (:%l temp)))
1868 (pushl (:@ x8632::interrupt-level-binding-index (:%l temp)))
1869 (pushl (:$b x8632::interrupt-level-binding-index))
1870 (pushl (:@ (:%seg :rcontext) x8632::tcr.db-link))
1871 (movl (:$l 0) (:@ x8632::interrupt-level-binding-index (:%l temp)))
1872 (movl (:%l x8632::esp) (:@ (:%seg :rcontext) x8632::tcr.db-link))
[9692]1873 (jns :done)
[7286]1874 (btrl (:$ub 31) (:@ (:%seg :rcontext) x8632::tcr.interrupt-pending))
[9692]1875 (jae :done)
[7286]1876 (ud2a)
1877 (:byte 2)
1878 :done)
[7222]1879
[7659]1880(define-x8632-vinsn bind-interrupt-level-m1-inline (()
1881 ()
1882 ((temp :imm)))
1883 (movl (:@ (:%seg :rcontext) x8632::tcr.tlb-pointer) (:%l temp))
1884 (pushl (:@ x8632::interrupt-level-binding-index (:%l temp)))
1885 (pushl (:$b x8632::interrupt-level-binding-index))
1886 (pushl (:@ (:%seg :rcontext) x8632::tcr.db-link))
1887 (movl (:$l (ash -1 x8632::fixnumshift)) (:@ x8632::interrupt-level-binding-index (:%l temp)))
1888 (movl (:%l x8632::esp) (:@ (:%seg :rcontext) x8632::tcr.db-link)))
1889
[7339]1890(define-x8632-subprim-lea-jmp-vinsn (bind-interrupt-level-m1) .SPbind-interrupt-level-m1)
1891
1892(define-x8632-subprim-lea-jmp-vinsn (bind-interrupt-level) .SPbind-interrupt-level)
1893
1894(define-x8632-subprim-call-vinsn (unbind-interrupt-level) .SPunbind-interrupt-level)
1895
[8902]1896#||
[7659]1897(define-x8632-vinsn unbind-interrupt-level-inline (()
1898 ()
1899 ((link :imm)
1900 (curval :imm)
1901 (oldval :imm)
1902 (tlb :imm)))
1903 (movl (:@ (:%seg :rcontext) x8632::tcr.tlb-pointer) (:%l tlb))
1904 (movl (:@ (:%seg :rcontext) x8632::tcr.db-link) (:%l link))
1905 (movl (:@ x8632::interrupt-level-binding-index (:%l tlb)) (:%l curval))
1906 (testl (:%l curval) (:%l curval))
[8875]1907 (movl (:@ 8 #|binding.val|# (:%l link)) (:%l oldval))
[7659]1908 (movl (:@ #|binding.link|# (:%l link)) (:%l link))
1909 (movl (:%l oldval) (:@ x8632::interrupt-level-binding-index (:%l tlb)))
1910 (movl (:%l link) (:@ (:%seg :rcontext) x8632::tcr.db-link))
[9692]1911 (jns :done)
[7659]1912 (testl (:%l oldval) (:%l oldval))
[9692]1913 (js :done)
[7659]1914 (btrl (:$ub 31) (:@ (:%seg :rcontext) x8632::tcr.interrupt-pending))
[9692]1915 (jae :done)
[7659]1916 (ud2a)
1917 (:byte 2)
1918 :done)
[8902]1919||#
[7659]1920
[7428]1921(define-x8632-vinsn (jump-return-pc :jumpLR) (()
1922 ())
1923 (ret))
1924
[7360]1925;;; xxx
1926(define-x8632-vinsn (nmkcatchmv :call :subprim-call) (()
1927 ((lab :label))
1928 ((entry (:label 1))
1929 (xfn (:lisp #.x8632::xfn))))
1930 (leal (:@ (:^ lab) (:%l x8632::fn)) (:%l xfn))
1931 (:talign 5)
1932 (call (:@ .SPmkcatchmv))
1933 :back
1934 (movl (:$self 0) (:%l x8632::fn)))
1935
[7428]1936(define-x8632-vinsn (nmkcatch1v :call :subprim-call) (()
1937 ((lab :label))
[9678]1938 ((entry (:label 1))
1939 (xfn (:lisp #.x8632::xfn))))
[7428]1940 (leal (:@ (:^ lab) (:%l x8632::fn)) (:%l x8632::xfn))
1941 (:talign 5)
1942 (call (:@ .SPmkcatch1v))
1943 :back
1944 (movl (:$self 0) (:%l x8632::fn)))
[7360]1945
[7428]1946
1947(define-x8632-vinsn (make-simple-unwind :call :subprim-call) (()
1948 ((protform-lab :label)
1949 (cleanup-lab :label)))
1950 (leal (:@ (:^ protform-lab) (:%l x8632::fn)) (:%l x8632::ra0))
1951 (leal (:@ (:^ cleanup-lab) (:%l x8632::fn)) (:%l x8632::xfn))
1952 (jmp (:@ .SPmkunwind)))
1953
1954(define-x8632-vinsn (nmkunwind :call :subprim-call) (()
1955 ((protform-lab :label)
1956 (cleanup-lab :label)))
1957 (leal (:@ (:^ protform-lab) (:%l x8632::fn)) (:%l x8632::ra0))
1958 (leal (:@ (:^ cleanup-lab) (:%l x8632::fn)) (:%l x8632::xfn))
1959 (jmp (:@ .SPnmkunwind)))
1960
[11796]1961(define-x8632-vinsn u16->u32 (((dest :u32))
1962 ((src :u16)))
1963 (movzwl (:%w src) (:%l dest)))
[7428]1964
[11796]1965(define-x8632-vinsn u8->u32 (((dest :u32))
1966 ((src :u8)))
[15022]1967 ((:pred < (:apply %hard-regspec-value src) 4)
1968 (movzbl (:%b src) (:%l dest)))
1969 ((:pred >= (:apply %hard-regspec-value src) 4)
1970 (movl (:%l src) (:%l dest))
1971 (movzbl (:%b dest) (:%l dest))))
1972
[11796]1973
1974(define-x8632-vinsn s16->s32 (((dest :s32))
1975 ((src :s16)))
1976 (movswl (:%w src) (:%l dest)))
1977
1978(define-x8632-vinsn s8->s32 (((dest :s32))
1979 ((src :s8)))
1980 (movsbl (:%b src) (:%l dest)))
1981
[7286]1982(define-x8632-subprim-jump-vinsn (tail-call-fn-gen) .SPtcallnfngen)
[7222]1983
[7286]1984(define-x8632-subprim-jump-vinsn (tail-call-fn-vsp) .SPtcallnfnvsp)
[7222]1985
[7286]1986(define-x8632-vinsn set-eq-bit (()
1987 ())
1988 (testb (:%b x8632::arg_z) (:%b x8632::arg_z)))
1989
1990;;; %schar8
1991;;; %schar32
1992;;; %set-schar8
1993;;; %set-schar32
1994
1995(define-x8632-vinsn misc-set-c-single-float (((val :single-float))
1996 ((v :lisp)
1997 (idx :u32const)))
[9265]1998 (movss (:%xmm val) (:@ (:apply + x8632::misc-data-offset (:apply ash idx 2)) (:%l v))))
[7286]1999
2000(define-x8632-vinsn array-data-vector-ref (((dest :lisp))
2001 ((header :lisp)))
2002 (movl (:@ x8632::arrayH.data-vector (:%l header)) (:%l dest)))
2003
[7428]2004(define-x8632-vinsn set-z-flag-if-istruct-typep (()
2005 ((val :lisp)
2006 (type :lisp))
2007 ((tag :u8)
2008 (valtype :lisp)))
2009 (xorl (:%l valtype) (:%l valtype))
2010 (movl (:%l val) (:%l tag))
[11030]2011 (andl (:$b x8632::tagmask) (:%l tag))
2012 (cmpl (:$b x8632::tag-misc) (:%l tag))
[7428]2013 (jne :have-tag)
[11030]2014 (movsbl (:@ x8632::misc-subtag-offset (:%l val)) (:%l tag))
[7428]2015 :have-tag
[11030]2016 (cmpl (:$b x8632::subtag-istruct) (:%l tag))
[7428]2017 (jne :do-compare)
2018 (movl (:@ x8632::misc-data-offset (:%l val)) (:%l valtype))
2019 :do-compare
2020 (cmpl (:%l valtype) (:%l type)))
[7286]2021
[7222]2022(define-x8632-subprim-call-vinsn (subtag-misc-ref) .SPsubtag-misc-ref)
2023
2024(define-x8632-subprim-call-vinsn (subtag-misc-set) .SPsubtag-misc-set)
2025
[7659]2026(define-x8632-vinsn mem-set-c-constant-fullword (()
2027 ((val :s32const)
2028 (dest :address)
2029 (offset :s32const)))
2030 ((:pred = offset 0)
2031 (movl (:$l val) (:@ (:%l dest))))
2032 ((:not (:pred = offset 0))
2033 (movl (:$l val) (:@ offset (:%l dest)))))
2034
[7765]2035(define-x8632-vinsn mem-set-c-halfword (()
2036 ((val :u16)
2037 (dest :address)
2038 (offset :s32const)))
2039 ((:pred = offset 0)
2040 (movw (:%w val) (:@ (:%l dest))))
2041 ((:not (:pred = offset 0))
2042 (movw (:%w val) (:@ offset (:%l dest)))))
2043
[7659]2044(define-x8632-vinsn mem-set-c-constant-halfword (()
2045 ((val :s16const)
2046 (dest :address)
2047 (offset :s32const)))
2048 ((:pred = offset 0)
2049 (movw (:$w val) (:@ (:%l dest))))
2050 ((:not (:pred = offset 0))
2051 (movw (:$w val) (:@ offset (:%l dest)))))
2052
2053(define-x8632-vinsn mem-set-c-constant-byte (()
2054 ((val :s8const)
2055 (dest :address)
2056 (offset :s32const)))
2057 ((:pred = offset 0)
2058 (movb (:$b val) (:@ (:%l dest))))
2059 ((:not (:pred = offset 0))
2060 (movb (:$b val) (:@ offset (:%l dest)))))
2061
[7765]2062(define-x8632-vinsn mem-set-c-byte (()
2063 ((val :u8)
2064 (dest :address)
2065 (offset :s32const)))
2066 ((:pred = offset 0)
2067 (movb (:%b val) (:@ (:%l dest))))
2068 ((:not (:pred = offset 0))
2069 (movb (:%b val) (:@ offset (:%l dest)))))
2070
[7222]2071(define-x8632-vinsn mem-ref-c-absolute-u8 (((dest :u8))
2072 ((addr :s32const)))
2073 (movzbl (:@ addr) (:%l dest)))
2074
2075(define-x8632-vinsn mem-ref-c-absolute-s8 (((dest :s8))
2076 ((addr :s32const)))
2077 (movsbl (:@ addr) (:%l dest)))
2078
2079(define-x8632-vinsn mem-ref-c-absolute-u16 (((dest :u16))
2080 ((addr :s32const)))
2081 (movzwl (:@ addr) (:%l dest)))
2082
2083(define-x8632-vinsn mem-ref-c-absolute-s16 (((dest :s16))
2084 ((addr :s32const)))
2085 (movswl (:@ addr) (:%l dest)))
2086
2087(define-x8632-vinsn mem-ref-c-absolute-fullword (((dest :u32))
2088 ((addr :s32const)))
2089 (movl (:@ addr) (:%l dest)))
2090
2091(define-x8632-vinsn mem-ref-c-absolute-signed-fullword (((dest :s32))
2092 ((addr :s32const)))
2093 (movl (:@ addr) (:%l dest)))
2094
2095(define-x8632-vinsn mem-ref-c-absolute-natural (((dest :u32))
2096 ((addr :s32const)))
2097 (movl (:@ addr) (:%l dest)))
2098
[7659]2099(define-x8632-vinsn mem-ref-u8 (((dest :u8))
2100 ((src :address)
2101 (index :s32)))
2102 (movzbl (:@ (:%l src) (:%l index)) (:%l dest)))
2103
[7765]2104(define-x8632-vinsn mem-ref-c-u16 (((dest :u16))
2105 ((src :address)
2106 (index :s32const)))
2107 ((:pred = index 0)
2108 (movzwl (:@ (:%l src)) (:%l dest)))
2109 ((:not (:pred = index 0))
2110 (movzwl (:@ index (:%l src)) (:%l dest))))
2111
2112(define-x8632-vinsn mem-ref-u16 (((dest :u16))
2113 ((src :address)
2114 (index :s32)))
2115 (movzwl (:@ (:%l src) (:%l index)) (:%l dest)))
2116
[7817]2117(define-x8632-vinsn mem-ref-c-s16 (((dest :s16))
2118 ((src :address)
2119 (index :s32const)))
2120 ((:pred = index 0)
2121 (movswl (:@ (:%l src)) (:%l dest)))
2122 ((:not (:pred = index 0))
2123 (movswl (:@ index (:%l src)) (:%l dest))))
2124
2125(define-x8632-vinsn mem-ref-s16 (((dest :s16))
2126 ((src :address)
2127 (index :s32)))
2128 (movswl (:@ (:%l src) (:%l index)) (:%l dest)))
2129
[7772]2130(define-x8632-vinsn mem-ref-c-u8 (((dest :u8))
2131 ((src :address)
2132 (index :s16const)))
2133 ((:pred = index 0)
2134 (movzbl (:@ (:%l src)) (:%l dest)))
2135 ((:not (:pred = index 0))
2136 (movzbl (:@ index (:%l src)) (:%l dest))))
2137
2138(define-x8632-vinsn mem-ref-u8 (((dest :u8))
2139 ((src :address)
2140 (index :s32)))
2141 (movzbl (:@ (:%l src) (:%l index)) (:%l dest)))
2142
2143(define-x8632-vinsn mem-ref-c-s8 (((dest :s8))
2144 ((src :address)
2145 (index :s16const)))
2146 ((:pred = index 0)
2147 (movsbl (:@ (:%l src)) (:%l dest)))
2148 ((:not (:pred = index 0))
2149 (movsbl (:@ index (:%l src)) (:%l dest))))
2150
2151(define-x8632-vinsn misc-set-c-s8 (((val :s8))
2152 ((v :lisp)
2153 (idx :u32const))
2154 ())
2155 (movb (:%b val) (:@ (:apply + x8632::misc-data-offset idx) (:%l v))))
2156
2157(define-x8632-vinsn misc-set-s8 (((val :s8))
2158 ((v :lisp)
2159 (scaled-idx :s32))
2160 ())
2161 (movb (:%b val) (:@ x8632::misc-data-offset (:%l v) (:%l scaled-idx))))
2162
2163(define-x8632-vinsn mem-ref-s8 (((dest :s8))
2164 ((src :address)
2165 (index :s32)))
2166 (movsbl (:@ (:%l src) (:%l index)) (:%l dest)))
2167
[7659]2168(define-x8632-vinsn mem-set-constant-fullword (()
2169 ((val :s32const)
2170 (ptr :address)
2171 (offset :s32)))
2172 (movl (:$l val) (:@ (:%l ptr) (:%l offset))))
2173
2174
2175(define-x8632-vinsn mem-set-constant-halfword (()
2176 ((val :s16const)
2177 (ptr :address)
2178 (offset :s32)))
2179 (movw (:$w val) (:@ (:%l ptr) (:%l offset))))
2180
2181(define-x8632-vinsn mem-set-constant-byte (()
2182 ((val :s8const)
2183 (ptr :address)
2184 (offset :s32)))
2185 (movb (:$b val) (:@ (:%l ptr) (:%l offset))))
2186
[9755]2187(define-x8632-vinsn misc-set-c-u8 (((val :u8))
2188 ((v :lisp)
2189 (idx :u32const))
2190 ())
2191 (movb (:%b val) (:@ (:apply + x8632::misc-data-offset idx) (:%l v))))
2192
[7765]2193(define-x8632-vinsn misc-set-u8 (((val :u8))
2194 ((v :lisp)
2195 (scaled-idx :s32))
2196 ())
2197 (movb (:%b val) (:@ x8632::misc-data-offset (:%l v) (:%l scaled-idx))))
2198
[9802]2199(define-x8632-vinsn misc-set-c-u16 (()
2200 ((val :u16)
2201 (v :lisp)
2202 (idx :s32const))
2203 ())
2204 (movw (:%w val) (:@ (:apply + x8632::misc-data-offset (:apply * 2 idx)) (:%l v))))
2205
[7765]2206(define-x8632-vinsn misc-set-u16 (()
2207 ((val :u16)
2208 (v :lisp)
2209 (scaled-idx :s32))
2210 ())
2211 (movw (:%w val) (:@ x8632::misc-data-offset (:%l v) (:%l scaled-idx))))
2212
2213(define-x8632-vinsn misc-set-c-s16 (()
2214 ((val :s16)
2215 (v :lisp)
2216 (idx :s32const))
2217 ())
2218 (movw (:%w val) (:@ (:apply + x8632::misc-data-offset (:apply * 2 idx)) (:%l v))))
2219
2220(define-x8632-vinsn misc-set-s16 (()
2221 ((val :s16)
2222 (v :lisp)
2223 (scaled-idx :s32))
2224 ())
2225 (movw (:%w val) (:@ x8632::misc-data-offset (:%l v) (:%l scaled-idx))))
2226
2227(define-x8632-vinsn misc-set-c-u32 (()
2228 ((val :u32)
2229 (v :lisp)
2230 (idx :u32const)) ; sic
2231 ())
[9572]2232 (movl (:%l val) (:@ (:apply + x8632::misc-data-offset (:apply ash idx 2)) (:%l v))))
[7765]2233
[7428]2234(define-x8632-vinsn misc-set-u32 (()
2235 ((val :u32)
2236 (v :lisp)
[13446]2237 (scaled-idx :imm))
[7428]2238 ())
2239 (movl (:%l val) (:@ x8632::misc-data-offset (:%l v) (:%l scaled-idx))))
2240
[7765]2241(define-x8632-vinsn misc-set-c-s32 (()
2242 ((val :s32)
2243 (v :lisp)
2244 (idx :u32const)) ; sic
2245 ())
[9572]2246 (movl (:%l val) (:@ (:apply + x8632::misc-data-offset (:apply ash idx 2)) (:%l v))))
[7765]2247
2248(define-x8632-vinsn misc-set-s32 (()
2249 ((val :s32)
2250 (v :lisp)
[13446]2251 (scaled-idx :imm))
[7765]2252 ())
2253 (movl (:%l val) (:@ x8632::misc-data-offset (:%l v) (:%l scaled-idx))))
2254
[7817]2255(define-x8632-vinsn %iasr (((dest :imm))
2256 ((count :imm)
2257 (src :imm))
2258 ((temp :s32)
[8629]2259 (shiftcount (:s32 #.x8632::ecx))))
[7817]2260 (movl (:%l count) (:%l temp))
2261 (sarl (:$ub x8632::fixnumshift) (:%l temp))
[13457]2262 (movl (:$l 31) (:%l shiftcount))
2263 (rcmpl (:%l temp) (:%l shiftcount))
2264 (cmovbel (:%l temp) (:%l shiftcount))
[7817]2265 (movl (:%l src) (:%l temp))
2266 (sarl (:%shift x8632::cl) (:%l temp))
2267 (andl (:$l (lognot x8632::fixnummask)) (:%l temp))
2268 (movl (:%l temp) (:%l dest)))
2269
[7659]2270(define-x8632-vinsn %ilsr (((dest :imm))
2271 ((count :imm)
2272 (src :imm))
2273 ((temp :s32)
2274 (shiftcount (:s32 #.x8632::ecx))))
2275 (movl (:%l count) (:%l temp))
2276 (sarl (:$ub x8632::fixnumshift) (:%l temp))
[13457]2277 (movl (:$l 31) (:%l shiftcount))
2278 (rcmpl (:%l temp) (:%l shiftcount))
2279 (cmovbel (:%l temp) (:%l shiftcount))
[7659]2280 (movl (:%l src) (:%l temp))
2281 (shrl (:%shift x8632::cl) (:%l temp))
[13457]2282 (andl (:$b (lognot x8632::fixnummask)) (:%l temp))
[7659]2283 (movl (:%l temp) (:%l dest)))
2284
[7428]2285(define-x8632-vinsn %iasr-c (((dest :imm))
2286 ((count :u8const)
2287 (src :imm))
2288 ((temp :s32)))
2289 (movl (:%l src) (:%l temp))
2290 (sarl (:$ub count) (:%l temp))
2291 (andb (:$b (lognot x8632::fixnummask)) (:%b temp))
2292 (movl (:%l temp) (:%l dest)))
2293
2294(define-x8632-vinsn %ilsr-c (((dest :imm))
2295 ((count :u8const)
2296 (src :imm))
2297 ((temp :s32)))
2298 (movl (:%l src) (:%l temp))
2299 (shrl (:$ub count) (:%l temp))
2300 ;; xxx --- use :%acc
2301 (andb (:$b (lognot x8632::fixnummask)) (:%b temp))
2302 (movl (:%l temp) (:%l dest)))
2303
2304(define-x8632-vinsn %ilsl (((dest :imm))
2305 ((count :imm)
2306 (src :imm))
[14338]2307 ((shiftcount (:s32 #.x8632::ecx))))
2308
2309 (movl (:$l (ash 31 x8632::fixnumshift)) (:%l shiftcount))
2310 (rcmpl (:%l count) (:%l shiftcount))
2311 (cmovbl (:%l count) (:%l shiftcount))
2312 (sarl (:$ub x8632::fixnumshift) (:%l shiftcount))
2313 ((:not (:pred =
2314 (:apply %hard-regspec-value src)
2315 (:apply %hard-regspec-value dest)))
2316 (movl (:%l src) (:%l dest)))
2317 (shll (:%shift x8632::cl) (:%l dest)))
[7428]2318
2319(define-x8632-vinsn %ilsl-c (((dest :imm))
2320 ((count :u8const)
2321 (src :imm)))
2322 ((:not (:pred =
2323 (:apply %hard-regspec-value src)
2324 (:apply %hard-regspec-value dest)))
2325 (movl (:%l src) (:%l dest)))
2326 (shll (:$ub count) (:%l dest)))
2327
[7817]2328;;; In safe code, something else has ensured that the value is of type
2329;;; BIT.
2330(define-x8632-vinsn set-variable-bit-to-variable-value (()
2331 ((vec :lisp)
2332 (word-index :s32)
2333 (bitnum :u8)
2334 (value :lisp)))
2335 (testl (:%l value) (:%l value))
2336 (je :clr)
2337 (btsl (:%l bitnum) (:@ x8632::misc-data-offset (:%l vec) (:%l word-index) 4))
2338 (jmp :done)
2339 :clr
2340 (btrl (:%l bitnum) (:@ x8632::misc-data-offset (:%l vec) (:%l word-index) 4))
2341 :done)
2342
[8629]2343;;; In safe code, something else has ensured that the value is of type
2344;;; BIT.
2345(define-x8632-vinsn nset-variable-bit-to-variable-value (()
2346 ((vec :lisp)
2347 (index :s32)
2348 (value :lisp)))
2349 (testl (:%l value) (:%l value))
2350 (je :clr)
2351 (btsl (:%l index) (:@ x8632::misc-data-offset (:%l vec)))
2352 (jmp :done)
2353 :clr
2354 (btrl (:%l index) (:@ x8632::misc-data-offset (:%l vec)))
2355 :done)
2356
2357(define-x8632-vinsn nset-variable-bit-to-zero (()
2358 ((vec :lisp)
2359 (index :s32)))
2360 (btrl (:%l index) (:@ x8632::misc-data-offset (:%l vec))))
2361
2362(define-x8632-vinsn nset-variable-bit-to-one (()
2363 ((vec :lisp)
2364 (index :s32)))
2365 (btsl (:%l index) (:@ x8632::misc-data-offset (:%l vec))))
2366
[7817]2367(define-x8632-vinsn set-variable-bit-to-zero (()
2368 ((vec :lisp)
2369 (word-index :s32)
2370 (bitnum :u8)))
2371 (btrl (:%l bitnum) (:@ x8632::misc-data-offset (:%l vec) (:%l word-index) 4)))
2372
2373(define-x8632-vinsn set-variable-bit-to-one (()
2374 ((vec :lisp)
2375 (word-index :s32)
2376 (bitnum :u8)))
2377 (btsl (:%l bitnum) (:@ x8632::misc-data-offset (:%l vec) (:%l word-index) 4)))
2378
2379(define-x8632-vinsn set-constant-bit-to-zero (()
2380 ((src :lisp)
2381 (idx :u32const)))
2382 (btrl (:$ub (:apply logand 31 idx))
2383 (:@ (:apply + x8632::misc-data-offset (:apply ash (:apply ash idx -5) x8632::word-shift)) (:%l src))))
2384
2385(define-x8632-vinsn set-constant-bit-to-one (()
2386 ((src :lisp)
2387 (idx :u32const)))
2388 (btsl (:$ub (:apply logand 31 idx))
2389 (:@ (:apply + x8632::misc-data-offset (:apply ash (:apply ash idx -5) x8632::word-shift)) (:%l src))))
2390
2391(define-x8632-vinsn set-constant-bit-to-variable-value (()
2392 ((src :lisp)
2393 (idx :u32const)
2394 (value :lisp)))
2395 (testl (:%l value) (:%l value))
2396 (je :clr)
2397 (btsl (:$ub (:apply logand 31 idx))
2398 (:@ (:apply + x8632::misc-data-offset (:apply ash (:apply ash idx -5) x8632::word-shift)) (:%l src)))
2399 (jmp :done)
2400 :clr
2401 (btrl (:$ub (:apply logand 31 idx))
2402 (:@ (:apply + x8632::misc-data-offset (:apply ash (:apply ash idx -5) x8632::word-shift)) (:%l src)))
2403 :done)
2404
[7428]2405(define-x8632-vinsn require-fixnum (()
2406 ((object :lisp)))
2407 :again
2408 ((:and (:pred > (:apply %hard-regspec-value object) x8632::eax)
2409 (:pred <= (:apply %hard-regspec-value object) x8632::ebx))
[9233]2410 (testb (:$b x8632::fixnummask) (:%b object)))
[7428]2411 ((:pred > (:apply %hard-regspec-value object) x8632::ebx)
2412 (testl (:$l x8632::fixnummask) (:%l object)))
[10495]2413 (jne :bad)
[7428]2414
[10495]2415 (:anchored-uuo-section :again)
2416 :bad
2417 (:anchored-uuo (uuo-error-reg-not-type (:%l object) (:$ub arch::error-object-not-fixnum))))
2418
[7428]2419(define-x8632-vinsn require-integer (()
2420 ((object :lisp))
2421 ((tag :u8)))
2422 :again
2423 (movl (:%l object) (:%l tag))
2424 ((:pred = (:apply %hard-regspec-value tag) x8632::eax)
2425 (andb (:$b x8632::fixnummask) (:%accb tag)))
2426 ((:and (:pred > (:apply %hard-regspec-value tag) x8632::eax)
2427 (:pred <= (:apply %hard-regspec-value tag) x8632::ebx))
2428 (andb (:$b x8632::fixnummask) (:%b tag)))
2429 ((:pred > (:apply %hard-regspec-value object) x8632::ebx)
2430 (andl (:$l x8632::fixnummask) (:%l tag)))
[9692]2431 (je :got-it)
[7428]2432 ((:pred = (:apply %hard-regspec-value tag) x8632::eax)
2433 (cmpb (:$b x8632::tag-misc) (:%accb tag)))
2434 ((:and (:pred > (:apply %hard-regspec-value tag) x8632::eax)
2435 (:pred <= (:apply %hard-regspec-value tag) x8632::ebx))
2436 (cmpb (:$b x8632::tag-misc) (:%b tag)))
2437 ((:pred > (:apply %hard-regspec-value object) x8632::ebx)
2438 (cmpl (:$l x8632::tag-misc) (:%l tag)))
2439 (jne :bad)
2440 (cmpb (:$b x8632::subtag-bignum) (:@ x8632::misc-subtag-offset (:%l object)))
[10495]2441 (jne :bad)
2442 :got-it
2443
2444 (:anchored-uuo-section :again)
[7428]2445 :bad
[10495]2446 (:anchored-uuo (uuo-error-reg-not-type (:%l object) (:$ub arch::error-object-not-integer))))
[7428]2447
[7659]2448(define-x8632-vinsn require-simple-vector (()
2449 ((object :lisp))
2450 ((tag :u8)))
2451 :again
[11029]2452 (movl (:%l object) (:%l tag))
2453 (andl (:$b x8632::fixnummask) (:%l tag))
2454 (cmpl (:$b x8632::tag-misc) (:%l tag))
[7659]2455 (jne :bad)
2456 (cmpb (:$b x8632::subtag-simple-vector) (:@ x8632::misc-subtag-offset (:%l object)))
[10495]2457 (jne :bad)
2458
2459 (:anchored-uuo-section :again)
[7659]2460 :bad
[10495]2461 (:anchored-uuo (uuo-error-reg-not-type (:%l object) (:$ub arch::error-object-not-simple-vector))))
[7659]2462
2463(define-x8632-vinsn require-simple-string (()
2464 ((object :lisp))
2465 ((tag :u8)))
2466 :again
[11029]2467 (movl (:%l object) (:%l tag))
2468 (andl (:$b x8632::fixnummask) (:%l tag))
2469 (cmpl (:$b x8632::tag-misc) (:%l tag))
[7659]2470 (jne :bad)
2471 (cmpb (:$b x8632::subtag-simple-base-string) (:@ x8632::misc-subtag-offset (:%l object)))
[10495]2472 (jne :bad)
2473
2474 (:anchored-uuo-section :again)
[7659]2475 :bad
[10495]2476 (:anchored-uuo (uuo-error-reg-not-type (:%l object) (:$ub arch::error-object-not-simple-string))))
[7659]2477
2478
[7428]2479;;; naive
2480(define-x8632-vinsn require-real (()
2481 ((object :lisp))
[10495]2482 ((tag :u8)
2483 (mask :lisp)))
[7428]2484 :again
2485 (movl (:%l object) (:%l tag))
[10495]2486 (andl (:$b x8632::tagmask) (:%l tag))
[11029]2487 (cmpl (:$b x8632::tag-misc) (:%l tag))
[10495]2488 (jne :have-tag)
[11029]2489 (movzbl (:@ x8632::misc-subtag-offset (:%l object)) (:%l tag))
[10495]2490 :have-tag
[11029]2491 (cmpl (:$b (1- (- x8632::nbits-in-word x8632::fixnumshift))) (:%l tag))
[10495]2492 (movl (:$l (ash (logior (ash 1 x8632::tag-fixnum)
2493 (ash 1 x8632::subtag-single-float)
2494 (ash 1 x8632::subtag-double-float)
2495 (ash 1 x8632::subtag-bignum)
2496 (ash 1 x8632::subtag-ratio))
2497 x8632::fixnumshift)) (:%l mask))
2498 (ja :bad)
2499 (addl (:$b x8632::fixnumshift) (:%l tag))
2500 (btl (:%l tag) (:%l mask))
2501 (jnc :bad)
2502
2503 (:anchored-uuo-section :again)
[7428]2504 :bad
[10495]2505 (:anchored-uuo (uuo-error-reg-not-type (:%l object) (:$ub arch::error-object-not-real))))
[7428]2506
[7659]2507;;; naive
2508(define-x8632-vinsn require-number (()
2509 ((object :lisp))
[10495]2510 ((tag :u8)
2511 (mask :lisp)))
[7659]2512 :again
2513 (movl (:%l object) (:%l tag))
[10495]2514 (andl (:$b x8632::tagmask) (:%l tag))
[11029]2515 (cmpl (:$b x8632::tag-misc) (:%l tag))
[10495]2516 (jne :have-tag)
[11029]2517 (movzbl (:@ x8632::misc-subtag-offset (:%l object)) (:%l tag))
[10495]2518 :have-tag
[11029]2519 (cmpl (:$b (1- (- x8632::nbits-in-word x8632::fixnumshift))) (:%l tag))
[10495]2520 (movl (:$l (ash (logior (ash 1 x8632::tag-fixnum)
2521 (ash 1 x8632::subtag-single-float)
2522 (ash 1 x8632::subtag-double-float)
2523 (ash 1 x8632::subtag-bignum)
2524 (ash 1 x8632::subtag-ratio)
2525 (ash 1 x8632::subtag-complex))
2526 x8632::fixnumshift)) (:%l mask))
2527 (ja :bad)
2528 (addl (:$b x8632::fixnumshift) (:%l tag))
2529 (btl (:%l tag) (:%l mask))
2530 (jnc :bad)
2531
2532 (:anchored-uuo-section :again)
[7659]2533 :bad
[10495]2534 (:anchored-uuo (uuo-error-reg-not-type (:%l object) (:$ub arch::error-object-not-number))))
[7659]2535
2536(define-x8632-vinsn require-list (()
2537 ((object :lisp))
2538 ((tag :u8)))
2539 :again
2540 (movl (:%l object) (:%l tag))
[11029]2541 (andl (:$b x8632::fulltagmask) (:%l tag))
2542 (cmpl (:$b x8632::fulltag-cons) (:%l tag))
[10495]2543 (jne :bad)
[7659]2544
[10495]2545 (:anchored-uuo-section :again)
2546 :bad
2547 (:anchored-uuo (uuo-error-reg-not-type (:%l object) (:$ub arch::error-object-not-list))))
2548
[7428]2549(define-x8632-vinsn require-symbol (()
2550 ((object :lisp))
2551 ((tag :u8)))
2552 :again
[10984]2553 (cmpl (:$l (:apply target-nil-value)) (:%l object))
[7428]2554 (je :got-it)
2555 (movl (:%l object) (:%l tag))
[11029]2556 (andl (:$b x8632::tagmask) (:%l tag))
2557 (cmpl (:$b x8632::tag-misc) (:%l tag))
[7428]2558 (jne :bad)
2559 (cmpb (:$b x8632::subtag-symbol) (:@ x8632::misc-subtag-offset (:%l object)))
[10495]2560 (jne :bad)
2561 :got-it
2562
2563 (:anchored-uuo-section :again)
[7428]2564 :bad
[10495]2565 (:anchored-uuo (uuo-error-reg-not-type (:%l object) (:$ub arch::error-object-not-symbol)))
2566)
[7428]2567
[7659]2568(define-x8632-vinsn require-character (()
[14979]2569 ((object :lisp))
2570 ((tag (:u8 #.x8632::imm0))))
[7659]2571 :again
[14979]2572 ((:pred < (:apply %hard-regspec-value object) 4)
2573 (cmpb (:$b x8632::subtag-character) (:%b object)))
2574 ((:not (:pred < (:apply %hard-regspec-value object) 4))
2575 (movl (:%l object) (:%l tag))
2576 (cmpb (:$b x8632::subtag-character) (:%b tag)))
2577
[10495]2578 (jne :bad)
[7659]2579
[10495]2580 (:anchored-uuo-section :again)
2581 :bad
2582 (:anchored-uuo (uuo-error-reg-not-type (:%l object) (:$ub arch::error-object-not-character))))
2583
[7765]2584(define-x8632-vinsn require-s8 (()
2585 ((object :lisp))
2586 ((tag :u32)))
2587 :again
2588 (movl (:%l object) (:%l tag))
2589 (shll (:$ub (- x8632::nbits-in-word (+ 8 x8632::fixnumshift))) (:%l tag))
2590 (sarl (:$ub (- x8632::nbits-in-word 8)) (:%l tag))
2591 (shll (:$ub x8632::fixnumshift) (:%l tag))
2592 (cmpl (:%l object) (:%l tag))
[10495]2593 (jne :bad)
2594
2595 (:anchored-uuo-section :again)
[7765]2596 :bad
[10495]2597 (:anchored-uuo (uuo-error-reg-not-type (:%l object) (:$ub arch::error-object-not-signed-byte-8))))
[7765]2598
2599(define-x8632-vinsn require-u8 (()
2600 ((object :lisp))
2601 ((tag :u32)))
2602 :again
2603 (movl (:$l (lognot (ash #xff x8632::fixnumshift))) (:%l tag))
2604 (andl (:%l object) (:%l tag))
[10495]2605 (jne :bad)
[7765]2606
[10495]2607 (:anchored-uuo-section :again)
2608 :bad
2609 (:anchored-uuo (uuo-error-reg-not-type (:%l object) (:$ub arch::error-object-not-unsigned-byte-8))))
2610
[7765]2611(define-x8632-vinsn require-s16 (()
2612 ((object :lisp))
2613 ((tag :s32)))
2614 :again
2615 (movl (:%l object) (:%l tag))
2616 (shll (:$ub (- x8632::nbits-in-word (+ 16 x8632::fixnumshift))) (:%l tag))
2617 (sarl (:$ub (- x8632::nbits-in-word 16)) (:%l tag))
2618 (shll (:$ub x8632::fixnumshift) (:%l tag))
2619 (cmpl (:%l object) (:%l tag))
[10495]2620 (jne :bad)
2621
2622 (:anchored-uuo-section :again)
[7765]2623 :bad
[10495]2624 (:anchored-uuo (uuo-error-reg-not-type (:%l object) (:$ub arch::error-object-not-signed-byte-16))))
[7765]2625
2626(define-x8632-vinsn require-u16 (()
2627 ((object :lisp))
2628 ((tag :u32)))
2629 :again
2630 (movl (:$l (lognot (ash #xffff x8632::fixnumshift))) (:%l tag))
2631 (andl (:%l object) (:%l tag))
[10495]2632 (jne :bad)
[7765]2633
[10495]2634 (:anchored-uuo-section :again)
2635 :bad
2636 (:anchored-uuo (uuo-error-reg-not-type (:%l object) (:$ub arch::error-object-not-unsigned-byte-16))))
2637
[7765]2638(define-x8632-vinsn require-s32 (()
2639 ((object :lisp))
2640 ((tag :s32)))
2641 :again
2642 (testl (:$l x8632::fixnummask) (:%l object))
2643 (movl (:%l object) (:%l tag))
[9692]2644 (je :ok)
[7765]2645 (andl (:$l x8632::fulltagmask) (:%l tag))
2646 (cmpl (:$l x8632::fulltag-misc) (:%l tag))
[9692]2647 (jne :bad)
[7765]2648 (cmpl (:$l x8632::one-digit-bignum-header) (:@ x8632::misc-header-offset (:%l object)))
[10495]2649 (jne :bad)
2650 :ok
2651
2652 (:anchored-uuo-section :again)
[7765]2653 :bad
[10495]2654 (:anchored-uuo (uuo-error-reg-not-type (:%l object) (:$ub arch::error-object-not-signed-byte-32))))
[7765]2655
2656(define-x8632-vinsn require-u32 (()
2657 ((object :lisp))
2658 ((tag :s32)))
2659 :again
2660 (testl (:$l x8632::fixnummask) (:%l object))
2661 (movl (:%l object) (:%l tag))
[9692]2662 (je :ok-if-non-negative)
[7765]2663 (andl (:$l x8632::fulltagmask) (:%l tag))
2664 (cmpl (:$l x8632::fulltag-misc) (:%l tag))
[9692]2665 (jne :bad)
[7765]2666 (cmpl (:$l x8632::one-digit-bignum-header) (:@ x8632::misc-header-offset (:%l object)))
2667 (je :one)
2668 (cmpl (:$l x8632::two-digit-bignum-header) (:@ x8632::misc-header-offset (:%l object)))
[9692]2669 (jne :bad)
[7765]2670 (cmpl (:$b 0) (:@ (+ x8632::misc-data-offset 4) (:%l object)))
2671 (je :ok)
2672 :bad
2673 (uuo-error-reg-not-type (:%l object) (:$ub arch::error-object-not-unsigned-byte-32))
2674 (jmp :again)
2675 :one
2676 (movl (:@ x8632::misc-data-offset (:%l object)) (:%l tag))
2677 :ok-if-non-negative
2678 (testl (:%l tag) (:%l tag))
2679 (js :bad)
2680 :ok)
2681
[7817]2682(define-x8632-vinsn require-s64 (()
2683 ((object :lisp))
2684 ((tag :s32)))
2685 :again
2686 (testl (:$l x8632::fixnummask) (:%l object))
2687 (movl (:%l object) (:%l tag))
[9692]2688 (je :ok)
[7817]2689 (andl (:$l x8632::fulltagmask) (:%l tag))
2690 (cmpl (:$l x8632::fulltag-misc) (:%l tag))
[9692]2691 (jne :bad)
[7817]2692 (cmpl (:$l x8632::two-digit-bignum-header) (:@ x8632::misc-header-offset (:%l object)))
[10495]2693 (jne :bad)
2694 :ok
2695
2696 (:anchored-uuo-section :again)
[7817]2697 :bad
[10495]2698 (:anchored-uuo (uuo-error-reg-not-type (:%l object) (:$ub arch::error-object-not-signed-byte-64))))
[7817]2699
2700(define-x8632-vinsn require-u64 (()
2701 ((object :lisp))
2702 ((tag :s32)))
2703 :again
2704 (testl (:$l x8632::fixnummask) (:%l object))
2705 (movl (:%l object) (:%l tag))
[9692]2706 (je :ok-if-non-negative)
[7817]2707 (andl (:$l x8632::fulltagmask) (:%l tag))
2708 (cmpl (:$l x8632::fulltag-misc) (:%l tag))
[9692]2709 (jne :bad)
[7817]2710 (cmpl (:$l x8632::two-digit-bignum-header) (:@ x8632::misc-header-offset (:%l object)))
2711 (je :two)
2712 (cmpl (:$l x8632::three-digit-bignum-header) (:@ x8632::misc-header-offset (:%l object)))
[9692]2713 (jne :bad)
[7817]2714 (cmpl (:$b 0) (:@ (+ x8632::misc-data-offset 8) (:%l object)))
2715 (je :ok)
2716 :bad
2717 (uuo-error-reg-not-type (:%l object) (:$ub arch::error-object-not-unsigned-byte-64))
2718 (jmp :again)
2719 :two
2720 (movl (:@ x8632::misc-data-offset (:%l object)) (:%l tag))
2721 :ok-if-non-negative
2722 (testl (:%l tag) (:%l tag))
2723 (js :bad)
2724 :ok)
2725
[7765]2726(define-x8632-vinsn require-char-code (()
2727 ((object :lisp))
2728 ((tag :u32)))
2729 :again
2730 (testb (:$b x8632::fixnummask) (:%b object))
[9692]2731 (jne :bad)
[7765]2732 (cmpl (:$l (ash #x110000 x8632::fixnumshift)) (:%l object))
[10495]2733 (jae :bad)
2734
2735 (:anchored-uuo-section :again)
[7765]2736 :bad
[10495]2737 (:anchored-uuo (uuo-error-reg-not-type (:%l object) (:$ub arch::error-object-not-mod-char-code-limit))))
[7765]2738
[7428]2739(define-x8632-vinsn mask-base-char (((dest :u8))
2740 ((src :lisp)))
[15022]2741 ((:pred < (:apply %hard-regspec-value src) 4)
2742 (movzbl (:%b src) (:%l dest)))
2743 ((:pred >= (:apply %hard-regspec-value src) 4)
2744 (movl (:%l src) (:%l dest))
2745 (movzbl (:%b dest) (:%l dest))))
2746
2747
[7428]2748
[7222]2749(define-x8632-vinsn event-poll (()
2750 ())
2751 (btrl (:$ub 31) (:@ (:%seg :rcontext) x8632::tcr.interrupt-pending))
2752 (jae :no-interrupt)
2753 (ud2a)
2754 (:byte 2)
2755 :no-interrupt)
2756
2757;;; check-2d-bound
2758;;; check-3d-bound
[7286]2759
2760(define-x8632-vinsn 2d-dim1 (((dest :u32))
2761 ((header :lisp)))
2762 (movl (:@ (+ x8632::misc-data-offset (* 4 (1+ x8632::arrayH.dim0-cell)))
2763 (:%l header)) (:%l dest))
2764 (sarl (:$ub x8632::fixnumshift) (:%l dest)))
2765
[7222]2766;;; 3d-dims
2767
[7339]2768;;; xxx
2769(define-x8632-vinsn 2d-unscaled-index (((dest :imm)
2770 (dim1 :u32))
2771 ((dim1 :u32)
2772 (i :imm)
2773 (j :imm)))
2774
2775 (imull (:%l i) (:%l dim1))
2776 (leal (:@ (:%l j) (:%l dim1)) (:%l dest)))
2777
[7222]2778;;; 3d-unscaled-index
2779
[7009]2780(define-x8632-vinsn branch-unless-both-args-fixnums (()
2781 ((a :lisp)
2782 (b :lisp)
2783 (dest :label))
[7222]2784 ((tag :u8)))
2785 (movl (:%l a) (:%l tag))
2786 (orl (:%l b) (:%l tag))
[7286]2787 ((:pred = (:apply %hard-regspec-value tag) x8632::eax)
2788 (testb (:$b x8632::fixnummask) (:%accb tag)))
2789 ((:and (:pred > (:apply %hard-regspec-value tag) x8632::eax)
2790 (:pred <= (:apply %hard-regspec-value tag) x8632::ebx))
2791 (testb (:$b x8632::fixnummask) (:%b tag)))
2792 ((:pred > (:apply %hard-regspec-value tag) x8632::ebx)
2793 (testl (:$l x8632::fixnummask) (:%l tag)))
[7009]2794 (jne dest))
2795
2796(define-x8632-vinsn branch-unless-arg-fixnum (()
2797 ((a :lisp)
2798 (dest :label)))
[7112]2799 ((:pred <= (:apply %hard-regspec-value a) x8632::ebx)
2800 (testb (:$b x8632::fixnummask) (:%b a)))
2801 ((:pred > (:apply %hard-regspec-value a) x8632::ebx)
[7222]2802 (testl (:$l x8632::fixnummask) (:%l a)))
[7009]2803 (jne dest))
2804
2805(define-x8632-vinsn fixnum->single-float (((f :single-float))
2806 ((arg :lisp))
2807 ((unboxed :s32)))
2808 (movl (:%l arg) (:%l unboxed))
2809 (sarl (:$ub x8632::fixnumshift) (:%l unboxed))
2810 (cvtsi2ssl (:%l unboxed) (:%xmm f)))
2811
2812(define-x8632-vinsn fixnum->double-float (((f :double-float))
2813 ((arg :lisp))
2814 ((unboxed :s32)))
2815 (movl (:%l arg) (:%l unboxed))
2816 (sarl (:$ub x8632::fixnumshift) (:%l unboxed))
2817 (cvtsi2sdl (:%l unboxed) (:%xmm f)))
2818
2819(define-x8632-vinsn xchg-registers (()
2820 ((a t)
2821 (b t)))
2822 (xchgl (:%l a) (:%l b)))
2823
2824(define-x8632-vinsn establish-fn (()
2825 ())
[7222]2826 (movl (:$self 0) (:%l x8632::fn)))
[7009]2827
[7659]2828(define-x8632-vinsn %scharcode32 (((code :imm))
2829 ((str :lisp)
2830 (idx :imm))
2831 ((imm :u32)))
[8629]2832 (movl (:@ x8632::misc-data-offset (:%l str) (:%l idx)) (:%l imm))
2833 (imull (:$b x8632::fixnumone) (:%l imm) (:%l code)))
[7222]2834
[8629]2835(define-x8632-vinsn %set-scharcode32 (()
2836 ((str :lisp)
2837 (idx :imm)
2838 (code :imm))
2839 ((imm :u32)))
2840 (movl (:%l code) (:%l imm))
2841 (shrl (:$ub x8632::fixnumshift) (:%l imm))
2842 (movl (:%l imm) (:@ x8632::misc-data-offset (:%l str) (:%l idx))))
[7659]2843
[8629]2844
[7339]2845(define-x8632-subprim-jump-vinsn (tail-call-sym-slide) .SPtcallsymslide)
2846
2847(define-x8632-subprim-jump-vinsn (tail-call-sym-vsp) .SPtcallsymvsp)
2848
2849
2850(define-x8632-vinsn character->code (((dest :u32))
2851 ((src :lisp)))
2852 (movl (:%l src) (:%l dest))
2853 (sarl (:$ub x8632::charcode-shift) (:%l dest)))
2854
[15022]2855(define-x8632-vinsn (adjust-vsp :vsp :pop :discard)
2856 (()
2857 ((amount :s32const)))
[7339]2858 ((:and (:pred >= amount -128) (:pred <= amount 127))
2859 (addl (:$b amount) (:%l x8632::esp)))
2860 ((:not (:and (:pred >= amount -128) (:pred <= amount 127)))
2861 (addl (:$l amount) (:%l x8632::esp))))
2862
2863
[7222]2864(define-x8632-vinsn (call-subprim-2 :call :subprim-call) (((dest t))
2865 ((spno :s32const)
2866 (y t)
2867 (z t))
2868 ((entry (:label 1))))
2869 (:talign 5)
2870 (call (:@ spno))
2871 (movl (:$self 0) (:%l x8632::fn)))
2872
[7659]2873(define-x8632-vinsn %symbol->symptr (((dest :lisp))
2874 ((src :lisp))
2875 ((tag :u8)))
[10495]2876 :resume
[10984]2877 (cmpl (:$l (:apply target-nil-value)) (:%l src))
[7659]2878 (je :nilsym)
[8349]2879 (movl (:%l src) (:%l tag))
[11029]2880 (andl (:$b x8632::tagmask) (:%l tag))
2881 (cmpl (:$b x8632::tag-misc) (:%l tag))
[7659]2882 (jne :bad)
[11029]2883 (movsbl (:@ x8632::misc-subtag-offset (:%l src)) (:%l tag))
2884 (cmpl (:$b x8632::subtag-symbol) (:%l tag))
[7659]2885 (jne :bad)
2886 ((:not (:pred =
2887 (:apply %hard-regspec-value dest)
2888 (:apply %hard-regspec-value src)))
2889 (movl (:% src) (:% dest)))
2890 (jmp :ok)
2891 :nilsym
[10984]2892 (movl (:$l (:apply + (:apply target-nil-value) x8632::nilsym-offset)) (:%l dest))
[10495]2893 :ok
2894
2895 (:anchored-uuo-section :resume)
2896 :bad
2897 (:anchored-uuo (uuo-error-reg-not-tag (:%l src) (:$ub x8632::subtag-symbol))))
[7659]2898
[11066]2899(define-x8632-vinsn single-float-bits (((dest :u32))
2900 ((src :lisp)))
2901 (movl (:@ x8632::misc-data-offset (:%l src)) (:%l dest)))
[10495]2902
[7286]2903(define-x8632-vinsn zero-double-float-register (((dest :double-float))
2904 ())
2905 (movsd (:%xmm x8632::fpzero) (:%xmm dest)))
[7251]2906
[7286]2907(define-x8632-vinsn zero-single-float-register (((dest :single-float))
2908 ())
2909 (movss (:%xmm x8632::fpzero) (:%xmm dest)))
2910
[7428]2911(define-x8632-subprim-lea-jmp-vinsn (heap-rest-arg) .SPheap-rest-arg)
2912(define-x8632-subprim-lea-jmp-vinsn (stack-rest-arg) .SPstack-rest-arg)
2913(define-x8632-subprim-lea-jmp-vinsn (req-stack-rest-arg) .SPreq-stack-rest-arg)
2914
2915
[7286]2916(define-x8632-subprim-call-vinsn (stack-misc-alloc) .SPstack-misc-alloc)
2917
2918(define-x8632-vinsn misc-element-count-fixnum (((dest :imm))
2919 ((src :lisp))
2920 ((temp :u32)))
2921 (movl (:@ x8632::misc-header-offset (:%l src)) (:%l temp))
[11029]2922 (shrl (:$ub x8632::num-subtag-bits) (:%l temp))
2923 (leal (:@ (:%l temp) 4) (:%l dest)))
[7286]2924
2925(define-x8632-vinsn %logior2 (((dest :imm))
2926 ((x :imm)
2927 (y :imm)))
2928 ((:pred =
2929 (:apply %hard-regspec-value x)
2930 (:apply %hard-regspec-value dest))
2931 (orl (:%l y) (:%l dest)))
2932 ((:not (:pred =
2933 (:apply %hard-regspec-value x)
2934 (:apply %hard-regspec-value dest)))
2935 ((:pred =
2936 (:apply %hard-regspec-value y)
2937 (:apply %hard-regspec-value dest))
2938 (orl (:%l x) (:%l dest)))
2939 ((:not (:pred =
2940 (:apply %hard-regspec-value y)
2941 (:apply %hard-regspec-value dest)))
2942 (movl (:%l x) (:%l dest))
2943 (orl (:%l y) (:%l dest)))))
2944
2945(define-x8632-vinsn %logand2 (((dest :imm))
2946 ((x :imm)
2947 (y :imm)))
2948 ((:pred =
2949 (:apply %hard-regspec-value x)
2950 (:apply %hard-regspec-value dest))
2951 (andl (:%l y) (:%l dest)))
2952 ((:not (:pred =
2953 (:apply %hard-regspec-value x)
2954 (:apply %hard-regspec-value dest)))
2955 ((:pred =
2956 (:apply %hard-regspec-value y)
2957 (:apply %hard-regspec-value dest))
2958 (andl (:%l x) (:%l dest)))
2959 ((:not (:pred =
2960 (:apply %hard-regspec-value y)
2961 (:apply %hard-regspec-value dest)))
2962 (movl (:%l x) (:%l dest))
2963 (andl (:%l y) (:%l dest)))))
2964
2965(define-x8632-vinsn %logxor2 (((dest :imm))
2966 ((x :imm)
2967 (y :imm)))
2968 ((:pred =
2969 (:apply %hard-regspec-value x)
2970 (:apply %hard-regspec-value dest))
2971 (xorl (:%l y) (:%l dest)))
2972 ((:not (:pred =
2973 (:apply %hard-regspec-value x)
2974 (:apply %hard-regspec-value dest)))
2975 ((:pred =
2976 (:apply %hard-regspec-value y)
2977 (:apply %hard-regspec-value dest))
2978 (xorl (:%l x) (:%l dest)))
2979 ((:not (:pred =
2980 (:apply %hard-regspec-value y)
2981 (:apply %hard-regspec-value dest)))
2982 (movl (:%l x) (:%l dest))
2983 (xorl (:%l y) (:%l dest)))))
2984
[7659]2985
[7251]2986(define-x8632-subprim-call-vinsn (integer-sign) .SPinteger-sign)
2987
2988(define-x8632-subprim-call-vinsn (misc-ref) .SPmisc-ref)
2989
2990(define-x8632-subprim-call-vinsn (ksignalerr) .SPksignalerr)
2991
2992(define-x8632-subprim-call-vinsn (misc-alloc-init) .SPmisc-alloc-init)
2993
[7428]2994(define-x8632-subprim-call-vinsn (misc-alloc) .SPmisc-alloc)
[7251]2995
[7428]2996(define-x8632-subprim-lea-jmp-vinsn (make-stack-gvector) .SPstkgvector)
2997
2998(define-x8632-vinsn load-character-constant (((dest :lisp))
2999 ((code :u32const))
3000 ())
3001 (movl (:$l (:apply logior (:apply ash code 8) x8632::subtag-character))
3002 (:%l dest)))
3003
3004
[7817]3005(define-x8632-vinsn setup-single-float-allocation (()
3006 ())
3007 (movl (:$l (arch::make-vheader x8632::single-float.element-count x8632::subtag-single-float)) (:%l x8632::imm0))
3008 (movd (:%l x8632::imm0) (:%mmx x8632::mm0))
3009 (movl (:$l (- x8632::single-float.size x8632::fulltag-misc)) (:%l x8632::imm0)))
3010
[7286]3011(define-x8632-vinsn setup-double-float-allocation (()
3012 ())
3013 (movl (:$l (arch::make-vheader x8632::double-float.element-count x8632::subtag-double-float)) (:%l x8632::imm0))
[7817]3014 (movd (:%l x8632::imm0) (:%mmx x8632::mm0))
3015 (movl (:$l (- x8632::double-float.size x8632::fulltag-misc)) (:%l x8632::imm0)))
[7286]3016
[7817]3017(define-x8632-vinsn set-single-float-value (()
3018 ((node :lisp)
3019 (val :single-float)))
3020 (movss (:%xmm val) (:@ x8632::single-float.value (:%l node))))
3021
[7286]3022(define-x8632-vinsn set-double-float-value (()
3023 ((node :lisp)
3024 (val :double-float)))
[7765]3025 (movsd (:%xmm val) (:@ x8632::double-float.value (:%l node))))
[7286]3026
[7817]3027(define-x8632-vinsn word-index-and-bitnum-from-index (((word-index :u32)
3028 (bitnum :u8))
3029 ((index :imm)))
3030 (movl (:%l index) (:%l word-index))
3031 (shrl (:$ub x8632::fixnumshift) (:%l word-index))
3032 (movl (:$l 31) (:%l bitnum))
3033 (andl (:%l word-index) (:%l bitnum))
3034 (shrl (:$ub 5) (:%l word-index)))
3035
3036(define-x8632-vinsn ref-bit-vector-fixnum (((dest :imm)
3037 (bitnum :u8))
3038 ((bitnum :u8)
3039 (bitvector :lisp)
3040 (word-index :u32)))
3041 (btl (:%l bitnum) (:@ x8632::misc-data-offset (:%l bitvector) (:%l word-index) 4))
3042 (setb (:%b bitnum))
3043 (negb (:%b bitnum))
3044 (andl (:$l x8632::fixnumone) (:%l bitnum))
3045 (movl (:%l bitnum) (:%l dest)))
3046
[8629]3047(define-x8632-vinsn nref-bit-vector-fixnum (((dest :imm)
3048 (bitnum :s32))
3049 ((bitnum :s32)
3050 (bitvector :lisp))
3051 ())
3052 (btl (:%l bitnum) (:@ x8632::misc-data-offset (:%l bitvector)))
3053 (setc (:%b bitnum))
3054 (movzbl (:%b bitnum) (:%l bitnum))
3055 (imull (:$b x8632::fixnumone) (:%l bitnum) (:%l dest)))
3056
[10363]3057(define-x8632-vinsn nref-bit-vector-flags (()
3058 ((bitnum :s32)
3059 (bitvector :lisp))
3060 ())
3061 (btl (:%l bitnum) (:@ x8632::misc-data-offset (:%l bitvector))))
3062
3063(define-x8632-vinsn misc-ref-c-bit-fixnum (((dest :imm))
3064 ((src :lisp)
3065 (idx :u32const))
3066 ((temp :u8)))
3067 (btl (:$ub (:apply logand 31 idx))
3068 (:@ (:apply + x8632::misc-data-offset (:apply ash (:apply ash idx -5) x8632::word-shift)) (:%l src)))
3069 (setc (:%b temp))
3070 (movzbl (:%b temp) (:%l temp))
3071 (imull (:$b x8632::fixnumone) (:%l temp) (:%l dest)))
3072
3073(define-x8632-vinsn misc-ref-c-bit-flags (()
3074 ((src :lisp)
3075 (idx :u64const)))
3076 (btl (:$ub (:apply logand 31 idx))
3077 (:@ (:apply + x8632::misc-data-offset (:apply ash (:apply ash idx -5) x8632::word-shift)) (:%l src))))
3078
[7659]3079(define-x8632-vinsn set-macptr-address (()
3080 ((addr :address)
3081 (src :lisp))
3082 ())
3083 (movl (:%l addr) (:@ x8632::macptr.address (:%l src))))
3084
3085(define-x8632-vinsn deref-macptr (((addr :address))
3086 ((src :lisp))
3087 ())
3088 (movl (:@ x8632::macptr.address (:%l src)) (:%l addr)))
3089
3090(define-x8632-vinsn setup-macptr-allocation (()
3091 ((src :address)))
[8349]3092 (movd (:%l src) (:%mmx x8632::mm1)) ;see %set-new-macptr-value, below
3093 (movl (:$l x8632::macptr-header) (:%l x8632::imm0))
3094 (movd (:%l x8632::imm0) (:%mmx x8632::mm0))
[7659]3095 (movl (:$l (- x8632::macptr.size x8632::fulltag-misc)) (:%l x8632::imm0)))
3096
3097(define-x8632-vinsn %set-new-macptr-value (()
3098 ((ptr :lisp)))
3099 (movd (:%mmx x8632::mm1) (:@ x8632::macptr.address (:%l ptr))))
3100
[7772]3101(define-x8632-vinsn mem-ref-natural (((dest :u32))
3102 ((src :address)
3103 (index :s32)))
3104 (movl (:@ (:%l src) (:%l index)) (:%l dest)))
3105
[7765]3106(define-x8632-vinsn mem-ref-c-fullword (((dest :u32))
3107 ((src :address)
3108 (index :s32const)))
3109 ((:pred = index 0)
3110 (movl (:@ (:%l src)) (:%l dest)))
3111 ((:not (:pred = index 0))
3112 (movl (:@ index (:%l src)) (:%l dest))))
3113
3114(define-x8632-vinsn mem-ref-c-signed-fullword (((dest :s32))
3115 ((src :address)
3116 (index :s32const)))
3117 ((:pred = index 0)
3118 (movl (:@ (:%l src)) (:%l dest)))
3119 ((:not (:pred = index 0))
3120 (movl (:@ index (:%l src)) (:%l dest))))
3121
[7772]3122(define-x8632-vinsn mem-ref-c-single-float (((dest :single-float))
3123 ((src :address)
3124 (index :s32const)))
3125 ((:pred = index 0)
3126 (movss (:@ (:%l src)) (:%xmm dest)))
3127 ((:not (:pred = index 0))
3128 (movss (:@ index (:%l src)) (:%xmm dest))))
3129
3130(define-x8632-vinsn mem-set-c-single-float (()
3131 ((val :single-float)
3132 (src :address)
3133 (index :s16const)))
3134 ((:pred = index 0)
3135 (movss (:%xmm val) (:@ (:%l src))))
3136 ((:not (:pred = index 0))
3137 (movss (:%xmm val) (:@ index (:%l src)))))
3138
3139(define-x8632-vinsn mem-ref-c-natural (((dest :u32))
3140 ((src :address)
3141 (index :s32const)))
3142 ((:pred = index 0)
3143 (movl (:@ (:%l src)) (:%l dest)))
3144 ((:not (:pred = index 0))
3145 (movl (:@ index (:%l src)) (:%l dest))))
3146
[7817]3147(define-x8632-vinsn mem-ref-c-double-float (((dest :double-float))
3148 ((src :address)
3149 (index :s32const)))
3150 ((:pred = index 0)
3151 (movsd (:@ (:%l src)) (:%xmm dest)))
3152 ((:not (:pred = index 0))
3153 (movsd (:@ index (:%l src)) (:%xmm dest))))
[7772]3154
[7817]3155(define-x8632-vinsn mem-set-c-double-float (()
3156 ((val :double-float)
3157 (src :address)
3158 (index :s32const)))
3159 ((:pred = index 0)
3160 (movsd (:%xmm val) (:@ (:%l src))))
3161 ((:not (:pred = index 0))
3162 (movsd (:%xmm val) (:@ index (:%l src)))))
3163
[7765]3164(define-x8632-vinsn mem-ref-fullword (((dest :u32))
3165 ((src :address)
3166 (index :s32)))
3167 (movl (:@ (:%l src) (:%l index)) (:%l dest)))
3168
3169(define-x8632-vinsn mem-ref-signed-fullword (((dest :s32))
3170 ((src :address)
3171 (index :s32)))
3172 (movl (:@ (:%l src) (:%l index)) (:%l dest)))
3173
[7659]3174(define-x8632-vinsn macptr->stack (((dest :lisp))
[8687]3175 ((ptr :address))
3176 ((temp :imm)))
[7659]3177 (movd (:@ (:%seg :rcontext) x8632::tcr.foreign-sp) (:%mmx x8632::stack-temp))
[8687]3178 (subl (:$b (+ 8 x8632::macptr.size)) (:@ (:%seg :rcontext) x8632::tcr.foreign-sp))
3179 (movl (:@ (:%seg :rcontext) x8632::tcr.foreign-sp) (:%l temp))
3180 (movd (:%mmx x8632::stack-temp) (:@ (:%l temp)))
[10561]3181 (movl (:%l x8632::ebp) (:@ 4 (:%l temp)))
[8687]3182 (leal (:@ (+ 8 x8632::fulltag-misc) (:%l temp)) (:%l dest))
[7659]3183 (movl (:$l x8632::macptr-header) (:@ x8632::macptr.header (:%l dest)))
3184 (movl (:%l ptr) (:@ x8632::macptr.address (:%l dest)))
[8687]3185 (movsd (:%xmm x8632::fpzero) (:@ x8632::macptr.domain (:%l dest))))
[7659]3186
3187(define-x8632-vinsn fixnum->signed-natural (((dest :s32))
3188 ((src :imm)))
3189 (movl (:%l src) (:%l dest))
3190 (sarl (:$ub x8632::fixnumshift) (:%l dest)))
3191
[8629]3192(define-x8632-vinsn fixnum->unsigned-natural (((dest :u32))
3193 ((src :imm)))
3194 (movl (:%l src) (:%l dest))
3195 (shrl (:$ub x8632::fixnumshift) (:%l dest)))
3196
[7765]3197(define-x8632-vinsn mem-set-double-float (()
3198 ((val :double-float)
3199 (src :address)
3200 (index :s32)))
3201 (movsd (:%xmm val) (:@ (:%l src) (:%l index))))
3202
3203(define-x8632-vinsn mem-set-single-float (()
3204 ((val :single-float)
3205 (src :address)
3206 (index :s32)))
3207 (movss (:%xmm val) (:@ (:%l src) (:%l index))))
3208
3209(define-x8632-vinsn mem-set-c-fullword (()
3210 ((val :u32)
3211 (dest :address)
3212 (offset :s32const)))
3213 ((:pred = offset 0)
3214 (movl (:%l val) (:@ (:%l dest))))
3215 ((:not (:pred = offset 0))
3216 (movl (:%l val) (:@ offset (:%l dest)))))
3217
[7817]3218(define-x8632-vinsn mem-set-bit-variable-value (((src :address))
3219 ((src :address)
3220 (offset :lisp)
3221 (value :lisp))
[9456]3222 ((temp :lisp)))
3223 ;; (mark-as-imm temp)
3224 (btrl (:$ub (:apply %hard-regspec-value temp))
3225 (:@ (:%seg :rcontext) x8632::tcr.node-regs-mask))
[7817]3226 (movl (:%l offset) (:%l temp))
3227 (shrl (:$ub (+ 5 x8632::fixnumshift)) (:%l temp))
3228 (leal (:@ (:%l src) (:%l temp) 4) (:%l src))
3229 (movl (:%l offset) (:%l temp))
3230 (shrl (:$ub x8632::fixnumshift) (:%l temp))
3231 (andl (:$l 31) (:%l temp))
3232 (testl (:%l value) (:%l value))
3233 (jne :set)
3234 (btrl (:%l temp) (:@ (:%l src)))
3235 (jmp :done)
3236 :set
3237 (btsl (:%l temp) (:@ (:%l src)))
[9456]3238 :done
3239 ;; (mark-as-node temp)
3240 (xorl (:%l temp) (:%l temp))
3241 (btsl (:$ub (:apply %hard-regspec-value temp))
3242 (:@ (:%seg :rcontext) x8632::tcr.node-regs-mask)))
[7817]3243
[10542]3244
3245(define-x8632-vinsn mem-set-c-bit-variable-value (()
3246 ((src :address)
3247 (offset :s32const)
3248 (value :lisp)))
3249 (testl (:%l value) (:%l value))
3250 (jne :set)
3251 ((:pred = 0 (:apply ash offset -5))
3252 (btrl (:$ub (:apply logand 31 offset))
[11467]3253 (:@ (:%l src))))
[10542]3254 ((:not (:pred = 0 (:apply ash offset -5)))
3255 (btrl (:$ub (:apply logand 31 offset))
[11467]3256 (:@ (:apply ash (:apply ash offset -5) 4) (:%l src))))
[10542]3257 (jmp :done)
3258 :set
3259 ((:pred = 0 (:apply ash offset -5))
3260 (btsl (:$ub (:apply logand 31 offset))
[11467]3261 (:@ (:%l src))))
[10542]3262 ((:not (:pred = 0 (:apply ash offset -5)))
3263 (btsl (:$ub (:apply logand 31 offset))
[11467]3264 (:@ (:apply ash (:apply ash offset -5) 2) (:%l src))))
[10542]3265 :done)
3266
[7286]3267(define-x8632-vinsn %natural+ (((result :u32))
3268 ((result :u32)
3269 (other :u32)))
3270 (addl (:%l other) (:%l result)))
3271
3272(define-x8632-vinsn %natural+-c (((result :u32))
3273 ((result :u32)
[9802]3274 (constant :u32const)))
3275 (addl (:$l (:apply unsigned-to-signed constant 32)) (:%l result)))
[7286]3276
3277(define-x8632-vinsn %natural- (((result :u32))
[7772]3278 ((result :u32)
3279 (other :u32)))
[7286]3280 (subl (:%l other) (:%l result)))
3281
3282(define-x8632-vinsn %natural--c (((result :u32))
3283 ((result :u32)
[9802]3284 (constant :u32const)))
3285 (subl (:$l (:apply unsigned-to-signed constant 32)) (:%l result)))
[7286]3286
3287(define-x8632-vinsn %natural-logior (((result :u32))
3288 ((result :u32)
3289 (other :u32)))
3290 (orl (:%l other) (:%l result)))
3291
3292(define-x8632-vinsn %natural-logior-c (((result :u32))
3293 ((result :u32)
[9802]3294 (constant :u32const)))
3295 (orl (:$l (:apply unsigned-to-signed constant 32)) (:%l result)))
[7286]3296
3297(define-x8632-vinsn %natural-logand (((result :u32))
3298 ((result :u32)
3299 (other :u32)))
3300 (andl (:%l other) (:%l result)))
3301
3302(define-x8632-vinsn %natural-logand-c (((result :u32))
3303 ((result :u32)
[9802]3304 (constant :u32const)))
3305 (andl (:$l (:apply unsigned-to-signed constant 32)) (:%l result)))
[7286]3306
3307(define-x8632-vinsn %natural-logxor (((result :u32))
3308 ((result :u32)
3309 (other :u32)))
3310 (xorl (:%l other) (:%l result)))
3311
3312(define-x8632-vinsn %natural-logxor-c (((result :u32))
3313 ((result :u32)
[9802]3314 (constant :u32const)))
3315 (xorl (:$l (:apply unsigned-to-signed constant 32)) (:%l result)))
[7286]3316
3317(define-x8632-vinsn natural-shift-left (((dest :u32))
3318 ((dest :u32)
3319 (amt :u8const)))
3320 (shll (:$ub amt) (:%l dest)))
3321
3322(define-x8632-vinsn natural-shift-right (((dest :u32))
3323 ((dest :u32)
3324 (amt :u8const)))
3325 (shrl (:$ub amt) (:%l dest)))
3326
[7339]3327(define-x8632-vinsn recover-fn (()
3328 ())
3329 (movl (:$self 0) (:%l x8632::fn)))
[7286]3330
[7339]3331;;; xxx probably wrong
3332(define-x8632-vinsn (call-subprim-3 :call :subprim-call) (((dest t))
3333 ((spno :s32const)
3334 (x t)
3335 (y t)
3336 (z t))
3337 ((entry (:label 1))))
3338 (:talign 5)
3339 (call (:@ spno))
3340 (movl (:$self 0) (:%l x8632::fn)))
[7286]3341
[7360]3342(define-x8632-vinsn vcell-ref (((dest :lisp))
3343 ((vcell :lisp)))
3344 (movl (:@ x8632::misc-data-offset (:%l vcell)) (:%l dest)))
3345
3346(define-x8632-vinsn setup-vcell-allocation (()
3347 ())
3348 (movl (:$l x8632::value-cell-header) (:%l x8632::imm0))
3349 (movd (:%l x8632::imm0) (:%mmx x8632::mm0))
3350 (movl (:$l (- x8632::value-cell.size x8632::fulltag-misc)) (:%l x8632::imm0)))
3351
3352(define-x8632-vinsn %init-vcell (()
3353 ((vcell :lisp)
3354 (closed :lisp)))
3355 (movl (:%l closed) (:@ x8632::value-cell.value (:%l vcell))))
3356
[7428]3357;;; "old" mkunwind. Used by PROGV, since the binding of *interrupt-level*
3358;;; on entry to the new mkunwind confuses the issue.
3359
3360(define-x8632-vinsn (mkunwind :call :subprim-call) (()
3361 ((protform-lab :label)
3362 (cleanup-lab :label)))
3363 (leal (:@ (:^ protform-lab) (:%l x8632::fn)) (:%l x8632::ra0))
3364 (leal (:@ (:^ cleanup-lab) (:%l x8632::fn)) (:%l x8632::xfn))
3365 (jmp (:@ .SPmkunwind)))
3366
3367;;; Funcall the function or symbol in temp0 and obtain the single
3368;;; value that it returns.
[8349]3369(define-x8632-subprim-call-vinsn (funcall) .SPfuncall)
[7428]3370
3371(define-x8632-vinsn tail-funcall (()
3372 ()
3373 ((tag :u8)))
[10495]3374 :resume
[7428]3375 (movl (:%l x8632::temp0) (:%l tag))
3376 ((:pred = (:apply %hard-regspec-value tag) x8632::eax)
[8231]3377 (andl (:$b x8632::tagmask) (:%accl tag))
3378 (cmpl (:$b x8632::tag-misc) (:%accl tag)))
3379 ((:pred > (:apply %hard-regspec-value tag) x8632::eax)
3380 (andl (:$b x8632::tagmask) (:%l tag))
[7428]3381 (cmpl (:$b x8632::tag-misc) (:%l tag)))
3382 (jne :bad)
[11029]3383 (movsbl (:@ x8632::misc-subtag-offset (:%l x8632::temp0)) (:%l tag))
3384 (cmpl (:$b x8632::subtag-function) (:%l tag))
[7428]3385 (je :go)
[11029]3386 (cmpl (:$b x8632::subtag-symbol) (:%l tag))
[9191]3387 (cmovel (:@ x8632::symbol.fcell (:%l x8632::temp0)) (:%l x8632::temp0))
[7428]3388 (jne :bad)
3389 :go
[8629]3390 (jmp (:%l x8632::temp0))
[10495]3391
3392 (:anchored-uuo-section :resume)
[7428]3393 :bad
[10495]3394 (:anchored-uuo (uuo-error-not-callable)))
[7428]3395
[7360]3396;;; Magic numbers in here include the address of .SPcall-closure.
3397
3398;;; movl $self, %fn
3399;;; jmp *20660 (.SPcall-closure)
3400(define-x8632-vinsn init-nclosure (()
3401 ((closure :lisp)))
[8750]3402 (movb (:$b 6) (:@ x8632::misc-data-offset (:%l closure))) ;imm word count
[7360]3403 (movb (:$b #xbf) (:@ (+ x8632::misc-data-offset 2) (:%l closure))) ;movl $self, %fn
3404 (movb (:$b #xff) (:@ (+ x8632::misc-data-offset 7) (:%l closure))) ;jmp
[10234]3405 (movl (:$l #x0150b425) (:@ (+ x8632::misc-data-offset 8) (:%l closure))) ;.SPcall-closure
[7360]3406 ;; already aligned
[8750]3407 ;; (movl ($ 0) (:@ (+ x8632::misc-data-offset 12))) ;"end" of self-references
[9191]3408 (movb (:$b 7) (:@ (+ x8632::misc-data-offset 16) (:%l closure))) ;self-reference offset
[15260]3409 (movb (:$b x8632::function-boundary-marker) (:@ (+ x8632::misc-data-offset 20) (:%l closure)))
3410 ;; If the GC moved the closure before we finished creating its
3411 ;; self-reference table, it wouldn't have updated this self-reference
3412 (movl (:%l closure) (:@ (+ x8632::misc-data-offset 3) (:%l closure))))
[7360]3413
3414(define-x8632-vinsn finalize-closure (((closure :lisp))
3415 ((closure :lisp)))
3416 (nop))
3417
3418
3419(define-x8632-vinsn (ref-symbol-value :call :subprim-call)
3420 (((val :lisp))
3421 ((sym (:lisp (:ne val)))))
3422 (:talign 5)
3423 (call (:@ .SPspecrefcheck))
3424 (movl (:$self 0) (:%l x8632::fn)))
3425
[7659]3426(define-x8632-vinsn ref-symbol-value-inline (((dest :lisp))
3427 ((src (:lisp (:ne dest))))
3428 ((table :imm)
3429 (idx :imm)))
[10495]3430 :resume
[7659]3431 (movl (:@ x8632::symbol.binding-index (:%l src)) (:%l idx))
[13561]3432 (xorl (:%l table) (:%l table))
[7659]3433 (rcmpl (:%l idx) (:@ (:%seg :rcontext) x8632::tcr.tlb-limit))
[13561]3434 (cmovael (:%l table) (:%l idx))
[7659]3435 (movl (:@ (:%seg :rcontext) x8632::tcr.tlb-pointer) (:%l table))
3436 (movl (:@ (:%l table) (:%l idx)) (:%l dest))
3437 (cmpl (:$l x8632::subtag-no-thread-local-binding) (:%l dest))
[13561]3438 (cmovel (:@ x8632::symbol.vcell (:%l src)) (:%l dest))
[7659]3439 (cmpl (:$l x8632::unbound-marker) (:%l dest))
[10495]3440 (je :bad)
[7659]3441
[10495]3442 (:anchored-uuo-section :resume)
3443 :bad
3444 (:anchored-uuo (uuo-error-unbound (:%l src))))
3445
[9743]3446(define-x8632-vinsn (%ref-symbol-value :call :subprim-call)
3447 (((val :lisp))
3448 ((sym (:lisp (:ne val)))))
3449 (:talign 5)
3450 (call (:@ .SPspecref))
3451 (movl (:$self 0) (:%l x8632::fn)))
3452
[7428]3453(define-x8632-vinsn %ref-symbol-value-inline (((dest :lisp))
3454 ((src (:lisp (:ne dest))))
[13561]3455 ((idx :imm)))
3456 ;; binding index 0 always contains a no-thread-local-binding
3457 ;; marker, so treat out-of-range indices as 0 to avoid branches.
[7428]3458 (movl (:@ x8632::symbol.binding-index (:%l src)) (:%l idx))
[13561]3459 (xorl (:% dest) (:% dest))
[7428]3460 (rcmpl (:%l idx) (:@ (:%seg :rcontext) x8632::tcr.tlb-limit))
[13561]3461 (cmovael (:% dest) (:% idx))
[7428]3462 (addl (:@ (:%seg :rcontext) x8632::tcr.tlb-pointer) (:%l idx))
3463 (movl (:@ (:%l idx)) (:%l dest))
3464 (cmpl (:$l x8632::subtag-no-thread-local-binding) (:%l dest))
[13561]3465 (cmovel (:@ x8632::symbol.vcell (:%l src)) (:%l dest)))
[7428]3466
[7772]3467(define-x8632-vinsn ref-interrupt-level (((dest :imm))
3468 ()
3469 ((temp :u32)))
3470 (movl (:@ (:%seg :rcontext) x8632::tcr.tlb-pointer) (:%l temp))
3471 (movl (:@ x8632::interrupt-level-binding-index (:%l temp)) (:%l dest)))
3472
[7360]3473(define-x8632-subprim-lea-jmp-vinsn (bind-nil) .SPbind-nil)
3474
3475(define-x8632-subprim-lea-jmp-vinsn (bind-self) .SPbind-self)
3476
3477(define-x8632-subprim-lea-jmp-vinsn (bind-self-boundp-check) .SPbind-self-boundp-check)
3478
3479(define-x8632-subprim-lea-jmp-vinsn (bind) .SPbind)
3480
3481(define-x8632-vinsn (dpayback :call :subprim-call) (()
3482 ((n :s16const))
3483 ((temp (:u32 #.x8632::imm0))
3484 (entry (:label 1))))
3485 ((:pred > n 0)
3486 ((:pred > n 1)
3487 (movl (:$l n) (:%l temp))
[8349]3488 (:talign 5)
[7360]3489 (call (:@ .SPunbind-n)))
3490 ((:pred = n 1)
3491 (:talign 5)
3492 (call (:@ .SPunbind)))
3493 (movl (:$self 0) (:%l x8632::fn))))
3494
[7428]3495(define-x8632-subprim-jump-vinsn (tail-call-sym-gen) .SPtcallsymgen)
3496
3497(define-x8632-subprim-call-vinsn (make-stack-list) .Spmakestacklist)
3498
3499(define-x8632-vinsn node-slot-ref (((dest :lisp))
3500 ((node :lisp)
3501 (cellno :u32const)))
3502 (movl (:@ (:apply + x8632::misc-data-offset (:apply ash cellno 2))
3503 (:%l node)) (:%l dest)))
3504
3505(define-x8632-subprim-lea-jmp-vinsn (stack-cons-list) .SPstkconslist)
3506
[7659]3507(define-x8632-vinsn save-lexpr-argregs (()
3508 ((min-fixed :u16const)))
3509 ((:pred >= min-fixed $numx8632argregs)
3510 (pushl (:%l x8632::arg_y))
3511 (pushl (:%l x8632::arg_z)))
3512 ((:pred = min-fixed 1) ; at least one arg
[8367]3513 (rcmpl (:%l x8632::nargs) (:$b (ash 1 x8632::word-shift)))
[7659]3514 (je :z1) ;skip arg_y if exactly 1
3515 (pushl (:%l x8632::arg_y))
3516 :z1
3517 (pushl (:%l x8632::arg_z)))
3518 ((:pred = min-fixed 0)
[8367]3519 (rcmpl (:%l x8632::nargs) (:$b (ash 1 x8632::word-shift)))
[7659]3520 (je :z0) ;exactly one
3521 (jl :none) ;none
3522 ;two or more...
3523 (pushl (:%l x8632::arg_y))
3524 :z0
3525 (pushl (:%l x8632::arg_z))
3526 :none
3527 )
3528 ((:not (:pred = min-fixed 0))
3529 (leal (:@ (:apply - (:apply ash min-fixed x8632::word-shift)) (:%l x8632::nargs))
3530 (:%l x8632::nargs)))
3531 (pushl (:%l x8632::nargs))
3532 (movl (:%l x8632::esp) (:%l x8632::arg_z)))
[7428]3533
[7659]3534;;; The frame that was built (by SAVE-LISP-CONTEXT-VARIABLE-ARG-COUNT
3535;;; and SAVE-LEXPR-ARGREGS) contains an unknown number of arguments
3536;;; followed by the count of non-required arguments; the count is on
3537;;; top of the stack and its address is in %arg_z. We need to build a
3538;;; frame so that the function can address its arguments (copies of
3539;;; the required arguments and the lexpr) and locals; when the
3540;;; function returns, it should one or more values (depending on how
3541;;; it was called) and discard the hidden lexpr frame. At this point,
3542;;; %ra0 still contains the "real" return address. If it's not the
3543;;; magic multiple-value address, we can make the function return to
3544;;; something that does a single-value return (.SPpopj); otherwise, we
3545;;; need to make it return multiple values to the real caller. (Unlike
3546;;; the PPC, this case only involves creating one frame here, but that
3547;;; frame has two return addresses.)
3548(define-x8632-vinsn build-lexpr-frame (()
3549 ()
[9123]3550 ((temp :imm)
3551 (ra0 (:lisp #.x8632::ra0))))
[10984]3552 (movl (:@ (:apply + (:apply target-nil-value) (x8632::%kernel-global 'x86::ret1valaddr)))
[7659]3553 (:%l temp))
[9123]3554 (cmpl (:%l temp) (:%l ra0))
[7659]3555 (je :multiple)
[10984]3556 (pushl (:@ (:apply + (:apply target-nil-value) (x8632::%kernel-global 'x86::lexpr-return1v))))
[7659]3557 (jmp :finish)
3558 :multiple
[10984]3559 (pushl (:@ (:apply + (:apply target-nil-value) (x8632::%kernel-global 'x86::lexpr-return))))
[7659]3560 (pushl (:%l temp))
3561 :finish
3562 (pushl (:%l x8632::ebp))
3563 (movl (:%l x8632::esp) (:%l x8632::ebp)))
3564
3565(define-x8632-vinsn copy-lexpr-argument (()
3566 ((n :u16const))
3567 ((temp :imm)))
3568 (movl (:@ (:%l x8632::arg_z)) (:%l temp))
3569 (pushl (:@ (:apply ash n x8632::word-shift) (:%l x8632::arg_z) (:%l temp))))
3570
3571(define-x8632-vinsn %current-tcr (((dest :lisp))
3572 ())
3573 (movl (:@ (:%seg :rcontext) x8632::tcr.linear) (:%l dest)))
3574
[7360]3575(define-x8632-vinsn (setq-special :call :subprim-call)
3576 (()
3577 ((sym :lisp)
3578 (val :lisp))
3579 ((entry (:label 1))))
3580 (:talign 5)
3581 (call (:@ .SPspecset))
3582 (movl (:$self 0) (:%l x8632::fn)))
3583
[7817]3584(define-x8632-vinsn pop-argument-registers (()
3585 ())
[8367]3586 (testl (:%l x8632::nargs) (:%l x8632::nargs))
[7817]3587 (je :done)
[8367]3588 (rcmpl (:%l x8632::nargs) (:$l (ash 1 x8632::word-shift)))
[7817]3589 (popl (:%l x8632::arg_z))
3590 (je :done)
[8629]3591 (popl (:%l x8632::arg_y))
[7817]3592 :done)
3593
[7360]3594(define-x8632-vinsn %symptr->symvector (((target :lisp))
3595 ((target :lisp)))
3596 (nop))
3597
3598(define-x8632-vinsn %symvector->symptr (((target :lisp))
3599 ((target :lisp)))
3600 (nop))
3601
[7659]3602(define-x8632-subprim-lea-jmp-vinsn (spread-lexpr) .SPspread-lexpr-z)
3603
[7772]3604(define-x8632-vinsn mem-ref-double-float (((dest :double-float))
3605 ((src :address)
3606 (index :s32)))
3607 (movsd (:@ (:%l src) (:%l index)) (:%xmm dest)))
3608
3609(define-x8632-vinsn mem-ref-single-float (((dest :single-float))
3610 ((src :address)
3611 (index :s32)))
3612 (movss (:@ (:%l src) (:%l index)) (:%xmm dest)))
3613
[9678]3614;;; This would normally be put in %nargs, but we need an
3615;;; extra node register for passing stuff into
3616;;; SPdestructuring_bind and friends.
[7772]3617(define-x8632-vinsn load-adl (()
3618 ((n :u32const)))
[9678]3619 (movl (:$l n) (:%l x8632::imm0)))
[7772]3620
3621(define-x8632-subprim-lea-jmp-vinsn (macro-bind) .SPmacro-bind)
3622
3623(define-x8632-subprim-lea-jmp-vinsn (destructuring-bind-inner) .SPdestructuring-bind-inner)
3624
3625(define-x8632-subprim-lea-jmp-vinsn (destructuring-bind) .SPdestructuring-bind)
3626
3627
[7360]3628(define-x8632-vinsn symbol-function (((val :lisp))
3629 ((sym (:lisp (:ne val))))
3630 ((tag :u8)))
[10495]3631 :resume
[7360]3632 (movl (:@ x8632::symbol.fcell (:%l sym)) (:%l val))
3633 (movl (:%l val) (:%l tag))
[11029]3634 (andl (:$b x8632::tagmask) (:%l tag))
3635 (cmpl (:$b x8632::tag-misc) (:%l tag))
[9692]3636 (jne :bad)
[11029]3637 (movsbl (:@ x8632::misc-subtag-offset (:%l val)) (:%l tag))
3638 (cmpl (:$b x8632::subtag-function) (:%l tag))
[10495]3639 (jne :bad)
3640
3641 (:anchored-uuo-section :resume)
[7360]3642 :bad
[10495]3643 (:anchored-uuo (uuo-error-udf (:%l sym))))
[7360]3644
[7428]3645(define-x8632-subprim-jump-vinsn (tail-call-fn-slide) .SPtcallnfnslide)
3646
3647(define-x8632-vinsn load-double-float-constant (((dest :double-float))
3648 ((lab :label)))
3649 (movsd (:@ (:^ lab) (:%l x8632::fn)) (:%xmm dest)))
3650
3651(define-x8632-vinsn load-single-float-constant (((dest :single-float))
3652 ((lab :label)))
3653 (movss (:@ (:^ lab) (:%l x8632::fn)) (:%xmm dest)))
3654
3655(define-x8632-subprim-call-vinsn (misc-set) .SPmisc-set)
3656
3657(define-x8632-subprim-lea-jmp-vinsn (slide-values) .SPmvslide)
3658
3659(define-x8632-subprim-lea-jmp-vinsn (spread-list) .SPspreadargz)
3660
[7659]3661;;; Even though it's implemented by calling a subprim, THROW is really
3662;;; a JUMP (to a possibly unknown destination). If the destination's
3663;;; really known, it should probably be inlined (stack-cleanup, value
3664;;; transfer & jump ...)
[10339]3665(define-x8632-vinsn (throw :jump-unknown) (()
[7659]3666 ()
[9678]3667 ((entry (:label 1))
3668 (ra (:lisp #.x8632::ra0))))
3669 (leal (:@ (:^ :back) (:%l x8632::fn)) (:%l ra))
[7659]3670 (:talign 5)
3671 (jmp (:@ .SPthrow))
3672 :back
[10339]3673 (movl (:$self 0) (:%l x8632::fn))
3674 (uuo-error-reg-not-tag (:%l x8632::temp0) (:$ub x8632::subtag-catch-frame)))
[7659]3675
[7428]3676(define-x8632-vinsn unbox-base-char (((dest :u32))
3677 ((src :lisp)))
3678 (movl (:%l src) (:%l dest))
3679 ((:pred = (:apply %hard-regspec-value dest) x8632::eax)
3680 (cmpb (:$b x8632::subtag-character) (:%accb dest)))
3681 ((:and (:pred > (:apply %hard-regspec-value dest) x8632::eax)
3682 (:pred <= (:apply %hard-regspec-value dest) x8632::ebx))
3683 (cmpb (:$b x8632::subtag-character) (:%b dest)))
3684 ((:pred > (:apply %hard-regspec-value dest) x8632::ebx)
3685 ;; very rare case, if even possible...
3686 (andl (:$l #xff) (:%l dest))
3687 (cmpl (:$b x8632::subtag-character) (:%l dest))
3688 (cmovel (:%l src) (:%l dest)))
[9692]3689 (je ::got-it)
[7428]3690 (uuo-error-reg-not-tag (:%l src) (:$ub x8632::subtag-character))
3691 :got-it
3692 (shrl (:$ub x8632::charcode-shift) (:%l dest)))
3693
3694(define-x8632-subprim-lea-jmp-vinsn (save-values) .SPsave-values)
3695
3696(define-x8632-subprim-lea-jmp-vinsn (recover-values) .SPrecover-values)
3697
3698(define-x8632-subprim-lea-jmp-vinsn (recover-values-for-mvcall) .SPrecover-values-for-mvcall)
3699
3700(define-x8632-subprim-lea-jmp-vinsn (add-values) .SPadd-values)
3701
3702(define-x8632-subprim-call-vinsn (make-stack-block) .SPmakestackblock)
3703
3704(define-x8632-subprim-call-vinsn (make-stack-block0) .Spmakestackblock0)
3705
3706;;; "dest" is preallocated, presumably on a stack somewhere.
[7817]3707(define-x8632-vinsn store-single (()
3708 ((dest :lisp)
3709 (source :single-float))
3710 ())
3711 (movss (:%xmm source) (:@ x8632::single-float.value (:%l dest))))
3712
3713;;; "dest" is preallocated, presumably on a stack somewhere.
[7428]3714(define-x8632-vinsn store-double (()
3715 ((dest :lisp)
3716 (source :double-float))
3717 ())
3718 (movsd (:%xmm source) (:@ x8632::double-float.value (:%l dest))))
3719
[7765]3720(define-x8632-vinsn fixnum->char (((dest :lisp))
3721 ((src :imm))
3722 ((temp :u32)))
3723 (movl (:%l src) (:%l temp))
[10363]3724 (sarl (:$ub (+ x8632::fixnumshift 1)) (:%l temp))
3725 (cmpl (:$l (ash #xfffe -1)) (:%l temp))
3726 (je :bad-if-eq)
3727 (sarl (:$ub (- 11 1)) (:%l temp))
[7765]3728 (cmpl (:$b (ash #xd800 -11))(:%l temp))
[10363]3729 :bad-if-eq
[10984]3730 (movl (:$l (:apply target-nil-value)) (:%l temp))
[7765]3731 (cmovel (:%l temp) (:%l dest))
3732 (je :done)
3733 ((:not (:pred =
3734 (:apply %hard-regspec-value dest)
3735 (:apply %hard-regspec-value src)))
3736 (movl (:%l src) (:%l dest)))
3737 (shll (:$ub (- x8632::charcode-shift x8632::fixnumshift)) (:%l dest))
[10363]3738 (addl (:$b x8632::subtag-character) (:%l dest))
[7765]3739 :done)
[7428]3740
[10363]3741;;; src is known to be a code for which CODE-CHAR returns non-nil.
3742(define-x8632-vinsn code-char->char (((dest :lisp))
3743 ((src :imm))
3744 ())
3745 ((:not (:pred =
3746 (:apply %hard-regspec-value dest)
3747 (:apply %hard-regspec-value src)))
3748 (movl (:%l src) (:%l dest)))
3749 (shll (:$ub (- x8632::charcode-shift x8632::fixnumshift)) (:%l dest))
3750 (addl (:$b x8632::subtag-character) (:%l dest))
3751 :done)
3752
[7772]3753(define-x8632-vinsn sign-extend-halfword (((dest :imm))
3754 ((src :imm)))
3755 (movl (:%l src ) (:%l dest))
[11355]3756 (shll (:$ub (- 16 x8632::fixnumshift)) (:%l dest))
3757 (sarl (:$ub (- 16 x8632::fixnumshift)) (:%l dest)))
[7765]3758
[7428]3759(define-x8632-subprim-jump-vinsn (tail-funcall-gen) .SPtfuncallgen)
3760
3761(define-x8632-vinsn %init-gvector (()
3762 ((v :lisp)
3763 (nbytes :u32const))
3764 ((count :imm)))
3765 (movl (:$l nbytes) (:%l count))
3766 (jmp :test)
3767 :loop
3768 (popl (:@ x8632::misc-data-offset (:%l v) (:%l count)))
3769 :test
3770 (subl (:$b x8632::node-size) (:%l count))
3771 (jge :loop))
3772
3773(define-x8632-subprim-jump-vinsn (tail-funcall-slide) .SPtfuncallslide)
3774
3775(define-x8632-vinsn nth-value (((result :lisp))
3776 ()
[8629]3777 ((temp :u32)
3778 (nargs (:lisp #.x8632::nargs))))
[7428]3779 (leal (:@ (:%l x8632::esp) (:%l x8632::nargs)) (:%l temp))
3780 (subl (:@ (:%l temp)) (:%l x8632::nargs))
[10984]3781 (movl (:$l (:apply target-nil-value)) (:%l result))
[7428]3782 (jle :done)
3783 ;; I -think- that a CMOV would be safe here, assuming that N wasn't
3784 ;; extremely large. Don't know if we can assume that.
3785 (movl (:@ (- x8632::node-size) (:%l x8632::esp) (:%l x8632::nargs)) (:%l result))
3786 :done
3787 (leal (:@ x8632::node-size (:%l temp)) (:%l x8632::esp)))
3788
3789
3790(define-x8632-subprim-lea-jmp-vinsn (req-heap-rest-arg) .SPreq-heap-rest-arg)
3791
3792(define-x8632-subprim-call-vinsn (stack-misc-alloc-init) .SPstack-misc-alloc-init)
3793
3794(define-x8632-vinsn %debug-trap (()
3795 ())
3796 (uuo-error-debug-trap))
3797
[7659]3798(define-x8632-vinsn double-to-single (((result :single-float))
3799 ((arg :double-float)))
3800 (cvtsd2ss (:%xmm arg) (:%xmm result)))
[7428]3801
[7659]3802(define-x8632-vinsn single-to-double (((result :double-float))
3803 ((arg :single-float)))
3804 (cvtss2sd (:%xmm arg) (:%xmm result)))
[7428]3805
[7659]3806(define-x8632-vinsn alloc-c-frame (()
[8629]3807 ((nwords :u32const))
3808 ((temp :imm)))
[7659]3809 (movd (:@ (:%seg :rcontext) x8632::tcr.foreign-sp) (:%mmx x8632::stack-temp))
[11421]3810 ;; Work around Apple bug number 6386516 (open stub may clobber stack)
3811 ;; by leaving an extra word of space in the parameter area.
3812 (subl (:$l (:apply ash (:apply 1+ nwords) x8632::word-shift))
[8629]3813 (:@ (:%seg :rcontext) x8632::tcr.foreign-sp))
3814 ;; align stack to 16-byte boundary
3815 (andb (:$b -16) (:@ (:%seg :rcontext) x8632::tcr.foreign-sp))
[10561]3816 (subl (:$b (* 2 x8632::node-size)) (:@ (:%seg :rcontext) x8632::tcr.foreign-sp))
[8629]3817 (movl (:@ (:%seg :rcontext) x8632::tcr.foreign-sp) (:%l temp))
[10561]3818 (movd (:%mmx x8632::stack-temp) (:@ (:%l temp)))
3819 (movl (:% x8632::ebp) (:@ 4 (:%l temp))))
[7428]3820
[8902]3821(define-x8632-vinsn alloc-variable-c-frame (()
3822 ((nwords :imm))
3823 ((temp :imm)))
3824 (movd (:@ (:%seg :rcontext) x8632::tcr.foreign-sp) (:%mmx x8632::stack-temp))
[11421]3825 ;; Work around Apple bug number 6386516 (open stub may clobber stack)
3826 ;; by leaving an extra word of space in the parameter area.
3827 ;; Note that nwords is a fixnum.
3828 (leal (:@ 4 (:%l nwords)) (:%l temp))
[11414]3829 (subl (:%l temp) (:@ (:%seg :rcontext) x8632::tcr.foreign-sp))
[8902]3830 ;; align stack to 16-byte boundary
3831 (andb (:$b -16) (:@ (:%seg :rcontext) x8632::tcr.foreign-sp))
[10561]3832 (subl (:$b (* 2 x8632::node-size)) (:@ (:%seg :rcontext) x8632::tcr.foreign-sp))
[8902]3833 (movl (:@ (:%seg :rcontext) x8632::tcr.foreign-sp) (:%l temp))
[10561]3834 (movd (:%mmx x8632::stack-temp) (:@ (:%l temp)))
3835 (movl (:% x8632::ebp) (:@ 4 (:%l temp))))
[8902]3836
[7659]3837(define-x8632-vinsn set-c-arg (()
3838 ((arg :u32)
[8629]3839 (offset :u32const))
3840 ((temp :imm)))
3841 (movl (:@ (:%seg :rcontext) x8632::tcr.foreign-sp) (:%l temp))
[10561]3842 (movl (:%l arg) (:@ (:apply + 8 (:apply ash offset 2)) (:%l temp))))
[7428]3843
[8750]3844;;; This is a pretty big crock.
3845(define-x8632-vinsn set-c-arg-from-mm0 (()
3846 ((offset :u32const))
3847 ((temp :imm)))
3848 (movl (:@ (:%seg :rcontext) x8632::tcr.foreign-sp) (:%l temp))
[10561]3849 (movq (:%mmx x8632::mm0) (:@ (:apply + 8 (:apply ash offset 2)) (:%l temp))))
[8750]3850
[7659]3851(define-x8632-vinsn eep.address (((dest t))
3852 ((src (:lisp (:ne dest )))))
[10495]3853 :resume
[7659]3854 (movl (:@ (+ (ash 1 x8632::word-shift) x8632::misc-data-offset) (:%l src))
3855 (:%l dest))
[10984]3856 (cmpl (:$l (:apply target-nil-value)) (:%l dest))
[10495]3857 (je :bad)
[7659]3858
[10495]3859 (:anchored-uuo-section :resume)
3860 :bad
3861 (:anchored-uuo (uuo-error-eep-unresolved (:%l src) (:%l dest))))
3862
[7765]3863(define-x8632-subprim-lea-jmp-vinsn (heap-cons-rest-arg) .SPheap-cons-rest-arg)
3864
3865(define-x8632-subprim-lea-jmp-vinsn (stack-cons-rest-arg) .SPstack-cons-rest-arg)
3866
3867(define-x8632-subprim-lea-jmp-vinsn (make-stack-vector) .SPmkstackv)
3868
[7772]3869(define-x8632-vinsn %current-frame-ptr (((dest :imm))
3870 ())
3871 (movl (:%l x8632::ebp) (:%l dest)))
3872
3873(define-x8632-vinsn %foreign-stack-pointer (((dest :imm))
3874 ())
3875 (movl (:@ (:%seg :rcontext) x8632::tcr.foreign-sp) (:%l dest)))
3876
3877
[7360]3878(define-x8632-vinsn %slot-ref (((dest :lisp))
3879 ((instance (:lisp (:ne dest)))
3880 (index :lisp)))
3881 (movl (:@ x8632::misc-data-offset (:%l instance) (:%l index)) (:%l dest))
[7765]3882 (cmpl (:$l x8632::slot-unbound-marker) (:%l dest))
[10495]3883 (je :bad)
[11107]3884 :resume
[10495]3885 (:anchored-uuo-section :resume)
3886 :bad
3887 (:anchored-uuo (uuo-error-slot-unbound (:%l dest) (:%l instance) (:%l index))))
[7659]3888
3889
[10495]3890
[7360]3891(define-x8632-vinsn symbol-ref (((dest :lisp))
3892 ((src :lisp)
3893 (cellno :u32const)))
3894 (movl (:@ (:apply + (- x8632::node-size x8632::fulltag-misc)
3895 (:apply ash cellno 2))
3896 (:%l src)) (:%l dest)))
3897
[10542]3898(define-x8632-vinsn mem-ref-c-bit-fixnum (((dest :lisp))
3899 ((src :address)
3900 (offset :s32const))
3901 ((temp :imm)))
3902 ((:pred = 0 (:apply ash offset -5))
3903 (btl (:$ub (:apply logand 31 offset))
3904 (:@ (:%l src))))
3905 ((:not (:pred = 0 (:apply ash offset -5)))
3906 (btl (:$ub (:apply logand 31 offset))
[11467]3907 (:@ (:apply ash (:apply ash offset -5) 2) (:%l src))))
3908 (movl (:$l x8632::fixnumone) (:%l temp))
[10542]3909 (movl (:$l 0) (:%l dest))
3910 (cmovbl (:%l temp) (:%l dest)))
3911
[7817]3912(define-x8632-vinsn mem-ref-bit-fixnum (((dest :lisp)
3913 (src :address))
3914 ((src :address)
3915 (offset :lisp))
[9462]3916 ((temp :lisp)))
3917 ;; (mark-as-imm temp)
3918 (btrl (:$ub (:apply %hard-regspec-value temp))
3919 (:@ (:%seg :rcontext) x8632::tcr.node-regs-mask))
[7817]3920 (movl (:%l offset) (:%l temp))
3921 (shrl (:$ub (+ 5 x8632::fixnumshift)) (:%l temp))
3922 (leal (:@ (:%l src) (:%l temp) 4) (:%l src))
3923 (movl (:%l offset) (:%l temp))
3924 (shrl (:$ub x8632::fixnumshift) (:%l temp))
3925 (andl (:$l 31) (:%l temp))
3926 (btl (:%l temp) (:@ (:%l src)))
3927 (movl (:$l x8632::fixnumone) (:%l temp))
3928 (leal (:@ (- x8632::fixnumone) (:%l temp)) (:%l dest))
[9462]3929 (cmovbl (:%l temp) (:%l dest))
3930 ;; (mark-as-node temp)
3931 (xorl (:%l temp) (:%l temp))
3932 (btsl (:$ub (:apply %hard-regspec-value temp))
3933 (:@ (:%seg :rcontext) x8632::tcr.node-regs-mask)))
[7817]3934
[7428]3935(define-x8632-subprim-call-vinsn (progvsave) .SPprogvsave)
3936
3937(define-x8632-subprim-jump-vinsn (progvrestore) .SPprogvrestore)
3938
3939(define-x8632-subprim-lea-jmp-vinsn (simple-keywords) .SPsimple-keywords)
3940
3941(define-x8632-subprim-lea-jmp-vinsn (keyword-args) .SPkeyword-args)
3942
3943(define-x8632-subprim-lea-jmp-vinsn (keyword-bind) .SPkeyword-bind)
3944
[8629]3945(define-x8632-vinsn set-high-halfword (()
3946 ((dest :imm)
3947 (n :s16const)))
3948 (orl (:$l (:apply ash n 16)) (:%l dest)))
3949
[7360]3950(define-x8632-vinsn scale-nargs (()
3951 ((nfixed :s16const)))
3952 ((:pred > nfixed 0)
[8367]3953 ((:pred < nfixed 32)
3954 (subl (:$b (:apply ash nfixed x8632::word-shift)) (:%l x8632::nargs)))
3955 ((:pred >= nfixed 32)
3956 (subl (:$l (:apply ash nfixed x8632::word-shift)) (:%l x8632::nargs)))))
[7360]3957
[7428]3958(define-x8632-vinsn opt-supplied-p (()
[10234]3959 ((num-opt :u16const))
3960 ((nargs (:u32 #.x8632::nargs))
3961 (imm :imm)))
3962 (xorl (:%l imm) (:%l imm))
[10984]3963 (movl (:$l (:apply target-nil-value)) (:%l x8632::arg_y))
[10234]3964 :loop
3965 (rcmpl (:%l imm) (:%l nargs))
3966 (movl (:%l x8632::arg_y) (:%l x8632::arg_z))
3967 (cmovll (:@ (+ x8632::t-offset x8632::symbol.vcell) (:%l x8632::arg_y)) (:%l x8632::arg_z))
3968 (addl (:$b x8632::node-size) (:%l imm))
3969 (rcmpl (:%l imm) (:$l (:apply ash num-opt x8632::fixnumshift)))
3970 (pushl (:%l x8632::arg_z))
3971 (jne :loop))
[7428]3972
3973(define-x8632-vinsn one-opt-supplied-p (()
[8629]3974 ()
3975 ((temp :u32)))
[8367]3976 (testl (:%l x8632::nargs) (:%l x8632::nargs))
[8629]3977 (setne (:%b temp))
3978 (negb (:%b temp))
3979 (andl (:$b x8632::t-offset) (:%l temp))
[10984]3980 (addl (:$l (:apply target-nil-value)) (:%l temp))
[8629]3981 (pushl (:%l temp)))
[7428]3982
3983;; needs some love
[7360]3984(define-x8632-vinsn two-opt-supplied-p (()
[7428]3985 ())
[8367]3986 (rcmpl (:%l x8632::nargs) (:$b (:apply ash 2 x8632::word-shift)))
[7428]3987 (jge :two)
[8367]3988 (rcmpl (:%l x8632::nargs) (:$b (:apply ash 1 x8632::word-shift)))
[7428]3989 (je :one)
3990 ;; none
[10984]3991 (pushl (:$l (:apply target-nil-value)))
3992 (pushl (:$l (:apply target-nil-value)))
[7428]3993 (jmp :done)
3994 :one
[10984]3995 (pushl (:$l (:apply target-t-value)))
3996 (pushl (:$l (:apply target-nil-value)))
[7428]3997 (jmp :done)
3998 :two
[10984]3999 (pushl (:$l (:apply target-t-value)))
4000 (pushl (:$l (:apply target-t-value)))
[7428]4001 :done)
[7360]4002
[7428]4003(define-x8632-vinsn set-c-flag-if-constant-logbitp (()
4004 ((bit :u8const)
4005 (int :imm)))
4006 (btl (:$ub bit) (:%l int)))
4007
[7877]4008(define-x8632-vinsn set-c-flag-if-variable-logbitp (()
4009 ((bit :imm)
4010 (int :imm))
[9451]4011 ((temp :u32)))
4012 (movl (:%l bit) (:%l temp))
4013 (sarl (:$ub x8632::fixnumshift) (:%l temp))
4014 (addl (:$b x8632::fixnumshift) (:%l temp))
4015 ;; Would be nice to use a cmov here, but the branch is probably
4016 ;; cheaper than trying to scare up an additional unboxed temporary.
4017 (cmpb (:$ub 31) (:%b temp))
4018 (jbe :test)
4019 (movl (:$l 31) (:%l temp))
4020 :test
4021 (btl (:%l temp) (:%l int)))
[7877]4022
[7772]4023(define-x8632-vinsn multiply-immediate (((dest :imm))
4024 ((src :imm)
4025 (const :s32const)))
4026 ((:and (:pred >= const -128) (:pred <= const 127))
4027 (imull (:$b const) (:%l src) (:%l dest)))
4028 ((:not (:and (:pred >= const -128) (:pred <= const 127)))
4029 (imull (:$l const) (:%l src) (:%l dest))))
4030
4031(define-x8632-vinsn multiply-fixnums (((dest :imm))
4032 ((x :imm)
4033 (y :imm))
4034 ((unboxed :s32)))
4035 ((:pred =
4036 (:apply %hard-regspec-value x)
4037 (:apply %hard-regspec-value dest))
4038 (movl (:%l y) (:%l unboxed))
4039 (sarl (:$ub x8632::fixnumshift) (:%l unboxed))
4040 (imull (:%l unboxed) (:%l dest)))
4041 ((:and (:not (:pred =
4042 (:apply %hard-regspec-value x)
4043 (:apply %hard-regspec-value dest)))
4044 (:pred =
4045 (:apply %hard-regspec-value y)
4046 (:apply %hard-regspec-value dest)))
4047 (movl (:%l x) (:%l unboxed))
4048 (sarl (:$ub x8632::fixnumshift) (:%l unboxed))
4049 (imull (:%l unboxed) (:%l dest)))
4050 ((:and (:not (:pred =
4051 (:apply %hard-regspec-value x)
4052 (:apply %hard-regspec-value dest)))
4053 (:not (:pred =
4054 (:apply %hard-regspec-value y)
4055 (:apply %hard-regspec-value dest))))
4056 (movl (:%l y) (:%l dest))
4057 (movl (:%l x) (:%l unboxed))
4058 (sarl (:$ub x8632::fixnumshift) (:%l unboxed))
4059 (imull (:%l unboxed) (:%l dest))))
4060
4061
[7428]4062(define-x8632-vinsn mark-as-imm (()
[7659]4063 ((reg :imm)))
[7428]4064 (btrl (:$ub (:apply %hard-regspec-value reg)) (:@ (:%seg :rcontext) x8632::tcr.node-regs-mask)))
4065
[15022]4066(define-x8632-vinsn mark-as-node (((reg :imm))
[7659]4067 ((reg :imm)))
[7428]4068 (xorl (:%l reg) (:%l reg))
4069 (btsl (:$ub (:apply %hard-regspec-value reg)) (:@ (:%seg :rcontext) x8632::tcr.node-regs-mask)))
4070
[11297]4071(define-x8632-vinsn mark-temp1-as-node-preserving-flags (()
4072 ()
4073 ((reg (:u32 #.x8632::temp1))))
4074 (movl (:$l 0) (:%l reg)) ;not xorl!
4075 (cld)) ;well, preserving most flags.
4076
[11290]4077
[11297]4078
4079
[7765]4080(define-x8632-vinsn (temp-push-unboxed-word :push :word :csp)
4081 (()
[8629]4082 ((w :u32))
4083 ((temp :imm)))
[7765]4084 (movd (:@ (:%seg :rcontext) x8632::tcr.foreign-sp) (:%mmx x8632::stack-temp))
[10561]4085 (subl (:$b 16) (:@ (:%seg :rcontext) x8632::tcr.foreign-sp))
[8629]4086 (movl (:@ (:%seg :rcontext) x8632::tcr.foreign-sp) (:%l temp))
4087 (movd (:%mmx x8632::stack-temp) (:@ (:%l temp)))
[10561]4088 (movl (:%l x8632::ebp) (:@ 4 (:%l temp)))
4089 (movl (:%l w) (:@ 8 (:%l temp))))
[7765]4090
4091(define-x8632-vinsn (temp-pop-unboxed-word :pop :word :csp)
4092 (((w :u32))
[8687]4093 ())
4094 (movl (:@ (:%seg :rcontext) x8632::tcr.foreign-sp) (:%l w))
[10561]4095 (movl (:@ 8 (:%l w)) (:%l w))
4096 (addl (:$b 16) (:@ (:%seg :rcontext) x8632::tcr.foreign-sp)))
[7765]4097
[11297]4098(define-x8632-vinsn (temp-pop-temp1-as-unboxed-word :pop :word :csp)
4099 (()
4100 ()
4101 ((w (:u32 #.x8632::temp1))))
4102 (movl (:@ (:%seg :rcontext) x8632::tcr.foreign-sp) (:%l w))
4103 (std)
4104 (movl (:@ 8 (:%l w)) (:%l w))
4105 (addl (:$b 16) (:@ (:%seg :rcontext) x8632::tcr.foreign-sp)))
4106
[7817]4107(define-x8632-vinsn (temp-push-node :push :word :tsp)
4108 (()
4109 ((w :lisp))
4110 ((temp :imm)))
4111 (subl (:$b (* 2 x8632::dnode-size)) (:@ (:%seg :rcontext) x8632::tcr.next-tsp))
4112 (movd (:@ (:%seg :rcontext) x8632::tcr.save-tsp) (:%mmx x8632::stack-temp))
4113 (movl (:@ (:%seg :rcontext) x8632::tcr.next-tsp) (:%l temp))
[9123]4114 (movsd (:%xmm x8632::fpzero) (:@ (:%l temp)))
4115 (movsd (:%xmm x8632::fpzero) (:@ x8632::dnode-size (:%l temp)))
[7817]4116 (movd (:%mmx x8632::stack-temp) (:@ (:%l temp)))
4117 (movl (:%l temp) (:@ (:%seg :rcontext) x8632::tcr.save-tsp))
4118 (movl (:%l w) (:@ x8632::dnode-size (:%l temp))))
4119
4120(define-x8632-vinsn (temp-pop-node :pop :word :tsp)
4121 (((w :lisp))
4122 ()
4123 ((temp :imm)))
4124 (movl (:@ (:%seg :rcontext) x8632::tcr.save-tsp) (:%l temp))
4125 (movl (:@ x8632::dnode-size (:%l temp)) (:%l w))
4126 (movl (:@ (:%l temp)) (:%l temp))
4127 (movl (:%l temp) (:@ (:%seg :rcontext) x8632::tcr.save-tsp))
4128 (movl (:%l temp) (:@ (:%seg :rcontext) x8632::tcr.next-tsp)))
4129
[7877]4130(define-x8632-vinsn (temp-push-single-float :push :word :csp)
4131 (()
[8629]4132 ((f :single-float))
4133 ((temp :imm)))
[7877]4134 (movd (:@ (:%seg :rcontext) x8632::tcr.foreign-sp) (:%mmx x8632::stack-temp))
[10561]4135 (subl (:$b 16) (:@ (:%seg :rcontext) x8632::tcr.foreign-sp))
[8629]4136 (movl (:@ (:%seg :rcontext) x8632::tcr.foreign-sp) (:%l temp))
4137 (movd (:%mmx x8632::stack-temp) (:@ (:%l temp)))
[10561]4138 (movl (:%l x8632::ebp) (:@ 4 (:%l temp)))
4139 (movss (:%xmm f) (:@ 8 (:%l temp))))
[7877]4140
4141(define-x8632-vinsn (temp-pop-single-float :pop :word :csp)
4142 (((f :single-float))
[8629]4143 ()
4144 ((temp :imm)))
4145 (movl (:@ (:%seg :rcontext) x8632::tcr.foreign-sp) (:%l temp))
[10561]4146 (movss (:@ 8 (:%l temp)) (:%xmm f))
4147 (addl (:$b 16) (:@ (:%seg :rcontext) x8632::tcr.foreign-sp)))
[7877]4148
4149(define-x8632-vinsn (temp-push-double-float :push :word :csp)
4150 (()
[8629]4151 ((f :double-float))
4152 ((temp :imm)))
[7877]4153 (movd (:@ (:%seg :rcontext) x8632::tcr.foreign-sp) (:%mmx x8632::stack-temp))
4154 (subl (:$b 16) (:@ (:%seg :rcontext) x8632::tcr.foreign-sp))
[8629]4155 (movl (:@ (:%seg :rcontext) x8632::tcr.foreign-sp) (:%l temp))
4156 (movd (:%mmx x8632::stack-temp) (:@ (:%l temp)))
[10561]4157 (movl (:%l x8632::ebp) (:@ 4 (:%l temp)))
[8629]4158 (movsd (:%xmm f) (:@ 8 (:%l temp))))
[7877]4159
4160(define-x8632-vinsn (temp-pop-double-float :pop :word :csp)
4161 (((f :double-float))
[8629]4162 ()
4163 ((temp :imm)))
4164 (movl (:@ (:%seg :rcontext) x8632::tcr.foreign-sp) (:%l temp))
4165 (movsd (:@ 8 (:%l temp)) (:%xmm f))
[7877]4166 (addl (:$b 16) (:@ (:%seg :rcontext) x8632::tcr.foreign-sp)))
4167
[9041]4168(define-x8632-vinsn load-next-method-context (((dest :lisp))
4169 ())
[9042]4170 (movl (:@ (:%seg :rcontext) x8632::tcr.next-method-context) (:%l dest))
[9041]4171 (movl (:$l 0) (:@ (:%seg :rcontext) x8632::tcr.next-method-context)))
4172
[9265]4173(define-x8632-vinsn save-node-register-to-spill-area (()
4174 ((src :lisp)))
4175 ;; maybe add constant to index slot 0--3
4176 (movl (:%l src) (:@ (:%seg :rcontext) x8632::tcr.save3)))
4177
4178(define-x8632-vinsn load-node-register-from-spill-area (((dest :lisp))
4179 ())
4180 (movl (:@ (:%seg :rcontext) x8632::tcr.save3) (:%l dest))
4181 (movss (:%xmm x8632::fpzero) (:@ (:%seg :rcontext) x8632::tcr.save3)))
4182
[10234]4183(define-x8632-vinsn align-loop-head (()
4184 ())
[11297]4185)
[10234]4186
[14776]4187(define-x8632-vinsn double-float-negate (((reg :double-float))
[14777]4188 ((reg :double-float)
4189 (tmp :double-float)))
4190 (movsd (:@ (:^ :const) (:% x8632::fn)) (:%xmm tmp))
4191 (pxor (:%xmm tmp) (:%xmm reg))
4192
[14776]4193 (:uuo-section)
4194 :const
4195 (:long 0)
[14777]4196 (:long #x-80000000))
[14776]4197
4198(define-x8632-vinsn single-float-negate (((reg :single-float))
[14777]4199 ((reg :single-float)
4200 (tmp :single-float)))
4201 (movss (:@ (:^ :const) (:% x8632::fn)) (:%xmm tmp))
4202 (pxor (:%xmm tmp) (:%xmm reg))
[14776]4203 (:uuo-section)
4204 :const
[14777]4205 (:long #x80000000))
[14776]4206
[14943]4207(define-x8632-vinsn fixnum-ref-c-double-float (((dest :double-float))
4208 ((base :imm)
4209 (idx :u32const)))
4210 (movsd (:@ (:apply ash idx 3) (:%l base)) (:%xmm dest)))
4211
4212(define-x8632-vinsn fixnum-ref-double-float (((dest :double-float))
4213 ((base :imm)
4214 (idx :imm)))
4215 (movsd (:@ (:%l base) (:%l idx) 2) (:%xmm dest)))
4216
4217(define-x8632-vinsn fixnum-set-c-double-float (()
4218 ((base :imm)
4219 (idx :u32const)
4220 (val :double-float)))
4221 (movsd (:%xmm val) (:@ (:apply ash idx 3) (:%l base))))
4222
4223(define-x8632-vinsn fixnum-set-double-float (()
4224 ((base :imm)
4225 (idx :imm)
4226 (val :double-float)))
4227 (movsd (:%xmm val) (:@ (:%l base) (:%l idx) 2)))
4228
[14969]4229(define-x8632-vinsn pop-outgoing-arg (((n :u16const))
4230 ())
4231 (popl (:@ (:apply * n (- x8632::node-size)) (:%l x8632::ebp))))
4232
4233(define-x8632-vinsn slide-nth-arg (()
4234 ((n :u16const)
4235 (nstackargs :u16const)
4236 (temp :lisp)))
4237 (movl (:@ (:apply * (:apply - nstackargs (:apply + 1 n)) x8632::node-size) (:%l x8632::esp)) (:%l temp))
4238 (movl (:%l temp) (:@ (:apply * (:apply + n 1) (- x8632::node-size)) (:%l x8632::ebp))))
4239
4240(define-x8632-vinsn set-tail-vsp (((n :u16const))
4241 ())
4242 ((:pred = 0 n)
4243 (movl (:%l x8632::ebp) (:%l x8632::esp)))
4244 ((:not (:pred = 0 n))
4245 (leal (:@ (:apply * n (- x8632::node-size)) (:%l x8632::ebp)) (:%l x8632::esp))))
4246
4247;;; If we've have outgoing arguments in a tail call and are calling
4248;;; some function (rather than jumping to an internal entry point), we
4249;;; need to push the caller's return address and unlink its frame
4250;;; pointer.
4251(define-x8632-vinsn prepare-tail-call (()
4252 ())
4253 (pushl (:@ x8632::node-size (:%l x8632::ebp)))
4254 (movl (:@ (:% x8632::ebp)) (:% x8632::ebp)))
4255
[15006]4256(define-x8632-vinsn (skip-unless-fixnum-in-range :branch)
4257 (((idx :u32))
4258 ((reg :imm)
4259 (minval :s32const)
4260 (maxval :u32const)
4261 (default :label)))
[15004]4262 (testl (:$l x8632::fixnummask) (:%l reg))
[14998]4263 (jne default)
[15006]4264 (movl (:%l reg) (:%l idx))
4265 (sarl (:$ub x8632::fixnumshift) (:%l idx))
[14998]4266 ((:not (:pred zerop minval))
[15006]4267 ((:and (:pred < minval 128) (:pred >= minval -128))
4268 (subl (:$b minval) (:%l idx)))
4269 ((:not (:and (:pred < minval 128) (:pred >= minval -128)))
4270 (subl (:$l minval) (:%l idx))))
4271 ((:pred < maxval 128)
4272 (cmpl (:$b maxval) (:%l idx)))
4273 ((:pred >= maxval 128)
4274 (cmpl (:$l maxval) (:%l idx)))
4275 (jae default))
4276
4277(define-x8632-vinsn (ijmp :branch) (((reg :u32))
4278 ((reg :u32)
4279 (count :s32const))
4280 ((rjmp :lisp)))
4281 (movl (:@ (:^ :jtab) (:%l x8632::fn) (:%l reg) 4) (:%l reg))
[15004]4282 (leal (:@ (:%l x8632::fn) (:%l reg)) (:%l rjmp))
[14998]4283 (jmp (:%l rjmp))
4284 (:uuo-section)
4285 (:align 2)
[15006]4286 (:long count)
[14998]4287 :jtab)
4288
4289(define-x8632-vinsn jtabentry (()
4290 ((label :label)))
4291 (:uuo-section)
4292 (:long (:^ label)))
4293
[7286]4294(queue-fixup
4295 (fixup-x86-vinsn-templates
4296 *x8632-vinsn-templates*
[10754]4297 x86::*x86-opcode-template-lists* *x8632-backend*))
[7286]4298
[9376]4299(provide "X8632-VINSNS")
Note: See TracBrowser for help on using the repository browser.