close Warning: Can't use blame annotator:
No changeset 2899 in the repository

source: release/1.6/source/compiler/X86/X8664/x8664-vinsns.lisp

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

Merge fix to x8664 cons vinsn (r14457) from trunk.

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