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

source: branches/1.1/ccl/compiler/X86/x862.lisp

Last change on this file was 8468, checked in by Gary Byers, 17 years ago

(On 1.1 branch):Fix X862-NLEXIT: don't pop foreign/temp frames if
nthrow already did, try to coalesce nthrow calls, only adjust stacks
after last catch.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 400.0 KB
RevLine 
1;;;-*-Mode: LISP; Package: CCL -*-
2;;;
3;;; Copyright (C) 2005, Clozure Associates
4;;; This file is part of OpenMCL.
5;;;
6;;; OpenMCL is licensed under the terms of the Lisp Lesser GNU Public
7;;; License , known as the LLGPL and distributed with OpenMCL as the
8;;; file "LICENSE". The LLGPL consists of a preamble and the LGPL,
9;;; which is distributed with OpenMCL as the file "LGPL". Where these
10;;; conflict, the preamble takes precedence.
11;;;
12;;; OpenMCL is referenced in the preamble as the "LIBRARY."
13;;;
14;;; The LLGPL is also available online at
15;;; http://opensource.franz.com/preamble.html
16
17(in-package "CCL")
18
19(eval-when (:compile-toplevel :execute)
20 (require "NXENV")
21 (require "X8664ENV"))
22
23(eval-when (:load-toplevel :execute :compile-toplevel)
24 (require "X86-BACKEND"))
25
26(defparameter *x862-debug-mask* 0)
27(defconstant x862-debug-verbose-bit 0)
28(defconstant x862-debug-vinsns-bit 1)
29(defconstant x862-debug-lcells-bit 2)
30(defparameter *x862-target-lcell-size* 0)
31(defparameter *x862-target-node-size* 0)
32(defparameter *x862-target-dnode-size* 0)
33(defparameter *x862-target-fixnum-shift* 0)
34(defparameter *x862-target-node-shift* 0)
35(defparameter *x862-target-bits-in-word* 0)
36(defparameter *x862-target-num-arg-regs* 0)
37(defparameter *x862-target-num-save-regs* 0)
38(defparameter *x862-target-half-fixnum-type* nil)
39
40(defparameter *x862-operator-supports-u8-target* ())
41(defparameter *x862-operator-supports-push* ())
42
43
44
45
46
47(defun x862-immediate-operand (x)
48 (if (eq (acode-operator x) (%nx1-operator immediate))
49 (cadr x)
50 (error "~&Bug: not an immediate: ~s" x)))
51
52(defmacro with-x86-p2-declarations (declsform &body body)
53 `(let* ((*x862-tail-allow* *x862-tail-allow*)
54 (*x862-reckless* *x862-reckless*)
55 (*x862-open-code-inline* *x862-open-code-inline*)
56 (*x862-trust-declarations* *x862-trust-declarations*))
57 (x862-decls ,declsform)
58 ,@body))
59
60
61(defmacro with-x86-local-vinsn-macros ((segvar &optional vreg-var xfer-var) &body body)
62 (declare (ignorable xfer-var))
63 (let* ((template-name-var (gensym))
64 (template-temp (gensym))
65 (args-var (gensym))
66 (labelnum-var (gensym))
67 (retvreg-var (gensym))
68 (label-var (gensym)))
69 `(macrolet ((! (,template-name-var &rest ,args-var)
70 (let* ((,template-temp (get-vinsn-template-cell ,template-name-var (backend-p2-vinsn-templates *target-backend*))))
71 (unless ,template-temp
72 (warn "VINSN \"~A\" not defined" ,template-name-var))
73 `(%emit-vinsn ,',segvar ',,template-name-var (backend-p2-vinsn-templates *target-backend*) ,@,args-var))))
74 (macrolet ((<- (,retvreg-var)
75 `(x862-copy-register ,',segvar ,',vreg-var ,,retvreg-var))
76 (@ (,labelnum-var)
77 `(backend-gen-label ,',segvar ,,labelnum-var))
78 (@= (,labelnum-var)
79 `(x862-emit-aligned-label ,',segvar ,,labelnum-var))
80 (-> (,label-var)
81 `(! jump (aref *backend-labels* ,,label-var)))
82 (^ (&rest branch-args)
83 `(x862-branch ,',segvar ,',xfer-var ,@branch-args))
84 (? (&key (class :gpr)
85 (mode :lisp))
86 (let* ((class-val
87 (ecase class
88 (:gpr hard-reg-class-gpr)
89 (:fpr hard-reg-class-fpr)
90 (:crf hard-reg-class-crf)))
91 (mode-val
92 (if (eq class :gpr)
93 (gpr-mode-name-value mode)
94 (if (eq class :fpr)
95 (if (eq mode :single-float)
96 hard-reg-class-fpr-mode-single
97 hard-reg-class-fpr-mode-double)
98 0))))
99 `(make-unwired-lreg nil
100 :class ,class-val
101 :mode ,mode-val)))
102 ($ (reg &key (class :gpr) (mode :lisp))
103 (let* ((class-val
104 (ecase class
105 (:gpr hard-reg-class-gpr)
106 (:fpr hard-reg-class-fpr)
107 (:crf hard-reg-class-crf)))
108 (mode-val
109 (if (eq class :gpr)
110 (gpr-mode-name-value mode)
111 (if (eq class :fpr)
112 (if (eq mode :single-float)
113 hard-reg-class-fpr-mode-single
114 hard-reg-class-fpr-mode-double)
115 0))))
116 `(make-wired-lreg ,reg
117 :class ,class-val
118 :mode ,mode-val))))
119 ,@body))))
120
121
122
123(defvar *x86-current-context-annotation* nil)
124(defvar *x862-woi* nil)
125(defvar *x862-open-code-inline* nil)
126(defvar *x862-register-restore-count* 0)
127(defvar *x862-register-restore-ea* nil)
128(defvar *x862-compiler-register-save-label* nil)
129(defvar *x862-valid-register-annotations* 0)
130(defvar *x862-register-annotation-types* nil)
131(defvar *x862-register-ea-annotations* nil)
132(defvar *x862-constant-alist* nil)
133(defvar *x862-double-float-constant-alist* nil)
134(defvar *x862-single-float-constant-alist* nil)
135
136(defparameter *x862-tail-call-aliases*
137 ()
138 #| '((%call-next-method . (%tail-call-next-method . 1))) |#
139
140)
141
142(defvar *x862-popreg-labels* nil)
143(defvar *x862-popj-labels* nil)
144(defvar *x862-valret-labels* nil)
145(defvar *x862-nilret-labels* nil)
146
147(defvar *x862-icode* nil)
148(defvar *x862-undo-stack* nil)
149(defvar *x862-undo-because* nil)
150
151
152(defvar *x862-cur-afunc* nil)
153(defvar *x862-vstack* 0)
154(defvar *x862-cstack* 0)
155(defvar *x862-undo-count* 0)
156(defvar *x862-returning-values* nil)
157(defvar *x862-vcells* nil)
158(defvar *x862-fcells* nil)
159(defvar *x862-entry-vsp-saved-p* nil)
160
161(defvar *x862-entry-label* nil)
162(defvar *x862-tail-label* nil)
163(defvar *x862-tail-vsp* nil)
164(defvar *x862-tail-nargs* nil)
165(defvar *x862-tail-allow* t)
166(defvar *x862-reckless* nil)
167(defvar *x862-trust-declarations* nil)
168(defvar *x862-entry-vstack* nil)
169(defvar *x862-fixed-nargs* nil)
170(defvar *x862-need-nargs* t)
171
172(defparameter *x862-inhibit-register-allocation* nil)
173(defvar *x862-record-symbols* nil)
174(defvar *x862-recorded-symbols* nil)
175
176(defvar *x862-result-reg* x8664::arg_z)
177
178
179(declaim (fixnum *x862-vstack* *x862-cstack*))
180
181
182
183
184
185(defvar *x862-all-lcells* ())
186
187(defun x86-immediate-label (imm)
188 (or (cdr (assoc imm *x862-constant-alist* :test #'eq))
189 (let* ((lab (aref *backend-labels* (backend-get-next-label))))
190 (push (cons imm lab) *x862-constant-alist*)
191 lab)))
192
193(defun x86-double-float-constant-label (imm)
194 (or (cdr (assoc imm *x862-double-float-constant-alist*))
195 (let* ((lab (aref *backend-labels* (backend-get-next-label))))
196 (push (cons imm lab) *x862-double-float-constant-alist*)
197 lab)))
198
199(defun x86-single-float-constant-label (imm)
200 (or (cdr (assoc imm *x862-single-float-constant-alist*))
201 (let* ((lab (aref *backend-labels* (backend-get-next-label))))
202 (push (cons imm lab) *x862-single-float-constant-alist*)
203 lab)))
204
205
206(defun x862-free-lcells ()
207 (without-interrupts
208 (let* ((prev (pool.data *lcell-freelist*)))
209 (dolist (r *x862-all-lcells*)
210 (setf (lcell-kind r) prev
211 prev r))
212 (setf (pool.data *lcell-freelist*) prev)
213 (setq *x862-all-lcells* nil))))
214
215(defun x862-note-lcell (c)
216 (push c *x862-all-lcells*)
217 c)
218
219(defvar *x862-top-vstack-lcell* ())
220(defvar *x862-bottom-vstack-lcell* ())
221
222(defun x862-new-lcell (kind parent width attributes info)
223 (x862-note-lcell (make-lcell kind parent width attributes info)))
224
225(defun x862-new-vstack-lcell (kind width attributes info)
226 (setq *x862-top-vstack-lcell* (x862-new-lcell kind *x862-top-vstack-lcell* width attributes info)))
227
228(defun x862-reserve-vstack-lcells (n)
229 (dotimes (i n) (x862-new-vstack-lcell :reserved *x862-target-lcell-size* 0 nil)))
230
231(defun x862-vstack-mark-top ()
232 (x862-new-lcell :tos *x862-top-vstack-lcell* 0 0 nil))
233
234;;; Alist mapping VARs to lcells/lregs
235(defvar *x862-var-cells* ())
236
237(defun x862-note-var-cell (var cell)
238 ;(format t "~& ~s -> ~s" (var-name var) cell)
239 (push (cons var cell) *x862-var-cells*))
240
241(defun x862-note-top-cell (var)
242 (x862-note-var-cell var *x862-top-vstack-lcell*))
243
244(defun x862-lookup-var-cell (var)
245 (or (cdr (assq var *x862-var-cells*))
246 (and nil (warn "Cell not found for ~s" (var-name var)))))
247
248(defun x862-collect-lcells (kind &optional (bottom *x862-bottom-vstack-lcell*) (top *x862-top-vstack-lcell*))
249 (do* ((res ())
250 (cell top (lcell-parent cell)))
251 ((eq cell bottom) res)
252 (if (null cell)
253 (error "Horrible compiler bug.")
254 (if (eq (lcell-kind cell) kind)
255 (push cell res)))))
256
257
258
259;;; ensure that lcell's offset matches what we expect it to.
260;;; For bootstrapping.
261
262(defun x862-ensure-lcell-offset (c expected)
263 (if c (= (calc-lcell-offset c) expected) (zerop expected)))
264
265(defun x862-check-lcell-depth (&optional (context "wherever"))
266 (when (logbitp x862-debug-verbose-bit *x862-debug-mask*)
267 (let* ((depth (calc-lcell-depth *x862-top-vstack-lcell*)))
268 (or (= depth *x862-vstack*)
269 (warn "~a: lcell depth = ~d, vstack = ~d" context depth *x862-vstack*)))))
270
271(defun x862-do-lexical-reference (seg vreg ea)
272 (when vreg
273 (with-x86-local-vinsn-macros (seg vreg)
274 (if (eq vreg :push)
275 (if (memory-spec-p ea)
276 (if (addrspec-vcell-p ea)
277 (with-node-target () target
278 (x862-stack-to-register seg ea target)
279 (! vcell-ref target target)
280 (! vpush-register target))
281 (! vframe-push (memspec-frame-address-offset ea) *x862-vstack*))
282 (! vpush-register ea))
283 (if (memory-spec-p ea)
284 (ensuring-node-target (target vreg)
285 (progn
286 (x862-stack-to-register seg ea target)
287 (if (addrspec-vcell-p ea)
288 (! vcell-ref target target))))
289 (<- ea))))))
290
291(defun x862-do-lexical-setq (seg vreg ea valreg)
292 (with-x86-local-vinsn-macros (seg vreg)
293 (cond ((typep ea 'lreg)
294 (x862-copy-register seg ea valreg))
295 ((addrspec-vcell-p ea) ; closed-over vcell
296 (x862-copy-register seg x8664::arg_z valreg)
297 (x862-stack-to-register seg ea x8664::arg_x)
298 (x862-lri seg x8664::arg_y 0)
299 (! call-subprim-3 x8664::arg_z (subprim-name->offset '.SPgvset) x8664::arg_x x8664::arg_y x8664::arg_z))
300 ((memory-spec-p ea) ; vstack slot
301 (x862-register-to-stack seg valreg ea))
302 (t
303 (x862-copy-register seg ea valreg)))
304 (when vreg
305 (<- valreg))))
306
307;;; ensure that next-method-var is heap-consed (if it's closed over.)
308;;; it isn't ever setqed, is it ?
309(defun x862-heap-cons-next-method-var (seg var)
310 (with-x86-local-vinsn-macros (seg)
311 (when (eq (ash 1 $vbitclosed)
312 (logand (logior (ash 1 $vbitclosed)
313 (ash 1 $vbitcloseddownward))
314 (the fixnum (nx-var-bits var))))
315 (let* ((ea (var-ea var))
316 (arg ($ x8664::arg_z))
317 (result ($ x8664::arg_z)))
318 (x862-do-lexical-reference seg arg ea)
319 (x862-set-nargs seg 1)
320 (! ref-constant ($ x8664::fname) (x86-immediate-label (x862-symbol-entry-locative '%cons-magic-next-method-arg)))
321 (! call-known-symbol arg)
322 (x862-do-lexical-setq seg nil ea result)))))
323
324;;; If we change the order of operands in a binary comparison operation,
325;;; what should the operation change to ? (eg., (< X Y) means the same
326;;; thing as (> Y X)).
327(defparameter *x862-reversed-cr-bits*
328 (vector
329 nil ;o ?
330 nil ;no ?
331 x86::x86-a-bits ;b -> a
332 x86::x86-be-bits ;ae -> be
333 x86::x86-e-bits ;e->e
334 x86::x86-ne-bits ;ne->ne
335 x86::x86-ae-bits ;be->ae
336 x86::x86-b-bits ;a->b
337 nil ;s ?
338 nil ;ns ?
339 nil ;pe ?
340 nil ;po ?
341 x86::x86-g-bits ;l->g
342 x86::x86-le-bits ;ge->le
343 x86::x86-ge-bits ;le->ge
344 x86::x86-l-bits ;g->l
345 ))
346
347(defun x862-reverse-cr-bit (cr-bit)
348 (or (svref *x862-reversed-cr-bits* cr-bit)
349 (error "Can't reverse CR bit ~d" cr-bit)))
350
351
352(defun acode-condition-to-x86-cr-bit (cond)
353 (condition-to-x86-cr-bit (cadr cond)))
354
355(defun condition-to-x86-cr-bit (cond)
356 (case cond
357 (:EQ (values x86::x86-e-bits t))
358 (:NE (values x86::x86-e-bits nil))
359 (:GT (values x86::x86-le-bits nil))
360 (:LE (values x86::x86-le-bits t))
361 (:LT (values x86::x86-l-bits t))
362 (:GE (values x86::x86-l-bits nil))))
363
364;;; Generate the start and end bits for a RLWINM instruction that
365;;; would be equivalent to to LOGANDing the constant with some value.
366;;; Return (VALUES NIL NIL) if the constant contains more than one
367;;; sequence of consecutive 1-bits, else bit indices.
368;;; The caller generally wants to treat the constant as an (UNSIGNED-BYTE 32);
369;;; since this uses LOGCOUNT and INTEGER-LENGTH to find the significant
370;;; bits, it ensures that the constant is a (SIGNED-BYTE 32) that has
371;;; the same least-significant 32 bits.
372(defun x862-mask-bits (constant)
373 (if (< constant 0) (setq constant (logand #xffffffff constant)))
374 (if (= constant #xffffffff)
375 (values 0 31)
376 (if (zerop constant)
377 (values nil nil)
378 (let* ((signed (if (and (logbitp 31 constant)
379 (> constant 0))
380 (- constant (ash 1 32))
381 constant))
382 (count (logcount signed))
383 (len (integer-length signed))
384 (highbit (logbitp (the fixnum (1- len)) constant)))
385 (declare (fixnum count len))
386 (do* ((i 1 (1+ i))
387 (pos (- len 2) (1- pos)))
388 ((= i count)
389 (let* ((start (- 32 len))
390 (end (+ count start)))
391 (declare (fixnum start end))
392 (if highbit
393 (values start (the fixnum (1- end)))
394 (values (logand 31 end)
395 (the fixnum (1- start))))))
396 (declare (fixnum i pos))
397 (unless (eq (logbitp pos constant) highbit)
398 (return (values nil nil))))))))
399
400
401(defun x862-ensure-binding-indices-for-vcells (vcells)
402 (dolist (cell vcells)
403 (ensure-binding-index (car cell)))
404 vcells)
405
406(defun x862-register-mask-byte (count)
407 (if (> count 0)
408 (logior
409 (ash 1 (- x8664::save0 8))
410 (if (> count 1)
411 (logior
412 (ash 1 (- x8664::save1 8))
413 (if (> count 2)
414 (logior
415 (ash 1 (- x8664::save2 8))
416 (if (> count 3)
417 (ash 1 (- x8664::save3 8))
418 0))
419 0))
420 0))
421 0))
422
423(defun x862-encode-register-save-ea (ea count)
424 (if (zerop count)
425 0
426 (min (- (ash ea (- x8664::word-shift)) count) #xff)))
427
428
429(defun x862-compile (afunc &optional lambda-form *x862-record-symbols*)
430 (progn
431 (dolist (a (afunc-inner-functions afunc))
432 (unless (afunc-lfun a)
433 (x862-compile a
434 (if lambda-form
435 (afunc-lambdaform a))
436 *x862-record-symbols*))) ; always compile inner guys
437 (let* ((*x862-cur-afunc* afunc)
438 (*x862-returning-values* nil)
439 (*x86-current-context-annotation* nil)
440 (*x862-woi* nil)
441 (*next-lcell-id* -1)
442 (*x862-open-code-inline* nil)
443 (*x862-register-restore-count* nil)
444 (*x862-compiler-register-save-label* nil)
445 (*x862-valid-register-annotations* 0)
446 (*x862-register-ea-annotations* (x862-make-stack 16))
447 (*x862-register-restore-ea* nil)
448 (*x862-constant-alist* nil)
449 (*x862-double-float-constant-alist* nil)
450 (*x862-single-float-constant-alist* nil)
451 (*x862-vstack* 0)
452 (*x862-cstack* 0)
453 (*x862-target-num-arg-regs* (target-arch-case (:x8664 $numx8664argregs)))
454 (*x862-target-num-save-regs* (target-arch-case (:x8664 $numx8664saveregs)))
455 (*x862-target-lcell-size* (arch::target-lisp-node-size (backend-target-arch *target-backend*)))
456 (*x862-target-fixnum-shift* (arch::target-fixnum-shift (backend-target-arch *target-backend*)))
457 (*x862-target-node-shift* (arch::target-word-shift (backend-target-arch *target-backend*)))
458 (*x862-target-bits-in-word* (arch::target-nbits-in-word (backend-target-arch *target-backend*)))
459 (*x862-target-node-size* *x862-target-lcell-size*)
460 (*x862-target-half-fixnum-type* `(signed-byte ,(- *x862-target-bits-in-word*
461 (1+ *x862-target-fixnum-shift*))))
462 (*x862-target-dnode-size* (* 2 *x862-target-lcell-size*))
463 (*x862-all-lcells* ())
464 (*x862-top-vstack-lcell* nil)
465 (*x862-bottom-vstack-lcell* (x862-new-vstack-lcell :bottom 0 0 nil))
466 (*x862-var-cells* nil)
467 (*backend-vinsns* (backend-p2-vinsn-templates *target-backend*))
468 (*backend-node-regs* (target-arch-case (:x8664 x8664-node-regs)))
469 (*backend-node-temps* (target-arch-case (:x8664 x8664-temp-node-regs)))
470 (*available-backend-node-temps* (target-arch-case (:x8664 x8664-temp-node-regs)))
471 (*backend-imm-temps* (target-arch-case (:x8664 x8664-imm-regs)))
472 (*available-backend-imm-temps* (target-arch-case (:x8664 x8664-imm-regs)))
473 (*backend-crf-temps* (target-arch-case (:x8664 x8664-cr-fields)))
474 (*available-backend-crf-temps* (target-arch-case (:x8664 x8664-cr-fields)))
475 (*backend-fp-temps* (target-arch-case (:x8664 x8664-temp-fp-regs)))
476 (*available-backend-fp-temps* (target-arch-case (:x8664 x8664-temp-fp-regs)))
477 (bits 0)
478 (*logical-register-counter* -1)
479 (*backend-all-lregs* ())
480 (*x862-popj-labels* nil)
481 (*x862-popreg-labels* nil)
482 (*x862-valret-labels* nil)
483 (*x862-nilret-labels* nil)
484 (*x862-undo-count* 0)
485 (*backend-labels* (x862-make-stack 64 target::subtag-simple-vector))
486 (*x862-undo-stack* (x862-make-stack 64 target::subtag-simple-vector))
487 (*x862-undo-because* (x862-make-stack 64))
488 (*x862-entry-label* nil)
489 (*x862-tail-label* nil)
490 (*x862-tail-vsp* nil)
491 (*x862-tail-nargs* nil)
492 (*x862-inhibit-register-allocation* nil)
493 (*x862-tail-allow* t)
494 (*x862-reckless* nil)
495 (*x862-trust-declarations* t)
496 (*x862-entry-vstack* nil)
497 (*x862-fixed-nargs* nil)
498 (*x862-need-nargs* t)
499 (fname (afunc-name afunc))
500 (*x862-entry-vsp-saved-p* nil)
501 (*x862-vcells* (x862-ensure-binding-indices-for-vcells (afunc-vcells afunc)))
502 (*x862-fcells* (afunc-fcells afunc))
503 *x862-recorded-symbols*)
504 (set-fill-pointer
505 *backend-labels*
506 (set-fill-pointer
507 *x862-undo-stack*
508 (set-fill-pointer
509 *x862-undo-because*
510 0)))
511 (backend-get-next-label) ; start @ label 1, 0 is confused with NIL in compound cd
512 (with-dll-node-freelist (vinsns *vinsn-freelist*)
513 (unwind-protect
514 (progn
515 (setq bits (x862-form vinsns (make-wired-lreg *x862-result-reg*) $backend-return (afunc-acode afunc)))
516 (do* ((constants *x862-constant-alist* (cdr constants)))
517 ((null constants))
518 (let* ((imm (caar constants)))
519 (when (x862-symbol-locative-p imm)
520 (setf (caar constants) (car imm)))))
521 (optimize-vinsns vinsns)
522 (when (logbitp x862-debug-vinsns-bit *x862-debug-mask*)
523 (format t "~% vinsns for ~s (after generation)" (afunc-name afunc))
524 (do-dll-nodes (v vinsns) (format t "~&~s" v))
525 (format t "~%~%"))
526
527 (with-dll-node-freelist ((frag-list make-frag-list) *frag-freelist*)
528 (let* ((*x86-lap-labels* nil)
529 (instruction (x86::make-x86-instruction))
530 (end-code-tag (gensym))
531 debug-info)
532 (make-x86-lap-label end-code-tag)
533 (x86-lap-directive frag-list :long `(ash (+ (- (:^ ,end-code-tag ) 8)
534 *x86-lap-entry-offset*) -3))
535 (x86-lap-directive frag-list :byte 0) ;regsave PC
536 (x86-lap-directive frag-list :byte 0) ;regsave ea
537 (x86-lap-directive frag-list :byte 0) ;regsave mask
538
539 (x862-expand-vinsns vinsns frag-list instruction)
540 (when (or *x862-double-float-constant-alist*
541 *x862-single-float-constant-alist*)
542 (x86-lap-directive frag-list :align 3)
543 (dolist (double-pair *x862-double-float-constant-alist*)
544 (destructuring-bind (dfloat . lab) double-pair
545 (setf (vinsn-label-info lab) (emit-x86-lap-label frag-list lab))
546 (multiple-value-bind (high low)
547 (x862-double-float-bits dfloat)
548 (x86-lap-directive frag-list :long low)
549 (x86-lap-directive frag-list :long high))))
550 (dolist (single-pair *x862-single-float-constant-alist*)
551 (destructuring-bind (sfloat . lab) single-pair
552 (setf (vinsn-label-info lab) (emit-x86-lap-label frag-list lab))
553 (let* ((val (single-float-bits sfloat)))
554 (x86-lap-directive frag-list :long val)))))
555 (x86-lap-directive frag-list :align 3)
556 (x86-lap-directive frag-list :quad x8664::function-boundary-marker)
557 (emit-x86-lap-label frag-list end-code-tag)
558 (dolist (c (reverse *x862-constant-alist*))
559 (let* ((vinsn-label (cdr c)))
560 (or (vinsn-label-info vinsn-label)
561 (setf (vinsn-label-info vinsn-label)
562 (find-or-create-x86-lap-label
563 vinsn-label)))
564 (emit-x86-lap-label frag-list vinsn-label)
565 (x86-lap-directive frag-list :quad 0)))
566
567 (if (logbitp $fbitnonnullenv (the fixnum (afunc-bits afunc)))
568 (setq bits (+ bits (ash 1 $lfbits-nonnullenv-bit))))
569 (let* ((function-debugging-info (afunc-lfun-info afunc)))
570 (when (or function-debugging-info lambda-form *x862-record-symbols*)
571 (if lambda-form (setq function-debugging-info
572 (list* 'function-lambda-expression lambda-form function-debugging-info)))
573 (if *x862-record-symbols*
574 (setq function-debugging-info (nconc (list 'function-symbol-map *x862-recorded-symbols*)
575 function-debugging-info)))
576 (setq bits (logior (ash 1 $lfbits-symmap-bit) bits))
577 (setq debug-info function-debugging-info)))
578 (unless (or fname lambda-form *x862-recorded-symbols*)
579 (setq bits (logior (ash 1 $lfbits-noname-bit) bits)))
580 (unless (afunc-parent afunc)
581 (x862-fixup-fwd-refs afunc))
582 (setf (afunc-all-vars afunc) nil)
583 (setf (afunc-argsword afunc) bits)
584 (let* ((regsave-label (if (typep *x862-compiler-register-save-label* 'vinsn-note)
585 (vinsn-label-info (vinsn-note-label *x862-compiler-register-save-label*))))
586 (regsave-mask (if regsave-label (x862-register-mask-byte
587 *x862-register-restore-count*)))
588 (regsave-addr (if regsave-label (x862-encode-register-save-ea
589 *x862-register-restore-ea*
590 *x862-register-restore-count*))))
591 (when debug-info
592 (x86-lap-directive frag-list :quad 0))
593 (when fname
594 (x86-lap-directive frag-list :quad 0))
595 (x86-lap-directive frag-list :quad 0)
596 (relax-frag-list frag-list)
597 (apply-relocs frag-list)
598 (fill-for-alignment frag-list)
599 (x862-lap-process-regsave-info frag-list regsave-label regsave-mask regsave-addr)
600 (setf (afunc-lfun afunc)
601 #+x86-target
602 (if (eq *host-backend* *target-backend*)
603 (create-x86-function fname frag-list *x862-constant-alist* bits debug-info)
604 (cross-create-x86-function fname frag-list *x862-constant-alist* bits debug-info))
605 #-x86-target
606 (cross-create-x86-function fname frag-list *x862-constant-alist* bits debug-info)))
607 (x862-digest-symbols))))
608 (backend-remove-labels))))
609 afunc))
610
611
612
613
614(defun x862-make-stack (size &optional (subtype target::subtag-s16-vector))
615 (make-uarray-1 subtype size t 0 nil nil nil nil t nil))
616
617(defun x862-fixup-fwd-refs (afunc)
618 (dolist (f (afunc-inner-functions afunc))
619 (x862-fixup-fwd-refs f))
620 (let ((fwd-refs (afunc-fwd-refs afunc)))
621 (when fwd-refs
622 (let* ((native-x8664-functions #-x8664-target nil
623 #+x8664-target (eq *target-backend*
624 *host-backend*))
625 (v (if native-x8664-functions
626 (function-to-function-vector (afunc-lfun afunc))
627 (afunc-lfun afunc)))
628 (vlen (uvsize v)))
629 (declare (fixnum vlen))
630 (dolist (ref fwd-refs)
631 (let* ((ref-fun (afunc-lfun ref)))
632 (do* ((i (if native-x8664-functions
633 (%function-code-words
634 (%function-vector-to-function v))
635 1)
636 (1+ i)))
637 ((= i vlen))
638 (declare (fixnum i))
639 (if (eq (%svref v i) ref)
640 (setf (%svref v i) ref-fun)))))))))
641
642(defun x862-digest-symbols ()
643 (if *x862-recorded-symbols*
644 (let* ((symlist *x862-recorded-symbols*)
645 (len (length symlist))
646 (syms (make-array len))
647 (ptrs (make-array (%i+ (%i+ len len) len)))
648 (i -1)
649 (j -1))
650 (declare (fixnum i j))
651 (dolist (info symlist (progn (%rplaca symlist syms)
652 (%rplacd symlist ptrs)))
653 (flet ((label-address (note start-p sym)
654 (-
655 (let* ((label (vinsn-note-label note))
656 (lap-label (if label (vinsn-label-info label))))
657 (if lap-label
658 (x86-lap-label-address lap-label)
659 (error "Missing or bad ~s label: ~s"
660 (if start-p 'start 'end) sym)))
661 x8664::fulltag-function)))
662 (destructuring-bind (var sym startlab endlab) info
663 (let* ((ea (var-ea var))
664 (ea-val (ldb (byte 16 0) ea)))
665 (setf (aref ptrs (incf i)) (if (memory-spec-p ea)
666 (logior (ash ea-val 6) #o77)
667 ea-val)))
668 (setf (aref syms (incf j)) sym)
669 (setf (aref ptrs (incf i)) (label-address startlab t sym))
670 (setf (aref ptrs (incf i)) (label-address endlab nil sym))))))))
671
672(defun x862-decls (decls)
673 (if (fixnump decls)
674 (locally (declare (fixnum decls))
675 (setq *x862-tail-allow* (neq 0 (%ilogand2 $decl_tailcalls decls))
676 *x862-open-code-inline* (neq 0 (%ilogand2 $decl_opencodeinline decls))
677 *x862-reckless* (neq 0 (%ilogand2 $decl_unsafe decls))
678 *x862-trust-declarations* (neq 0 (%ilogand2 $decl_trustdecls decls))))))
679
680
681(defun %x862-bigger-cdr-than (x y)
682 (declare (cons x y))
683 (> (the fixnum (cdr x)) (the fixnum (cdr y))))
684
685;;; Return an unordered list of "varsets": each var in a varset can be
686;;; assigned a register and all vars in a varset can be assigned the
687;;; same register (e.g., no scope conflicts.)
688
689(defun x862-partition-vars (vars)
690 (labels ((var-weight (var)
691 (let* ((bits (nx-var-bits var)))
692 (declare (fixnum bits))
693 (if (eql 0 (logand bits (logior
694 (ash 1 $vbitpuntable)
695 (ash -1 $vbitspecial)
696 (ash 1 $vbitnoreg))))
697 (if (eql (logior (ash 1 $vbitclosed) (ash 1 $vbitsetq))
698 (logand bits (logior (ash 1 $vbitclosed) (ash 1 $vbitsetq))))
699 0
700 (%i+ (%ilogand $vrefmask bits) (%ilsr 8 (%ilogand $vsetqmask bits))))
701 0)))
702 (sum-weights (varlist)
703 (let ((sum 0))
704 (dolist (v varlist sum) (incf sum (var-weight v)))))
705 (vars-disjoint-p (v1 v2)
706 (if (eq v1 v2)
707 nil
708 (if (memq v1 (var-binding-info v2))
709 nil
710 (if (memq v2 (var-binding-info v1))
711 nil
712 t)))))
713 (setq vars (%sort-list-no-key
714 ;(delete-if #'(lambda (v) (eql (var-weight v) 0)) vars)
715 (do* ((handle (cons nil vars))
716 (splice handle))
717 ((null (cdr splice)) (cdr handle))
718 (declare (dynamic-extent handle) (type cons handle splice))
719 (if (eql 0 (var-weight (%car (cdr splice))))
720 (rplacd splice (%cdr (cdr splice)))
721 (setq splice (cdr splice))))
722 #'(lambda (v1 v2) (%i> (var-weight v1) (var-weight v2)))))
723 ;; This isn't optimal. It partitions all register-allocatable
724 ;; variables into sets such that
725 ;; 1) no variable is a member of more than one set and
726 ;; 2) all variables in a given set are disjoint from each other
727 ;; A set might have exactly one member.
728 ;; If a register is allocated for any member of a set, it's
729 ;; allocated for all members of that set.
730 (let* ((varsets nil))
731 (do* ((all vars (cdr all)))
732 ((null all))
733 (let* ((var (car all)))
734 (when (dolist (already varsets t)
735 (when (memq var (car already)) (return)))
736 (let* ((varset (cons var nil)))
737 (dolist (v (cdr all))
738 (when (dolist (already varsets t)
739 (when (memq v (car already)) (return)))
740 (when (dolist (d varset t)
741 (unless (vars-disjoint-p v d) (return)))
742 (push v varset))))
743 (let* ((weight (sum-weights varset)))
744 (declare (fixnum weight))
745 (if (>= weight 3)
746 (push (cons (nreverse varset) weight) varsets)))))))
747 varsets)))
748
749;;; Maybe globally allocate registers to symbols naming functions & variables,
750;;; and to simple lexical variables.
751(defun x862-allocate-global-registers (fcells vcells all-vars no-regs)
752 (if no-regs
753 (progn
754 (dolist (c fcells) (%rplacd c nil))
755 (dolist (c vcells) (%rplacd c nil))
756 (values 0 nil))
757 (let* ((maybe (x862-partition-vars all-vars)))
758 (dolist (c fcells)
759 (if (>= (the fixnum (cdr c)) 3) (push c maybe)))
760 (dolist (c vcells)
761 (if (>= (the fixnum (cdr c)) 3) (push c maybe)))
762 (do* ((things (%sort-list-no-key maybe #'%x862-bigger-cdr-than) (cdr things))
763 (n 0 (1+ n))
764 (registers (target-arch-case (:x8664
765 (list x8664::save0 x8664::save1 x8664::save2 x8664::save3))))
766 (regno (pop registers) (pop registers))
767 (constant-alist ()))
768 ((or (null things) (= n *x862-target-num-save-regs*))
769 (dolist (cell fcells) (%rplacd cell nil))
770 (dolist (cell vcells) (%rplacd cell nil))
771 (values n constant-alist))
772 (declare (list things)
773 (fixnum n regno))
774 (let* ((thing (car things)))
775 (if (or (memq thing fcells)
776 (memq thing vcells))
777 (push (cons thing regno) constant-alist)
778 (dolist (var (car thing))
779 (nx-set-var-bits var
780 (%ilogior (%ilogand (%ilognot $vrefmask) (nx-var-bits var))
781 regno
782 (%ilsl $vbitreg 1))))))))))
783
784
785
786;;; Vpush the last N non-volatile-registers.
787(defun x862-save-nvrs (seg n)
788 (declare (fixnum n))
789 (when (> n 0)
790 (setq *x862-compiler-register-save-label* (x862-emit-note seg :regsave))
791 (with-x86-local-vinsn-macros (seg)
792 (let* ((mask (target-arch-case (:x8664 x8664-nonvolatile-node-regs))))
793 (dotimes (i n)
794 (let* ((reg (1- (integer-length mask))))
795 (x862-vpush-register seg reg :regsave reg 0)
796 (setq mask (logandc2 mask (ash 1 reg)))))))
797 (setq *x862-register-restore-ea* *x862-vstack*
798 *x862-register-restore-count* n)))
799
800
801;;; If there are an indefinite number of args/values on the vstack,
802;;; we have to restore from a register that matches the compiler's
803;;; notion of the vstack depth. This can be computed by the caller
804;;; (sum of vsp & nargs, or copy of vsp before indefinite number of
805;;; args pushed, etc.)
806
807
808(defun x862-restore-nvrs (seg ea nregs &optional (can-pop t))
809 (when (and ea nregs)
810 (with-x86-local-vinsn-macros (seg)
811 (let* ((mask (target-arch-case (:x8664 x8664-nonvolatile-node-regs)))
812 (regs ()))
813 (dotimes (i nregs)
814 (let* ((reg (1- (integer-length mask))))
815 (push reg regs)
816 (setq mask (logandc2 mask (ash 1 reg)))))
817 (cond (can-pop
818 (let* ((diff-in-bytes (- *x862-vstack* ea)))
819 (unless (zerop diff-in-bytes)
820 (x862-adjust-vstack diff-in-bytes)
821 (! vstack-discard (floor diff-in-bytes *x862-target-node-size*)))
822 (dolist (reg regs)
823 (! vpop-register reg))))
824 (t
825 (dolist (reg regs)
826 (! vframe-load reg (- ea *x862-target-node-size*) ea)
827 (decf ea *x862-target-node-size*))))))))
828
829
830(defun x862-bind-lambda (seg lcells req opt rest keys auxen optsupvloc passed-in-regs lexpr &optional inherited
831 &aux (vloc 0) (numopt (list-length (%car opt)))
832 (nkeys (list-length (%cadr keys)))
833 reg)
834 (declare (fixnum vloc))
835 (x862-check-lcell-depth)
836 (dolist (arg inherited)
837 (if (memq arg passed-in-regs)
838 (x862-set-var-ea seg arg (var-ea arg))
839 (let* ((lcell (pop lcells)))
840 (if (setq reg (x862-assign-register-var arg))
841 (x862-init-regvar seg arg reg (x862-vloc-ea vloc))
842 (x862-bind-var seg arg vloc lcell))
843 (setq vloc (%i+ vloc *x862-target-node-size*)))))
844 (dolist (arg req)
845 (if (memq arg passed-in-regs)
846 (x862-set-var-ea seg arg (var-ea arg))
847 (let* ((lcell (pop lcells)))
848 (if (setq reg (x862-assign-register-var arg))
849 (x862-init-regvar seg arg reg (x862-vloc-ea vloc))
850 (x862-bind-var seg arg vloc lcell))
851 (setq vloc (%i+ vloc *x862-target-node-size*)))))
852 (when opt
853 (if (x862-hard-opt-p opt)
854 (setq vloc (apply #'x862-initopt seg vloc optsupvloc lcells (nthcdr (- (length lcells) numopt) lcells) opt)
855 lcells (nthcdr numopt lcells))
856
857 (dolist (var (%car opt))
858 (if (memq var passed-in-regs)
859 (x862-set-var-ea seg var (var-ea var))
860 (let* ((lcell (pop lcells)))
861 (if (setq reg (x862-assign-register-var var))
862 (x862-init-regvar seg var reg (x862-vloc-ea vloc))
863 (x862-bind-var seg var vloc lcell))
864 (setq vloc (+ vloc *x862-target-node-size*)))))))
865
866 (when rest
867 (if lexpr
868 (progn
869 (if (setq reg (x862-assign-register-var rest))
870 (progn
871 (x862-copy-register seg reg x8664::arg_z)
872 (x862-set-var-ea seg rest reg))
873 (let* ((loc *x862-vstack*))
874 (x862-vpush-register seg x8664::arg_z :reserved)
875 (x862-note-top-cell rest)
876 (x862-bind-var seg rest loc *x862-top-vstack-lcell*))))
877 (let* ((rvloc (+ vloc (* 2 *x862-target-node-size* nkeys))))
878 (if (setq reg (x862-assign-register-var rest))
879 (x862-init-regvar seg rest reg (x862-vloc-ea rvloc))
880 (x862-bind-var seg rest rvloc (pop lcells))))))
881 (when keys
882 (apply #'x862-init-keys seg vloc lcells keys))
883 (x862-seq-bind seg (%car auxen) (%cadr auxen)))
884
885
886(defun x862-initopt (seg vloc spvloc lcells splcells vars inits spvars)
887 (with-x86-local-vinsn-macros (seg)
888 (dolist (var vars vloc)
889 (let* ((initform (pop inits))
890 (spvar (pop spvars))
891 (lcell (pop lcells))
892 (splcell (pop splcells))
893 (reg (x862-assign-register-var var))
894 (regloadedlabel (if reg (backend-get-next-label))))
895 (unless (nx-null initform)
896 (let ((skipinitlabel (backend-get-next-label)))
897 (with-crf-target () crf
898 (x862-compare-ea-to-nil seg crf (x862-make-compound-cd 0 skipinitlabel) (x862-vloc-ea spvloc) x86::x86-e-bits t))
899 (if reg
900 (x862-form seg reg regloadedlabel initform)
901 (x862-register-to-stack seg (x862-one-untargeted-reg-form seg initform ($ x8664::arg_z)) (x862-vloc-ea vloc)))
902 (@ skipinitlabel)))
903 (if reg
904 (progn
905 (x862-init-regvar seg var reg (x862-vloc-ea vloc))
906 (@ regloadedlabel))
907 (x862-bind-var seg var vloc lcell))
908 (when spvar
909 (if (setq reg (x862-assign-register-var spvar))
910 (x862-init-regvar seg spvar reg (x862-vloc-ea spvloc))
911 (x862-bind-var seg spvar spvloc splcell))))
912 (setq vloc (%i+ vloc *x862-target-node-size*))
913 (if spvloc (setq spvloc (%i+ spvloc *x862-target-node-size*))))))
914
915(defun x862-init-keys (seg vloc lcells allow-others keyvars keysupp keyinits keykeys)
916 (declare (ignore keykeys allow-others))
917 (with-x86-local-vinsn-macros (seg)
918 (dolist (var keyvars)
919 (let* ((spvar (pop keysupp))
920 (initform (pop keyinits))
921 (reg (x862-assign-register-var var))
922 (regloadedlabel (if reg (backend-get-next-label)))
923 (var-lcell (pop lcells))
924 (sp-lcell (pop lcells))
925 (sploc (%i+ vloc *x862-target-node-size*)))
926 (unless (nx-null initform)
927 (let ((skipinitlabel (backend-get-next-label)))
928 (with-crf-target () crf
929 (x862-compare-ea-to-nil seg crf (x862-make-compound-cd 0 skipinitlabel) (x862-vloc-ea sploc) x86::x86-e-bits t))
930 (if reg
931 (x862-form seg reg regloadedlabel initform)
932 (x862-register-to-stack seg (x862-one-untargeted-reg-form seg initform ($ x8664::arg_z)) (x862-vloc-ea vloc)))
933 (@ skipinitlabel)))
934 (if reg
935 (progn
936 (x862-init-regvar seg var reg (x862-vloc-ea vloc))
937 (@ regloadedlabel))
938 (x862-bind-var seg var vloc var-lcell))
939 (when spvar
940 (if (setq reg (x862-assign-register-var spvar))
941 (x862-init-regvar seg spvar reg (x862-vloc-ea sploc))
942 (x862-bind-var seg spvar sploc sp-lcell))))
943 (setq vloc (%i+ vloc (* 2 *x862-target-node-size*))))))
944
945;;; Vpush register r, unless var gets a globally-assigned register.
946;;; Return NIL if register was vpushed, else var.
947(defun x862-vpush-arg-register (seg reg var)
948 (when var
949 (let* ((bits (nx-var-bits var)))
950 (declare (fixnum bits))
951 (if (logbitp $vbitreg bits)
952 var
953 (progn
954 (x862-vpush-register seg reg :reserved)
955 nil)))))
956
957
958;;; nargs has been validated, arguments defaulted and canonicalized.
959;;; Save caller's context, then vpush any argument registers that
960;;; didn't get global registers assigned to their variables.
961;;; Return a list of vars/nils for each argument register
962;;; (nil if vpushed, var if still in arg_reg).
963(defun x862-argregs-entry (seg revargs &optional variable-args-entry)
964 (with-x86-local-vinsn-macros (seg)
965 (let* ((nargs (length revargs))
966 (reg-vars ()))
967 (declare (type (unsigned-byte 16) nargs))
968 (unless variable-args-entry
969 (if (<= nargs *x862-target-num-arg-regs*) ; caller didn't vpush anything
970 (! save-lisp-context-no-stack-args)
971 (let* ((offset (* (the fixnum (- nargs *x862-target-num-arg-regs*)) *x862-target-node-size*)))
972 (declare (fixnum offset))
973 (! save-lisp-context-offset offset))))
974 (destructuring-bind (&optional zvar yvar xvar &rest stack-args) revargs
975 (let* ((nstackargs (length stack-args)))
976 (x862-set-vstack (* nstackargs *x862-target-node-size*))
977 (dotimes (i nstackargs)
978 (x862-new-vstack-lcell :reserved *x862-target-lcell-size* 0 nil))
979 (if (>= nargs 3)
980 (push (x862-vpush-arg-register seg ($ x8664::arg_x) xvar) reg-vars))
981 (if (>= nargs 2)
982 (push (x862-vpush-arg-register seg ($ x8664::arg_y) yvar) reg-vars))
983 (if (>= nargs 1)
984 (push (x862-vpush-arg-register seg ($ x8664::arg_z) zvar) reg-vars))))
985 reg-vars)))
986
987;;; Just required args.
988;;; Since this is just a stupid bootstrapping port, always save
989;;; lisp context.
990(defun x862-req-nargs-entry (seg rev-fixed-args)
991 (let* ((nargs (length rev-fixed-args)))
992 (declare (type (unsigned-byte 16) nargs))
993 (with-x86-local-vinsn-macros (seg)
994 (unless *x862-reckless*
995 (! check-exact-nargs nargs))
996 (x862-argregs-entry seg rev-fixed-args))))
997
998;;; No more &optional args than register args; all &optionals default
999;;; to NIL and none have supplied-p vars. No &key/&rest.
1000(defun x862-simple-opt-entry (seg rev-opt-args rev-req-args)
1001 (let* ((min (length rev-req-args))
1002 (nopt (length rev-opt-args))
1003 (max (+ min nopt)))
1004 (declare (type (unsigned-byte 16) min nopt max))
1005 (with-x86-local-vinsn-macros (seg)
1006 (unless *x862-reckless*
1007 (when rev-req-args
1008 (! check-min-nargs min))
1009 (! check-max-nargs max))
1010 (if (> min $numx8664argregs)
1011 (! save-lisp-context-in-frame)
1012 (if (<= max $numx8664argregs)
1013 (! save-lisp-context-no-stack-args)
1014 (! save-lisp-context-variable-arg-count)))
1015 (if (= nopt 1)
1016 (! default-1-arg min)
1017 (if (= nopt 2)
1018 (! default-2-args min)
1019 (! default-3-args min)))
1020 (x862-argregs-entry seg (append rev-opt-args rev-req-args) t))))
1021
1022;;; if "num-fixed" is > 0, we've already ensured that at least that many args
1023;;; were provided; that may enable us to generate better code for saving the
1024;;; argument registers.
1025;;; We're responsible for computing the caller's VSP and saving
1026;;; caller's state.
1027(defun x862-lexpr-entry (seg num-fixed)
1028 (with-x86-local-vinsn-macros (seg)
1029 (! save-lexpr-argregs num-fixed)
1030 ;; The "lexpr" (address of saved nargs register, basically
1031 ;; is now in arg_z
1032 (! build-lexpr-frame)
1033 (dotimes (i num-fixed)
1034 (! copy-lexpr-argument (- num-fixed i)))))
1035
1036
1037(defun x862-structured-initopt (seg lcells vloc context vars inits spvars)
1038 (with-x86-local-vinsn-macros (seg)
1039 (dolist (var vars vloc)
1040 (let* ((initform (pop inits))
1041 (spvar (pop spvars))
1042 (spvloc (%i+ vloc *x862-target-node-size*))
1043 (var-lcell (pop lcells))
1044 (sp-lcell (pop lcells)))
1045 (unless (nx-null initform)
1046 (let ((skipinitlabel (backend-get-next-label)))
1047 (with-crf-target () crf
1048 (x862-compare-ea-to-nil seg crf (x862-make-compound-cd 0 skipinitlabel) (x862-vloc-ea spvloc) x86::x86-e-bits t))
1049 (x862-register-to-stack seg (x862-one-untargeted-reg-form seg initform ($ x8664::arg_z)) (x862-vloc-ea vloc))
1050 (@ skipinitlabel)))
1051 (x862-bind-structured-var seg var vloc var-lcell context)
1052 (when spvar
1053 (x862-bind-var seg spvar spvloc sp-lcell)))
1054 (setq vloc (%i+ vloc (* 2 *x862-target-node-size*))))))
1055
1056
1057
1058(defun x862-structured-init-keys (seg lcells vloc context allow-others keyvars keysupp keyinits keykeys)
1059 (declare (ignore keykeys allow-others))
1060 (with-x86-local-vinsn-macros (seg)
1061 (dolist (var keyvars)
1062 (let* ((spvar (pop keysupp))
1063 (initform (pop keyinits))
1064 (sploc (%i+ vloc *x862-target-node-size*))
1065 (var-lcell (pop lcells))
1066 (sp-reg ($ x8664::arg_z))
1067 (sp-lcell (pop lcells)))
1068 (unless (nx-null initform)
1069 (x862-stack-to-register seg (x862-vloc-ea sploc) sp-reg)
1070 (let ((skipinitlabel (backend-get-next-label)))
1071 (with-crf-target () crf
1072 (x862-compare-register-to-nil seg crf (x862-make-compound-cd 0 skipinitlabel) sp-reg x86::x86-e-bits t))
1073 (x862-register-to-stack seg (x862-one-untargeted-reg-form seg initform ($ x8664::arg_z)) (x862-vloc-ea vloc))
1074 (@ skipinitlabel)))
1075 (x862-bind-structured-var seg var vloc var-lcell context)
1076 (when spvar
1077 (x862-bind-var seg spvar sploc sp-lcell)))
1078 (setq vloc (%i+ vloc (* 2 *x862-target-node-size*))))))
1079
1080(defun x862-vloc-ea (n &optional vcell-p)
1081 (setq n (make-memory-spec (dpb memspec-frame-address memspec-type-byte n)))
1082 (if vcell-p
1083 (make-vcell-memory-spec n)
1084 n))
1085
1086
1087(defun x862-form (seg vreg xfer form)
1088 (if (nx-null form)
1089 (x862-nil seg vreg xfer)
1090 (if (nx-t form)
1091 (x862-t seg vreg xfer)
1092 (let* ((op nil)
1093 (fn nil))
1094 (if (and (consp form)
1095 (setq fn (svref *x862-specials* (%ilogand #.operator-id-mask (setq op (acode-operator form))))))
1096 (if (and (null vreg)
1097 (%ilogbitp operator-acode-subforms-bit op)
1098 (%ilogbitp operator-assignment-free-bit op))
1099 (dolist (f (%cdr form) (x862-branch seg xfer))
1100 (x862-form seg nil nil f ))
1101 (apply fn seg vreg xfer (%cdr form)))
1102 (error "x862-form ? ~s" form))))))
1103
1104;;; dest is a float reg - form is acode
1105(defun x862-form-float (seg freg xfer form)
1106 (declare (ignore xfer))
1107 (when (or (nx-null form)(nx-t form))(error "x862-form to freg ~s" form))
1108 (when (and (= (get-regspec-mode freg) hard-reg-class-fpr-mode-double)
1109 (x862-form-typep form 'double-float))
1110 ;; kind of screwy - encoding the source type in the dest register spec
1111 (set-node-regspec-type-modes freg hard-reg-class-fpr-type-double))
1112 (let* ((fn nil))
1113 (if (and (consp form)
1114 (setq fn (svref *x862-specials* (%ilogand #.operator-id-mask (acode-operator form)))))
1115 (apply fn seg freg nil (%cdr form))
1116 (error "x862-form ? ~s" form))))
1117
1118
1119
1120(defun x862-form-typep (form type)
1121 (acode-form-typep form type *x862-trust-declarations*)
1122)
1123
1124(defun x862-form-type (form)
1125 (acode-form-type form *x862-trust-declarations*))
1126
1127(defun x862-use-operator (op seg vreg xfer &rest forms)
1128 (declare (dynamic-extent forms))
1129 (apply (svref *x862-specials* (%ilogand operator-id-mask op)) seg vreg xfer forms))
1130
1131;;; Returns true iff lexical variable VAR isn't setq'ed in FORM.
1132;;; Punts a lot ...
1133(defun x862-var-not-set-by-form-p (var form)
1134 (or (not (%ilogbitp $vbitsetq (nx-var-bits var)))
1135 (x862-setqed-var-not-set-by-form-p var form)))
1136
1137(defun x862-setqed-var-not-set-by-form-p (var form)
1138 (setq form (acode-unwrapped-form form))
1139 (or (atom form)
1140 (x86-constant-form-p form)
1141 (x862-lexical-reference-p form)
1142 (let ((op (acode-operator form))
1143 (subforms nil))
1144 (if (eq op (%nx1-operator setq-lexical))
1145 (and (neq var (cadr form))
1146 (x862-setqed-var-not-set-by-form-p var (caddr form)))
1147 (and (%ilogbitp operator-side-effect-free-bit op)
1148 (flet ((not-set-in-formlist (formlist)
1149 (dolist (subform formlist t)
1150 (unless (x862-setqed-var-not-set-by-form-p var subform) (return)))))
1151 (if
1152 (cond ((%ilogbitp operator-acode-subforms-bit op) (setq subforms (%cdr form)))
1153 ((%ilogbitp operator-acode-list-bit op) (setq subforms (cadr form))))
1154 (not-set-in-formlist subforms)
1155 (and (or (eq op (%nx1-operator call))
1156 (eq op (%nx1-operator lexical-function-call)))
1157 (x862-setqed-var-not-set-by-form-p var (cadr form))
1158 (setq subforms (caddr form))
1159 (not-set-in-formlist (car subforms))
1160 (not-set-in-formlist (cadr subforms))))))))))
1161
1162(defun x862-check-fixnum-overflow (seg target &optional labelno)
1163 (with-x86-local-vinsn-macros (seg)
1164 (if *x862-open-code-inline*
1165 (let* ((no-overflow (backend-get-next-label)))
1166 (! set-bigits-and-header-for-fixnum-overflow target (aref *backend-labels* (or labelno no-overflow)))
1167 (! %allocate-uvector target)
1168 (! set-bigits-after-fixnum-overflow target)
1169 (when labelno
1170 (-> labelno))
1171 (@ no-overflow))
1172 (if labelno
1173 (! fix-fixnum-overflow-ool-and-branch target (aref *backend-labels* labelno))
1174 (! fix-fixnum-overflow-ool target)))))
1175
1176(defun x862-nil (seg vreg xfer)
1177 (with-x86-local-vinsn-macros (seg vreg xfer)
1178 (if (eq vreg :push)
1179 (progn
1180 (! vpush-fixnum x8664::nil-value)
1181 (^))
1182 (progn
1183 (if (x862-for-value-p vreg)
1184 (ensuring-node-target (target vreg)
1185 (! load-nil target)))
1186 (x862-branch seg (x862-cd-false xfer))))))
1187
1188(defun x862-t (seg vreg xfer)
1189 (with-x86-local-vinsn-macros (seg vreg xfer)
1190 (if (eq vreg :push)
1191 (progn
1192 (! vpush-fixnum x8664::t-value)
1193 (^))
1194 (progn
1195 (if (x862-for-value-p vreg)
1196 (ensuring-node-target (target vreg)
1197 (! load-t target)))
1198 (x862-branch seg (x862-cd-true xfer))))))
1199
1200(defun x862-for-value-p (vreg)
1201 (and vreg (not (backend-crf-p vreg))))
1202
1203(defun x862-mvpass (seg form &optional xfer)
1204 (with-x86-local-vinsn-macros (seg)
1205 (x862-form seg ($ x8664::arg_z) (logior (or xfer 0) $backend-mvpass-mask) form)))
1206
1207(defun x862-adjust-vstack (delta)
1208 (x862-set-vstack (%i+ *x862-vstack* delta)))
1209
1210(defun x862-set-vstack (new)
1211 (setq *x862-vstack* new))
1212
1213
1214;;; Emit a note at the end of the segment.
1215(defun x862-emit-note (seg class &rest info)
1216 (declare (dynamic-extent info))
1217 (let* ((note (make-vinsn-note class info)))
1218 (append-dll-node (vinsn-note-label note) seg)
1219 note))
1220
1221;;; Emit a note immediately before the target vinsn.
1222(defun x86-prepend-note (vinsn class &rest info)
1223 (declare (dynamic-extent info))
1224 (let* ((note (make-vinsn-note class info)))
1225 (insert-dll-node-before (vinsn-note-label note) vinsn)
1226 note))
1227
1228(defun x862-close-note (seg note)
1229 (let* ((end (close-vinsn-note note)))
1230 (append-dll-node (vinsn-note-label end) seg)
1231 end))
1232
1233
1234
1235
1236
1237
1238(defun x862-stack-to-register (seg memspec reg)
1239 (with-x86-local-vinsn-macros (seg)
1240 (! vframe-load reg (memspec-frame-address-offset memspec) *x862-vstack*)))
1241
1242(defun x862-lcell-to-register (seg lcell reg)
1243 (with-x86-local-vinsn-macros (seg)
1244 (! lcell-load reg lcell (x862-vstack-mark-top))))
1245
1246(defun x862-register-to-lcell (seg reg lcell)
1247 (with-x86-local-vinsn-macros (seg)
1248 (! lcell-store reg lcell (x862-vstack-mark-top))))
1249
1250(defun x862-register-to-stack (seg reg memspec)
1251 (with-x86-local-vinsn-macros (seg)
1252 (! vframe-store reg (memspec-frame-address-offset memspec) *x862-vstack*)))
1253
1254
1255(defun x862-ea-open (ea)
1256 (if (and ea (not (typep ea 'lreg)) (addrspec-vcell-p ea))
1257 (make-memory-spec (memspec-frame-address-offset ea))
1258 ea))
1259
1260(defun x862-set-NARGS (seg n)
1261 (if (> n call-arguments-limit)
1262 (error "~s exceeded." call-arguments-limit)
1263 (with-x86-local-vinsn-macros (seg)
1264 (! set-nargs n))))
1265
1266(defun x862-assign-register-var (v)
1267 (let ((bits (nx-var-bits v)))
1268 (when (%ilogbitp $vbitreg bits)
1269 (%ilogand bits $vrefmask))))
1270
1271(defun x862-single-float-bits (the-sf)
1272 (single-float-bits the-sf))
1273
1274(defun x862-double-float-bits (the-df)
1275 (double-float-bits the-df))
1276
1277(defun x862-push-immediate (seg xfer form)
1278 (with-x86-local-vinsn-macros (seg)
1279 (if (typep form 'character)
1280 (! vpush-fixnum (logior (ash (char-code form) 8) x8664::subtag-character))
1281 (let* ((reg (x862-register-constant-p form)))
1282 (if reg
1283 (! vpush-register reg)
1284 (let* ((lab (x86-immediate-label form)))
1285 (! vpush-constant lab)))))
1286 (x862-branch seg xfer)))
1287
1288
1289(pushnew (%nx1-operator immediate) *x862-operator-supports-push*)
1290(defun x862-immediate (seg vreg xfer form)
1291 (if (eq vreg :push)
1292 (x862-push-immediate seg xfer form)
1293 (with-x86-local-vinsn-macros (seg vreg xfer)
1294 (if vreg
1295 (if (and (= (hard-regspec-class vreg) hard-reg-class-fpr)
1296 (or (and (typep form 'double-float) (= (get-regspec-mode vreg) hard-reg-class-fpr-mode-double))
1297 (and (typep form 'short-float)(= (get-regspec-mode vreg) hard-reg-class-fpr-mode-single))))
1298 (if (zerop form)
1299 (if (eql form 0.0d0)
1300 (! zero-double-float-register vreg)
1301 (! zero-single-float-register vreg))
1302 (if (typep form 'short-float)
1303 (let* ((lab (x86-single-float-constant-label form)))
1304 (! load-single-float-constant vreg lab))
1305 (let* ((lab (x86-double-float-constant-label form)))
1306 (! load-double-float-constant vreg lab))))
1307 (if (and (typep form '(unsigned-byte 32))
1308 (= (hard-regspec-class vreg) hard-reg-class-gpr)
1309 (= (get-regspec-mode vreg)
1310 hard-reg-class-gpr-mode-u32))
1311 (x862-lri seg vreg form)
1312 (ensuring-node-target
1313 (target vreg)
1314 (if (characterp form)
1315 (! load-character-constant target (char-code form))
1316 (x862-store-immediate seg form target)))))
1317 (if (and (listp form) *load-time-eval-token* (eq (car form) *load-time-eval-token*))
1318 (x862-store-immediate seg form ($ x8664::temp0))))
1319 (^))))
1320
1321(defun x862-register-constant-p (form)
1322 (and (consp form)
1323 (or (memq form *x862-vcells*)
1324 (memq form *x862-fcells*))
1325 (%cdr form)))
1326
1327(defun x862-store-immediate (seg imm dest)
1328 (with-x86-local-vinsn-macros (seg)
1329 (let* ((reg (x862-register-constant-p imm)))
1330 (if reg
1331 (x862-copy-register seg dest reg)
1332 (let* ((lab (x86-immediate-label imm)))
1333 (! ref-constant dest lab)))
1334 dest)))
1335
1336
1337;;; Returns label iff form is (local-go <tag>) and can go without adjusting stack.
1338(defun x862-go-label (form)
1339 (let ((current-stack (x862-encode-stack)))
1340 (while (and (acode-p form) (or (eq (acode-operator form) (%nx1-operator progn))
1341 (eq (acode-operator form) (%nx1-operator local-tagbody))))
1342 (setq form (caadr form)))
1343 (when (acode-p form)
1344 (let ((op (acode-operator form)))
1345 (if (and (eq op (%nx1-operator local-go))
1346 (x862-equal-encodings-p (%caddr (%cadr form)) current-stack))
1347 (%cadr (%cadr form))
1348 (if (and (eq op (%nx1-operator local-return-from))
1349 (nx-null (caddr form)))
1350 (let ((tagdata (car (cadr form))))
1351 (and (x862-equal-encodings-p (cdr tagdata) current-stack)
1352 (null (caar tagdata))
1353 (< 0 (cdar tagdata) $backend-mvpass)
1354 (cdar tagdata)))))))))
1355
1356(defun x862-single-valued-form-p (form)
1357 (setq form (acode-unwrapped-form form))
1358 (or (nx-null form)
1359 (nx-t form)
1360 (if (acode-p form)
1361 (let ((op (acode-operator form)))
1362 (or (%ilogbitp operator-single-valued-bit op)
1363 (and (eql op (%nx1-operator values))
1364 (let ((values (cadr form)))
1365 (and values (null (cdr values)))))
1366 nil ; Learn about functions someday
1367 )))))
1368
1369
1370(defun x862-box-s32 (seg node-dest s32-src)
1371 (with-x86-local-vinsn-macros (seg)
1372 (if (target-arch-case
1373
1374 (:x8664 t))
1375 (! box-fixnum node-dest s32-src)
1376 (let* ((arg_z ($ x8664::arg_z))
1377 (imm0 ($ x8664::imm0 :mode :s32)))
1378 (x862-copy-register seg imm0 s32-src)
1379 (! call-subprim (subprim-name->offset '.SPmakes32))
1380 (x862-copy-register seg node-dest arg_z)))))
1381
1382(defun x862-box-s64 (seg node-dest s64-src)
1383 (with-x86-local-vinsn-macros (seg)
1384 (if (target-arch-case
1385 (:x8664 *x862-open-code-inline*))
1386 (let* ((no-overflow (backend-get-next-label)))
1387 (! %set-z-flag-if-s64-fits-in-fixnum node-dest s64-src)
1388 (! cbranch-true (aref *backend-labels* no-overflow) x86::x86-e-bits)
1389 (! setup-bignum-alloc-for-s64-overflow s64-src)
1390 (! %allocate-uvector node-dest)
1391 (! set-bigits-after-fixnum-overflow node-dest)
1392 (@ no-overflow))
1393 (let* ((arg_z ($ x8664::arg_z))
1394 (imm0 (make-wired-lreg x8664::imm0 :mode (get-regspec-mode s64-src))))
1395 (x862-copy-register seg imm0 s64-src)
1396 (! call-subprim (subprim-name->offset '.SPmakes64))
1397 (x862-copy-register seg node-dest arg_z)))))
1398
1399(defun x862-box-u32 (seg node-dest u32-src)
1400 (with-x86-local-vinsn-macros (seg)
1401 (if (target-arch-case
1402
1403 (:x8664 t))
1404 (! box-fixnum node-dest u32-src)
1405 (let* ((arg_z ($ x8664::arg_z))
1406 (imm0 ($ x8664::imm0 :mode :u32)))
1407 (x862-copy-register seg imm0 u32-src)
1408 (! call-subprim (subprim-name->offset '.SPmakeu32))
1409 (x862-copy-register seg node-dest arg_z)))))
1410
1411(defun x862-box-u64 (seg node-dest u64-src)
1412 (with-x86-local-vinsn-macros (seg)
1413 (if (target-arch-case
1414
1415 (:x8664 *x862-open-code-inline*))
1416 (let* ((no-overflow (backend-get-next-label)))
1417 (! %set-z-flag-if-u64-fits-in-fixnum node-dest u64-src)
1418 (! cbranch-true (aref *backend-labels* no-overflow) x86::x86-e-bits)
1419 (! setup-bignum-alloc-for-u64-overflow u64-src)
1420 (! %allocate-uvector node-dest)
1421 (! set-bigits-after-fixnum-overflow node-dest)
1422 (@ no-overflow))
1423 (let* ((arg_z ($ x8664::arg_z))
1424 (imm0 ($ x8664::imm0 :mode :u64)))
1425 (x862-copy-register seg imm0 u64-src)
1426 (! call-subprim (subprim-name->offset '.SPmakeu64))
1427 (x862-copy-register seg node-dest arg_z)))))
1428
1429(defun x862-double->heap (seg dest src)
1430 (with-x86-local-vinsn-macros (seg)
1431 (! setup-double-float-allocation)
1432 (! %allocate-uvector dest)
1433 (! set-double-float-value dest src)))
1434
1435
1436(defun x862-vref1 (seg vreg xfer type-keyword src unscaled-idx index-known-fixnum)
1437 (with-x86-local-vinsn-macros (seg vreg xfer)
1438 (when vreg
1439 (let* ((arch (backend-target-arch *target-backend*))
1440 (is-node (member type-keyword (arch::target-gvector-types arch)))
1441 (is-1-bit (member type-keyword (arch::target-1-bit-ivector-types arch)))
1442
1443 (is-8-bit (member type-keyword (arch::target-8-bit-ivector-types arch)))
1444 (is-16-bit (member type-keyword (arch::target-16-bit-ivector-types arch)))
1445 (is-32-bit (member type-keyword (arch::target-32-bit-ivector-types arch)))
1446 (is-64-bit (member type-keyword (arch::target-64-bit-ivector-types arch)))
1447 (is-signed (member type-keyword '(:signed-8-bit-vector :signed-16-bit-vector :signed-32-bit-vector :signed-64-bit-vector :fixnum-vector)))
1448 (vreg-class (and (not (eq vreg :push)) (hard-regspec-class vreg)))
1449 (vreg-mode
1450 (if (eql vreg-class hard-reg-class-gpr)
1451 (get-regspec-mode vreg)
1452 hard-reg-class-gpr-mode-invalid)))
1453 (cond
1454 (is-node
1455 (if (eq vreg :push)
1456 (if (and index-known-fixnum (<= index-known-fixnum (arch::target-max-64-bit-constant-index arch)))
1457 (! push-misc-ref-c-node src index-known-fixnum)
1458 (! push-misc-ref-node src unscaled-idx))
1459 (ensuring-node-target (target vreg)
1460 (if (and index-known-fixnum (<= index-known-fixnum (arch::target-max-64-bit-constant-index arch)))
1461 (! misc-ref-c-node target src index-known-fixnum)
1462 (! misc-ref-node target src unscaled-idx)))))
1463 (is-32-bit
1464 (if (and index-known-fixnum (<= index-known-fixnum (arch::target-max-32-bit-constant-index arch)))
1465 (cond ((eq type-keyword :single-float-vector)
1466 (with-fp-target () (fp-val :single-float)
1467 (if (and (eql vreg-class hard-reg-class-fpr)
1468 (eql vreg-mode hard-reg-class-fpr-mode-single))
1469 (setq fp-val vreg))
1470 (! misc-ref-c-single-float fp-val src index-known-fixnum)
1471 (if (eql vreg-class hard-reg-class-fpr)
1472 (<- fp-val)
1473 (ensuring-node-target (target vreg)
1474 (! single->node target fp-val)))))
1475 (t
1476 (with-imm-target () temp
1477 (if is-signed
1478 (! misc-ref-c-s32 temp src index-known-fixnum)
1479 (! misc-ref-c-u32 temp src index-known-fixnum))
1480 (ensuring-node-target (target vreg)
1481 (if (eq type-keyword :simple-string)
1482 (! u32->char target temp)
1483 (! box-fixnum target temp))))))
1484 (with-imm-target () idx-reg
1485 (if index-known-fixnum
1486 (x862-absolute-natural seg idx-reg nil (+ (arch::target-misc-data-offset arch) (ash index-known-fixnum 2)))
1487 (! scale-32bit-misc-index idx-reg unscaled-idx))
1488 (cond ((eq type-keyword :single-float-vector)
1489 (with-fp-target () (fp-val :single-float)
1490 (if (and (eql vreg-class hard-reg-class-fpr)
1491 (eql vreg-mode hard-reg-class-fpr-mode-single))
1492 (setq fp-val vreg))
1493 (! misc-ref-single-float fp-val src idx-reg)
1494 (if (eq vreg-class hard-reg-class-fpr)
1495 (<- fp-val)
1496 (ensuring-node-target (target vreg)
1497 (! single->node target fp-val)))))
1498 (t (with-imm-target () temp
1499 (if is-signed
1500 (! misc-ref-s32 temp src idx-reg)
1501 (! misc-ref-u32 temp src idx-reg))
1502 (ensuring-node-target (target vreg)
1503 (if (eq type-keyword :simple-string)
1504 (! u32->char target temp)
1505 (! box-fixnum target temp)))))))))
1506 (is-8-bit
1507 (with-imm-target () temp
1508 (if (and index-known-fixnum (<= index-known-fixnum (arch::target-max-8-bit-constant-index arch)))
1509 (if is-signed
1510 (! misc-ref-c-s8 temp src index-known-fixnum)
1511 (! misc-ref-c-u8 temp src index-known-fixnum))
1512 (with-imm-target () idx-reg
1513 (if index-known-fixnum
1514 (x862-absolute-natural seg idx-reg nil (+ (arch::target-misc-data-offset arch) index-known-fixnum))
1515 (! scale-8bit-misc-index idx-reg unscaled-idx))
1516 (if is-signed
1517 (! misc-ref-s8 temp src idx-reg)
1518 (! misc-ref-u8 temp src idx-reg))))
1519 (if (eq type-keyword :simple-string)
1520 (ensuring-node-target (target vreg)
1521 (! u32->char target temp))
1522 (if (and (= vreg-mode hard-reg-class-gpr-mode-u8)
1523 (eq type-keyword :unsigned-8-bit-vector))
1524 (x862-copy-register seg vreg temp)
1525 (ensuring-node-target (target vreg)
1526 (! box-fixnum target temp))))))
1527 (is-16-bit
1528 (with-imm-target () temp
1529 (ensuring-node-target (target vreg)
1530 (if (and index-known-fixnum
1531 (<= index-known-fixnum (arch::target-max-16-bit-constant-index arch)))
1532 (if is-signed
1533 (! misc-ref-c-s16 temp src index-known-fixnum)
1534 (! misc-ref-c-u16 temp src index-known-fixnum))
1535 (with-imm-target () idx-reg
1536 (if index-known-fixnum
1537 (x862-absolute-natural seg idx-reg nil (+ (arch::target-misc-data-offset arch) (ash index-known-fixnum 1)))
1538 (! scale-16bit-misc-index idx-reg unscaled-idx))
1539 (if is-signed
1540 (! misc-ref-s16 temp src idx-reg)
1541 (! misc-ref-u16 temp src idx-reg))))
1542 (! box-fixnum target temp))))
1543 ;; Down to the dregs.
1544 (is-64-bit
1545 (case type-keyword
1546 (:double-float-vector
1547 (with-fp-target () (fp-val :double-float)
1548 (if (and (eql vreg-class hard-reg-class-fpr)
1549 (eql vreg-mode hard-reg-class-fpr-mode-double))
1550 (setq fp-val vreg))
1551 (if (and index-known-fixnum (<= index-known-fixnum (arch::target-max-64-bit-constant-index arch)))
1552 (! misc-ref-c-double-float fp-val src index-known-fixnum)
1553 (progn
1554 (if index-known-fixnum
1555 (x862-absolute-natural seg unscaled-idx nil (+ (arch::target-misc-data-offset arch) (ash index-known-fixnum 3))))
1556 (! misc-ref-double-float fp-val src unscaled-idx)))
1557 (if (eq vreg-class hard-reg-class-fpr)
1558 (<- fp-val)
1559 (ensuring-node-target (target vreg)
1560 (x862-double->heap seg target fp-val)))))
1561 ((:signed-64-bit-vector :fixnum-vector)
1562 (ensuring-node-target (target vreg)
1563
1564 (with-imm-target () (s64-reg :s64)
1565 (if (and index-known-fixnum (<= index-known-fixnum (arch::target-max-64-bit-constant-index arch)))
1566 (! misc-ref-c-s64 s64-reg src index-known-fixnum)
1567 (progn
1568 (if index-known-fixnum
1569 (x862-absolute-natural seg unscaled-idx nil (+ (arch::target-misc-data-offset arch) (ash index-known-fixnum 3))))
1570 (! misc-ref-s64 s64-reg src unscaled-idx)))
1571 (if (eq type-keyword :fixnum-vector)
1572 (! box-fixnum target s64-reg)
1573 (x862-box-s64 seg target s64-reg)))))
1574 (t
1575 (with-imm-target () (u64-reg :u64)
1576 (if (eql vreg-mode hard-reg-class-gpr-mode-u64)
1577 (setq u64-reg vreg))
1578 (if (and index-known-fixnum (<= index-known-fixnum (arch::target-max-64-bit-constant-index arch)))
1579 (! misc-ref-c-u64 u64-reg src index-known-fixnum)
1580 (progn
1581 (if index-known-fixnum
1582 (x862-absolute-natural seg unscaled-idx nil (+ (arch::target-misc-data-offset arch) (ash index-known-fixnum 3))))
1583 (! misc-ref-u64 u64-reg src unscaled-idx)))
1584 (unless (eq u64-reg vreg)
1585 (ensuring-node-target (target vreg)
1586 (x862-box-u64 seg target u64-reg)))))))
1587 (t
1588 (unless is-1-bit
1589 (nx-error "~& unsupported vector type: ~s"
1590 type-keyword))
1591 (ensuring-node-target (target vreg)
1592 (if (and index-known-fixnum (<= index-known-fixnum (arch::target-max-1-bit-constant-index arch)))
1593 (! misc-ref-c-bit-fixnum target src index-known-fixnum)
1594 (with-imm-temps
1595 () (word-index bitnum)
1596 (if index-known-fixnum
1597 (progn
1598 (x862-lri seg word-index (+ (arch::target-misc-data-offset arch) (ash index-known-fixnum -6)))
1599 (x862-lri seg bitnum (logand index-known-fixnum #x63)))
1600 (! word-index-and-bitnum-from-index word-index bitnum unscaled-idx))
1601 (! ref-bit-vector-fixnum target bitnum src word-index))))))))
1602 (^)))
1603
1604;;; safe = T means assume "vector" is miscobj, do bounds check.
1605;;; safe = fixnum means check that subtag of vector = "safe" and do
1606;;; bounds check.
1607;;; safe = nil means crash&burn.
1608;;; This mostly knows how to reference the elements of an immediate miscobj.
1609(defun x862-vref (seg vreg xfer type-keyword vector index safe)
1610 (with-x86-local-vinsn-macros (seg vreg xfer)
1611 (if (null vreg)
1612 (progn
1613 (x862-form seg nil nil vector)
1614 (x862-form seg nil xfer index))
1615 (let* ((index-known-fixnum (acode-fixnum-form-p index))
1616 (unscaled-idx nil)
1617 (src nil))
1618 (if (or safe (not index-known-fixnum))
1619 (multiple-value-setq (src unscaled-idx)
1620 (x862-two-untargeted-reg-forms seg vector x8664::arg_y index x8664::arg_z))
1621 (setq src (x862-one-untargeted-reg-form seg vector x8664::arg_z)))
1622 (when safe
1623 (if (typep safe 'fixnum)
1624 (! trap-unless-typecode= src safe))
1625 (unless index-known-fixnum
1626 (! trap-unless-fixnum unscaled-idx))
1627 (! check-misc-bound unscaled-idx src))
1628 (x862-vref1 seg vreg xfer type-keyword src unscaled-idx index-known-fixnum)))))
1629
1630
1631
1632(defun x862-aset2 (seg vreg xfer array i j new safe type-keyword dim0 dim1)
1633 (with-x86-local-vinsn-macros (seg target)
1634 (let* ((i-known-fixnum (acode-fixnum-form-p i))
1635 (j-known-fixnum (acode-fixnum-form-p j))
1636 (arch (backend-target-arch *target-backend*))
1637 (is-node (member type-keyword (arch::target-gvector-types arch)))
1638 (constval (x862-constant-value-ok-for-type-keyword type-keyword new))
1639 (needs-memoization (and is-node (x862-acode-needs-memoization new)))
1640 (src)
1641 (unscaled-i)
1642 (unscaled-j)
1643 (val-reg (x862-target-reg-for-aset vreg type-keyword))
1644 (constidx
1645 (and dim0 dim1 i-known-fixnum j-known-fixnum
1646 (>= i-known-fixnum 0)
1647 (>= j-known-fixnum 0)
1648 (< i-known-fixnum dim0)
1649 (< j-known-fixnum dim1)
1650 (+ (* i-known-fixnum dim1) j-known-fixnum))))
1651 (progn
1652 (if constidx
1653 (multiple-value-setq (src val-reg)
1654 (x862-two-targeted-reg-forms seg array ($ x8664::temp0) new val-reg))
1655 (multiple-value-setq (src unscaled-i unscaled-j val-reg)
1656 (if needs-memoization
1657 (progn
1658 (x862-four-targeted-reg-forms seg
1659 array ($ x8664::temp0)
1660 i ($ x8664::arg_x)
1661 j ($ x8664::arg_y)
1662 new val-reg)
1663 (values ($ x8664::temp0) ($ x8664::arg_x) ($ x8664::arg_y) ($ x8664::arg_z)))
1664 (x862-four-untargeted-reg-forms seg
1665 array ($ x8664::temp0)
1666 i ($ x8664::arg_x)
1667 j ($ x8664::arg_y)
1668 new val-reg))))
1669 (let* ((*available-backend-imm-temps* *available-backend-imm-temps*))
1670 (when (and (= (hard-regspec-class val-reg) hard-reg-class-gpr)
1671 (logbitp (hard-regspec-value val-reg)
1672 *backend-imm-temps*))
1673 (use-imm-temp (hard-regspec-value val-reg)))
1674 (when safe
1675 (when (typep safe 'fixnum)
1676 (! trap-unless-simple-array-2
1677 src
1678 (dpb safe target::arrayH.flags-cell-subtag-byte
1679 (ash 1 $arh_simple_bit))
1680 (nx-error-for-simple-2d-array-type type-keyword)))
1681 (unless i-known-fixnum
1682 (! trap-unless-fixnum unscaled-i))
1683 (unless j-known-fixnum
1684 (! trap-unless-fixnum unscaled-j)))
1685 (with-imm-target () dim1
1686 (let* ((idx-reg ($ x8664::arg_y)))
1687 (if constidx
1688 (if needs-memoization
1689 (x862-lri seg x8664::arg_y (ash constidx *x862-target-fixnum-shift*)))
1690 (progn
1691 (if safe
1692 (! check-2d-bound dim1 unscaled-i unscaled-j src)
1693 (! 2d-dim1 dim1 src))
1694 (! 2d-unscaled-index idx-reg dim1 unscaled-i unscaled-j)))
1695 (let* ((v ($ x8664::arg_x)))
1696 (! array-data-vector-ref v src)
1697 (x862-vset1 seg vreg xfer type-keyword v idx-reg constidx val-reg (x862-unboxed-reg-for-aset seg type-keyword val-reg safe constval) constval needs-memoization)))))))))
1698
1699
1700(defun x862-aset3 (seg vreg xfer array i j k new safe type-keyword dim0 dim1 dim2)
1701 (with-x86-local-vinsn-macros (seg target)
1702 (let* ((i-known-fixnum (acode-fixnum-form-p i))
1703 (j-known-fixnum (acode-fixnum-form-p j))
1704 (k-known-fixnum (acode-fixnum-form-p k))
1705 (arch (backend-target-arch *target-backend*))
1706 (is-node (member type-keyword (arch::target-gvector-types arch)))
1707 (constval (x862-constant-value-ok-for-type-keyword type-keyword new))
1708 (needs-memoization (and is-node (x862-acode-needs-memoization new)))
1709 (src)
1710 (unscaled-i)
1711 (unscaled-j)
1712 (unscaled-k)
1713 (val-reg (x862-target-reg-for-aset vreg type-keyword))
1714 (constidx
1715 (and dim0 dim1 dim2 i-known-fixnum j-known-fixnum k-known-fixnum
1716 (>= i-known-fixnum 0)
1717 (>= j-known-fixnum 0)
1718 (>= k-known-fixnum 0)
1719 (< i-known-fixnum dim0)
1720 (< j-known-fixnum dim1)
1721 (< k-known-fixnum dim2)
1722 (+ (* i-known-fixnum dim1 dim2)
1723 (* j-known-fixnum dim2)
1724 k-known-fixnum))))
1725 (progn
1726 (if constidx
1727 (multiple-value-setq (src val-reg)
1728 (x862-two-targeted-reg-forms seg array ($ x8664::temp0) new val-reg))
1729 (progn
1730 (setq src ($ x8664::temp1)
1731 unscaled-i ($ x8664::temp0)
1732 unscaled-j ($ x8664::arg_x)
1733 unscaled-k ($ x8664::arg_y))
1734 (x862-push-register
1735 seg
1736 (x862-one-untargeted-reg-form seg array ($ x8664::arg_z)))
1737 (x862-four-targeted-reg-forms seg
1738 i ($ x8664::temp0)
1739 j ($ x8664::arg_x)
1740 k ($ x8664::arg_y)
1741 new val-reg)
1742 (x862-pop-register seg src)))
1743 (let* ((*available-backend-imm-temps* *available-backend-imm-temps*))
1744 (when (and (= (hard-regspec-class val-reg) hard-reg-class-gpr)
1745 (logbitp (hard-regspec-value val-reg)
1746 *backend-imm-temps*))
1747 (use-imm-temp (hard-regspec-value val-reg)))
1748
1749 (when safe
1750 (when (typep safe 'fixnum)
1751 (! trap-unless-simple-array-3
1752 src
1753 (dpb safe target::arrayH.flags-cell-subtag-byte
1754 (ash 1 $arh_simple_bit))
1755 (nx-error-for-simple-3d-array-type type-keyword)))
1756 (unless i-known-fixnum
1757 (! trap-unless-fixnum unscaled-i))
1758 (unless j-known-fixnum
1759 (! trap-unless-fixnum unscaled-j))
1760 (unless k-known-fixnum
1761 (! trap-unless-fixnum unscaled-k)))
1762 (with-imm-target () dim1
1763 (with-imm-target (dim1) dim2
1764 (let* ((idx-reg ($ x8664::arg_y)))
1765 (if constidx
1766 (when needs-memoization
1767 (x862-lri seg idx-reg (ash constidx *x862-target-fixnum-shift*)))
1768 (progn
1769 (if safe
1770 (! check-3d-bound dim1 dim2 unscaled-i unscaled-j unscaled-k src)
1771 (! 3d-dims dim1 dim2 src))
1772 (! 3d-unscaled-index idx-reg dim1 dim2 unscaled-i unscaled-j unscaled-k)))
1773 (let* ((v ($ x8664::arg_x)))
1774 (! array-data-vector-ref v src)
1775 (x862-vset1 seg vreg xfer type-keyword v idx-reg constidx val-reg (x862-unboxed-reg-for-aset seg type-keyword val-reg safe constval) constval needs-memoization))))))))))
1776
1777
1778(defun x862-aref2 (seg vreg xfer array i j safe typekeyword &optional dim0 dim1)
1779 (with-x86-local-vinsn-macros (seg vreg xfer)
1780 (let* ((i-known-fixnum (acode-fixnum-form-p i))
1781 (j-known-fixnum (acode-fixnum-form-p j))
1782 (src)
1783 (unscaled-i)
1784 (unscaled-j)
1785 (constidx
1786 (and dim0 dim1 i-known-fixnum j-known-fixnum
1787 (>= i-known-fixnum 0)
1788 (>= j-known-fixnum 0)
1789 (< i-known-fixnum dim0)
1790 (< j-known-fixnum dim1)
1791 (+ (* i-known-fixnum dim1) j-known-fixnum))))
1792 (if constidx
1793 (setq src (x862-one-targeted-reg-form seg array ($ x8664::arg_z)))
1794 (multiple-value-setq (src unscaled-i unscaled-j)
1795 (x862-three-untargeted-reg-forms seg
1796 array x8664::arg_x
1797 i x8664::arg_y
1798 j x8664::arg_z)))
1799 (when safe
1800 (when (typep safe 'fixnum)
1801 (! trap-unless-simple-array-2
1802 src
1803 (dpb safe target::arrayH.flags-cell-subtag-byte
1804 (ash 1 $arh_simple_bit))
1805 (nx-error-for-simple-2d-array-type typekeyword)))
1806 (unless i-known-fixnum
1807 (! trap-unless-fixnum unscaled-i))
1808 (unless j-known-fixnum
1809 (! trap-unless-fixnum unscaled-j)))
1810 (with-node-target (src) idx-reg
1811 (with-imm-target () dim1
1812 (unless constidx
1813 (if safe
1814 (! check-2d-bound dim1 unscaled-i unscaled-j src)
1815 (! 2d-dim1 dim1 src))
1816 (! 2d-unscaled-index idx-reg dim1 unscaled-i unscaled-j))
1817 (with-node-target (idx-reg) v
1818 (! array-data-vector-ref v src)
1819 (x862-vref1 seg vreg xfer typekeyword v idx-reg constidx)))))))
1820
1821(defun x862-aref3 (seg vreg xfer array i j k safe typekeyword &optional dim0 dim1 dim2)
1822 (with-x86-local-vinsn-macros (seg vreg xfer)
1823 (let* ((i-known-fixnum (acode-fixnum-form-p i))
1824 (j-known-fixnum (acode-fixnum-form-p j))
1825 (k-known-fixnum (acode-fixnum-form-p k))
1826 (src)
1827 (unscaled-i)
1828 (unscaled-j)
1829 (unscaled-k)
1830 (constidx
1831 (and dim0 dim1 i-known-fixnum j-known-fixnum k-known-fixnum
1832 (>= i-known-fixnum 0)
1833 (>= j-known-fixnum 0)
1834 (>= k-known-fixnum 0)
1835 (< i-known-fixnum dim0)
1836 (< j-known-fixnum dim1)
1837 (< k-known-fixnum dim2)
1838 (+ (* i-known-fixnum dim1 dim2)
1839 (* j-known-fixnum dim2)
1840 k-known-fixnum))))
1841 (if constidx
1842 (setq src (x862-one-targeted-reg-form seg array ($ x8664::arg_z)))
1843 (multiple-value-setq (src unscaled-i unscaled-j unscaled-k)
1844 (x862-four-untargeted-reg-forms seg
1845 array x8664::temp0
1846 i x8664::arg_x
1847 j x8664::arg_y
1848 k x8664::arg_z)))
1849 (when safe
1850 (when (typep safe 'fixnum)
1851 (! trap-unless-simple-array-3
1852 src
1853 (dpb safe target::arrayH.flags-cell-subtag-byte
1854 (ash 1 $arh_simple_bit))
1855 (nx-error-for-simple-3d-array-type typekeyword)))
1856 (unless i-known-fixnum
1857 (! trap-unless-fixnum unscaled-i))
1858 (unless j-known-fixnum
1859 (! trap-unless-fixnum unscaled-j))
1860 (unless k-known-fixnum
1861 (! trap-unless-fixnum unscaled-k)))
1862 (with-node-target (src) idx-reg
1863 (with-imm-target () dim1
1864 (with-imm-target (dim1) dim2
1865 (unless constidx
1866 (if safe
1867 (! check-3d-bound dim1 dim2 unscaled-i unscaled-j unscaled-k src)
1868 (! 3d-dims dim1 dim2 src))
1869 (! 3d-unscaled-index idx-reg dim1 dim2 unscaled-i unscaled-j unscaled-k))))
1870 (with-node-target (idx-reg) v
1871 (! array-data-vector-ref v src)
1872 (x862-vref1 seg vreg xfer typekeyword v idx-reg constidx))))))
1873
1874
1875
1876(defun x862-natural-vset (seg vreg xfer vector index value safe)
1877 (with-x86-local-vinsn-macros (seg vreg xfer)
1878 (let* ((index-known-fixnum (acode-fixnum-form-p index))
1879 (arch (backend-target-arch *target-backend*))
1880 (src nil)
1881 (unscaled-idx nil))
1882 (with-imm-target () (target :natural)
1883 (if (or safe (not index-known-fixnum))
1884 (multiple-value-setq (src unscaled-idx target)
1885 (x862-three-untargeted-reg-forms seg vector x8664::arg_y index x8664::arg_z value (or vreg target)))
1886 (multiple-value-setq (src target)
1887 (x862-two-untargeted-reg-forms seg vector x8664::arg_y value (or vreg target))))
1888 (when safe
1889 (with-imm-temps (target) () ; Don't use target in type/bounds check
1890 (if (typep safe 'fixnum)
1891 (! trap-unless-typecode= src safe))
1892 (unless index-known-fixnum
1893 (! trap-unless-fixnum unscaled-idx))
1894 (! check-misc-bound unscaled-idx src)))
1895 (target-arch-case
1896
1897 (:x8664
1898 (if (and index-known-fixnum
1899 (<= index-known-fixnum (arch::target-max-64-bit-constant-index arch)))
1900 (! misc-set-c-u64 target src index-known-fixnum)
1901 (progn
1902 (if index-known-fixnum
1903 (x862-absolute-natural seg unscaled-idx nil (+ (arch::target-misc-data-offset arch) (ash index-known-fixnum 3))))
1904 (! misc-set-u64 target src unscaled-idx)))))
1905 (<- target) ; should be a no-op in this case
1906 (^)))))
1907
1908
1909(defun x862-constant-value-ok-for-type-keyword (type-keyword form)
1910 (let* ((arch (backend-target-arch *target-backend*))
1911 (is-node (member type-keyword (arch::target-gvector-types arch))))
1912 (if is-node
1913 (cond ((eq form *nx-nil*)
1914 (arch::target-nil-value arch))
1915 ((eq form *nx-t*)
1916 (+ (arch::target-nil-value arch) (arch::target-t-offset arch)))
1917 (t
1918 (let* ((fixval (acode-fixnum-form-p form)))
1919 (if fixval
1920 (ash fixval (arch::target-fixnum-shift arch))))))
1921 (if (and (acode-p form)
1922 (or (eq (acode-operator form) (%nx1-operator immediate))
1923 (eq (acode-operator form) (%nx1-operator fixnum))))
1924 (let* ((val (%cadr form))
1925
1926 (typep (cond ((eq type-keyword :signed-32-bit-vector)
1927 (typep val '(signed-byte 32)))
1928 ((eq type-keyword :single-float-vector)
1929 (typep val 'short-float))
1930 ((eq type-keyword :double-float-vector)
1931 (typep val 'double-float))
1932 ((eq type-keyword :simple-string)
1933 (typep val 'base-char))
1934 ((eq type-keyword :signed-8-bit-vector)
1935 (typep val '(signed-byte 8)))
1936 ((eq type-keyword :unsigned-8-bit-vector)
1937 (typep val '(unsigned-byte 8)))
1938 ((eq type-keyword :signed-16-bit-vector)
1939 (typep val '(signed-byte 16)))
1940 ((eq type-keyword :unsigned-16-bit-vector)
1941 (typep val '(unsigned-byte 16)))
1942 ((eq type-keyword :bit-vector)
1943 (typep val 'bit)))))
1944 (if typep val))))))
1945
1946(defun x862-target-reg-for-aset (vreg type-keyword)
1947 (let* ((arch (backend-target-arch *target-backend*))
1948 (is-node (member type-keyword (arch::target-gvector-types arch)))
1949 (is-1-bit (member type-keyword (arch::target-1-bit-ivector-types arch)))
1950 (is-8-bit (member type-keyword (arch::target-8-bit-ivector-types arch)))
1951 (is-16-bit (member type-keyword (arch::target-16-bit-ivector-types arch)))
1952 (is-32-bit (member type-keyword (arch::target-32-bit-ivector-types arch)))
1953 (is-64-bit (member type-keyword (arch::target-64-bit-ivector-types arch)))
1954 (is-signed (member type-keyword '(:signed-8-bit-vector :signed-16-bit-vector :signed-32-bit-vector :signed-64-bit-vector :fixnum-vector)))
1955 (vreg-class (if (and vreg (not (eq vreg :push))) (hard-regspec-class vreg)))
1956 (vreg-mode (if (or (eql vreg-class hard-reg-class-gpr)
1957 (eql vreg-class hard-reg-class-fpr))
1958 (get-regspec-mode vreg)))
1959 (next-imm-target (available-imm-temp *available-backend-imm-temps*))
1960 (next-fp-target (available-fp-temp *available-backend-fp-temps*))
1961 (acc (make-wired-lreg x8664::arg_z)))
1962 (cond ((or is-node
1963 (eq vreg :push)
1964 is-1-bit
1965 (eq type-keyword :simple-string)
1966 (eq type-keyword :fixnum-vector)
1967 (and (eql vreg-class hard-reg-class-gpr)
1968 (eql vreg-mode hard-reg-class-gpr-mode-node)))
1969 acc)
1970 ;; If there's no vreg - if we're setting for effect only, and
1971 ;; not for value - we can target an unboxed register directly.
1972 ;; Usually.
1973 ((null vreg)
1974 (cond (is-64-bit
1975 (if (eq type-keyword :double-float-vector)
1976 (make-unwired-lreg next-fp-target :mode hard-reg-class-fpr-mode-double)
1977 (make-unwired-lreg next-imm-target :mode (if is-signed hard-reg-class-gpr-mode-s64 hard-reg-class-gpr-mode-u64))))
1978 (is-32-bit
1979 (if (eq type-keyword :single-float-vector)
1980 (make-unwired-lreg next-fp-target :mode hard-reg-class-fpr-mode-single)
1981 (make-unwired-lreg next-imm-target :mode (if is-signed hard-reg-class-gpr-mode-s32 hard-reg-class-gpr-mode-u32))))
1982 (is-16-bit
1983 (make-unwired-lreg next-imm-target :mode (if is-signed hard-reg-class-gpr-mode-s16 hard-reg-class-gpr-mode-u16)))
1984 (is-8-bit
1985 (make-unwired-lreg next-imm-target :mode (if is-signed hard-reg-class-gpr-mode-s8 hard-reg-class-gpr-mode-u8)))
1986 (t "Bug: can't determine operand size for ~s" type-keyword)))
1987 ;; Vreg is non-null. We might be able to use it directly.
1988 (t
1989 (let* ((lreg (if vreg-mode
1990 (make-unwired-lreg (lreg-value vreg)))))
1991 (if
1992 (cond
1993 (is-64-bit
1994 (if (eq type-keyword :double-float-vector)
1995 (and (eql vreg-class hard-reg-class-fpr)
1996 (eql vreg-mode hard-reg-class-fpr-mode-double))
1997 (if is-signed
1998 (and (eql vreg-class hard-reg-class-gpr)
1999 (eql vreg-mode hard-reg-class-gpr-mode-s64))
2000 (and (eql vreg-class hard-reg-class-gpr)
2001 (eql vreg-mode hard-reg-class-gpr-mode-u64)))))
2002 (is-32-bit
2003 (if (eq type-keyword :single-float-vector)
2004 (and (eql vreg-class hard-reg-class-fpr)
2005 (eql vreg-mode hard-reg-class-fpr-mode-single))
2006 (if is-signed
2007 (and (eql vreg-class hard-reg-class-gpr)
2008 (or (eql vreg-mode hard-reg-class-gpr-mode-s32)
2009 (eql vreg-mode hard-reg-class-gpr-mode-s64)))
2010 (and (eql vreg-class hard-reg-class-gpr)
2011 (or (eql vreg-mode hard-reg-class-gpr-mode-u32)
2012 (eql vreg-mode hard-reg-class-gpr-mode-u64)
2013 (eql vreg-mode hard-reg-class-gpr-mode-s64))))))
2014 (is-16-bit
2015 (if is-signed
2016 (and (eql vreg-class hard-reg-class-gpr)
2017 (or (eql vreg-mode hard-reg-class-gpr-mode-s16)
2018 (eql vreg-mode hard-reg-class-gpr-mode-s32)
2019 (eql vreg-mode hard-reg-class-gpr-mode-s64)))
2020 (and (eql vreg-class hard-reg-class-gpr)
2021 (or (eql vreg-mode hard-reg-class-gpr-mode-u16)
2022 (eql vreg-mode hard-reg-class-gpr-mode-u32)
2023 (eql vreg-mode hard-reg-class-gpr-mode-u64)
2024 (eql vreg-mode hard-reg-class-gpr-mode-s32)
2025 (eql vreg-mode hard-reg-class-gpr-mode-s64)))))
2026 (t
2027 (if is-signed
2028 (and (eql vreg-class hard-reg-class-gpr)
2029 (or (eql vreg-mode hard-reg-class-gpr-mode-s8)
2030 (eql vreg-mode hard-reg-class-gpr-mode-s16)
2031 (eql vreg-mode hard-reg-class-gpr-mode-s32)
2032 (eql vreg-mode hard-reg-class-gpr-mode-s64)))
2033 (and (eql vreg-class hard-reg-class-gpr)
2034 (or (eql vreg-mode hard-reg-class-gpr-mode-u8)
2035 (eql vreg-mode hard-reg-class-gpr-mode-u16)
2036 (eql vreg-mode hard-reg-class-gpr-mode-u32)
2037 (eql vreg-mode hard-reg-class-gpr-mode-u64)
2038 (eql vreg-mode hard-reg-class-gpr-mode-s16)
2039 (eql vreg-mode hard-reg-class-gpr-mode-s32)
2040 (eql vreg-mode hard-reg-class-gpr-mode-s64))))))
2041 lreg
2042 acc))))))
2043
2044(defun x862-unboxed-reg-for-aset (seg type-keyword result-reg safe constval)
2045 (with-x86-local-vinsn-macros (seg)
2046 (let* ((arch (backend-target-arch *target-backend*))
2047 (is-node (member type-keyword (arch::target-gvector-types arch)))
2048 (is-8-bit (member type-keyword (arch::target-8-bit-ivector-types arch)))
2049 (is-16-bit (member type-keyword (arch::target-16-bit-ivector-types arch)))
2050 (is-32-bit (member type-keyword (arch::target-32-bit-ivector-types arch)))
2051 (is-64-bit (member type-keyword (arch::target-64-bit-ivector-types arch)))
2052 (is-signed (member type-keyword '(:signed-8-bit-vector :signed-16-bit-vector :signed-32-bit-vector :signed-64-bit-vector :fixnum-vector)))
2053 (result-is-node-gpr (and (eql (hard-regspec-class result-reg)
2054 hard-reg-class-gpr)
2055 (eql (get-regspec-mode result-reg)
2056 hard-reg-class-gpr-mode-node)))
2057 (next-imm-target (available-imm-temp *available-backend-imm-temps*))
2058 (next-fp-target (available-fp-temp *available-backend-fp-temps*)))
2059 (if (or is-node (not result-is-node-gpr))
2060 result-reg
2061 (cond (is-64-bit
2062 (if (eq type-keyword :double-float-vector)
2063 (let* ((reg (make-unwired-lreg next-fp-target :mode hard-reg-class-fpr-mode-double)))
2064 (if safe
2065 (! get-double? reg result-reg)
2066 (! get-double reg result-reg))
2067 reg)
2068 (if is-signed
2069 (let* ((reg (make-unwired-lreg next-imm-target :mode hard-reg-class-gpr-mode-s64)))
2070 (if (eq type-keyword :fixnum-vector)
2071 (progn
2072 (when safe
2073 (! trap-unless-fixnum result-reg))
2074 (! fixnum->signed-natural reg result-reg))
2075 (! unbox-s64 reg result-reg))
2076 reg)
2077 (let* ((reg (make-unwired-lreg next-imm-target :mode hard-reg-class-gpr-mode-u64)))
2078 (! unbox-u64 reg result-reg)
2079 reg))))
2080 (is-32-bit
2081 ;; Generally better to use a GPR for the :SINGLE-FLOAT-VECTOR
2082 ;; case here.
2083 (if is-signed
2084 (let* ((reg (make-unwired-lreg next-imm-target :mode hard-reg-class-gpr-mode-s32)))
2085 (if (eq type-keyword :fixnum-vector)
2086 (progn
2087 (when safe
2088 (! trap-unless-fixnum result-reg))
2089 (! fixnum->signed-natural reg result-reg))
2090 (! unbox-s32 reg result-reg))
2091 reg)
2092 (let* ((reg (make-unwired-lreg next-imm-target :mode hard-reg-class-gpr-mode-u32)))
2093 (cond ((eq type-keyword :simple-string)
2094 (if (characterp constval)
2095 (x862-lri seg reg (char-code constval))
2096 (! unbox-base-char reg result-reg)))
2097 ((eq type-keyword :single-float-vector)
2098 (if (typep constval 'single-float)
2099 (x862-lri seg reg (single-float-bits constval))
2100 (progn
2101 (when safe
2102 (! trap-unless-single-float result-reg))
2103 (! single-float-bits reg result-reg))))
2104 (t
2105 (if (typep constval '(unsigned-byte 32))
2106 (x862-lri seg reg constval)
2107 (if *x862-reckless*
2108 (! %unbox-u32 reg result-reg)
2109 (! unbox-u32 reg result-reg)))))
2110 reg)))
2111 (is-16-bit
2112 (if is-signed
2113 (let* ((reg (make-unwired-lreg next-imm-target :mode hard-reg-class-gpr-mode-s16)))
2114 (if (typep constval '(signed-byte 16))
2115 (x862-lri seg reg constval)
2116 (if *x862-reckless*
2117 (! %unbox-s16 reg result-reg)
2118 (! unbox-s16 reg result-reg)))
2119 reg)
2120 (let* ((reg (make-unwired-lreg next-imm-target :mode hard-reg-class-gpr-mode-u16)))
2121 (if (typep constval '(unsigned-byte 16))
2122 (x862-lri seg reg constval)
2123 (if *x862-reckless*
2124 (! %unbox-u16 reg result-reg)
2125 (! unbox-u16 reg result-reg)))
2126 reg)))
2127 (is-8-bit
2128 (if is-signed
2129 (let* ((reg (make-unwired-lreg next-imm-target :mode hard-reg-class-gpr-mode-s8)))
2130 (if (typep constval '(signed-byte 8))
2131 (x862-lri seg reg constval)
2132 (if *x862-reckless*
2133 (! %unbox-s8 reg result-reg)
2134 (! unbox-s8 reg result-reg)))
2135 reg)
2136 (let* ((reg (make-unwired-lreg next-imm-target :mode hard-reg-class-gpr-mode-u8)))
2137 (if (typep constval '(unsigned-byte 8))
2138 (x862-lri seg reg constval)
2139 (if *x862-reckless*
2140 (! %unbox-u8 reg result-reg)
2141 (! unbox-u8 reg result-reg)))
2142 reg)))
2143 (t
2144 (let* ((reg result-reg))
2145 (unless (typep constval 'bit)
2146 (when safe
2147 (! trap-unless-bit reg )))
2148 reg)))))))
2149
2150(defun x862-vset1 (seg vreg xfer type-keyword src unscaled-idx index-known-fixnum val-reg unboxed-val-reg constval node-value-needs-memoization)
2151 (with-x86-local-vinsn-macros (seg vreg xfer)
2152 (let* ((arch (backend-target-arch *target-backend*))
2153 (is-node (member type-keyword (arch::target-gvector-types arch)))
2154 (is-1-bit (member type-keyword (arch::target-1-bit-ivector-types arch)))
2155 (is-8-bit (member type-keyword (arch::target-8-bit-ivector-types arch)))
2156 (is-16-bit (member type-keyword (arch::target-16-bit-ivector-types arch)))
2157 (is-32-bit (member type-keyword (arch::target-32-bit-ivector-types arch)))
2158 (is-64-bit (member type-keyword (arch::target-64-bit-ivector-types arch)))
2159 (is-signed (member type-keyword '(:signed-8-bit-vector :signed-16-bit-vector :signed-32-bit-vector :signed-64-bit-vector :fixnum-vector))))
2160 (cond ((and is-node node-value-needs-memoization)
2161 (unless (and (eql (hard-regspec-value src) x8664::arg_x)
2162 (eql (hard-regspec-value unscaled-idx) x8664::arg_y)
2163 (eql (hard-regspec-value val-reg) x8664::arg_z))
2164 (nx-error "Bug: invalid register targeting for gvset: ~s" (list src unscaled-idx val-reg)))
2165 (! call-subprim-3 val-reg (subprim-name->offset '.SPgvset) src unscaled-idx val-reg))
2166 (is-node
2167 (if (and index-known-fixnum (<= index-known-fixnum
2168 (target-word-size-case
2169 (32 (arch::target-max-32-bit-constant-index arch))
2170 (64 (arch::target-max-64-bit-constant-index arch)))))
2171 (if (typep constval '(signed-byte 32))
2172 (! misc-set-immediate-c-node constval src index-known-fixnum)
2173 (! misc-set-c-node val-reg src index-known-fixnum))
2174 (progn
2175 (if index-known-fixnum
2176 (x862-absolute-natural seg unscaled-idx nil (+ (arch::target-misc-data-offset arch) (ash index-known-fixnum *x862-target-node-shift*))))
2177 (if (typep constval '(signed-byte 32))
2178 (! misc-set-immediate-node constval src unscaled-idx)
2179 (! misc-set-node val-reg src unscaled-idx)))))
2180 (t
2181 (with-imm-target (unboxed-val-reg) scaled-idx
2182 (cond
2183 (is-64-bit
2184 (if (and index-known-fixnum
2185 (<= index-known-fixnum
2186 (arch::target-max-64-bit-constant-index arch)))
2187 (if (eq type-keyword :double-float-vector)
2188 (! misc-set-c-double-float unboxed-val-reg src index-known-fixnum)
2189 (if is-signed
2190 (! misc-set-c-s64 unboxed-val-reg src index-known-fixnum)
2191 (! misc-set-c-u64 unboxed-val-reg src index-known-fixnum)))
2192 (progn
2193 (if index-known-fixnum
2194 (x862-absolute-natural seg unscaled-idx nil (+ (arch::target-misc-dfloat-offset arch) (ash index-known-fixnum 3))))
2195 (if (eq type-keyword :double-float-vector)
2196 (! misc-set-double-float unboxed-val-reg src unscaled-idx)
2197 (if is-signed
2198 (! misc-set-s64 unboxed-val-reg src unscaled-idx)
2199 (! misc-set-u64 unboxed-val-reg src unscaled-idx))))))
2200 (is-32-bit
2201 (if (and index-known-fixnum
2202 (<= index-known-fixnum
2203 (arch::target-max-32-bit-constant-index arch)))
2204 (if (eq type-keyword :single-float-vector)
2205 (if (eq (hard-regspec-class unboxed-val-reg)
2206 hard-reg-class-fpr)
2207 (! misc-set-c-single-float unboxed-val-reg src index-known-fixnum)
2208 (! misc-set-c-u32 unboxed-val-reg src index-known-fixnum))
2209 (if is-signed
2210 (! misc-set-c-s32 unboxed-val-reg src index-known-fixnum)
2211 (! misc-set-c-u32 unboxed-val-reg src index-known-fixnum)))
2212 (progn
2213 (if index-known-fixnum
2214 (x862-absolute-natural seg scaled-idx nil (+ (arch::target-misc-data-offset arch) (ash index-known-fixnum 2)))
2215 (! scale-32bit-misc-index scaled-idx unscaled-idx))
2216 (if (and (eq type-keyword :single-float-vector)
2217 (eql (hard-regspec-class unboxed-val-reg)
2218 hard-reg-class-fpr))
2219 (! misc-set-single-float unboxed-val-reg src scaled-idx)
2220 (if is-signed
2221 (! misc-set-s32 unboxed-val-reg src scaled-idx)
2222 (! misc-set-u32 unboxed-val-reg src scaled-idx))))))
2223 (is-16-bit
2224 (if (and index-known-fixnum
2225 (<= index-known-fixnum
2226 (arch::target-max-16-bit-constant-index arch)))
2227 (if is-signed
2228 (! misc-set-c-s16 unboxed-val-reg src index-known-fixnum)
2229 (! misc-set-c-u16 unboxed-val-reg src index-known-fixnum))
2230 (progn
2231 (if index-known-fixnum
2232 (x862-absolute-natural seg scaled-idx nil (+ (arch::target-misc-data-offset arch) (ash index-known-fixnum 1)))
2233 (! scale-16bit-misc-index scaled-idx unscaled-idx))
2234 (if is-signed
2235 (! misc-set-s16 unboxed-val-reg src scaled-idx)
2236 (! misc-set-u16 unboxed-val-reg src scaled-idx)))))
2237 (is-8-bit
2238 (if (and index-known-fixnum
2239 (<= index-known-fixnum
2240 (arch::target-max-8-bit-constant-index arch)))
2241 (if is-signed
2242 (! misc-set-c-s8 unboxed-val-reg src index-known-fixnum)
2243 (! misc-set-c-u8 unboxed-val-reg src index-known-fixnum))
2244 (progn
2245 (if index-known-fixnum
2246 (x862-absolute-natural seg scaled-idx nil (+ (arch::target-misc-data-offset arch) index-known-fixnum))
2247 (! scale-8bit-misc-index scaled-idx unscaled-idx))
2248 (if is-signed
2249 (! misc-set-s8 unboxed-val-reg src scaled-idx)
2250 (! misc-set-u8 unboxed-val-reg src scaled-idx)))))
2251 (is-1-bit
2252 (if (and index-known-fixnum (<= index-known-fixnum (arch::target-max-1-bit-constant-index arch)))
2253 (if constval
2254 (if (zerop constval)
2255 (! set-constant-bit-to-zero src index-known-fixnum)
2256 (! set-constant-bit-to-one src index-known-fixnum))
2257 (progn
2258 (! set-constant-bit-to-variable-value src index-known-fixnum val-reg)))
2259 (with-imm-temps () (word-index bit-number)
2260 (if index-known-fixnum
2261 (progn
2262 (x862-lri seg word-index (+ (arch::target-misc-data-offset arch) (ash index-known-fixnum -6)))
2263 (x862-lri seg bit-number (logand index-known-fixnum #x63)))
2264 (! word-index-and-bitnum-from-index word-index bit-number unscaled-idx))
2265 (if constval
2266 (if (zerop constval)
2267 (! set-variable-bit-to-zero src word-index bit-number)
2268 (! set-variable-bit-to-one src word-index bit-number))
2269 (progn
2270 (! set-variable-bit-to-variable-value src word-index bit-number val-reg))))))))))
2271 (when (and vreg val-reg) (<- val-reg))
2272 (^))))
2273
2274
2275
2276(defun x862-vset (seg vreg xfer type-keyword vector index value safe)
2277 (with-x86-local-vinsn-macros (seg)
2278 (let* ((arch (backend-target-arch *target-backend*))
2279 (is-node (member type-keyword (arch::target-gvector-types arch)))
2280 (constval (x862-constant-value-ok-for-type-keyword type-keyword value))
2281 (needs-memoization (and is-node (x862-acode-needs-memoization value)))
2282 (index-known-fixnum (acode-fixnum-form-p index)))
2283 (let* ((src ($ x8664::arg_x))
2284 (unscaled-idx ($ x8664::arg_y))
2285 (result-reg ($ x8664::arg_z)))
2286 (cond (needs-memoization
2287 (x862-three-targeted-reg-forms seg
2288 vector src
2289 index unscaled-idx
2290 value result-reg))
2291 (t
2292 (setq result-reg (x862-target-reg-for-aset vreg type-keyword))
2293 (x862-three-targeted-reg-forms seg
2294 vector src
2295 index unscaled-idx
2296 value result-reg)))
2297 (when safe
2298 (let* ((*available-backend-imm-temps* *available-backend-imm-temps*)
2299 (value (if (eql (hard-regspec-class result-reg)
2300 hard-reg-class-gpr)
2301 (hard-regspec-value result-reg))))
2302 (when (and value (logbitp value *available-backend-imm-temps*))
2303 (setq *available-backend-imm-temps* (bitclr value *available-backend-imm-temps*)))
2304 (if (typep safe 'fixnum)
2305 (! trap-unless-typecode= src safe))
2306 (unless index-known-fixnum
2307 (! trap-unless-fixnum unscaled-idx))
2308 (! check-misc-bound unscaled-idx src)))
2309 (x862-vset1 seg vreg xfer type-keyword src unscaled-idx index-known-fixnum result-reg (x862-unboxed-reg-for-aset seg type-keyword result-reg safe constval) constval needs-memoization)))))
2310
2311
2312
2313(defun x862-tail-call-alias (immref sym &optional arglist)
2314 (let ((alias (cdr (assq sym *x862-tail-call-aliases*))))
2315 (if (and alias (or (null arglist) (eq (+ (length (car arglist)) (length (cadr arglist))) (cdr alias))))
2316 (make-acode (%nx1-operator immediate) (car alias))
2317 immref)))
2318
2319;;; If BODY is essentially an APPLY involving an &rest arg, try to avoid
2320;;; consing it.
2321(defun x862-eliminate-&rest (body rest key-p auxen rest-values)
2322 (when (and rest (not key-p) (not (cadr auxen)) rest-values)
2323 (when (eq (logand (the fixnum (nx-var-bits rest))
2324 (logior $vsetqmask (ash -1 $vbitspecial)
2325 (ash 1 $vbitclosed) (ash 1 $vbitsetq) (ash 1 $vbitcloseddownward)))
2326 0) ; Nothing but simple references
2327 (do* ()
2328 ((not (acode-p body)))
2329 (let* ((op (acode-operator body)))
2330 (if (or (eq op (%nx1-operator lexical-function-call))
2331 (eq op (%nx1-operator call)))
2332 (destructuring-bind (fn-form (stack-args reg-args) &optional spread-p) (%cdr body)
2333 (unless (and (eq spread-p t)
2334 (eq (x862-lexical-reference-p (%car reg-args)) rest))
2335 (return nil))
2336 (flet ((independent-of-all-values (form)
2337 (setq form (acode-unwrapped-form form))
2338 (or (x86-constant-form-p form)
2339 (let* ((lexref (x862-lexical-reference-p form)))
2340 (and lexref
2341 (neq lexref rest)
2342 (dolist (val rest-values t)
2343 (unless (x862-var-not-set-by-form-p lexref val)
2344 (return))))))))
2345 (unless (or (eq op (%nx1-operator lexical-function-call))
2346 (independent-of-all-values fn-form))
2347 (return nil))
2348 (if (dolist (s stack-args t)
2349 (unless (independent-of-all-values s)
2350 (return nil)))
2351 (let* ((arglist (append stack-args rest-values)))
2352 (return
2353 (make-acode op
2354 fn-form
2355 (if (<= (length arglist) *x862-target-num-arg-regs*)
2356 (list nil (reverse arglist))
2357 (list (butlast arglist *x862-target-num-arg-regs*)
2358 (reverse (last arglist *x862-target-num-arg-regs*))))
2359 nil)))
2360 (return nil))))
2361 (if (eq op (%nx1-operator local-block))
2362 (setq body (%cadr body))
2363 (if (and (eq op (%nx1-operator if))
2364 (eq (x862-lexical-reference-p (%cadr body)) rest))
2365 (setq body (%caddr body))
2366 (return nil)))))))))
2367
2368(defun x862-call-fn (seg vreg xfer fn arglist spread-p)
2369 (with-x86-local-vinsn-macros (seg vreg xfer)
2370 (when spread-p
2371 (destructuring-bind (stack-args reg-args) arglist
2372 (when (and (null (cdr reg-args))
2373 (nx-null (acode-unwrapped-form (car reg-args))))
2374 (setq spread-p nil)
2375 (let* ((nargs (length stack-args)))
2376 (declare (fixnum nargs))
2377 (if (<= nargs *x862-target-num-arg-regs*)
2378 (setq arglist (list nil (reverse stack-args)))
2379 (setq arglist (list (butlast stack-args *x862-target-num-arg-regs*) (reverse (last stack-args *x862-target-num-arg-regs*)))))))))
2380 (let* ((lexref (x862-lexical-reference-p fn))
2381 (simple-case (or (fixnump fn)
2382 (typep fn 'lreg)
2383 (x862-immediate-function-p fn)
2384 (and
2385 lexref
2386 (not spread-p)
2387 (flet ((all-simple (args)
2388 (dolist (arg args t)
2389 (when (and arg (not (x862-var-not-set-by-form-p lexref arg)))
2390 (return)))))
2391 (and (all-simple (car arglist))
2392 (all-simple (cadr arglist))
2393 (setq fn (var-ea lexref)))))))
2394 (cstack *x862-cstack*)
2395 (top *x862-top-vstack-lcell*)
2396 (vstack *x862-vstack*))
2397 (setq xfer (or xfer 0))
2398 (when (and (eq xfer $backend-return)
2399 (eq 0 *x862-undo-count*)
2400 (acode-p fn)
2401 (eq (acode-operator fn) (%nx1-operator immediate))
2402 (symbolp (cadr fn)))
2403 (setq fn (x862-tail-call-alias fn (%cadr fn) arglist)))
2404
2405 (if (and (eq xfer $backend-return) (not (x862-tailcallok xfer)))
2406 (progn
2407 (x862-call-fn seg vreg $backend-mvpass fn arglist spread-p)
2408 (x862-set-vstack (%i+ (if simple-case 0 *x862-target-node-size*) vstack))
2409 (setq *x862-cstack* cstack)
2410 (let ((*x862-returning-values* t)) (x862-do-return seg)))
2411 (let* ((mv-p (x862-mv-p xfer))
2412 (mv-return-label (if (and mv-p
2413 (not (x862-tailcallok xfer)))
2414 (backend-get-next-label))))
2415 (unless simple-case
2416 (x862-vpush-register seg (x862-one-untargeted-reg-form seg fn x8664::arg_z))
2417 (setq fn (x862-vloc-ea vstack)))
2418 (x862-invoke-fn seg fn (x862-arglist seg arglist mv-return-label) spread-p xfer mv-return-label)
2419 (if (and (logbitp $backend-mvpass-bit xfer)
2420 (not simple-case))
2421 (progn
2422 (! save-values)
2423 (! vstack-discard 1)
2424 (x862-set-nargs seg 0)
2425 (! recover-values))
2426 (unless (or mv-p simple-case)
2427 (! vstack-discard 1)))
2428 (x862-set-vstack vstack)
2429 (setq *x862-top-vstack-lcell* top)
2430 (setq *x862-cstack* cstack)
2431 (when (or (logbitp $backend-mvpass-bit xfer) (not mv-p))
2432 (<- x8664::arg_z)
2433 (x862-branch seg (logand (lognot $backend-mvpass-mask) xfer)))))
2434 nil)))
2435
2436(defun x862-restore-full-lisp-context (seg)
2437 (with-x86-local-vinsn-macros (seg)
2438 (! restore-full-lisp-context)))
2439
2440(defun x862-emit-aligned-label (seg labelnum)
2441 (with-x86-local-vinsn-macros (seg)
2442 (! emit-aligned-label (aref *backend-labels* labelnum))
2443 (@ labelnum)
2444 (! recover-fn-from-rip)))
2445
2446
2447(defun x862-call-symbol (seg jump-p)
2448 (with-x86-local-vinsn-macros (seg)
2449 (if jump-p
2450 (! jump-known-symbol)
2451 (! call-known-symbol x8664::arg_z))))
2452
2453;;; Nargs = nil -> multiple-value case.
2454(defun x862-invoke-fn (seg fn nargs spread-p xfer &optional mvpass-label)
2455 (with-x86-local-vinsn-macros (seg)
2456 (let* ((f-op (acode-unwrapped-form fn))
2457 (immp (and (consp f-op)
2458 (eq (%car f-op) (%nx1-operator immediate))))
2459 (symp (and immp (symbolp (%cadr f-op))))
2460 (label-p (and (fixnump fn)
2461 (locally (declare (fixnum fn))
2462 (and (= fn -2) (- fn)))))
2463 (tail-p (eq xfer $backend-return))
2464 (func (if (consp f-op) (%cadr f-op)))
2465 (a-reg nil)
2466 (lfunp (and (acode-p f-op)
2467 (eq (acode-operator f-op) (%nx1-operator simple-function))))
2468 (expression-p (or (typep fn 'lreg) (and (fixnump fn) (not label-p))))
2469 (callable (or symp lfunp label-p))
2470 (destreg (if symp ($ x8664::fname) (unless label-p ($ x8664::temp0))))
2471 (alternate-tail-call
2472 (and tail-p label-p *x862-tail-label* (eql nargs *x862-tail-nargs*) (not spread-p))))
2473 (when expression-p
2474 ;;Have to do this before spread args, since might be vsp-relative.
2475 (if nargs
2476 (x862-do-lexical-reference seg destreg fn)
2477 (x862-copy-register seg destreg fn)))
2478 (if (or symp lfunp)
2479 (setq func (if symp
2480 (x862-symbol-entry-locative func)
2481 (x862-afunc-lfun-ref func))
2482 a-reg (x862-register-constant-p func)))
2483 (when tail-p
2484 #-no-compiler-bugs
2485 (unless (or immp symp lfunp (typep fn 'lreg) (fixnump fn)) (error "Well, well, well. How could this have happened ?"))
2486 (when a-reg
2487 (x862-copy-register seg destreg a-reg))
2488 (unless spread-p
2489 (unless alternate-tail-call
2490 (x862-restore-nvrs seg *x862-register-restore-ea* *x862-register-restore-count* (and nargs (<= nargs *x862-target-num-arg-regs*))))))
2491 (if spread-p
2492 (progn
2493 (x862-set-nargs seg (%i- nargs 1))
2494 ; .SPspread-lexpr-z & .SPspreadargz preserve temp1
2495 (if (eq spread-p 0)
2496 (! spread-lexpr)
2497 (! spread-list))
2498 (when (and tail-p *x862-register-restore-count*)
2499 (x862-restore-nvrs seg *x862-register-restore-ea* *x862-register-restore-count* nil)))
2500 (if nargs
2501 (unless alternate-tail-call (x862-set-nargs seg nargs))
2502 (! pop-argument-registers)))
2503 (if callable
2504 (if (not tail-p)
2505 (if (x862-mvpass-p xfer)
2506 (let* ((call-reg (if symp ($ x8664::fname) ($ x8664::temp0))))
2507 (unless mvpass-label (error "bug: no label for mvpass"))
2508 (if label-p
2509 (x862-copy-register seg call-reg ($ x8664::fn))
2510 (if a-reg
2511 (x862-copy-register seg call-reg a-reg)
2512 (x862-store-immediate seg func call-reg)))
2513 (if symp
2514 (! pass-multiple-values-symbol)
2515 (! pass-multiple-values))
2516 (when mvpass-label
2517 (@= mvpass-label)))
2518 (progn
2519 (if label-p
2520 (progn
2521 (! call-label (aref *backend-labels* 2)))
2522 (progn
2523 (if a-reg
2524 (x862-copy-register seg destreg a-reg)
2525 (x862-store-immediate seg func destreg))
2526 (if symp
2527 (x862-call-symbol seg nil)
2528 (! call-known-function))))))
2529 (if alternate-tail-call
2530 (progn
2531 (x862-unwind-stack seg xfer 0 0 *x862-tail-vsp*)
2532 (! jump (aref *backend-labels* *x862-tail-label*)))
2533 (progn
2534 (x862-unwind-stack seg xfer 0 0 #x7fffff)
2535 (if (and (not spread-p) nargs (%i<= nargs *x862-target-num-arg-regs*))
2536 (progn
2537 (unless (or label-p a-reg) (x862-store-immediate seg func destreg))
2538 (x862-restore-full-lisp-context seg)
2539 (if label-p
2540 (! jump (aref *backend-labels* 1))
2541 (progn
2542 (if symp
2543 (x862-call-symbol seg t)
2544 (! jump-known-function)))))
2545 (progn
2546 (unless (or label-p a-reg) (x862-store-immediate seg func destreg))
2547 (when label-p
2548 (x862-copy-register seg x8664::temp0 x8664::fn))
2549
2550 (cond ((or spread-p (null nargs))
2551 (if symp
2552 (! tail-call-sym-gen)
2553 (! tail-call-fn-gen)))
2554 ((%i> nargs *x862-target-num-arg-regs*)
2555 (if symp
2556 (! tail-call-sym-slide)
2557 (! tail-call-fn-slide)))
2558 (t
2559 (if symp
2560 (! tail-call-sym-vsp)
2561 (! tail-call-fn-vsp)))))))))
2562 ;; The general (funcall) case: we don't know (at compile-time)
2563 ;; for sure whether we've got a symbol or a (local, constant)
2564 ;; function.
2565 (progn
2566 (unless (or (fixnump fn) (typep fn 'lreg))
2567 (x862-one-targeted-reg-form seg fn destreg))
2568 (if (not tail-p)
2569 (if (x862-mvpass-p xfer)
2570 (progn (! pass-multiple-values)
2571 (when mvpass-label
2572 (@= mvpass-label)))
2573 (! funcall))
2574 (cond ((or (null nargs) spread-p)
2575 (! tail-funcall-gen))
2576 ((%i> nargs *x862-target-num-arg-regs*)
2577 (! tail-funcall-slide))
2578 (t
2579 (! restore-full-lisp-context)
2580 (! tail-funcall)))))))
2581 nil))
2582
2583(defun x862-seq-fbind (seg vreg xfer vars afuncs body p2decls)
2584 (let* ((old-stack (x862-encode-stack))
2585 (copy afuncs)
2586 (func nil))
2587 (with-x86-p2-declarations p2decls
2588 (dolist (var vars)
2589 (when (neq 0 (afunc-fn-refcount (setq func (pop afuncs))))
2590 (x862-seq-bind-var seg var (nx1-afunc-ref func))))
2591 (x862-undo-body seg vreg xfer body old-stack)
2592 (dolist (var vars)
2593 (when (neq 0 (afunc-fn-refcount (setq func (pop copy))))
2594 (x862-close-var seg var))))))
2595
2596(defun x862-make-closure (seg afunc downward-p)
2597 (with-x86-local-vinsn-macros (seg)
2598 (flet ((var-to-reg (var target)
2599 (let* ((ea (var-ea (var-bits var))))
2600 (if ea
2601 (x862-addrspec-to-reg seg (x862-ea-open ea) target)
2602 (! load-nil target))
2603 target))
2604 (set-some-cells (dest cellno c0 c1 c2 c3)
2605 (declare (fixnum cellno))
2606 (! misc-set-c-node c0 dest cellno)
2607 (incf cellno)
2608 (when c1
2609 (! misc-set-c-node c1 dest cellno)
2610 (incf cellno)
2611 (when c2
2612 (! misc-set-c-node c2 dest cellno)
2613 (incf cellno)
2614 (when c3
2615 (! misc-set-c-node c3 dest cellno)
2616 (incf cellno))))
2617 cellno))
2618 (let* ((inherited-vars (afunc-inherited-vars afunc))
2619 (arch (backend-target-arch *target-backend*))
2620 (dest ($ x8664::arg_z))
2621 (vsize (+ (length inherited-vars)
2622 5 ; %closure-code%, afunc
2623 1))) ; lfun-bits
2624 (declare (list inherited-vars))
2625 (let* ((cell 4))
2626 (declare (fixnum cell))
2627 (if downward-p
2628 (progn
2629 (! make-fixed-stack-gvector
2630 dest
2631 (ash (logandc2 (+ vsize 2) 1) (arch::target-word-shift arch))
2632 (arch::make-vheader vsize (nx-lookup-target-uvector-subtag :function)))
2633 (x862-open-undo $undostkblk))
2634 (progn
2635 (x862-lri seg
2636 x8664::imm0
2637 (arch::make-vheader vsize (nx-lookup-target-uvector-subtag :function)))
2638 (x862-lri seg x8664::imm1 (- (ash (logandc2 (+ vsize 2) 1) (arch::target-word-shift arch)) (target-arch-case (:x8664 x8664::fulltag-misc))))
2639 (! %allocate-uvector dest)))
2640 (! init-nclosure x8664::arg_z)
2641 (x862-store-immediate seg (x862-afunc-lfun-ref afunc) x8664::ra0)
2642 (with-node-temps (x8664::arg_z) (t0 t1 t2 t3)
2643 (do* ((func x8664::ra0 nil))
2644 ((null inherited-vars))
2645 (let* ((t0r (or func (if inherited-vars (var-to-reg (pop inherited-vars) t0))))
2646 (t1r (if inherited-vars (var-to-reg (pop inherited-vars) t1)))
2647 (t2r (if inherited-vars (var-to-reg (pop inherited-vars) t2)))
2648 (t3r (if inherited-vars (var-to-reg (pop inherited-vars) t3))))
2649 (setq cell (set-some-cells dest cell t0r t1r t2r t3r)))))
2650 (x862-lri seg x8664::arg_y (ash (logior (ash 1 $lfbits-noname-bit) (ash 1 $lfbits-trampoline-bit)) *x862-target-fixnum-shift*))
2651 (! misc-set-c-node x8664::arg_y dest cell))
2652 (! finalize-closure dest)
2653 dest))))
2654
2655(defun x862-symbol-entry-locative (sym)
2656 (setq sym (require-type sym 'symbol))
2657 (when (eq sym '%call-next-method-with-args)
2658 (setf (afunc-bits *x862-cur-afunc*)
2659 (%ilogior (%ilsl $fbitnextmethargsp 1) (afunc-bits *x862-cur-afunc*))))
2660 (or (assq sym *x862-fcells*)
2661 (let ((new (list sym)))
2662 (push new *x862-fcells*)
2663 new)))
2664
2665(defun x862-symbol-value-cell (sym)
2666 (setq sym (require-type sym 'symbol))
2667 (or (assq sym *x862-vcells*)
2668 (let ((new (list sym)))
2669 (push new *x862-vcells*)
2670 (ensure-binding-index sym)
2671 new)))
2672
2673
2674(defun x862-symbol-locative-p (imm)
2675 (and (consp imm)
2676 (or (memq imm *x862-vcells*)
2677 (memq imm *x862-fcells*))))
2678
2679
2680
2681
2682(defun x862-immediate-function-p (f)
2683 (setq f (acode-unwrapped-form f))
2684 (and (acode-p f)
2685 (or (eq (%car f) (%nx1-operator immediate))
2686 (eq (%car f) (%nx1-operator simple-function)))))
2687
2688(defun x86-constant-form-p (form)
2689 (setq form (nx-untyped-form form))
2690 (if form
2691 (or (nx-null form)
2692 (nx-t form)
2693 (and (consp form)
2694 (or (eq (acode-operator form) (%nx1-operator immediate))
2695 (eq (acode-operator form) (%nx1-operator fixnum))
2696 (eq (acode-operator form) (%nx1-operator simple-function)))))))
2697
2698
2699
2700(defun x862-long-constant-p (form)
2701 (setq form (acode-unwrapped-form form))
2702 (or (acode-fixnum-form-p form)
2703 (and (acode-p form)
2704 (eq (acode-operator form) (%nx1-operator immediate))
2705 (setq form (%cadr form))
2706 (if (integerp form)
2707 form))))
2708
2709
2710(defun x86-side-effect-free-form-p (form)
2711 (when (consp (setq form (acode-unwrapped-form form)))
2712 (or (x86-constant-form-p form)
2713 ;(eq (acode-operator form) (%nx1-operator bound-special-ref))
2714 (if (eq (acode-operator form) (%nx1-operator lexical-reference))
2715 (not (%ilogbitp $vbitsetq (nx-var-bits (%cadr form))))))))
2716
2717(defun x862-formlist (seg stkargs &optional revregargs)
2718 (with-x86-local-vinsn-macros (seg)
2719 (let* ((nregs (length revregargs))
2720 (n nregs))
2721 (declare (fixnum n))
2722 (dolist (arg stkargs)
2723 (let* ((pushform (x862-acode-operator-supports-push arg)))
2724 (if pushform
2725 (progn
2726 (x862-form seg :push nil pushform)
2727 (x862-new-vstack-lcell :outgoing-argument *x862-target-lcell-size* 0 nil)
2728 (x862-adjust-vstack *x862-target-node-size*))
2729
2730 (let* ((reg (x862-one-untargeted-reg-form seg arg x8664::arg_z)))
2731 (x862-vpush-register-arg seg reg)))
2732 (incf n)))
2733 (when revregargs
2734 (let* ((zform (%car revregargs))
2735 (yform (%cadr revregargs))
2736 (xform (%caddr revregargs)))
2737 (if (eq 3 nregs)
2738 (x862-three-targeted-reg-forms seg xform ($ x8664::arg_x) yform ($ x8664::arg_y) zform ($ x8664::arg_z))
2739 (if (eq 2 nregs)
2740 (x862-two-targeted-reg-forms seg yform ($ x8664::arg_y) zform ($ x8664::arg_z))
2741 (x862-one-targeted-reg-form seg zform ($ x8664::arg_z))))))
2742 n)))
2743
2744(defun x862-arglist (seg args &optional mv-label)
2745 (with-x86-local-vinsn-macros (seg)
2746 (when mv-label
2747 (x862-vpush-label seg (aref *backend-labels* mv-label)))
2748 (when (car args)
2749 (! reserve-outgoing-frame)
2750 (x862-new-vstack-lcell :reserverd *x862-target-lcell-size* 0 nil)
2751 (x862-new-vstack-lcell :reserverd *x862-target-lcell-size* 0 nil)
2752 (setq *x862-vstack* (+ *x862-vstack* (* 2 *x862-target-node-size*))))
2753 (x862-formlist seg (car args) (cadr args))))
2754
2755
2756
2757
2758;;; treat form as a 32-bit immediate value and load it into immreg.
2759;;; This is the "lenient" version of 32-bit-ness; OSTYPEs and chars
2760;;; count, and we don't care about the integer's sign.
2761
2762(defun x862-unboxed-integer-arg-to-reg (seg form immreg &optional ffi-arg-type)
2763 (let* ((mode (ecase ffi-arg-type
2764 ((nil) :natural)
2765 (:signed-byte :s8)
2766 (:unsigned-byte :u8)
2767 (:signed-halfword :s16)
2768 (:unsigned-halfword :u16)
2769 (:signed-fullword :s32)
2770 (:unsigned-fullword :u32)
2771 (:unsigned-doubleword :u64)
2772 (:signed-doubleword :s64)))
2773 (modeval (gpr-mode-name-value mode)))
2774 (with-x86-local-vinsn-macros (seg)
2775 (let* ((value (x862-long-constant-p form)))
2776 (if value
2777 (progn
2778 (unless (typep immreg 'lreg)
2779 (setq immreg (make-unwired-lreg immreg :mode modeval)))
2780 (x862-lri seg immreg value)
2781 immreg)
2782 (progn
2783 (x862-one-targeted-reg-form seg form (make-wired-lreg x8664::imm0 :mode modeval))))))))
2784
2785
2786(defun x862-macptr-arg-to-reg (seg form address-reg)
2787 (x862-one-targeted-reg-form seg
2788 form
2789 address-reg))
2790
2791
2792(defun x862-one-lreg-form (seg form lreg)
2793 (let ((is-float (= (hard-regspec-class lreg) hard-reg-class-fpr)))
2794 (if is-float
2795 (x862-form-float seg lreg nil form)
2796 (x862-form seg lreg nil form))
2797 lreg))
2798
2799(defun x862-one-targeted-reg-form (seg form reg)
2800 (x862-one-lreg-form seg form reg))
2801
2802(defun x862-one-untargeted-lreg-form (seg form reg)
2803 (x862-one-lreg-form seg form (if (typep reg 'lreg) reg (make-unwired-lreg reg))))
2804
2805(defun x862-one-untargeted-reg-form (seg form suggested)
2806 (with-x86-local-vinsn-macros (seg)
2807 (let* ((gpr-p (= (hard-regspec-class suggested) hard-reg-class-gpr))
2808 (node-p (if gpr-p (= (get-regspec-mode suggested) hard-reg-class-gpr-mode-node))))
2809 (if node-p
2810 (let* ((ref (x862-lexical-reference-ea form))
2811 (reg (backend-ea-physical-reg ref hard-reg-class-gpr)))
2812 (if reg
2813 ref
2814 (if (nx-null form)
2815 (progn
2816 (! load-nil suggested)
2817 suggested)
2818 (if (and (acode-p form)
2819 (eq (acode-operator form) (%nx1-operator immediate))
2820 (setq reg (x862-register-constant-p (cadr form))))
2821 reg
2822 (x862-one-untargeted-lreg-form seg form suggested)))))
2823 (x862-one-untargeted-lreg-form seg form suggested)))))
2824
2825
2826(defun x862-push-register (seg areg)
2827 (let* ((a-float (= (hard-regspec-class areg) hard-reg-class-fpr))
2828 (a-single (if a-float (= (get-regspec-mode areg) hard-reg-class-fpr-mode-single)))
2829 (a-node (unless a-float (= (get-regspec-mode areg) hard-reg-class-gpr-mode-node)))
2830 vinsn)
2831 (with-x86-local-vinsn-macros (seg)
2832 (if a-node
2833 (setq vinsn (x862-vpush-register seg areg :node-temp))
2834 (if a-single
2835 (progn
2836 (setq vinsn (! vpush-single-float areg))
2837 (x862-new-vstack-lcell :single-float *x862-target-lcell-size* 0 nil)
2838 (x862-adjust-vstack *x862-target-node-size*))
2839 (progn
2840 (setq vinsn
2841 (if a-float
2842 (! temp-push-double-float areg)
2843 (! temp-push-unboxed-word areg)))
2844 (setq *x862-cstack* (+ *x862-cstack* 16)))))
2845 vinsn)))
2846
2847(defun x862-pop-register (seg areg)
2848 (let* ((a-float (= (hard-regspec-class areg) hard-reg-class-fpr))
2849 (a-single (if a-float (= (get-regspec-mode areg) hard-reg-class-fpr-mode-single)))
2850 (a-node (unless a-float (= (get-regspec-mode areg) hard-reg-class-gpr-mode-node)))
2851 vinsn)
2852 (with-x86-local-vinsn-macros (seg)
2853 (if a-node
2854 (setq vinsn (x862-vpop-register seg areg))
2855 (if a-single
2856 (progn
2857 (setq vinsn (! vpop-single-float areg))
2858 (setq *x862-top-vstack-lcell* (lcell-parent *x862-top-vstack-lcell*))
2859 (x862-adjust-vstack (- *x862-target-node-size*)))
2860 (progn
2861 (setq vinsn
2862 (if a-float
2863 (! temp-pop-double-float areg)
2864 (! temp-pop-unboxed-word areg)))
2865 (setq *x862-cstack* (- *x862-cstack* 16)))))
2866 vinsn)))
2867
2868(defun x862-acc-reg-for (reg)
2869 (with-x86-local-vinsn-macros (seg)
2870 (let* ((class (hard-regspec-class reg))
2871 (mode (get-regspec-mode reg)))
2872 (declare (fixnum class mode))
2873 (cond ((= class hard-reg-class-fpr)
2874 (make-wired-lreg x8664::fp1 :class class :mode mode))
2875 ((= class hard-reg-class-gpr)
2876 (if (= mode hard-reg-class-gpr-mode-node)
2877 ($ x8664::arg_z)
2878 (make-wired-lreg x8664::imm0 :mode mode)))
2879 (t (error "Unknown register class for reg ~s" reg))))))
2880
2881;;; The compiler often generates superfluous pushes & pops. Try to
2882;;; eliminate them.
2883(defun x862-elide-pushes (seg push-vinsn pop-vinsn)
2884 (with-x86-local-vinsn-macros (seg)
2885 (let* ((pushed-reg (svref (vinsn-variable-parts push-vinsn) 0))
2886 (popped-reg (svref (vinsn-variable-parts pop-vinsn) 0))
2887 (same-reg (eq (hard-regspec-value pushed-reg)
2888 (hard-regspec-value popped-reg)))
2889 (csp-p (vinsn-attribute-p push-vinsn :csp)))
2890 (when csp-p ; vsp case is harder.
2891 (let* ((pushed-reg-is-set (vinsn-sequence-sets-reg-p
2892 push-vinsn pop-vinsn pushed-reg))
2893 (popped-reg-is-set (if same-reg
2894 pushed-reg-is-set
2895 (vinsn-sequence-sets-reg-p
2896 push-vinsn pop-vinsn popped-reg))))
2897 (unless (and pushed-reg-is-set popped-reg-is-set)
2898 (unless same-reg
2899 (let* ((copy (if (eq (hard-regspec-class pushed-reg)
2900 hard-reg-class-fpr)
2901 (if (= (get-regspec-mode pushed-reg)
2902 hard-reg-class-fpr-mode-double)
2903 (! copy-double-float popped-reg pushed-reg)
2904 (! copy-single-float popped-reg pushed-reg))
2905 (! copy-gpr popped-reg pushed-reg))))
2906 (remove-dll-node copy)
2907 (if pushed-reg-is-set
2908 (insert-dll-node-after copy push-vinsn)
2909 (insert-dll-node-before copy push-vinsn))))
2910 (elide-vinsn push-vinsn)
2911 (elide-vinsn pop-vinsn)))))))
2912
2913
2914;;; we never leave the first form pushed (the 68K compiler had some subprims that
2915;;; would vpop the first argument out of line.)
2916(defun x862-two-targeted-reg-forms (seg aform areg bform breg)
2917 (unless (typep areg 'lreg)
2918 (warn "~s is not an lreg (1/2)" areg))
2919 (unless (typep breg 'lreg)
2920 (warn "~s is not an lreg (2/2)" breg))
2921 (let* ((avar (x862-lexical-reference-p aform))
2922 (atriv (x862-trivial-p bform))
2923 (aconst (and (not atriv) (or (x86-side-effect-free-form-p aform)
2924 (if avar (x862-var-not-set-by-form-p avar bform)))))
2925 apushed)
2926 (progn
2927 (unless aconst
2928 (if atriv
2929 (x862-one-targeted-reg-form seg aform areg)
2930 (setq apushed (x862-push-register seg (x862-one-untargeted-reg-form seg aform (x862-acc-reg-for areg))))))
2931 (x862-one-targeted-reg-form seg bform breg)
2932 (if aconst
2933 (x862-one-targeted-reg-form seg aform areg)
2934 (if apushed
2935 (x862-elide-pushes seg apushed (x862-pop-register seg areg)))))
2936 (values areg breg)))
2937
2938
2939(defun x862-two-untargeted-reg-forms (seg aform areg bform breg)
2940 (with-x86-local-vinsn-macros (seg)
2941 (let* ((avar (x862-lexical-reference-p aform))
2942 (adest areg)
2943 (bdest breg)
2944 (atriv (x862-trivial-p bform))
2945 (aconst (and (not atriv) (or (x86-side-effect-free-form-p aform)
2946 (if avar (x862-var-not-set-by-form-p avar bform)))))
2947 (apushed (not (or atriv aconst))))
2948 (progn
2949 (unless aconst
2950 (if atriv
2951 (setq adest (x862-one-untargeted-reg-form seg aform areg))
2952 (setq apushed (x862-push-register seg (x862-one-untargeted-reg-form seg aform (x862-acc-reg-for areg))))))
2953 (setq bdest (x862-one-untargeted-reg-form seg bform breg))
2954 (if aconst
2955 (setq adest (x862-one-untargeted-reg-form seg aform areg))
2956 (if apushed
2957 (x862-elide-pushes seg apushed (x862-pop-register seg areg)))))
2958 (values adest bdest))))
2959
2960
2961(defun x862-three-targeted-reg-forms (seg aform areg bform breg cform creg)
2962 (unless (typep areg 'lreg)
2963 (warn "~s is not an lreg (1/3)" areg))
2964 (unless (typep breg 'lreg)
2965 (warn "~s is not an lreg (2/3)" breg))
2966 (unless (typep creg 'lreg)
2967 (warn "~s is not an lreg (3/3)" creg))
2968 (let* ((atriv (or (null aform)
2969 (and (x862-trivial-p bform)
2970 (x862-trivial-p cform))))
2971 (btriv (or (null bform)
2972 (x862-trivial-p cform)))
2973 (aconst (and (not atriv)
2974 (or (x86-side-effect-free-form-p aform)
2975 (let ((avar (x862-lexical-reference-p aform)))
2976 (and avar
2977 (x862-var-not-set-by-form-p avar bform)
2978 (x862-var-not-set-by-form-p avar cform))))))
2979 (bconst (and (not btriv)
2980 (or
2981 (x86-side-effect-free-form-p bform)
2982 (let ((bvar (x862-lexical-reference-p bform)))
2983 (and bvar (x862-var-not-set-by-form-p bvar cform))))))
2984 (apushed nil)
2985 (bpushed nil))
2986 (if (and aform (not aconst))
2987 (if atriv
2988 (x862-one-targeted-reg-form seg aform areg)
2989 (setq apushed (x862-push-register seg (x862-one-untargeted-reg-form seg aform (x862-acc-reg-for areg))))))
2990 (if (and bform (not bconst))
2991 (if btriv
2992 (x862-one-targeted-reg-form seg bform breg)
2993 (setq bpushed (x862-push-register seg (x862-one-untargeted-reg-form seg bform (x862-acc-reg-for breg))))))
2994 (x862-one-targeted-reg-form seg cform creg)
2995 (unless btriv
2996 (if bconst
2997 (x862-one-targeted-reg-form seg bform breg)
2998 (x862-elide-pushes seg bpushed (x862-pop-register seg breg))))
2999 (unless atriv
3000 (if aconst
3001 (x862-one-targeted-reg-form seg aform areg)
3002 (x862-elide-pushes seg apushed (x862-pop-register seg areg))))
3003 (values areg breg creg)))
3004
3005(defun x862-four-targeted-reg-forms (seg aform areg bform breg cform creg dform dreg)
3006 (unless (typep areg 'lreg)
3007 (warn "~s is not an lreg (1/4)" areg))
3008 (unless (typep breg 'lreg)
3009 (warn "~s is not an lreg (2/4)" breg))
3010 (unless (typep creg 'lreg)
3011 (warn "~s is not an lreg (3/4)" creg))
3012 (unless (typep dreg 'lreg)
3013 (warn "~s is not an lreg (4/4)" dreg))
3014 (let* ((atriv (or (null aform)
3015 (and (x862-trivial-p bform)
3016 (x862-trivial-p cform)
3017 (x862-trivial-p dform))))
3018 (btriv (or (null bform)
3019 (and (x862-trivial-p cform)
3020 (x862-trivial-p dform))))
3021 (ctriv (or (null cform)
3022 (x862-trivial-p dform)))
3023 (aconst (and (not atriv)
3024 (or (x86-side-effect-free-form-p aform)
3025 (let ((avar (x862-lexical-reference-p aform)))
3026 (and avar
3027 (x862-var-not-set-by-form-p avar bform)
3028 (x862-var-not-set-by-form-p avar cform)
3029 (x862-var-not-set-by-form-p avar dform))))))
3030 (bconst (and (not btriv)
3031 (or
3032 (x86-side-effect-free-form-p bform)
3033 (let ((bvar (x862-lexical-reference-p bform)))
3034 (and bvar
3035 (x862-var-not-set-by-form-p bvar cform)
3036 (x862-var-not-set-by-form-p bvar dform))))))
3037 (cconst (and (not ctriv)
3038 (or
3039 (x86-side-effect-free-form-p cform)
3040 (let ((cvar (x862-lexical-reference-p cform)))
3041 (and cvar (x862-var-not-set-by-form-p cvar dform))))))
3042 (apushed nil)
3043 (bpushed nil)
3044 (cpushed nil))
3045 (if (and aform (not aconst))
3046 (if atriv
3047 (x862-one-targeted-reg-form seg aform areg)
3048 (setq apushed (x862-push-register seg (x862-one-untargeted-reg-form seg aform (x862-acc-reg-for areg))))))
3049 (if (and bform (not bconst))
3050 (if btriv
3051 (x862-one-targeted-reg-form seg bform breg)
3052 (setq bpushed (x862-push-register seg (x862-one-untargeted-reg-form seg bform (x862-acc-reg-for breg))))))
3053 (if (and cform (not cconst))
3054 (if ctriv
3055 (x862-one-targeted-reg-form seg cform creg)
3056 (setq cpushed (x862-push-register seg (x862-one-untargeted-reg-form seg cform (x862-acc-reg-for creg))))))
3057 (x862-one-targeted-reg-form seg dform dreg)
3058 (unless ctriv
3059 (if cconst
3060 (x862-one-targeted-reg-form seg cform creg)
3061 (x862-elide-pushes seg cpushed (x862-pop-register seg creg))))
3062 (unless btriv
3063 (if bconst
3064 (x862-one-targeted-reg-form seg bform breg)
3065 (x862-elide-pushes seg bpushed (x862-pop-register seg breg))))
3066 (unless atriv
3067 (if aconst
3068 (x862-one-targeted-reg-form seg aform areg)
3069 (x862-elide-pushes seg apushed (x862-pop-register seg areg))))
3070 (values areg breg creg)))
3071
3072(defun x862-three-untargeted-reg-forms (seg aform areg bform breg cform creg)
3073 (with-x86-local-vinsn-macros (seg)
3074 (let* ((atriv (or (null aform)
3075 (and (x862-trivial-p bform)
3076 (x862-trivial-p cform))))
3077 (btriv (or (null bform)
3078 (x862-trivial-p cform)))
3079 (aconst (and (not atriv)
3080 (or (x86-side-effect-free-form-p aform)
3081 (let ((avar (x862-lexical-reference-p aform)))
3082 (and avar
3083 (x862-var-not-set-by-form-p avar bform)
3084 (x862-var-not-set-by-form-p avar cform))))))
3085 (bconst (and (not btriv)
3086 (or
3087 (x86-side-effect-free-form-p bform)
3088 (let ((bvar (x862-lexical-reference-p bform)))
3089 (and bvar (x862-var-not-set-by-form-p bvar cform))))))
3090 (adest areg)
3091 (bdest breg)
3092 (cdest creg)
3093 (apushed nil)
3094 (bpushed nil))
3095 (if (and aform (not aconst))
3096 (if atriv
3097 (setq adest (x862-one-untargeted-reg-form seg aform ($ areg)))
3098 (setq apushed (x862-push-register seg (x862-one-untargeted-reg-form seg aform (x862-acc-reg-for areg))))))
3099 (if (and bform (not bconst))
3100 (if btriv
3101 (setq bdest (x862-one-untargeted-reg-form seg bform ($ breg)))
3102 (setq bpushed (x862-push-register seg (x862-one-untargeted-reg-form seg bform (x862-acc-reg-for breg))))))
3103 (setq cdest (x862-one-untargeted-reg-form seg cform creg))
3104 (unless btriv
3105 (if bconst
3106 (setq bdest (x862-one-untargeted-reg-form seg bform breg))
3107 (x862-elide-pushes seg bpushed (x862-pop-register seg breg))))
3108 (unless atriv
3109 (if aconst
3110 (setq adest (x862-one-untargeted-reg-form seg aform areg))
3111 (x862-elide-pushes seg apushed (x862-pop-register seg areg))))
3112 (values adest bdest cdest))))
3113
3114(defun x862-four-untargeted-reg-forms (seg aform areg bform breg cform creg dform dreg)
3115 (let* ((atriv (or (null aform)
3116 (and (x862-trivial-p bform)
3117 (x862-trivial-p cform)
3118 (x862-trivial-p dform))))
3119 (btriv (or (null bform)
3120 (and (x862-trivial-p cform)
3121 (x862-trivial-p dform))))
3122 (ctriv (or (null cform)
3123 (x862-trivial-p dform)))
3124 (aconst (and (not atriv)
3125 (or (x86-side-effect-free-form-p aform)
3126 (let ((avar (x862-lexical-reference-p aform)))
3127 (and avar
3128 (x862-var-not-set-by-form-p avar bform)
3129 (x862-var-not-set-by-form-p avar cform)
3130 (x862-var-not-set-by-form-p avar dform))))))
3131 (bconst (and (not btriv)
3132 (or
3133 (x86-side-effect-free-form-p bform)
3134 (let ((bvar (x862-lexical-reference-p bform)))
3135 (and bvar
3136 (x862-var-not-set-by-form-p bvar cform)
3137 (x862-var-not-set-by-form-p bvar dform))))))
3138 (cconst (and (not ctriv)
3139 (or
3140 (x86-side-effect-free-form-p cform)
3141 (let ((cvar (x862-lexical-reference-p cform)))
3142 (and cvar
3143 (x862-var-not-set-by-form-p cvar dform))))))
3144 (adest areg)
3145 (bdest breg)
3146 (cdest creg)
3147 (ddest dreg)
3148 (apushed nil)
3149 (bpushed nil)
3150 (cpushed nil))
3151 (if (and aform (not aconst))
3152 (if atriv
3153 (setq adest (x862-one-targeted-reg-form seg aform areg))
3154 (setq apushed (x862-push-register seg (x862-one-untargeted-reg-form seg aform (x862-acc-reg-for areg))))))
3155 (if (and bform (not bconst))
3156 (if btriv
3157 (setq bdest (x862-one-untargeted-reg-form seg bform breg))
3158 (setq bpushed (x862-push-register seg (x862-one-untargeted-reg-form seg bform (x862-acc-reg-for breg))))))
3159 (if (and cform (not cconst))
3160 (if ctriv
3161 (setq cdest (x862-one-untargeted-reg-form seg cform creg))
3162 (setq cpushed (x862-push-register seg (x862-one-untargeted-reg-form seg cform (x862-acc-reg-for creg))))))
3163 (setq ddest (x862-one-untargeted-reg-form seg dform dreg))
3164 (unless ctriv
3165 (if cconst
3166 (setq cdest (x862-one-untargeted-reg-form seg cform creg))
3167 (x862-elide-pushes seg cpushed (x862-pop-register seg creg))))
3168 (unless btriv
3169 (if bconst
3170 (setq bdest (x862-one-untargeted-reg-form seg bform breg))
3171 (x862-elide-pushes seg bpushed (x862-pop-register seg breg))))
3172 (unless atriv
3173 (if aconst
3174 (setq adest (x862-one-untargeted-reg-form seg aform areg))
3175 (x862-elide-pushes seg apushed (x862-pop-register seg areg))))
3176 (values adest bdest cdest ddest)))
3177
3178(defun x862-lri (seg reg value)
3179 (with-x86-local-vinsn-macros (seg)
3180 (! lri reg value)))
3181
3182
3183(defun x862-multiple-value-body (seg form)
3184 (let* ((lab (backend-get-next-label))
3185 (*x862-vstack* *x862-vstack*)
3186 (*x862-top-vstack-lcell* *x862-top-vstack-lcell*)
3187 (old-stack (x862-encode-stack)))
3188 (with-x86-local-vinsn-macros (seg)
3189 (x862-open-undo $undomvexpect)
3190 (x862-undo-body seg nil (logior $backend-mvpass-mask lab) form old-stack)
3191 (@ lab))))
3192
3193(defun x862-afunc-lfun-ref (afunc)
3194 (or
3195 (afunc-lfun afunc)
3196 (progn (pushnew afunc (afunc-fwd-refs *x862-cur-afunc*) :test #'eq)
3197 afunc)))
3198
3199(defun x862-augment-arglist (afunc arglist &optional (maxregs *x862-target-num-arg-regs*))
3200 (let ((inherited-args (afunc-inherited-vars afunc)))
3201 (when inherited-args
3202 (let* ((current-afunc *x862-cur-afunc*)
3203 (stkargs (car arglist))
3204 (regargs (cadr arglist))
3205 (inhforms nil)
3206 (numregs (length regargs))
3207 (own-inhvars (afunc-inherited-vars current-afunc)))
3208 (dolist (var inherited-args)
3209 (let* ((root-var (nx-root-var var))
3210 (other-guy
3211 (dolist (v own-inhvars #|(error "other guy not found")|# root-var)
3212 (when (eq root-var (nx-root-var v)) (return v)))))
3213 (push (make-acode (%nx1-operator inherited-arg) other-guy) inhforms)))
3214 (dolist (form inhforms)
3215 (if (%i< numregs maxregs)
3216 (progn
3217 (setq regargs (nconc regargs (list form)))
3218 (setq numregs (%i+ numregs 1)))
3219 (push form stkargs)))
3220 (%rplaca (%cdr arglist) regargs) ; might have started out NIL.
3221 (%rplaca arglist stkargs))))
3222 arglist)
3223
3224(defun x862-acode-operator-supports-u8 (form)
3225 (setq form (acode-unwrapped-form form))
3226 (when (acode-p form)
3227 (let* ((operator (acode-operator form)))
3228 (if (member operator *x862-operator-supports-u8-target*)
3229 (values operator (acode-operand 1 form))))))
3230
3231(defun x862-acode-operator-supports-push (form)
3232 (setq form (acode-unwrapped-form form))
3233 (when (acode-p form)
3234 (if (or (eq form *nx-t*)
3235 (eq form *nx-nil*)
3236 (let* ((operator (acode-operator form)))
3237 (member operator *x862-operator-supports-push*)))
3238 form)))
3239
3240(defun x862-compare-u8 (seg vreg xfer form u8constant cr-bit true-p u8-operator)
3241 (with-x86-local-vinsn-macros (seg vreg xfer)
3242 (with-imm-target () (u8 :u8)
3243 (if (and (eql u8-operator (%nx1-operator lisptag))
3244 (eql 0 u8constant))
3245 (let* ((formreg (x862-one-untargeted-reg-form seg form x8664::arg_z)))
3246
3247 (! set-flags-from-lisptag formreg))
3248 (progn
3249 (x862-use-operator u8-operator seg u8 nil form)
3250 (if (zerop u8constant)
3251 (! compare-u8-reg-to-zero u8)
3252 (! compare-u8-constant u8 u8constant))))
3253 ;; Flags set. Branch or return a boolean value ?
3254 (setq cr-bit (x862-cr-bit-for-unsigned-comparison cr-bit))
3255 (regspec-crf-gpr-case
3256 (vreg dest)
3257 (^ cr-bit true-p)
3258 (progn
3259 (ensuring-node-target (target dest)
3260 (if (not true-p)
3261 (setq cr-bit (logxor 1 cr-bit)))
3262 (! cr-bit->boolean target cr-bit))
3263 (^))))))
3264
3265;;; There are other cases involving constants that are worth exploiting.
3266(defun x862-compare (seg vreg xfer i j cr-bit true-p)
3267 (with-x86-local-vinsn-macros (seg vreg xfer)
3268 (let* ((iu8 (let* ((i-fixnum (acode-fixnum-form-p i)))
3269 (if (typep i-fixnum '(unsigned-byte 8))
3270 i-fixnum)))
3271 (ju8 (let* ((j-fixnum (acode-fixnum-form-p j)))
3272 (if (typep j-fixnum '(unsigned-byte 8))
3273 j-fixnum)))
3274 (u8 (or iu8 ju8))
3275 (other-u8 (if iu8 j (if ju8 i)))
3276 (js32 (acode-s32-constant-p j))
3277 (is32 (acode-s32-constant-p i))
3278 (boolean (backend-crf-p vreg)))
3279 (multiple-value-bind (u8-operator u8-operand) (if other-u8 (x862-acode-operator-supports-u8 other-u8))
3280 (if u8-operator
3281 (x862-compare-u8 seg vreg xfer u8-operand u8 (if (and iu8 (not (eq cr-bit x86::x86-e-bits))) (logxor 1 cr-bit) cr-bit) true-p u8-operator)
3282 (if (and boolean (or js32 is32))
3283 (let* ((reg (x862-one-untargeted-reg-form seg (if js32 i j) x8664::arg_z))
3284 (constant (or js32 is32)))
3285 (if (zerop constant)
3286 (! compare-reg-to-zero reg)
3287 (! compare-s32-constant reg (or js32 is32)))
3288 (unless (or js32 (eq cr-bit x86::x86-e-bits))
3289 (setq cr-bit (x862-reverse-cr-bit cr-bit)))
3290 (^ cr-bit true-p))
3291 (if (and (eq cr-bit x86::x86-e-bits)
3292 (or js32 is32))
3293 (x862-test-reg-%izerop
3294 seg
3295 vreg
3296 xfer
3297 (x862-one-untargeted-reg-form
3298 seg
3299 (if js32 i j)
3300 x8664::arg_z)
3301 cr-bit
3302 true-p
3303 (or js32 is32))
3304 (multiple-value-bind (ireg jreg) (x862-two-untargeted-reg-forms seg i x8664::arg_y j x8664::arg_z)
3305 (x862-compare-registers seg vreg xfer ireg jreg cr-bit true-p)))))))))
3306
3307(defun x862-natural-compare (seg vreg xfer i j cr-bit true-p)
3308 (with-x86-local-vinsn-macros (seg vreg xfer)
3309 (let* ((jconstant (acode-fixnum-form-p j))
3310 (ju31 (typep jconstant '(unsigned-byte 31)))
3311 (iconstant (acode-fixnum-form-p i))
3312 (iu31 (typep iconstant '(unsigned-byte 31)))
3313 (boolean (backend-crf-p vreg)))
3314 (if (and boolean (or ju31 iu31))
3315 (with-imm-target
3316 () (reg :natural)
3317 (x862-one-targeted-reg-form seg (if ju31 i j) reg)
3318 (! compare-u31-constant reg (if ju31 jconstant iconstant))
3319 (unless (or ju31 (eq cr-bit x86::x86-e-bits))
3320 (setq cr-bit (x862-reverse-cr-bit cr-bit)))
3321 (^ cr-bit true-p))
3322 (with-imm-target ()
3323 (ireg :natural)
3324 (with-imm-target
3325 (ireg) (jreg :natural)
3326 (x862-two-targeted-reg-forms seg i ireg j jreg)
3327 (x862-compare-natural-registers seg vreg xfer ireg jreg cr-bit true-p)))))))
3328
3329
3330(defun x862-cr-bit-for-logical-comparison (cr-bit true-p)
3331 (declare (fixnum cr-bit))
3332 (let* ((unsigned
3333 (case cr-bit
3334 (#.x86::x86-l-bits x86::x86-b-bits)
3335 (#.x86::x86-le-bits x86::x86-be-bits )
3336 (#.x86::x86-g-bits x86::x86-a-bits)
3337 (#.x86::x86-ge-bits x86::x86-ae-bits)
3338 (t cr-bit))))
3339 (declare (fixnum unsigned))
3340 (if true-p
3341 unsigned
3342 (logxor unsigned 1))))
3343
3344(defun x862-compare-natural-registers (seg vreg xfer ireg jreg cr-bit true-p)
3345 (with-x86-local-vinsn-macros (seg vreg xfer)
3346 (if vreg
3347 (progn
3348 (setq cr-bit (x862-cr-bit-for-logical-comparison cr-bit true-p))
3349 (! compare ireg jreg)
3350 (regspec-crf-gpr-case
3351 (vreg dest)
3352 (^ cr-bit true-p)
3353 (progn
3354 (ensuring-node-target (target dest)
3355 (! cr-bit->boolean target cr-bit))
3356 (^))))
3357 (^))))
3358
3359
3360(defun x862-compare-registers (seg vreg xfer ireg jreg cr-bit true-p)
3361 (with-x86-local-vinsn-macros (seg vreg xfer)
3362 (if vreg
3363 (progn
3364 (! compare ireg jreg)
3365 (regspec-crf-gpr-case
3366 (vreg dest)
3367 (^ cr-bit true-p)
3368 (progn
3369 (ensuring-node-target (target dest)
3370 (if (not true-p)
3371 (setq cr-bit (logxor 1 cr-bit)))
3372 (! cr-bit->boolean target cr-bit))
3373 (^))))
3374 (^))))
3375
3376(defun x862-compare-register-to-nil (seg vreg xfer ireg cr-bit true-p)
3377 (with-x86-local-vinsn-macros (seg vreg xfer)
3378 (when vreg
3379 (! compare-to-nil ireg)
3380 (regspec-crf-gpr-case
3381 (vreg dest)
3382 (^ cr-bit true-p)
3383 (progn
3384 (ensuring-node-target (target dest)
3385 (if (not true-p)
3386 (setq cr-bit (logxor 1 cr-bit)))
3387 (! cr-bit->boolean target cr-bit))
3388 (^))))))
3389
3390(defun x862-compare-ea-to-nil (seg vreg xfer ea cr-bit true-p)
3391 (with-x86-local-vinsn-macros (seg vreg xfer)
3392 (when vreg
3393 (if (addrspec-vcell-p ea)
3394 (with-node-target () temp
3395 (x862-stack-to-register seg ea temp)
3396 (! compare-value-cell-to-nil temp))
3397 (! compare-vframe-offset-to-nil (memspec-frame-address-offset ea) *x862-vstack*))
3398 (regspec-crf-gpr-case
3399 (vreg dest)
3400 (^ cr-bit true-p)
3401 (progn
3402 (ensuring-node-target (target dest)
3403 (if (not true-p)
3404 (setq cr-bit (logxor 1 cr-bit)))
3405 (! cr-bit->boolean target cr-bit))
3406 (^))))))
3407
3408(defun x862-cr-bit-for-unsigned-comparison (cr-bit)
3409 (ecase cr-bit
3410 (#.x86::x86-e-bits #.x86::x86-e-bits)
3411 (#.x86::x86-ne-bits #.x86::x86-ne-bits)
3412 (#.x86::x86-l-bits #.x86::x86-b-bits)
3413 (#.x86::x86-le-bits #.x86::x86-be-bits)
3414 (#.x86::x86-ge-bits #.x86::x86-ae-bits)
3415 (#.x86::x86-g-bits #.x86::x86-a-bits)))
3416
3417
3418(defun x862-compare-double-float-registers (seg vreg xfer ireg jreg cr-bit true-p)
3419 (with-x86-local-vinsn-macros (seg vreg xfer)
3420 (if vreg
3421 (progn
3422 (setq cr-bit (x862-cr-bit-for-unsigned-comparison cr-bit))
3423 (regspec-crf-gpr-case
3424 (vreg dest)
3425 (progn
3426 (! double-float-compare ireg jreg)
3427 (^ cr-bit true-p))
3428 (progn
3429 (! double-float-compare ireg jreg)
3430 (ensuring-node-target (target dest)
3431 (if (not true-p)
3432 (setq cr-bit (logxor 1 cr-bit)))
3433 (! cr-bit->boolean target cr-bit))
3434 (^))))
3435 (^))))
3436
3437(defun x862-compare-single-float-registers (seg vreg xfer ireg jreg cr-bit true-p)
3438 (with-x86-local-vinsn-macros (seg vreg xfer)
3439 (if vreg
3440 (progn
3441 (setq cr-bit (x862-cr-bit-for-unsigned-comparison cr-bit))
3442 (regspec-crf-gpr-case
3443 (vreg dest)
3444 (progn
3445 (! single-float-compare ireg jreg)
3446 (^ cr-bit true-p))
3447 (progn
3448 (! single-float-compare ireg jreg)
3449 (ensuring-node-target (target dest)
3450 (if (not true-p)
3451 (setq cr-bit (logxor 1 cr-bit)))
3452 (! cr-bit->boolean target cr-bit))
3453 (^))))
3454 (^))))
3455
3456
3457(defun x862-immediate-form-p (form)
3458 (if (and (consp form)
3459 (or (eq (%car form) (%nx1-operator immediate))
3460 (eq (%car form) (%nx1-operator simple-function))))
3461 t))
3462
3463(defun x862-test-%izerop (seg vreg xfer form cr-bit true-p)
3464 (x862-test-reg-%izerop seg vreg xfer (x862-one-untargeted-reg-form seg form x8664::arg_z) cr-bit true-p 0))
3465
3466(defun x862-test-reg-%izerop (seg vreg xfer reg cr-bit true-p zero)
3467 (declare (fixnum reg zero))
3468 (with-x86-local-vinsn-macros (seg vreg xfer)
3469 (if (zerop zero)
3470 (! compare-reg-to-zero reg)
3471 (! compare-s32-constant reg zero))
3472 (regspec-crf-gpr-case
3473 (vreg dest)
3474 (^ cr-bit true-p)
3475 (progn
3476 (ensuring-node-target (target dest)
3477 (if (not true-p)
3478 (setq cr-bit (logxor 1 cr-bit)))
3479 (! cr-bit->boolean target cr-bit))
3480 (^)))))
3481
3482(defun x862-lexical-reference-ea (form &optional (no-closed-p t))
3483 (when (acode-p (setq form (acode-unwrapped-form form)))
3484 (if (eq (acode-operator form) (%nx1-operator lexical-reference))
3485 (let* ((addr (var-ea (%cadr form))))
3486 (if (typep addr 'lreg)
3487 addr
3488 (unless (and no-closed-p (addrspec-vcell-p addr ))
3489 addr))))))
3490
3491
3492(defun x862-vpush-register (seg src &optional why info attr)
3493 (with-x86-local-vinsn-macros (seg)
3494 (prog1
3495 (! vpush-register src)
3496 (x862-new-vstack-lcell (or why :node) *x862-target-lcell-size* (or attr 0) info)
3497 (x862-adjust-vstack *x862-target-node-size*))))
3498
3499
3500;;; Need to track stack usage when pushing label for mv-call.
3501(defun x862-vpush-label (seg label)
3502 (with-x86-local-vinsn-macros (seg)
3503 (prog1
3504 (! vpush-label label)
3505 (x862-new-vstack-lcell :label *x862-target-lcell-size* 0 nil)
3506 (x862-adjust-vstack *x862-target-node-size*))))
3507
3508(defun x862-temp-push-node (seg reg)
3509 (with-x86-local-vinsn-macros (seg)
3510 (! temp-push-node reg)
3511 (x862-open-undo $undostkblk)))
3512
3513(defun x862-temp-pop-node (seg reg)
3514 (with-x86-local-vinsn-macros (seg)
3515 (! temp-pop-node reg)
3516 (x862-close-undo)))
3517
3518(defun x862-vpush-register-arg (seg src)
3519 (x862-vpush-register seg src :outgoing-argument))
3520
3521
3522(defun x862-vpop-register (seg dest)
3523 (with-x86-local-vinsn-macros (seg)
3524 (prog1
3525 (! vpop-register dest)
3526 (setq *x862-top-vstack-lcell* (lcell-parent *x862-top-vstack-lcell*))
3527 (x862-adjust-vstack (- *x862-target-node-size*)))))
3528
3529(defun x862-macptr->heap (seg dest src)
3530 (with-x86-local-vinsn-macros (seg)
3531 (! setup-macptr-allocation src)
3532 (! %allocate-uvector dest)
3533 (! %set-new-macptr-value dest)))
3534
3535(defun x862-copy-register (seg dest src)
3536 (with-x86-local-vinsn-macros (seg)
3537 (when dest
3538 (let* ((dest-gpr (backend-ea-physical-reg dest hard-reg-class-gpr))
3539 (src-gpr (if src (backend-ea-physical-reg src hard-reg-class-gpr)))
3540 (dest-fpr (backend-ea-physical-reg dest hard-reg-class-fpr))
3541 (src-fpr (if src (backend-ea-physical-reg src hard-reg-class-fpr)))
3542 (src-mode (if src (get-regspec-mode src)))
3543 (dest-mode (get-regspec-mode dest))
3544 (dest-crf (backend-ea-physical-reg dest hard-reg-class-crf)))
3545 (if (null src)
3546 (if dest-gpr
3547 (! load-nil dest-gpr)
3548 (if dest-crf
3549 (! set-eq-bit)))
3550 (if (and dest-crf src-gpr)
3551 ;; "Copying" a GPR to a CR field means comparing it to rnil
3552 (! compare-to-nil src)
3553 (if (and dest-gpr src-gpr)
3554 (if (eq src-mode dest-mode)
3555 (unless (eq src-gpr dest-gpr)
3556 (! copy-gpr dest src))
3557 ;; This is the "GPR <- GPR" case. There are
3558 ;; word-size dependencies, but there's also
3559 ;; lots of redundancy here.
3560 (target-arch-case
3561 (:x8664
3562 (ecase dest-mode
3563 (#.hard-reg-class-gpr-mode-node ; boxed result.
3564 (case src-mode
3565 (#.hard-reg-class-gpr-mode-node
3566 (unless (eql dest-gpr src-gpr)
3567 (! copy-gpr dest src)))
3568 (#.hard-reg-class-gpr-mode-u64
3569 (x862-box-u64 seg dest src))
3570 (#.hard-reg-class-gpr-mode-s64
3571 (x862-box-s64 seg dest src))
3572 (#.hard-reg-class-gpr-mode-u32
3573 (x862-box-u32 seg dest src))
3574 (#.hard-reg-class-gpr-mode-s32
3575 (x862-box-s32 seg dest src))
3576 (#.hard-reg-class-gpr-mode-u16
3577 (! box-fixnum dest src))
3578 (#.hard-reg-class-gpr-mode-s16
3579 (! box-fixnum dest src))
3580 (#.hard-reg-class-gpr-mode-u8
3581 (! box-fixnum dest src))
3582 (#.hard-reg-class-gpr-mode-s8
3583 (! box-fixnum dest src))
3584 (#.hard-reg-class-gpr-mode-address
3585 (x862-macptr->heap seg dest src))))
3586 ((#.hard-reg-class-gpr-mode-u64
3587 #.hard-reg-class-gpr-mode-address)
3588 (case src-mode
3589 (#.hard-reg-class-gpr-mode-node
3590 (let* ((src-type (get-node-regspec-type-modes src)))
3591 (declare (fixnum src-type))
3592 (case dest-mode
3593 (#.hard-reg-class-gpr-mode-u64
3594 (! unbox-u64 dest src))
3595 (#.hard-reg-class-gpr-mode-address
3596 (unless (or (logbitp #.hard-reg-class-gpr-mode-address src-type)
3597 *x862-reckless*)
3598 (! trap-unless-macptr src))
3599 (! deref-macptr dest src)))))
3600 ((#.hard-reg-class-gpr-mode-u64
3601 #.hard-reg-class-gpr-mode-s64
3602 #.hard-reg-class-gpr-mode-address)
3603 (unless (eql dest-gpr src-gpr)
3604 (! copy-gpr dest src)))
3605 ((#.hard-reg-class-gpr-mode-u16
3606 #.hard-reg-class-gpr-mode-s16)
3607 (! u16->u32 dest src))
3608 ((#.hard-reg-class-gpr-mode-u8
3609 #.hard-reg-class-gpr-mode-s8)
3610 (! u8->u32 dest src))))
3611 (#.hard-reg-class-gpr-mode-s64
3612 (case src-mode
3613 (#.hard-reg-class-gpr-mode-node
3614 (! unbox-s64 dest src))
3615 ((#.hard-reg-class-gpr-mode-u64
3616 #.hard-reg-class-gpr-mode-s64
3617 #.hard-reg-class-gpr-mode-address)
3618 (unless (eql dest-gpr src-gpr)
3619 (! copy-gpr dest src)))
3620 ((#.hard-reg-class-gpr-mode-u16
3621 #.hard-reg-class-gpr-mode-s16)
3622 (! s16->s32 dest src))
3623 ((#.hard-reg-class-gpr-mode-u8
3624 #.hard-reg-class-gpr-mode-s8)
3625 (! s8->s32 dest src))))
3626 (#.hard-reg-class-gpr-mode-s32
3627 (case src-mode
3628 (#.hard-reg-class-gpr-mode-node
3629 (! unbox-s32 dest src))
3630 ((#.hard-reg-class-gpr-mode-u32
3631 #.hard-reg-class-gpr-mode-s32
3632 #.hard-reg-class-gpr-mode-address)
3633 (unless (eql dest-gpr src-gpr)
3634 (! copy-gpr dest src)))
3635 (#.hard-reg-class-gpr-mode-u16
3636 (! u16->u32 dest src))
3637 (#.hard-reg-class-gpr-mode-s16
3638 (! s16->s32 dest src))
3639 (#.hard-reg-class-gpr-mode-u8
3640 (! u8->u32 dest src))
3641 (#.hard-reg-class-gpr-mode-s8
3642 (! s8->s32 dest src))))
3643 (#.hard-reg-class-gpr-mode-u32
3644 (case src-mode
3645 (#.hard-reg-class-gpr-mode-node
3646 (! unbox-u32 dest src))
3647 ((#.hard-reg-class-gpr-mode-u32
3648 #.hard-reg-class-gpr-mode-s32)
3649 (unless (eql dest-gpr src-gpr)
3650 (! copy-gpr dest src)))
3651 (#.hard-reg-class-gpr-mode-u16
3652 (! u16->u32 dest src))
3653 (#.hard-reg-class-gpr-mode-s16
3654 (! s16->s32 dest src))
3655 (#.hard-reg-class-gpr-mode-u8
3656 (! u8->u32 dest src))
3657 (#.hard-reg-class-gpr-mode-s8
3658 (! s8->s32 dest src))))
3659 (#.hard-reg-class-gpr-mode-u16
3660 (case src-mode
3661 (#.hard-reg-class-gpr-mode-node
3662 (! unbox-u16 dest src))
3663 ((#.hard-reg-class-gpr-mode-u8
3664 #.hard-reg-class-gpr-mode-s8)
3665 (! u8->u32 dest src))
3666 (t
3667 (unless (eql dest-gpr src-gpr)
3668 (! copy-gpr dest src)))))
3669 (#.hard-reg-class-gpr-mode-s16
3670 (case src-mode
3671 (#.hard-reg-class-gpr-mode-node
3672 (! unbox-s16 dest src))
3673 (#.hard-reg-class-gpr-mode-s8
3674 (! s8->s32 dest src))
3675 (#.hard-reg-class-gpr-mode-u8
3676 (! u8->u32 dest src))
3677 (t
3678 (unless (eql dest-gpr src-gpr)
3679 (! copy-gpr dest src)))))
3680 (#.hard-reg-class-gpr-mode-u8
3681 (case src-mode
3682 (#.hard-reg-class-gpr-mode-node
3683 (if *x862-reckless*
3684 (! %unbox-u8 dest src)
3685 (! unbox-u8 dest src)))
3686 (t
3687 (unless (eql dest-gpr src-gpr)
3688 (! copy-gpr dest src)))))
3689 (#.hard-reg-class-gpr-mode-s8
3690 (case src-mode
3691 (#.hard-reg-class-gpr-mode-node
3692 (! unbox-s8 dest src))
3693 (t
3694 (unless (eql dest-gpr src-gpr)
3695 (! copy-gpr dest src)))))))))
3696 (if src-gpr
3697 (if dest-fpr
3698 (progn
3699 (case src-mode
3700 (#.hard-reg-class-gpr-mode-node
3701 (case dest-mode
3702 (#.hard-reg-class-fpr-mode-double
3703 (unless (or (logbitp hard-reg-class-fpr-type-double
3704 (get-node-regspec-type-modes src))
3705 *x862-reckless*)
3706 (! trap-unless-double-float src))
3707 (! get-double dest src))
3708 (#.hard-reg-class-fpr-mode-single
3709 (unless *x862-reckless* (! trap-unless-single-float src))
3710 (! get-single dest src)))))))
3711 (if dest-gpr
3712 (case dest-mode
3713 (#.hard-reg-class-gpr-mode-node
3714 (case src-mode
3715 (#.hard-reg-class-fpr-mode-double
3716 (x862-double->heap seg dest src))
3717 (#.hard-reg-class-fpr-mode-single
3718 (! single->node dest src)))))
3719 (if (and src-fpr dest-fpr)
3720 (unless (eql dest-fpr src-fpr)
3721 (if (= src-mode hard-reg-class-fpr-mode-double)
3722 (if (= dest-mode hard-reg-class-fpr-mode-double)
3723 (! copy-double-float dest src)
3724 (! copy-double-to-single dest src))
3725 (if (= dest-mode hard-reg-class-fpr-mode-double)
3726 (! copy-single-to-double dest src)
3727 (! copy-single-float dest src))))))))))))))
3728
3729(defun x862-unreachable-store (&optional vreg)
3730 ;; I don't think that anything needs to be done here,
3731 ;; but leave this guy around until we're sure.
3732 ;; (X862-VPUSH-REGISTER will always vpush something, even
3733 ;; if code to -load- that "something" never gets generated.
3734 ;; If I'm right about this, that means that the compile-time
3735 ;; stack-discipline problem that this is supposed to deal
3736 ;; with can't happen.)
3737 (declare (ignore vreg))
3738 nil)
3739
3740;;; bind vars to initforms, as per let*, &aux.
3741(defun x862-seq-bind (seg vars initforms)
3742 (dolist (var vars)
3743 (x862-seq-bind-var seg var (pop initforms))))
3744
3745(defun x862-target-is-imm-subtag (subtag)
3746 (when subtag
3747 (target-arch-case
3748 (:x8664
3749 (let* ((masked (logand subtag x8664::fulltagmask)))
3750 (declare (fixnum masked))
3751 (or (= masked x8664::fulltag-immheader-0)
3752 (= masked x8664::fulltag-immheader-1)
3753 (= masked x8664::fulltag-immheader-2)))))))
3754
3755(defun x862-target-is-node-subtag (subtag)
3756 (when subtag
3757 (target-arch-case
3758 (:x8664
3759 (let* ((masked (logand subtag x8664::fulltagmask)))
3760 (declare (fixnum masked))
3761 (or (= masked x8664::fulltag-nodeheader-0)
3762 (= masked x8664::fulltag-nodeheader-1)))))))
3763
3764(defun x862-dynamic-extent-form (seg curstack val)
3765 (when (acode-p val)
3766 (with-x86-local-vinsn-macros (seg)
3767 (let* ((op (acode-operator val)))
3768 (cond ((eq op (%nx1-operator list))
3769 (let* ((*x862-vstack* *x862-vstack*)
3770 (*x862-top-vstack-lcell* *x862-top-vstack-lcell*))
3771 (x862-set-nargs seg (x862-formlist seg (%cadr val) nil))
3772 (x862-open-undo $undostkblk curstack)
3773 (! stack-cons-list))
3774 (setq val x8664::arg_z))
3775 ((eq op (%nx1-operator list*))
3776 (let* ((arglist (%cadr val)))
3777 (let* ((*x862-vstack* *x862-vstack*)
3778 (*x862-top-vstack-lcell* *x862-top-vstack-lcell*))
3779 (x862-formlist seg (car arglist) (cadr arglist)))
3780 (when (car arglist)
3781 (x862-set-nargs seg (length (%car arglist)))
3782 (! stack-cons-list*)
3783 (x862-open-undo $undostkblk curstack))
3784 (setq val x8664::arg_z)))
3785 ((eq op (%nx1-operator multiple-value-list))
3786 (x862-multiple-value-body seg (%cadr val))
3787 (x862-open-undo $undostkblk curstack)
3788 (! stack-cons-list)
3789 (setq val x8664::arg_z))
3790 ((eq op (%nx1-operator cons))
3791 (let* ((y ($ x8664::arg_y))
3792 (z ($ x8664::arg_z))
3793 (result ($ x8664::arg_z)))
3794 (x862-two-targeted-reg-forms seg (%cadr val) y (%caddr val) z)
3795 (x862-open-undo $undostkblk )
3796 (! make-tsp-cons result y z)
3797 (setq val result)))
3798 ((eq op (%nx1-operator %consmacptr%))
3799 (with-imm-target () (address :address)
3800 (x862-one-targeted-reg-form seg val address)
3801 (with-node-target () node
3802 (! macptr->stack node address)
3803 (x862-open-undo $undo-x86-c-frame)
3804 (setq val node))))
3805 ((eq op (%nx1-operator %new-ptr))
3806 (let ((clear-form (caddr val)))
3807 (if (nx-constant-form-p clear-form)
3808 (progn
3809 (x862-one-targeted-reg-form seg (%cadr val) ($ x8664::arg_z))
3810 (if (nx-null clear-form)
3811 (! make-stack-block)
3812 (! make-stack-block0)))
3813 (with-crf-target () crf
3814 (let ((stack-block-0-label (backend-get-next-label))
3815 (done-label (backend-get-next-label))
3816 (rval ($ x8664::arg_z))
3817 (rclear ($ x8664::arg_y)))
3818 (x862-two-targeted-reg-forms seg (%cadr val) rval clear-form rclear)
3819 (! compare-to-nil crf rclear)
3820 (! cbranch-false (aref *backend-labels* stack-block-0-label) crf x86::x86-e-bits)
3821 (! make-stack-block)
3822 (-> done-label)
3823 (@ stack-block-0-label)
3824 (! make-stack-block0)
3825 (@ done-label)))))
3826 (x862-open-undo $undo-x86-c-frame)
3827 (setq val ($ x8664::arg_z)))
3828 ((eq op (%nx1-operator make-list))
3829 (x862-two-targeted-reg-forms seg (%cadr val) ($ x8664::arg_y) (%caddr val) ($ x8664::arg_z))
3830 (x862-open-undo $undostkblk curstack)
3831 (! make-stack-list)
3832 (setq val x8664::arg_z))
3833 ((eq (%car val) (%nx1-operator vector))
3834 (let* ((*x862-vstack* *x862-vstack*)
3835 (*x862-top-vstack-lcell* *x862-top-vstack-lcell*))
3836 (x862-set-nargs seg (x862-formlist seg (%cadr val) nil))
3837 (! make-stack-vector))
3838 (x862-open-undo $undostkblk)
3839 (setq val x8664::arg_z))
3840 ((eq op (%nx1-operator %gvector))
3841 (let* ((*x862-vstack* *x862-vstack*)
3842 (*x862-top-vstack-lcell* *x862-top-vstack-lcell*)
3843 (arglist (%cadr val)))
3844 (x862-set-nargs seg (x862-formlist seg (append (car arglist) (reverse (cadr arglist))) nil))
3845 (! make-stack-gvector))
3846 (x862-open-undo $undostkblk)
3847 (setq val x8664::arg_z))
3848 ((eq op (%nx1-operator closed-function))
3849 (setq val (x862-make-closure seg (cadr val) t))) ; can't error
3850 ((eq op (%nx1-operator %make-uvector))
3851 (destructuring-bind (element-count subtag &optional (init 0 init-p)) (%cdr val)
3852 (let* ((fix-subtag (acode-fixnum-form-p subtag))
3853 (is-node (x862-target-is-node-subtag fix-subtag))
3854 (is-imm (x862-target-is-imm-subtag fix-subtag)))
3855 (when (or is-node is-imm)
3856 (if init-p
3857 (progn
3858 (x862-three-targeted-reg-forms seg element-count ($ x8664::arg_x) subtag ($ x8664::arg_y) init ($ x8664::arg_z))
3859 (! stack-misc-alloc-init))
3860 (progn
3861 (x862-two-targeted-reg-forms seg element-count ($ x8664::arg_y) subtag ($ x8664::arg_z))
3862 (! stack-misc-alloc)))
3863 (if is-node
3864 (x862-open-undo $undostkblk)
3865 (x862-open-undo $undo-x86-c-frame))
3866 (setq val ($ x8664::arg_z))))))))))
3867 val)
3868
3869(defun x862-addrspec-to-reg (seg addrspec reg)
3870 (if (memory-spec-p addrspec)
3871 (x862-stack-to-register seg addrspec reg)
3872 (x862-copy-register seg reg addrspec)))
3873
3874(defun x862-seq-bind-var (seg var val)
3875 (with-x86-local-vinsn-macros (seg)
3876 (let* ((sym (var-name var))
3877 (bits (nx-var-bits var))
3878 (closed-p (and (%ilogbitp $vbitclosed bits)
3879 (%ilogbitp $vbitsetq bits)))
3880 (curstack (x862-encode-stack))
3881 (make-vcell (and closed-p (eq bits (var-bits var))))
3882 (closed-downward (and closed-p (%ilogbitp $vbitcloseddownward bits))))
3883 (unless (fixnump val)
3884 (setq val (nx-untyped-form val))
3885 (when (and (%ilogbitp $vbitdynamicextent bits) (acode-p val))
3886 (setq val (x862-dynamic-extent-form seg curstack val))))
3887 (if (%ilogbitp $vbitspecial bits)
3888 (progn
3889 (x862-dbind seg val sym)
3890 (x862-set-var-ea seg var (x862-vloc-ea (- *x862-vstack* *x862-target-node-size*))))
3891 (let ((puntval nil))
3892 (flet ((x862-puntable-binding-p (var initform)
3893 ;; The value returned is acode.
3894 (let* ((bits (nx-var-bits var)))
3895 (if (%ilogbitp $vbitpuntable bits)
3896 (nx-untyped-form initform)))))
3897 (declare (inline x862-puntable-binding-p))
3898 (if (and (not (x862-load-ea-p val))
3899 (setq puntval (x862-puntable-binding-p var val)))
3900 (progn
3901 (nx-set-var-bits var (%ilogior (%ilsl $vbitpunted 1) bits))
3902 (x862-set-var-ea seg var puntval))
3903 (progn
3904 (let* ((vloc *x862-vstack*)
3905 (reg (let* ((r (x862-assign-register-var var)))
3906 (if r ($ r)))))
3907 (if (x862-load-ea-p val)
3908 (if reg
3909 (x862-addrspec-to-reg seg val reg)
3910 (if (memory-spec-p val)
3911 (with-node-temps () (temp)
3912 (x862-addrspec-to-reg seg val temp)
3913 (x862-vpush-register seg temp :node var bits))
3914 (x862-vpush-register seg val :node var bits)))
3915 (if reg
3916 (x862-one-targeted-reg-form seg val reg)
3917 (let* ((pushform (x862-acode-operator-supports-push val)))
3918 (if pushform
3919 (progn
3920 (x862-form seg :push nil pushform)
3921 (x862-new-vstack-lcell :node *x862-target-lcell-size* bits var)
3922 (x862-adjust-vstack *x862-target-node-size*))
3923 (x862-vpush-register seg (x862-one-untargeted-reg-form seg val x8664::arg_z) :node var bits)))))
3924 (x862-set-var-ea seg var (or reg (x862-vloc-ea vloc closed-p)))
3925 (if reg
3926 (x862-note-var-cell var reg)
3927 (x862-note-top-cell var))
3928 (when make-vcell
3929 (with-node-target (x8664::allocptr) closed
3930 (with-node-target (x8664::allocptr closed) vcell
3931 (x862-stack-to-register seg vloc closed)
3932 (if closed-downward
3933 (progn
3934 (! make-tsp-vcell vcell closed)
3935 (x862-open-undo $undostkblk))
3936 (progn
3937 (! setup-vcell-allocation)
3938 (! %allocate-uvector vcell)
3939 (! %init-vcell vcell closed)))
3940 (x862-register-to-stack seg vcell vloc)))))))))))))
3941
3942
3943
3944;;; Never make a vcell if this is an inherited var.
3945;;; If the var's inherited, its bits won't be a fixnum (and will
3946;;; therefore be different from what NX-VAR-BITS returns.)
3947(defun x862-bind-var (seg var vloc &optional lcell &aux
3948 (bits (nx-var-bits var))
3949 (closed-p (and (%ilogbitp $vbitclosed bits) (%ilogbitp $vbitsetq bits)))
3950 (closed-downward (if closed-p (%ilogbitp $vbitcloseddownward bits)))
3951 (make-vcell (and closed-p (eq bits (var-bits var))))
3952 (addr (x862-vloc-ea vloc)))
3953 (with-x86-local-vinsn-macros (seg)
3954 (if (%ilogbitp $vbitspecial bits)
3955 (progn
3956 (x862-dbind seg addr (var-name var))
3957 (x862-set-var-ea seg var (x862-vloc-ea (- *x862-vstack* *x862-target-node-size*)))
3958 t)
3959 (progn
3960 (when (%ilogbitp $vbitpunted bits)
3961 (error "bind-var: var ~s was punted" var))
3962 (when make-vcell
3963 (with-node-target (x8664::allocptr) closed
3964 (with-node-target (x8664::allocptr closed) vcell
3965 (x862-stack-to-register seg vloc closed)
3966 (if closed-downward
3967 (progn
3968 (! make-tsp-vcell vcell closed)
3969 (x862-open-undo $undostkblk))
3970 (progn
3971 (! setup-vcell-allocation)
3972 (! %allocate-uvector vcell)
3973 (! %init-vcell vcell closed)))
3974 (x862-register-to-stack seg vcell vloc))))
3975 (when lcell
3976 (setf (lcell-kind lcell) :node
3977 (lcell-attributes lcell) bits
3978 (lcell-info lcell) var)
3979 (x862-note-var-cell var lcell))
3980 (x862-set-var-ea seg var (x862-vloc-ea vloc closed-p))
3981 closed-downward))))
3982
3983(defun x862-set-var-ea (seg var ea)
3984 (setf (var-ea var) ea)
3985 (when (and *x862-record-symbols* (or (typep ea 'lreg) (typep ea 'fixnum)))
3986 (let* ((start (x862-emit-note seg :begin-variable-scope)))
3987 (push (list var (var-name var) start (close-vinsn-note start))
3988 *x862-recorded-symbols*)))
3989 ea)
3990
3991(defun x862-close-var (seg var)
3992 (let ((bits (nx-var-bits var)))
3993 (when (and *x862-record-symbols*
3994 (or (logbitp $vbitspecial bits)
3995 (not (logbitp $vbitpunted bits))))
3996 (let ((endnote (%car (%cdddr (assq var *x862-recorded-symbols*)))))
3997 (unless endnote (error "x862-close-var for ~s" (var-name var)))
3998 (setf (vinsn-note-class endnote) :end-variable-scope)
3999 (append-dll-node (vinsn-note-label endnote) seg)))))
4000
4001(defun x862-load-ea-p (ea)
4002 (or (typep ea 'fixnum)
4003 (typep ea 'lreg)
4004 (typep ea 'lcell)))
4005
4006(defun x862-dbind (seg value sym)
4007 (with-x86-local-vinsn-macros (seg)
4008 (let* ((ea-p (x862-load-ea-p value))
4009 (nil-p (unless ea-p (eq (setq value (nx-untyped-form value)) *nx-nil*)))
4010 (self-p (unless ea-p (and (or
4011 (eq (acode-operator value) (%nx1-operator bound-special-ref))
4012 (eq (acode-operator value) (%nx1-operator special-ref)))
4013 (eq (cadr value) sym)))))
4014 (cond ((eq sym '*interrupt-level*)
4015 (let* ((fixval (acode-fixnum-form-p value)))
4016 (cond ((eql fixval 0)
4017 (if *x862-open-code-inline*
4018 (! bind-interrupt-level-0-inline)
4019 (! bind-interrupt-level-0)))
4020 ((eql fixval -1)
4021 (if *x862-open-code-inline*
4022 (! bind-interrupt-level-m1-inline)
4023 (! bind-interrupt-level-m1)))
4024 (t
4025 (if ea-p
4026 (x862-store-ea seg value x8664::arg_z)
4027 (x862-one-targeted-reg-form seg value ($ x8664::arg_z)))
4028 (! bind-interrupt-level))))
4029 (x862-open-undo $undointerruptlevel))
4030 (t
4031 (if (or nil-p self-p)
4032 (progn
4033 (x862-store-immediate seg (x862-symbol-value-cell sym) x8664::arg_z)
4034 (if nil-p
4035 (! bind-nil)
4036 (if (or *x862-reckless* (eq (acode-operator value) (%nx1-operator special-ref)))
4037 (! bind-self)
4038 (! bind-self-boundp-check))))
4039 (progn
4040 (if ea-p
4041 (x862-store-ea seg value x8664::arg_z)
4042 (x862-one-targeted-reg-form seg value ($ x8664::arg_z)))
4043 (x862-store-immediate seg (x862-symbol-value-cell sym) ($ x8664::arg_y))
4044 (! bind)))
4045 (x862-open-undo $undospecial)))
4046 (x862-new-vstack-lcell :special-value *x862-target-lcell-size* 0 sym)
4047 (x862-new-vstack-lcell :special *x862-target-lcell-size* (ash 1 $vbitspecial) sym)
4048 (x862-new-vstack-lcell :special-link *x862-target-lcell-size* 0 sym)
4049 (x862-adjust-vstack (* 3 *x862-target-node-size*)))))
4050
4051;;; Store the contents of EA - which denotes either a vframe location
4052;;; or a hard register - in reg.
4053
4054(defun x862-store-ea (seg ea reg)
4055 (if (typep ea 'fixnum)
4056 (if (memory-spec-p ea)
4057 (x862-stack-to-register seg ea reg)
4058 (x862-copy-register seg reg ea))
4059 (if (typep ea 'lreg)
4060 (x862-copy-register seg reg ea)
4061 (if (typep ea 'lcell)
4062 (x862-lcell-to-register seg ea reg)))))
4063
4064
4065
4066
4067;;; Callers should really be sure that this is what they want to use.
4068(defun x862-absolute-natural (seg vreg xfer value)
4069 (with-x86-local-vinsn-macros (seg vreg xfer)
4070 (when vreg
4071 (x862-lri seg vreg value))
4072 (^)))
4073
4074
4075
4076(defun x862-store-macptr (seg vreg address-reg)
4077 (with-x86-local-vinsn-macros (seg vreg)
4078 (when (x862-for-value-p vreg)
4079 (if (logbitp vreg *backend-imm-temps*)
4080 (<- address-reg)
4081 (x862-macptr->heap seg vreg address-reg)))))
4082
4083(defun x862-store-signed-longword (seg vreg imm-reg)
4084 (with-x86-local-vinsn-macros (seg vreg)
4085 (when (x862-for-value-p vreg)
4086 (if (logbitp vreg *backend-imm-temps*)
4087 (<- imm-reg)
4088 (x862-box-s32 seg vreg imm-reg)))))
4089
4090
4091
4092
4093(defun x862-%immediate-set-ptr (seg vreg xfer ptr offset val)
4094 (with-x86-local-vinsn-macros (seg vreg xfer)
4095 (let* ((intval (acode-absolute-ptr-p val t))
4096 (offval (acode-fixnum-form-p offset))
4097 (for-value (x862-for-value-p vreg)))
4098 (flet ((address-and-node-regs ()
4099 (if for-value
4100 (progn
4101 (x862-one-targeted-reg-form seg val ($ x8664::arg_z))
4102 (progn
4103 (if intval
4104 (x862-lri seg x8664::imm0 intval)
4105 (! deref-macptr x8664::imm0 x8664::arg_z))
4106 (values x8664::imm0 x8664::arg_z)))
4107 (values (x862-macptr-arg-to-reg seg val ($ x8664::imm0 :mode :address)) nil))))
4108 (unless (typep offval '(signed-byte 32))
4109 (setq offval nil))
4110 (unless (typep intval '(signed-byte 32))
4111 (setq intval nil))
4112 (cond (intval
4113 (cond (offval
4114 (with-imm-target () (ptr-reg :address)
4115 (let* ((ptr-reg (x862-one-untargeted-reg-form seg
4116 ptr
4117 ptr-reg)))
4118 (! mem-set-c-constant-doubleword intval ptr-reg offval))))
4119 (t
4120 (with-imm-target () (ptr-reg :address)
4121 (with-imm-target (ptr-reg) (offsetreg :signed-natural)
4122 (x862-two-targeted-reg-forms seg ptr ptr-reg offset ($ x8664::arg_z))
4123 (! fixnum->signed-natural offsetreg x8664::arg_z)
4124 (! mem-set-constant-doubleword intval ptr-reg offsetreg)))))
4125 (if for-value
4126 (with-imm-target () (val-reg :s64)
4127 (x862-lri seg val-reg intval)
4128 (<- (set-regspec-mode val-reg (gpr-mode-name-value :address))))))
4129 (offval
4130 ;; Still simpler than the general case
4131 (with-imm-target () (ptr-reg :address)
4132 (x862-push-register seg
4133 (x862-one-untargeted-reg-form seg ptr ptr-reg)))
4134 (multiple-value-bind (address node)
4135 (address-and-node-regs)
4136 (with-imm-target (address) (ptr-reg :address)
4137 (x862-pop-register seg ptr-reg)
4138 (! mem-set-c-doubleword address ptr-reg offval))
4139 (if for-value
4140 (<- node))))
4141 (t
4142 (with-imm-target () (ptr-reg :address)
4143 (with-imm-target (ptr-reg) (offset-reg :address)
4144 (x862-two-targeted-reg-forms seg ptr ptr-reg offset ($ x8664::arg_z))
4145 (! fixnum->signed-natural offset-reg x8664::arg_z)
4146 (! fixnum-add2 ptr-reg offset-reg)
4147 (x862-push-register seg ptr-reg)))
4148 (multiple-value-bind (address node)
4149 (address-and-node-regs)
4150 (with-imm-target (address) (ptr-reg :address)
4151 (x862-pop-register seg ptr-reg)
4152 (! mem-set-c-doubleword address ptr-reg 0))
4153 (if for-value
4154 (<- node))))))
4155 (^))))
4156
4157
4158
4159
4160(defun x862-%immediate-store (seg vreg xfer bits ptr offset val)
4161 (with-x86-local-vinsn-macros (seg vreg xfer)
4162 (if (eql 0 (%ilogand #xf bits))
4163 (x862-%immediate-set-ptr seg vreg xfer ptr offset val)
4164 (let* ((size (logand #xf bits))
4165 (signed (not (logbitp 5 bits)))
4166 (nbits (ash size 3))
4167 (intval (acode-integer-constant-p val nbits))
4168 (ncbits (if (eql nbits 64) 32 nbits))
4169 (signed-intval (or (and intval
4170 (> intval 0)
4171 (logbitp (1- ncbits) intval)
4172 (- intval (ash 1 ncbits)))
4173 intval))
4174 (offval (acode-fixnum-form-p offset))
4175 (for-value (x862-for-value-p vreg)))
4176 (declare (fixnum size))
4177 (flet ((val-to-argz-and-imm0 ()
4178 (x862-one-targeted-reg-form seg val ($ x8664::arg_z))
4179 (if (eq size 8)
4180 (if signed
4181 (! gets64)
4182 (! getu64))
4183 (! fixnum->signed-natural x8664::imm0 x8664::arg_z))))
4184
4185 (and offval (%i> (integer-length offval) 31) (setq offval nil))
4186 (and intval (%i> (integer-length intval) 31) (setq intval nil))
4187 (and intval
4188 (case size
4189 (2
4190 (if (>= intval 32768) (setq intval (- intval 65536))))
4191 (1
4192 (if (>= intval 128) (setq intval (- intval 256))))))
4193 (cond (intval
4194 (cond (offval
4195 (with-imm-target () (ptr-reg :address)
4196 (let* ((ptr-reg (x862-one-untargeted-reg-form seg
4197 ptr
4198 ptr-reg)))
4199 (case size
4200 (8 (! mem-set-c-constant-doubleword signed-intval ptr-reg offval))
4201 (4 (! mem-set-c-constant-fullword signed-intval ptr-reg offval))
4202 (2 (! mem-set-c-constant-halfword signed-intval ptr-reg offval))
4203 (1 (! mem-set-c-constant-byte signed-intval ptr-reg offval))))))
4204 (t
4205 (with-imm-target () (ptr-reg :address)
4206 (with-imm-target (ptr-reg) (offsetreg :signed-natural)
4207 (x862-two-targeted-reg-forms seg ptr ptr-reg offset ($ x8664::arg_z))
4208 (! fixnum->signed-natural offsetreg x8664::arg_z)
4209 (case size
4210 (8 (! mem-set-constant-doubleword intval ptr-reg offsetreg))
4211 (4 (! mem-set-constant-fullword intval ptr-reg offsetreg))
4212 (2 (! mem-set-constant-halfword intval ptr-reg offsetreg))
4213 (1 (! mem-set-constant-byte intval ptr-reg offsetreg)))))))
4214 (if for-value
4215 (ensuring-node-target (target vreg)
4216 (x862-lri seg vreg (ash intval *x862-target-fixnum-shift*)))))
4217 (offval
4218 ;; simpler thant the general case
4219 (with-imm-target () (ptr-reg :address)
4220 (x862-push-register seg
4221 (x862-one-untargeted-reg-form seg ptr ptr-reg)))
4222 (val-to-argz-and-imm0)
4223 (with-imm-target (x8664::imm0) (ptr-reg :address)
4224 (x862-pop-register seg ptr-reg)
4225 (case size
4226 (8 (! mem-set-c-doubleword x8664::imm0 ptr-reg offval))
4227 (4 (! mem-set-c-fullword x8664::imm0 ptr-reg offval))
4228 (2 (! mem-set-c-halfword x8664::imm0 ptr-reg offval))
4229 (1 (! mem-set-c-byte x8664::imm0 ptr-reg offval))))
4230 (if for-value
4231 (<- x8664::arg_z)))
4232 (t
4233 (with-imm-target () (ptr-reg :address)
4234 (with-imm-target (ptr-reg) (offset-reg :address)
4235 (x862-two-targeted-reg-forms seg ptr ptr-reg offset ($ x8664::arg_z))
4236 (! fixnum->signed-natural offset-reg x8664::arg_z)
4237 (! fixnum-add2 ptr-reg offset-reg)
4238 (x862-push-register seg ptr-reg)))
4239 (val-to-argz-and-imm0)
4240 (with-imm-target (x8664::imm0) (ptr-reg :address)
4241 (x862-pop-register seg ptr-reg)
4242 (case size
4243 (8 (! mem-set-c-doubleword x8664::imm0 ptr-reg 0))
4244 (4 (! mem-set-c-fullword x8664::imm0 ptr-reg 0))
4245 (2 (! mem-set-c-halfword x8664::imm0 ptr-reg 0))
4246 (1 (! mem-set-c-byte x8664::imm0 ptr-reg 0))))
4247 (if for-value
4248 (< x8664::arg_z))))
4249
4250 (^))))))
4251
4252
4253
4254
4255
4256(defun x862-encoding-undo-count (encoding)
4257 (svref encoding 0))
4258
4259(defun x862-encoding-cstack-depth (encoding) ; hardly ever interesting
4260 (svref encoding 1))
4261
4262(defun x862-encoding-vstack-depth (encoding)
4263 (svref encoding 2))
4264
4265(defun x862-encoding-vstack-top (encoding)
4266 (svref encoding 3))
4267
4268(defun x862-encode-stack ()
4269 (vector *x862-undo-count* *x862-cstack* *x862-vstack* *x862-top-vstack-lcell*))
4270
4271(defun x862-decode-stack (encoding)
4272 (values (x862-encoding-undo-count encoding)
4273 (x862-encoding-cstack-depth encoding)
4274 (x862-encoding-vstack-depth encoding)
4275 (x862-encoding-vstack-top encoding)))
4276
4277(defun x862-equal-encodings-p (a b)
4278 (dotimes (i 3 t)
4279 (unless (eq (svref a i) (svref b i)) (return))))
4280
4281(defun x862-open-undo (&optional (reason $undocatch) (curstack (x862-encode-stack)))
4282 (set-fill-pointer
4283 *x862-undo-stack*
4284 (set-fill-pointer *x862-undo-because* *x862-undo-count*))
4285 (vector-push-extend curstack *x862-undo-stack*)
4286 (vector-push-extend reason *x862-undo-because*)
4287 (setq *x862-undo-count* (%i+ *x862-undo-count* 1)))
4288
4289(defun x862-close-undo (&aux
4290 (new-count (%i- *x862-undo-count* 1))
4291 (i (aref *x862-undo-stack* new-count)))
4292 (multiple-value-setq (*x862-undo-count* *x862-cstack* *x862-vstack* *x862-top-vstack-lcell*)
4293 (x862-decode-stack i))
4294 (set-fill-pointer
4295 *x862-undo-stack*
4296 (set-fill-pointer *x862-undo-because* new-count)))
4297
4298
4299
4300
4301
4302;;; "Trivial" means can be evaluated without allocating or modifying registers.
4303;;; Interim definition, which will probably stay here forever.
4304(defun x862-trivial-p (form &aux op bits)
4305 (setq form (nx-untyped-form form))
4306 (and
4307 (consp form)
4308 (not (eq (setq op (%car form)) (%nx1-operator call)))
4309 (or
4310 (nx-null form)
4311 (nx-t form)
4312 (eq op (%nx1-operator simple-function))
4313 (eq op (%nx1-operator fixnum))
4314 (eq op (%nx1-operator immediate))
4315 #+nil
4316 (eq op (%nx1-operator bound-special-ref))
4317 (and (or (eq op (%nx1-operator inherited-arg))
4318 (eq op (%nx1-operator lexical-reference)))
4319 (or (%ilogbitp $vbitpunted (setq bits (nx-var-bits (cadr form))))
4320 (neq (%ilogior (%ilsl $vbitclosed 1) (%ilsl $vbitsetq 1))
4321 (%ilogand (%ilogior (%ilsl $vbitclosed 1) (%ilsl $vbitsetq 1)) bits)))))))
4322
4323(defun x862-lexical-reference-p (form)
4324 (when (acode-p form)
4325 (let ((op (acode-operator (setq form (acode-unwrapped-form form)))))
4326 (when (or (eq op (%nx1-operator lexical-reference))
4327 (eq op (%nx1-operator inherited-arg)))
4328 (%cadr form)))))
4329
4330(defun x862-ref-symbol-value (seg vreg xfer sym check-boundp)
4331 (declare (ignorable check-boundp))
4332 (setq check-boundp (not *x862-reckless*))
4333 (with-x86-local-vinsn-macros (seg vreg xfer)
4334 (when vreg
4335 (if (eq sym '*interrupt-level*)
4336 (ensuring-node-target (target vreg)
4337 (! ref-interrupt-level target))
4338 (if *x862-open-code-inline*
4339 (ensuring-node-target (target vreg)
4340 (with-node-target (target) src
4341 (let* ((vcell (x862-symbol-value-cell sym))
4342 (reg (x862-register-constant-p vcell)))
4343 (if reg
4344 (setq src reg)
4345 (x862-store-immediate seg vcell src)))
4346 (if check-boundp
4347 (! ref-symbol-value-inline target src)
4348 (! %ref-symbol-value-inline target src))))
4349 (let* ((src ($ x8664::arg_z))
4350 (dest ($ x8664::arg_z)))
4351 (x862-store-immediate seg (x862-symbol-value-cell sym) src)
4352 (if check-boundp
4353 (! ref-symbol-value dest src)
4354 (! %ref-symbol-value dest src))
4355 (<- dest)))))
4356 (^)))
4357
4358;;; Should be less eager to box result
4359(defun x862-extract-charcode (seg vreg xfer char safe)
4360 (with-x86-local-vinsn-macros (seg vreg xfer)
4361 (let* ((src (x862-one-untargeted-reg-form seg char x8664::arg_z)))
4362 (when safe
4363 (! trap-unless-character src))
4364 (if vreg
4365 (ensuring-node-target (target vreg)
4366 (! character->fixnum target src)))
4367 (^))))
4368
4369
4370(defun x862-reference-list (seg vreg xfer listform safe refcdr)
4371 (if (x862-form-typep listform 'list)
4372 (setq safe nil)) ; May also have been passed as NIL.
4373 (with-x86-local-vinsn-macros (seg vreg xfer)
4374 (let* ((src (x862-one-untargeted-reg-form seg listform x8664::arg_z)))
4375 (when safe
4376 (! trap-unless-list src))
4377 (if vreg
4378 (if (eq vreg :push)
4379 (if refcdr
4380 (! %vpush-cdr src)
4381 (! %vpush-car src))
4382 (ensuring-node-target (target vreg)
4383 (if refcdr
4384 (! %cdr target src)
4385 (! %car target src)))))
4386 (^))))
4387
4388
4389
4390(defun x862-misc-byte-count (subtag element-count)
4391 (funcall (arch::target-array-data-size-function
4392 (backend-target-arch *target-backend*))
4393 subtag element-count))
4394
4395
4396;;; The naive approach is to vpush all of the initforms, allocate the
4397;;; miscobj, then sit in a loop vpopping the values into the vector.
4398;;; That's "naive" when most of the initforms in question are
4399;;; "side-effect-free" (constant references or references to un-SETQed
4400;;; lexicals), in which case it makes more sense to just store the
4401;;; things into the vector cells, vpushing/ vpopping only those things
4402;;; that aren't side-effect-free. (It's necessary to evaluate any
4403;;; non-trivial forms before allocating the miscobj, since that
4404;;; ensures that the initforms are older (in the EGC sense) than it
4405;;; is.) The break-even point space-wise is when there are around 3
4406;;; non-trivial initforms to worry about.
4407
4408
4409(defun x862-allocate-initialized-gvector (seg vreg xfer subtag initforms)
4410 (with-x86-local-vinsn-macros (seg vreg xfer)
4411 (if (null vreg)
4412 (dolist (f initforms) (x862-form seg nil nil f))
4413 (let* ((*x862-vstack* *x862-vstack*)
4414 (*x862-top-vstack-lcell* *x862-top-vstack-lcell*)
4415 (arch (backend-target-arch *target-backend*))
4416 (n (length initforms))
4417 (nntriv (let* ((count 0))
4418 (declare (fixnum count))
4419 (dolist (f initforms count)
4420 (unless (x86-side-effect-free-form-p f)
4421 (incf count)))))
4422 (header (arch::make-vheader n subtag)))
4423 (declare (fixnum n nntriv))
4424 (cond ((or *x862-open-code-inline* (> nntriv 3))
4425 (x862-formlist seg initforms nil)
4426 (x862-lri seg x8664::imm0 header)
4427 (x862-lri seg x8664::imm1 (- (ash (logandc2 (+ n 2) 1) (arch::target-word-shift arch)) (target-arch-case (:x8664 x8664::fulltag-misc))))
4428 (! %allocate-uvector vreg)
4429 (unless (eql n 0)
4430 (! %init-gvector vreg (ash n (arch::target-word-shift arch)))))
4431 (t
4432 (let* ((pending ())
4433 (vstack *x862-vstack*))
4434 (declare (fixnum vstack))
4435 (dolist (form initforms)
4436 (if (x86-side-effect-free-form-p form)
4437 (push form pending)
4438 (progn
4439 (push nil pending)
4440 (x862-vpush-register seg (x862-one-untargeted-reg-form seg form x8664::arg_z)))))
4441 (x862-lri seg x8664::imm0 header)
4442 (x862-lri seg x8664::imm1 (- (ash (logandc2 (+ n 2) 1) (arch::target-word-shift arch)) (target-arch-case (:x8664 x8664::fulltag-misc))))
4443 (ensuring-node-target (target vreg)
4444 (! %allocate-uvector target)
4445 (with-node-temps (target) (nodetemp)
4446 (do* ((forms pending (cdr forms))
4447 (index (1- n) (1- index))
4448 (pushed-cell (+ vstack (the fixnum (ash nntriv (arch::target-word-shift arch))))))
4449 ((null forms))
4450 (declare (list forms) (fixnum pushed-cell))
4451 (let* ((form (car forms))
4452 (reg nodetemp))
4453 (if form
4454 (setq reg (x862-one-untargeted-reg-form seg form nodetemp))
4455 (progn
4456 (decf pushed-cell *x862-target-node-size*)
4457 (x862-stack-to-register seg (x862-vloc-ea pushed-cell) nodetemp)))
4458 (! misc-set-c-node reg target index)))))
4459 (! vstack-discard nntriv))
4460 ))))
4461 (^)))
4462
4463;;; Heap-allocated constants -might- need memoization: they might be newly-created,
4464;;; as in the case of synthesized toplevel functions in .pfsl files.
4465(defun x862-acode-needs-memoization (valform)
4466 (if (x862-form-typep valform 'fixnum)
4467 nil
4468 (let* ((val (acode-unwrapped-form valform)))
4469 (if (or (eq val *nx-t*)
4470 (eq val *nx-nil*)
4471 (and (acode-p val)
4472 (let* ((op (acode-operator val)))
4473 (or (eq op (%nx1-operator fixnum)) #|(eq op (%nx1-operator immediate))|#))))
4474 nil
4475 t))))
4476
4477(defun x862-modify-cons (seg vreg xfer ptrform valform safe setcdr returnptr)
4478 (if (x862-form-typep ptrform 'cons)
4479 (setq safe nil)) ; May also have been passed as NIL.
4480 (with-x86-local-vinsn-macros (seg vreg xfer)
4481 (multiple-value-bind (ptr-vreg val-vreg) (x862-two-targeted-reg-forms seg ptrform ($ x8664::arg_y) valform ($ x8664::arg_z))
4482 (when safe
4483 (! trap-unless-cons ptr-vreg))
4484 (if setcdr
4485 (! call-subprim-2 ($ x8664::arg_z) (subprim-name->offset '.SPrplacd) ptr-vreg val-vreg)
4486 (! call-subprim-2 ($ x8664::arg_z) (subprim-name->offset '.SPrplaca) ptr-vreg val-vreg))
4487 (if returnptr
4488 (<- ptr-vreg)
4489 (<- val-vreg))
4490 (^))))
4491
4492
4493
4494(defun x862-find-nilret-label ()
4495 (dolist (l *x862-nilret-labels*)
4496 (destructuring-bind (label vsp csp register-restore-count register-restore-ea &rest agenda) l
4497 (and (or (and (eql 0 register-restore-count)
4498 (or (not (eql 0 vsp))
4499 (eq vsp *x862-vstack*)))
4500 (and
4501 (eq register-restore-count *x862-register-restore-count*)
4502 (eq vsp *x862-vstack*)))
4503 (or agenda (eq csp *x862-cstack*))
4504 (eq register-restore-ea *x862-register-restore-ea*)
4505 (eq (%ilsr 1 (length agenda)) *x862-undo-count*)
4506 (dotimes (i (the fixnum *x862-undo-count*) t)
4507 (unless (and (eq (pop agenda) (aref *x862-undo-because* i))
4508 (eq (pop agenda) (aref *x862-undo-stack* i)))
4509 (return)))
4510 (return label)))))
4511
4512(defun x862-record-nilret-label ()
4513 (let* ((lab (backend-get-next-label))
4514 (info nil))
4515 (dotimes (i (the fixnum *x862-undo-count*))
4516 (push (aref *x862-undo-because* i) info)
4517 (push (aref *x862-undo-stack* i) info))
4518 (push (cons
4519 lab
4520 (cons
4521 *x862-vstack*
4522 (cons
4523 *x862-cstack*
4524 (cons
4525 *x862-register-restore-count*
4526 (cons
4527 *x862-register-restore-ea*
4528 (nreverse info))))))
4529 *x862-nilret-labels*)
4530 lab))
4531
4532;;; If we know that the form is something that sets a CR bit,
4533;;; allocate a CR field and evaluate the form in such a way
4534;;; as to set that bit.
4535;;; If it's a compile-time constant, branch accordingly and
4536;;; let the dead code die.
4537;;; Otherwise, evaluate it to some handy register and compare
4538;;; that register to RNIL.
4539;;; "XFER" is a compound destination.
4540(defun x862-conditional-form (seg xfer form)
4541 (let* ((uwf (acode-unwrapped-form form)))
4542 (if (nx-null uwf)
4543 (x862-branch seg (x862-cd-false xfer))
4544 (if (x86-constant-form-p uwf)
4545 (x862-branch seg (x862-cd-true xfer))
4546 (with-crf-target () crf
4547 (let* ((ea (x862-lexical-reference-ea form nil)))
4548 (if (and ea (memory-spec-p ea))
4549 (x862-compare-ea-to-nil seg crf xfer ea x86::x86-e-bits nil)
4550 (x862-form seg crf xfer form))))))))
4551
4552
4553(defun x862-branch (seg xfer &optional cr-bit true-p)
4554 (let* ((*x862-vstack* *x862-vstack*)
4555 (*x862-top-vstack-lcell* *x862-top-vstack-lcell*))
4556 (with-x86-local-vinsn-macros (seg)
4557 (setq xfer (or xfer 0))
4558 (when (logbitp $backend-mvpass-bit xfer) ;(x862-mvpass-p cd)
4559 (setq xfer (logand (lognot $backend-mvpass-mask) xfer))
4560 (unless *x862-returning-values*
4561 (x862-vpush-register seg x8664::arg_z)
4562 (x862-set-nargs seg 1)))
4563 (if (neq 0 xfer)
4564 (if (eq xfer $backend-return) ;; xfer : RETURN ==> popj
4565 (x862-do-return seg)
4566 (if (not (x862-cd-compound-p xfer))
4567 (-> xfer) ;; xfer : label# ==> jmp label#
4568 ;; cd is compound : (<true> / <false>)
4569 (let* ((truebranch (x862-cd-true xfer))
4570 (falsebranch (x862-cd-false xfer))
4571 (tbranch (if true-p truebranch falsebranch))
4572 (nbranch (if true-p falsebranch truebranch))
4573 (tn0 (neq 0 tbranch))
4574 (tnret (neq $backend-return tbranch))
4575 (nn0 (neq 0 nbranch))
4576 (nnret (neq $backend-return nbranch))
4577 (tlabel (if (and tnret tn0) (aref *backend-labels* tbranch)))
4578 (nlabel (if (and nnret nn0) (aref *backend-labels* nbranch))))
4579 (unless cr-bit (setq cr-bit x86::x86-e-bits))
4580 (if (and tn0 tnret nn0 nnret)
4581 (progn
4582 (! cbranch-true tlabel cr-bit ) ;; (label# / label#)
4583 (-> nbranch)))
4584 (if (and nnret tnret)
4585 (if nn0
4586 (! cbranch-false nlabel cr-bit)
4587 (! cbranch-true tlabel cr-bit))
4588 (let* ((aux-label (backend-get-next-label))
4589 (auxl (aref *backend-labels* aux-label)))
4590 (if tn0
4591 (! cbranch-true auxl cr-bit)
4592 (! cbranch-false auxl cr-bit) )
4593 (x862-do-return seg)
4594 (@ aux-label))))))))))
4595
4596(defun x862-cd-merge (cd label)
4597 (setq cd (or cd 0))
4598 (let ((mvpass (logbitp $backend-mvpass-bit cd)))
4599 (if (neq 0 (logand (lognot $backend-mvpass-mask) cd))
4600 (if (x862-cd-compound-p cd)
4601 (x862-make-compound-cd
4602 (x862-cd-merge (x862-cd-true cd) label)
4603 (x862-cd-merge (x862-cd-false cd) label)
4604 mvpass)
4605 cd)
4606 (if mvpass
4607 (logior $backend-mvpass-mask label)
4608 label))))
4609
4610(defun x862-mvpass-p (xfer)
4611 (if xfer (or (logbitp $backend-mvpass-bit xfer) (eq xfer $backend-mvpass))))
4612
4613(defun x862-cd-compound-p (xfer)
4614 (if xfer (logbitp $backend-compound-branch-target-bit xfer)))
4615
4616(defun x862-cd-true (xfer)
4617 (if (x862-cd-compound-p xfer)
4618 (ldb $backend-compound-branch-true-byte xfer)
4619 xfer))
4620
4621(defun x862-cd-false (xfer)
4622 (if (x862-cd-compound-p xfer)
4623 (ldb $backend-compound-branch-false-byte xfer)
4624 xfer))
4625
4626(defun x862-make-compound-cd (tpart npart &optional mvpass-p)
4627 (dpb (or npart 0) $backend-compound-branch-false-byte
4628 (dpb (or tpart 0) $backend-compound-branch-true-byte
4629 (logior (if mvpass-p $backend-mvpass-mask 0) $backend-compound-branch-target-mask))))
4630
4631(defun x862-invert-cd (cd)
4632 (if (x862-cd-compound-p cd)
4633 (x862-make-compound-cd (x862-cd-false cd) (x862-cd-true cd) (logbitp $backend-mvpass-bit cd))
4634 cd))
4635
4636(defun x862-long-constant-p (form)
4637 (setq form (acode-unwrapped-form form))
4638 (or (acode-fixnum-form-p form)
4639 (and (acode-p form)
4640 (eq (acode-operator form) (%nx1-operator immediate))
4641 (setq form (%cadr form))
4642 (if (integerp form)
4643 form
4644 (progn
4645 (if (symbolp form) (setq form (symbol-name form)))
4646 (if (and (stringp form) (eql (length form) 4))
4647 (logior (ash (%char-code (char form 0)) 24)
4648 (ash (%char-code (char form 1)) 16)
4649 (ash (%char-code (char form 2)) 8)
4650 (%char-code (char form 3)))
4651 (if (characterp form) (%char-code form))))))))
4652
4653;;; execute body, cleanup afterwards (if need to)
4654(defun x862-undo-body (seg vreg xfer body old-stack)
4655 (let* ((current-stack (x862-encode-stack))
4656 (numundo (%i- *x862-undo-count* (x862-encoding-undo-count old-stack))))
4657 (declare (fixnum numundo))
4658 (with-x86-local-vinsn-macros (seg vreg xfer)
4659 (if (eq current-stack old-stack)
4660 (x862-form seg vreg xfer body)
4661 (if (eq xfer $backend-return)
4662 (progn
4663 (x862-form seg vreg xfer body)
4664 (dotimes (i numundo) (x862-close-undo)))
4665 (if (x862-mvpass-p xfer)
4666 (progn
4667 (x862-mvpass seg body) ; presumed to be ok
4668 (let* ((*x862-returning-values* :pass))
4669 (x862-nlexit seg xfer numundo)
4670 (^))
4671 (dotimes (i numundo) (x862-close-undo)))
4672 (progn
4673 ;; There are some cases where storing thru x8664::arg_z
4674 ;; can be avoided (stores to vlocs, specials, etc.) and
4675 ;; some other case where it can't ($test, $vpush.) The
4676 ;; case of a null vd can certainly avoid it; the check
4677 ;; of numundo is to keep $acc boxed in case of nthrow.
4678 (x862-form seg (if (or vreg (not (%izerop numundo))) x8664::arg_z) nil body)
4679 (x862-unwind-set seg xfer old-stack)
4680 (when vreg (<- x8664::arg_z))
4681 (^))))))))
4682
4683
4684(defun x862-unwind-set (seg xfer encoding)
4685 (multiple-value-bind (target-catch target-cstack target-vstack target-vstack-lcell)
4686 (x862-decode-stack encoding)
4687 (x862-unwind-stack seg xfer target-catch target-cstack target-vstack)
4688 (setq *x862-undo-count* target-catch
4689 *x862-cstack* target-cstack
4690 *x862-vstack* target-vstack
4691 *x862-top-vstack-lcell* target-vstack-lcell)))
4692
4693(defun x862-unwind-stack (seg xfer target-catch target-cstack target-vstack)
4694 (let* ((current-catch *x862-undo-count*)
4695 (current-cstack *x862-cstack*)
4696 (current-vstack *x862-vstack*)
4697 (diff (%i- current-catch target-catch))
4698 target
4699 (exit-vstack current-vstack))
4700 (declare (ignorable target))
4701 (when (neq 0 diff)
4702 (setq exit-vstack (x862-nlexit seg xfer diff))
4703 (multiple-value-setq (target current-cstack current-vstack)
4704 (x862-decode-stack (aref *x862-undo-stack* target-catch))))
4705 (if (%i< 0 (setq diff (%i- current-cstack target-cstack)))
4706 (error "Bug: adjust foreign stack ?"))
4707 (if (%i< 0 (setq diff (%i- current-vstack target-vstack)))
4708 (with-x86-local-vinsn-macros (seg)
4709 (! vstack-discard (ash diff (- *x862-target-fixnum-shift*)))))
4710 exit-vstack))
4711
4712;;; We can sometimes combine unwinding the catch stack with returning
4713;;; from the function by jumping to a subprim that knows how to do
4714;;; this. If catch frames were distinguished from unwind-protect
4715;;; frames, we might be able to do this even when saved registers are
4716;;; involved (but the subprims restore them from the last catch
4717;;; frame.) *** there are currently only subprims to handle the "1
4718;;; frame" case; add more ***
4719(defun x862-do-return (seg)
4720 (let* ((*x862-vstack* *x862-vstack*)
4721 (*x862-top-vstack-lcell* *x862-top-vstack-lcell*)
4722 (mask *x862-register-restore-count*)
4723 (ea *x862-register-restore-ea*)
4724 (label nil)
4725 (vstack nil)
4726 (foldp (not *x862-open-code-inline*)))
4727 (if (%izerop mask) (setq mask nil))
4728 (with-x86-local-vinsn-macros (seg)
4729 (progn
4730 (setq vstack (x862-set-vstack (x862-unwind-stack seg $backend-return 0 0 #x7fffff)))
4731 (if *x862-returning-values*
4732 (cond ((and mask foldp (setq label (%cdr (assq vstack *x862-valret-labels*))))
4733 (-> label))
4734 (t
4735 (@ (setq label (backend-get-next-label)))
4736 (push (cons vstack label) *x862-valret-labels*)
4737 (x862-restore-nvrs seg ea mask nil)
4738 (! nvalret)))
4739 (if (null mask)
4740 (! popj)
4741 (if (and foldp (setq label (assq *x862-vstack* *x862-popreg-labels*)))
4742 (-> (cdr label))
4743 (let* ((new-label (backend-get-next-label)))
4744 (@ new-label)
4745 (push (cons *x862-vstack* new-label) *x862-popreg-labels*)
4746 (x862-set-vstack (x862-restore-nvrs seg ea mask))
4747 (! popj)))))))
4748 nil))
4749
4750
4751(defun x862-mvcall (seg vreg xfer fn arglist &optional recursive-p)
4752 (with-x86-local-vinsn-macros (seg vreg xfer)
4753 (if (and (eq xfer $backend-return) (not (x862-tailcallok xfer)))
4754 (progn
4755 (x862-mvcall seg vreg $backend-mvpass fn arglist t)
4756 (let* ((*x862-returning-values* t)) (^)))
4757 (let* ((mv-p (x862-mv-p xfer)))
4758 (if (null arglist)
4759 (x862-call-fn seg vreg xfer fn arglist nil)
4760 (let* ((label (when (or recursive-p (x862-mvpass-p xfer)) (backend-get-next-label))))
4761 (when label
4762 (x862-vpush-label seg (aref *backend-labels* label)))
4763 (x862-temp-push-node seg (x862-one-untargeted-reg-form seg fn x8664::arg_z))
4764 (x862-multiple-value-body seg (pop arglist))
4765 (x862-open-undo $undostkblk)
4766 (! save-values)
4767 (dolist (form arglist)
4768 (x862-multiple-value-body seg form)
4769 (! add-values))
4770 (! recover-values-for-mvcall)
4771 (x862-close-undo)
4772 (x862-temp-pop-node seg x8664::temp0)
4773 (x862-invoke-fn seg x8664::temp0 nil nil xfer label)
4774 (when label
4775 ;; Pushed a label earlier, then returned to it.
4776 (setq *x862-top-vstack-lcell* (lcell-parent *x862-top-vstack-lcell*))
4777 (x862-adjust-vstack (- *x862-target-node-size*)))))
4778 (unless recursive-p
4779 (if mv-p
4780 (unless (eq xfer $backend-return)
4781 (let* ((*x862-returning-values* t))
4782 (^)))
4783 (progn
4784 (<- x8664::arg_z)
4785 (^))))))))
4786
4787
4788
4789
4790(defun x862-hard-opt-p (opts)
4791 (or
4792 (dolist (x (%cadr opts))
4793 (unless (nx-null x) (return t)))
4794 (dolist (x (%caddr opts))
4795 (when x (return t)))))
4796
4797(defun x862-close-lambda (seg req opt rest keys auxen)
4798 (dolist (var req)
4799 (x862-close-var seg var))
4800 (dolist (var (%car opt))
4801 (x862-close-var seg var))
4802 (dolist (var (%caddr opt))
4803 (when var
4804 (x862-close-var seg var)))
4805 (if rest
4806 (x862-close-var seg rest))
4807 (dolist (var (%cadr keys))
4808 (x862-close-var seg var))
4809 (dolist (var (%caddr keys))
4810 (if var (x862-close-var seg var)))
4811 (dolist (var (%car auxen))
4812 (x862-close-var seg var)))
4813
4814(defun x862-close-structured-var (seg var)
4815 (if (x862-structured-var-p var)
4816 (apply #'x862-close-structured-lambda seg (cdr var))
4817 (x862-close-var seg var)))
4818
4819(defun x862-close-structured-lambda (seg whole req opt rest keys auxen)
4820 (if whole
4821 (x862-close-var seg whole))
4822 (dolist (var req)
4823 (x862-close-structured-var seg var))
4824 (dolist (var (%car opt))
4825 (x862-close-structured-var seg var))
4826 (dolist (var (%caddr opt))
4827 (when var
4828 (x862-close-var seg var)))
4829 (if rest
4830 (x862-close-structured-var seg rest))
4831 (dolist (var (%cadr keys))
4832 (x862-close-structured-var seg var))
4833 (dolist (var (%caddr keys))
4834 (if var (x862-close-var seg var)))
4835 (dolist (var (%car auxen))
4836 (x862-close-var seg var)))
4837
4838
4839(defun x862-init-regvar (seg var reg addr)
4840 (with-x86-local-vinsn-macros (seg)
4841 (x862-stack-to-register seg addr reg)
4842 (x862-set-var-ea seg var ($ reg))))
4843
4844(defun x862-bind-structured-var (seg var vloc lcell &optional context)
4845 (if (not (x862-structured-var-p var))
4846 (let* ((reg (x862-assign-register-var var)))
4847 (if reg
4848 (x862-init-regvar seg var reg (x862-vloc-ea vloc))
4849 (x862-bind-var seg var vloc lcell)))
4850 (let* ((v2 (%cdr var))
4851 (v v2)
4852 (vstack *x862-vstack*)
4853 (whole (pop v))
4854 (req (pop v))
4855 (opt (pop v))
4856 (rest (pop v))
4857 (keys (pop v)))
4858
4859 (apply #'x862-bind-structured-lambda seg
4860 (x862-spread-lambda-list seg (x862-vloc-ea vloc) whole req opt rest keys context)
4861 vstack context v2))))
4862
4863(defun x862-bind-structured-lambda (seg lcells vloc context whole req opt rest keys auxen
4864 &aux (nkeys (list-length (%cadr keys))))
4865 (declare (fixnum vloc))
4866 (when whole
4867 (x862-bind-structured-var seg whole vloc (pop lcells))
4868 (incf vloc *x862-target-node-size*))
4869 (dolist (arg req)
4870 (x862-bind-structured-var seg arg vloc (pop lcells) context)
4871 (incf vloc *x862-target-node-size*))
4872 (when opt
4873 (if (x862-hard-opt-p opt)
4874 (setq vloc (apply #'x862-structured-initopt seg lcells vloc context opt)
4875 lcells (nthcdr (ash (length (car opt)) 1) lcells))
4876 (dolist (var (%car opt))
4877 (x862-bind-structured-var seg var vloc (pop lcells) context)
4878 (incf vloc *x862-target-node-size*))))
4879 (when rest
4880 (x862-bind-structured-var seg rest vloc (pop lcells) context)
4881 (incf vloc *x862-target-node-size*))
4882 (when keys
4883 (apply #'x862-structured-init-keys seg lcells vloc context keys)
4884 (setq vloc (%i+ vloc (* *x862-target-node-size* (+ nkeys nkeys)))))
4885 (x862-seq-bind seg (%car auxen) (%cadr auxen)))
4886
4887(defun x862-structured-var-p (var)
4888 (and (consp var) (or (eq (%car var) *nx-lambdalist*)
4889 (eq (%car var) (%nx1-operator lambda-list)))))
4890
4891(defun x862-simple-var (var &aux (bits (cadr var)))
4892 (if (or (%ilogbitp $vbitclosed bits)
4893 (%ilogbitp $vbitspecial bits))
4894 (nx-error "Non-simple-variable ~S" (%car var))
4895 var))
4896
4897(defun x862-nlexit (seg xfer &optional (nlevels 0))
4898 (let* ((numnthrow 0)
4899 (n *x862-undo-count*)
4900 (cstack *x862-cstack*)
4901 (vstack *x862-vstack*)
4902 (target-vstack)
4903 (lastcatch n)
4904 (returning (eq xfer $backend-return))
4905 (junk1 nil)
4906 (unbind ())
4907 (dest (%i- n nlevels))
4908 (retval *x862-returning-values*)
4909 reason)
4910 (declare (ignorable junk1))
4911 (with-x86-local-vinsn-macros (seg)
4912 (when (neq 0 nlevels)
4913 (let* ((num-temp-frames 0)
4914 (num-c-frames 0))
4915 (declare (fixnum numnlispareas num-c-frames))
4916 (flet ((pop-temp-frames ()
4917 (dotimes (i num-temp-frames)
4918 (! discard-temp-frame)))
4919 (pop-c-frames ()
4920 (dotimes (i num-c-frames)
4921 (! discard-c-frame)))
4922 (throw-through-numnthrow-catch-frames ()
4923 (when (neq 0 numnthrow)
4924 (let* ((tag-label (backend-get-next-label))
4925 (tag-label-value (aref *backend-labels* tag-label)))
4926 (x862-lri seg x8664::imm0 (ash numnthrow *x862-target-fixnum-shift*))
4927 (if retval
4928 (! nthrowvalues tag-label-value)
4929 (! nthrow1value tag-label-value))
4930 (@= tag-label))
4931 (setq numnthrow 0)
4932 (multiple-value-setq (junk1 cstack vstack)
4933 (x862-decode-stack (aref *x862-undo-stack* lastcatch)))))
4934 (find-last-catch ()
4935 (do* ((n n)
4936 (reasons *x862-undo-because*))
4937 ((= n dest))
4938 (declare (fixnum n))
4939 (when (eql $undocatch (aref reasons (decf n)))
4940 (incf numnthrow)
4941 (setq lastcatch n)))))
4942
4943 (find-last-catch)
4944 (throw-through-numnthrow-catch-frames)
4945 (setq n lastcatch)
4946 (while (%i> n dest)
4947 (setq reason (aref *x862-undo-because* (setq n (%i- n 1))))
4948 (cond ((eql $undostkblk reason)
4949 (incf num-temp-frames))
4950 ((eql $undo-x86-c-frame reason)
4951 (incf num-c-frames))
4952 ((or (eql reason $undospecial)
4953 (eql reason $undointerruptlevel))
4954 (push reason unbind))))
4955 (if unbind
4956 (let* ((*available-backend-imm-temps* *available-backend-imm-temps*))
4957 (when retval (use-imm-temp x8664::nargs.q))
4958 (x862-dpayback-list seg (nreverse unbind))))
4959 (when (and (neq lastcatch dest)
4960 (%i>
4961 vstack
4962 (setq target-vstack
4963 (nth-value 2 (x862-decode-stack (aref *x862-undo-stack* dest)))))
4964 (neq retval t))
4965 (unless returning
4966 (let ((vdiff (%i- vstack target-vstack)))
4967 (if retval
4968 (progn
4969 (x862-lri seg x8664::imm0 vdiff)
4970 (! slide-values))
4971 (! adjust-vsp vdiff)))))
4972 (pop-temp-frames)
4973 (pop-c-frames)))
4974 vstack))))
4975
4976
4977;;; Restore the most recent dynamic bindings. Bindings
4978;;; of *INTERRUPT-LEVEL* get special treatment.
4979(defun x862-dpayback-list (seg reasons)
4980 (with-x86-local-vinsn-macros (seg)
4981 (let* ((n 0))
4982 (declare (fixnum n))
4983 (dolist (r reasons (if (> n 0) (! dpayback n)))
4984 (if (eql r $undospecial)
4985 (incf n)
4986 (if (eql r $undointerruptlevel)
4987 (progn
4988 (when (> n 0)
4989 (! dpayback n)
4990 (setq n 0))
4991 (if *x862-open-code-inline*
4992 (let* ((*available-backend-node-temps* (bitclr x8664::arg_z (bitclr x8664::rcx *available-backend-node-temps*))))
4993 (! unbind-interrupt-level-inline))
4994 (! unbind-interrupt-level)))
4995 (nx-error "unknown payback token ~s" r)))))))
4996
4997(defun x862-spread-lambda-list (seg listform whole req opt rest keys
4998 &optional enclosing-ea cdr-p)
4999 (with-x86-local-vinsn-macros (seg)
5000 (let* ((numopt (length (%car opt)))
5001 (nkeys (length (%cadr keys)))
5002 (numreq (length req))
5003 (vtotal numreq)
5004 (old-top *x862-top-vstack-lcell*)
5005 (argreg ($ x8664::temp0))
5006 (keyvectreg ($ x8664::arg_x))
5007 (doadlword (dpb nkeys (byte 8 16) (dpb numopt (byte 8 8) (dpb numreq (byte 8 0) 0 )))))
5008 (declare (fixnum numopt nkeys numreq vtotal doadlword))
5009 (when (or (> numreq 255) (> numopt 255) (> nkeys 255))
5010 (error "A lambda list can contain a maximum of 255 required, 255 optional, and 255 keywords args"))
5011 (if (fixnump listform)
5012 (x862-store-ea seg listform argreg)
5013 (x862-one-targeted-reg-form seg listform argreg))
5014 (when whole
5015 (x862-vpush-register seg argreg :reserved))
5016 (when keys
5017 (setq doadlword (%ilogior2 (ash #x80000000 -6) doadlword))
5018 (incf vtotal (%ilsl 1 nkeys))
5019 (if (%car keys) ; &allow-other-keys
5020 (setq doadlword (%ilogior doadlword (ash #x80000000 -5))))
5021 (x862-store-immediate seg (%car (%cdr (%cdr (%cdr (%cdr keys))))) keyvectreg))
5022 (when opt
5023 (setq vtotal (%i+ vtotal numopt))
5024 (when (x862-hard-opt-p opt)
5025 (setq doadlword (%ilogior2 doadlword (ash #x80000000 -7)))
5026 (setq vtotal (%i+ vtotal numopt))))
5027 (when rest
5028 (setq doadlword (%ilogior2 (ash #x80000000 -4) doadlword) vtotal (%i+ vtotal 1)))
5029 (x862-reserve-vstack-lcells vtotal)
5030 (! load-adl doadlword)
5031 (if cdr-p
5032 (! macro-bind)
5033 (if enclosing-ea
5034 (progn
5035 (x862-store-ea seg enclosing-ea x8664::arg_z)
5036 (! destructuring-bind-inner))
5037 (! destructuring-bind)))
5038 (x862-set-vstack (%i+ *x862-vstack* (* *x862-target-node-size* vtotal)))
5039 (x862-collect-lcells :reserved old-top))))
5040
5041
5042(defun x862-tailcallok (xfer)
5043 (and (eq xfer $backend-return)
5044 *x862-tail-allow*
5045 (eq 0 *x862-undo-count*)))
5046
5047(defun x862-mv-p (cd)
5048 (or (eq cd $backend-return) (x862-mvpass-p cd)))
5049
5050(defun x862-expand-note (frag-list note)
5051 (let* ((lab (vinsn-note-label note)))
5052 (case (vinsn-note-class note)
5053 ((:regsave :begin-variable-scope :end-variable-scope)
5054 (setf (vinsn-label-info lab) (emit-x86-lap-label frag-list lab))))))
5055
5056(defun x86-emit-instruction-from-vinsn (opcode-template
5057 form
5058 frag-list
5059 instruction
5060 immediate-operand)
5061 #+debug
5062 (format t "~&~a" (cons (x86::x86-opcode-template-mnemonic opcode-template)
5063 form))
5064 (set-x86-instruction-template instruction opcode-template)
5065 (let* ((operand-classes (x86::x86-opcode-template-operand-classes
5066 opcode-template))
5067 (operand-types (x86::x86-opcode-template-operand-types
5068 opcode-template))
5069 (register-table (target-arch-case
5070 (:x8664 x86::*x8664-register-entries*))))
5071 (dotimes (i (length operand-classes))
5072 (let* ((operand (pop form))
5073 (insert-function (svref operand-classes i))
5074 (type (svref operand-types i))
5075 (insert-keyword (svref x86::*x86-operand-insert-function-keywords*
5076 insert-function)))
5077 #+debug
5078 (format t "~& insert-function = ~s, operand = ~s"
5079 insert-keyword
5080 operand)
5081 (ecase insert-keyword
5082 (:insert-nothing )
5083 ((:insert-modrm-reg :insert-xmm-reg)
5084 (x86::insert-modrm-reg-entry instruction
5085 (if (logtest (x86::encode-operand-type
5086 :reg8)
5087 type)
5088 (x86::x86-reg8 operand)
5089 (svref register-table operand))))
5090 ((:insert-modrm-rm :insert-xmm-rm)
5091 (x86::insert-modrm-rm-entry instruction
5092 (if (logtest (x86::encode-operand-type
5093 :reg8)
5094 type)
5095 (x86::x86-reg8 operand)
5096 (svref register-table operand))))
5097 (:insert-memory
5098 (destructuring-bind (seg disp base index scale) operand
5099 (when seg (setq seg
5100 (svref x86::*x86-seg-entries* (x86::reg-entry-reg-num (svref register-table seg)))))
5101 ;; Optimize things like this later; almost all
5102 ;; displacements will be constants at this point.
5103 (when disp (setq disp (parse-x86-lap-expression disp)))
5104 (when base (setq base (svref register-table base)))
5105 (when index (setq index (svref register-table index)))
5106 (when scale (setq scale (1- (integer-length scale))))
5107 (x86::insert-memory-operand-values
5108 instruction
5109 seg
5110 disp
5111 base
5112 index
5113 scale
5114 (if (or base index)
5115 (if disp
5116 (logior (optimize-displacement-type disp)
5117 (x86::encode-operand-type :baseindex))
5118 (x86::encode-operand-type :baseindex))
5119 (optimize-displacement-type disp)))))
5120 (:insert-opcode-reg
5121 (x86::insert-opcode-reg-entry instruction
5122 (if (logtest (x86::encode-operand-type
5123 :reg8)
5124 type)
5125 (x86::x86-reg8 operand)
5126 (svref register-table operand))))
5127 (:insert-opcode-reg4
5128 (x86::insert-opcode-reg4-entry instruction
5129 (if (logtest (x86::encode-operand-type
5130 :reg8)
5131 type)
5132 (x86::x86-reg8 operand)
5133 (svref register-table operand))))
5134 (:insert-reg4-pseudo-rm-high
5135 (x86::insert-reg4-pseudo-rm-high-entry instruction
5136 (svref register-table operand)))
5137 (:insert-reg4-pseudo-rm-low
5138 (x86::insert-reg4-pseudo-rm-low-entry instruction
5139 (svref register-table operand)))
5140 (:insert-cc
5141 (unless (typep operand 'x86-lap-expression)
5142 (setq operand (parse-x86-lap-expression operand)))
5143 (setf (ldb (byte 4 0)
5144 (x86::x86-instruction-base-opcode instruction))
5145 (x86-lap-expression-value operand)))
5146 (:insert-label
5147 (setf (x86::x86-instruction-extra instruction)
5148 (find-or-create-x86-lap-label operand)))
5149 (:insert-imm8-for-int
5150 )
5151 (:insert-extra
5152 )
5153 (:insert-imm8
5154 (setf (x86::x86-immediate-operand-type immediate-operand)
5155 (x86::encode-operand-type :imm8)
5156 (x86::x86-immediate-operand-value immediate-operand)
5157 (parse-x86-lap-expression operand)
5158 (x86::x86-instruction-imm instruction)
5159 immediate-operand))
5160 (:insert-imm8s
5161 (setf (x86::x86-immediate-operand-type immediate-operand)
5162 (x86::encode-operand-type :imm8s)
5163 (x86::x86-immediate-operand-value immediate-operand)
5164 (parse-x86-lap-expression operand)
5165 (x86::x86-instruction-imm instruction)
5166 immediate-operand))
5167 (:insert-imm16
5168 (setf (x86::x86-immediate-operand-type immediate-operand)
5169 (x86::encode-operand-type :imm16)
5170 (x86::x86-immediate-operand-value immediate-operand)
5171 (parse-x86-lap-expression operand)
5172 (x86::x86-instruction-imm instruction)
5173 immediate-operand))
5174 (:insert-imm32s
5175 (setf (x86::x86-immediate-operand-type immediate-operand)
5176 (x86::encode-operand-type :imm32s)
5177 (x86::x86-immediate-operand-value immediate-operand)
5178 (parse-x86-lap-expression operand)
5179 (x86::x86-instruction-imm instruction)
5180 immediate-operand))
5181 (:insert-imm32
5182 (setf (x86::x86-immediate-operand-type immediate-operand)
5183 (x86::encode-operand-type :imm32)
5184 (x86::x86-immediate-operand-value immediate-operand)
5185 (parse-x86-lap-expression operand)
5186 (x86::x86-instruction-imm instruction)
5187 immediate-operand))
5188 (:insert-imm64
5189 (setf (x86::x86-immediate-operand-type immediate-operand)
5190 (x86::encode-operand-type :imm64)
5191 (x86::x86-immediate-operand-value immediate-operand)
5192 (parse-x86-lap-expression operand)
5193 (x86::x86-instruction-imm instruction)
5194 immediate-operand))
5195 (:insert-mmx-reg
5196 (x86::insert-mmx-reg-entry instruction
5197 (svref register-table operand)))
5198 (:insert-mmx-rm
5199 (x86::insert-mmx-rm-entry instruction
5200 (svref register-table operand))))))
5201 (x86-generate-instruction-code frag-list instruction)))
5202
5203
5204(defun x862-expand-vinsns (header frag-list instruction)
5205 (let* ((immediate-operand (x86::make-x86-immediate-operand)))
5206 (do-dll-nodes (v header)
5207 (if (%vinsn-label-p v)
5208 (let* ((id (vinsn-label-id v)))
5209 (if (typep id 'fixnum)
5210 (when (or t (vinsn-label-refs v))
5211 (setf (vinsn-label-info v) (emit-x86-lap-label frag-list v)))
5212 (x862-expand-note frag-list id)))
5213 (x862-expand-vinsn v frag-list instruction immediate-operand))))
5214 ;;; This doesn't have too much to do with anything else that's
5215 ;;; going on here, but it needs to happen before the lregs
5216 ;;; are freed. There really shouldn't be such a thing as a
5217 ;;; var-ea, of course ...
5218 (dolist (s *x862-recorded-symbols*)
5219 (let* ((var (car s))
5220 (ea (var-ea var)))
5221 (when (typep ea 'lreg)
5222 (setf (var-ea var) (lreg-value ea)))))
5223 (free-logical-registers)
5224 (x862-free-lcells))
5225
5226;;; It's not clear whether or not predicates, etc. want to look
5227;;; at an lreg or just at its value slot.
5228;;; It's clear that the assembler just wants the value, and that
5229;;; the value had better be assigned by the time we start generating
5230;;; machine code.
5231;;; For now, we replace lregs in the operand vector with their values
5232;;; on entry, but it might be reasonable to make PARSE-OPERAND-FORM
5233;;; deal with lregs ...
5234(defun x862-expand-vinsn (vinsn frag-list instruction immediate-operand)
5235 (let* ((template (vinsn-template vinsn))
5236 (vp (vinsn-variable-parts vinsn))
5237 (nvp (vinsn-template-nvp template))
5238 (unique-labels ()))
5239 (declare (fixnum nvp))
5240 (dotimes (i nvp)
5241 (let* ((val (svref vp i)))
5242 (when (typep val 'lreg)
5243 (setf (svref vp i) (lreg-value val)))))
5244 (dolist (name (vinsn-template-local-labels template))
5245 (let* ((unique (cons name nil)))
5246 (push unique unique-labels)
5247 (make-x86-lap-label unique)))
5248 (labels ((parse-operand-form (valform &optional for-pred)
5249 (cond ((typep valform 'keyword)
5250 (if (eq valform :rcontext)
5251 (backend-lisp-context-register *target-backend*)
5252 (or (assq valform unique-labels)
5253 (error
5254 "unknown vinsn label ~s" valform))))
5255 ((atom valform) valform)
5256 ((atom (cdr valform)) (svref vp (car valform)))
5257 ((eq (car valform) :@)
5258 (mapcar #'parse-operand-form (cdr valform)))
5259 ((eq (car valform) :^)
5260 (list :^ (parse-operand-form (cadr valform))))
5261 (t (let* ((op-vals (cdr valform))
5262 (parsed-ops (make-list (length op-vals)))
5263 (tail parsed-ops))
5264 (declare (dynamic-extent parsed-ops)
5265 (cons parsed-ops tail))
5266 (dolist (op op-vals
5267 (if for-pred
5268 (apply (car valform) parsed-ops)
5269 (parse-x86-lap-expression (cons (car valform) parsed-ops))))
5270 (setq tail (cdr (rplaca tail (parse-operand-form op)))))))))
5271 (expand-insn-form (f)
5272 (let* ((operands (cdr f))
5273 (head (make-list (length operands)))
5274 (tail head))
5275 (declare (dynamic-extent head)
5276 (cons (head tail)))
5277 (dolist (op operands)
5278 (rplaca tail (parse-operand-form op))
5279 (setq tail (cdr tail)))
5280 (x86-emit-instruction-from-vinsn
5281 (svref (target-arch-case
5282 (:x8664 x86::*x8664-opcode-templates*)) (car f))
5283 head
5284 frag-list
5285 instruction
5286 immediate-operand)))
5287 (eval-predicate (f)
5288 (case (car f)
5289 (:pred (let* ((op-vals (cddr f))
5290 (parsed-ops (make-list (length op-vals)))
5291 (tail parsed-ops))
5292 (declare (dynamic-extent parsed-ops)
5293 (cons parsed-ops tail))
5294 (dolist (op op-vals (apply (cadr f) parsed-ops))
5295 (setq tail (cdr (rplaca tail (parse-operand-form op t)))))))
5296 (:not (not (eval-predicate (cadr f))))
5297 (:or (dolist (pred (cadr f))
5298 (when (eval-predicate pred)
5299 (return t))))
5300 (:and (dolist (pred (cadr f) t)
5301 (unless (eval-predicate pred)
5302 (return nil))))
5303 (t (error "Unknown predicate: ~s" f))))
5304 (expand-pseudo-op (f)
5305 (destructuring-bind (directive arg) f
5306 (setq arg (parse-operand-form arg))
5307 (let* ((exp (parse-x86-lap-expression arg))
5308 (constantp (or (not (x86-lap-expression-p exp))
5309 (constant-x86-lap-expression-p exp))))
5310 (if constantp
5311 (let* ((val (x86-lap-expression-value exp)))
5312 (ecase directive
5313 (:byte (frag-list-push-byte frag-list val))
5314 (:short (frag-list-push-16 frag-list val))
5315 (:long (frag-list-push-32 frag-list val))
5316 (:quad (frag-list-push-64 frag-list val))
5317 (:align (finish-frag-for-align frag-list val))
5318 (:talign (finish-frag-for-talign frag-list val))))
5319 (let* ((pos (frag-list-position frag-list))
5320 (frag (frag-list-current frag-list))
5321 (reloctype nil))
5322 (ecase directive
5323 (:byte (frag-list-push-byte frag-list 0)
5324 (setq reloctype :expr8))
5325 (:short (frag-list-push-16 frag-list 0)
5326 (setq reloctype :expr16))
5327 (:long (frag-list-push-32 frag-list 0)
5328 (setq reloctype :expr32))
5329 (:quad (frag-list-push-64 frag-list 0)
5330 (setq reloctype :expr64))
5331 ((:align :talign) (error "~s expression ~s not constant" directive arg)))
5332 (when reloctype
5333 (push
5334 (make-reloc :type reloctype
5335 :arg exp
5336 :pos pos
5337 :frag frag)
5338 (frag-relocs frag))))))))
5339
5340 (expand-form (f)
5341 (if (keywordp f)
5342 (emit-x86-lap-label frag-list (assq f unique-labels))
5343 (if (atom f)
5344 (error "Invalid form in vinsn body: ~s" f)
5345 (if (atom (car f))
5346 (if (keywordp (car f))
5347 (expand-pseudo-op f)
5348 (expand-insn-form f))
5349 (if (eval-predicate (car f))
5350 (dolist (subform (cdr f))
5351 (expand-form subform))))))))
5352 (declare (dynamic-extent #'expand-form #'parse-operand-form #'expand-insn-form #'eval-predicate))
5353 ;(format t "~& vinsn = ~s" vinsn)
5354 (dolist (form (vinsn-template-body template))
5355 (expand-form form ))
5356 (setf (vinsn-variable-parts vinsn) nil)
5357 (when vp
5358 (free-varparts-vector vp)))))
5359
5360
5361
5362
5363
5364(defun x862-builtin-index-subprim (idx)
5365 (let* ((arch (backend-target-arch *target-backend*))
5366 (table (arch::target-primitive->subprims arch))
5367 (shift (arch::target-subprims-shift arch)))
5368 (dolist (cell table)
5369 (destructuring-bind ((low . high) . base) cell
5370 (if (and (>= idx low)
5371 (< idx high))
5372 (return (+ base (ash (- idx low) shift))))))))
5373
5374(defun x862-fixed-call-builtin (seg vreg xfer name subprim)
5375 (with-x86-local-vinsn-macros (seg vreg xfer)
5376 (let* ((index (arch::builtin-function-name-offset name))
5377 (idx-subprim (if index (x862-builtin-index-subprim index)))
5378 (tail-p (x862-tailcallok xfer)))
5379 (when tail-p
5380 (x862-restore-nvrs seg *x862-register-restore-ea* *x862-register-restore-count*)
5381 (x862-restore-full-lisp-context seg))
5382 (if idx-subprim
5383 (setq subprim idx-subprim)
5384 (if index (! lri ($ x8664::imm0) (ash index *x862-target-fixnum-shift*))))
5385 (if tail-p
5386 (! jump-subprim subprim)
5387 (progn
5388 (! call-subprim subprim)
5389 (<- ($ x8664::arg_z))
5390 (^))))))
5391
5392(defun x862-unary-builtin (seg vreg xfer name form)
5393 (with-x86-local-vinsn-macros (seg)
5394 (x862-one-targeted-reg-form seg form ($ x8664::arg_z))
5395 (x862-fixed-call-builtin seg vreg xfer name (subprim-name->offset '.SPcallbuiltin1))))
5396
5397(defun x862-binary-builtin (seg vreg xfer name form1 form2)
5398 (with-x86-local-vinsn-macros (seg)
5399 (x862-two-targeted-reg-forms seg form1 ($ x8664::arg_y) form2 ($ x8664::arg_z))
5400 (x862-fixed-call-builtin seg vreg xfer name (subprim-name->offset '.SPcallbuiltin2))))
5401
5402(defun x862-ternary-builtin (seg vreg xfer name form1 form2 form3)
5403 (with-x86-local-vinsn-macros (seg)
5404 (x862-three-targeted-reg-forms seg form1 ($ x8664::arg_x) form2 ($ x8664::arg_y) form3 ($ x8664::arg_z))
5405 (x862-fixed-call-builtin seg vreg xfer name (subprim-name->offset '.SPcallbuiltin3))))
5406
5407
5408(eval-when (:compile-toplevel :execute :load-toplevel)
5409
5410
5411(defmacro defx862 (name locative arglist &body forms)
5412 (multiple-value-bind (body decls)
5413 (parse-body forms nil t)
5414 (destructuring-bind (vcode-block dest control &rest other-args) arglist
5415 (let* ((fun `(nfunction ,name
5416 (lambda (,vcode-block ,dest ,control ,@other-args) ,@decls
5417 (block ,name (with-x86-local-vinsn-macros (,vcode-block ,dest ,control) ,@body))))))
5418 `(progn
5419 (record-source-file ',name 'function)
5420 (svset *x862-specials* (%ilogand #.operator-id-mask (%nx1-operator ,locative)) ,fun))))))
5421)
5422
5423(defx862 x862-lambda lambda-list (seg vreg xfer req opt rest keys auxen body p2decls)
5424 (with-x86-local-vinsn-macros (seg vreg xfer)
5425 (let* ((stack-consed-rest nil)
5426 (lexprp (if (consp rest) (progn (setq rest (car rest)) t)))
5427 (rest-var-bits (and rest (nx-var-bits rest)))
5428 (rest-ignored-p (and rest (not lexprp) (%ilogbitp $vbitignore rest-var-bits)))
5429 (want-stack-consed-rest (or rest-ignored-p
5430 (and rest (not lexprp) (%ilogbitp $vbitdynamicextent rest-var-bits))))
5431 (afunc *x862-cur-afunc*)
5432 (inherited-vars (afunc-inherited-vars afunc))
5433 (fbits (afunc-bits afunc))
5434 (methodp (%ilogbitp $fbitmethodp fbits))
5435 (method-var (if methodp (pop req)))
5436 (next-method-p (%ilogbitp $fbitnextmethp fbits))
5437 (allow-other-keys-p (%car keys))
5438 (hardopt (x862-hard-opt-p opt))
5439 (lap-p (when (and (consp (%car req)) (eq (%caar req) '&lap))
5440 (prog1 (%cdar req) (setq req nil))))
5441 (num-inh (length inherited-vars))
5442 (num-req (length req))
5443 (num-opt (length (%car opt)))
5444 (no-regs nil)
5445 (arg-regs nil)
5446 optsupvloc
5447 reglocatives
5448 pregs
5449 (reserved-lcells nil)
5450 (*x862-vstack* 0))
5451 (declare (type (unsigned-byte 16) num-req num-opt num-inh reqvloc))
5452 (with-x86-p2-declarations p2decls
5453 (setq *x862-inhibit-register-allocation*
5454 (setq no-regs (%ilogbitp $fbitnoregs fbits)))
5455 (multiple-value-setq (pregs reglocatives)
5456 (x862-allocate-global-registers *x862-fcells* *x862-vcells* (afunc-all-vars afunc) no-regs))
5457 (@ (backend-get-next-label)) ; generic self-reference label, should be label #1
5458 (! establish-fn)
5459 (@ (backend-get-next-label)) ; self-call label
5460 (unless next-method-p
5461 (setq method-var nil))
5462
5463 (let* ((rev-req (reverse req))
5464 (rev-fixed (if inherited-vars (reverse (append inherited-vars req)) rev-req))
5465 (num-fixed (length rev-fixed))
5466 (rev-opt (reverse (car opt)))
5467 (max-args (unless (or rest keys) (+ num-fixed num-opt))))
5468 (if (not (or opt rest keys))
5469 (setq arg-regs (x862-req-nargs-entry seg rev-fixed))
5470 (if (and (not (or hardopt rest keys))
5471 (<= num-opt *x862-target-num-arg-regs*))
5472 (setq arg-regs (x862-simple-opt-entry seg rev-opt rev-fixed))
5473 (progn
5474 ;; If the minumum acceptable number of args is
5475 ;; non-zero, ensure that at least that many were
5476 ;; received. If there's an upper bound, enforce it.
5477
5478 (when rev-fixed
5479 (x862-reserve-vstack-lcells num-fixed)
5480 (! check-min-nargs num-fixed))
5481 (when max-args
5482 (! check-max-nargs max-args))
5483 (if (not (or rest keys))
5484 (if (<= (+ num-fixed num-opt) $numx8664argregs)
5485 (! save-lisp-context-no-stack-args)
5486 (! save-lisp-context-variable-arg-count))
5487 (! save-lisp-context-variable-arg-count))
5488 ;; If there were &optional args, initialize their values
5489 ;; to NIL. All of the argregs get vpushed as a result of this.
5490 (when opt
5491 (x862-reserve-vstack-lcells num-opt)
5492 (if max-args
5493 (! push-max-argregs max-args)
5494 (! push-argregs))
5495 (! default-optionals (+ num-fixed num-opt)))
5496 (when keys
5497 (let* ((keyvect (%car (%cdr (%cdr (%cdr (%cdr keys))))))
5498 (flags (the fixnum (logior (the fixnum (if rest 4 0))
5499 (the fixnum (if (or methodp allow-other-keys-p) 1 0)))))
5500 (nkeys (length keyvect))
5501 (nprev (+ num-fixed num-opt)))
5502 (declare (fixnum flags nkeys nprev))
5503 (dotimes (i (the fixnum (+ nkeys nkeys)))
5504 (x862-new-vstack-lcell :reserved *x862-target-lcell-size* 0 nil))
5505 (x862-lri seg x8664::temp1 (ash flags *x862-target-fixnum-shift*))
5506 (unless (= nprev 0)
5507 (x862-lri seg x8664::imm0 (ash nprev *x862-target-fixnum-shift*)))
5508 (x86-immediate-label keyvect)
5509 (if (= 0 nprev)
5510 (! simple-keywords)
5511 (if (= 0 num-opt)
5512 (! keyword-args)
5513 (! keyword-bind)))))
5514 (when rest
5515 ;; If any keyword-binding's happened, the key/value
5516 ;; pairs have been slid to the top-of-stack for us.
5517 ;; There'll be an even number of them (nargs - the
5518 ;; "previous" (required/&optional) count.)
5519 (if lexprp
5520 (x862-lexpr-entry seg num-fixed)
5521 (progn
5522 (if want-stack-consed-rest
5523 (setq stack-consed-rest t))
5524 (let* ((nprev (+ num-fixed num-opt))
5525 (simple (and (not keys) (= 0 nprev))))
5526 (declare (fixnum nprev))
5527 (unless simple
5528 (x862-lri seg x8664::imm0 (ash nprev *x862-target-fixnum-shift*)))
5529 (if stack-consed-rest
5530 (if simple
5531 (! stack-rest-arg)
5532 (if (and (not keys) (= 0 num-opt))
5533 (! req-stack-rest-arg)
5534 (! stack-cons-rest-arg)))
5535 (if simple
5536 (! heap-rest-arg)
5537 (if (and (not keys) (= 0 num-opt))
5538 (! req-heap-rest-arg)
5539 (! heap-cons-rest-arg)))))
5540 ;; Make an lcell for the &rest arg
5541 (x862-reserve-vstack-lcells 1))))
5542 (when hardopt
5543 (x862-reserve-vstack-lcells num-opt)
5544 (x862-lri seg x8664::imm0 (ash num-opt *x862-target-fixnum-shift*))
5545
5546 ;; ! opt-supplied-p wants nargs to contain the
5547 ;; actual arg-count minus the number of "fixed"
5548 ;; (required, inherited) args.
5549
5550 (unless (= 0 num-fixed)
5551 (! scale-nargs num-fixed))
5552 (cond ((= 1 num-opt)
5553 (! one-opt-supplied-p))
5554 ((= 2 num-opt)
5555 (! two-opt-supplied-p))
5556 (t (! opt-supplied-p))))
5557 (let* ((nwords-vpushed (+ num-fixed
5558 num-opt
5559 (if hardopt num-opt 0)
5560 (if lexprp 0 (if rest 1 0))
5561 (ash (length (%cadr keys)) 1)))
5562 (nbytes-vpushed (* nwords-vpushed *x862-target-node-size*)))
5563 (declare (fixnum nwords-vpushed nbytes-vpushed))
5564 (x862-set-vstack nbytes-vpushed)
5565 (setq optsupvloc (- *x862-vstack* (* num-opt *x862-target-node-size*)))))))
5566 ;; Caller's context is saved; *x862-vstack* is valid. Might
5567 ;; still have method-var to worry about.
5568 (unless (= 0 pregs)
5569 ;; Save NVRs; load constants into any that get constants.
5570 (x862-save-nvrs seg pregs)
5571 (dolist (pair reglocatives)
5572 (declare (cons pair))
5573 (let* ((constant (car pair))
5574 (reg (cdr pair)))
5575 (declare (cons constant))
5576 (rplacd constant reg)
5577 (! ref-constant reg (x86-immediate-label (car constant))))))
5578 (when (and (not (or opt rest keys))
5579 (<= max-args $numx8664argregs)
5580 (not (some #'null arg-regs)))
5581 (setq *x862-tail-vsp* *x862-vstack*
5582 *x862-tail-nargs* max-args)
5583 (@ (setq *x862-tail-label* (backend-get-next-label))))
5584 (when method-var
5585 (x862-seq-bind-var seg method-var x8664::next-method-context))
5586 ;; If any arguments are still in arg_x, arg_y, arg_z, that's
5587 ;; because they weren't vpushed in a "simple" entry case and
5588 ;; belong in some NVR. Put them in their NVRs, so that we
5589 ;; can handle arbitrary expression evaluation (special
5590 ;; binding, value-cell consing, etc.) without clobbering the
5591 ;; argument registers.
5592 (when arg-regs
5593 (do* ((vars arg-regs (cdr vars))
5594 (arg-reg-numbers (target-arch-case
5595 (:x8664 (list x8664::arg_z x8664::arg_y x8664::arg_x))))
5596 (arg-reg-num (pop arg-reg-numbers) (pop arg-reg-numbers)))
5597 ((null vars))
5598 (declare (list vars) (fixnum arg-reg-num))
5599 (let* ((var (car vars)))
5600 (when var
5601 (let* ((reg (x862-assign-register-var var)))
5602 (x862-copy-register seg reg arg-reg-num)
5603 (setf (var-ea var) reg))))))
5604 (setq *x862-entry-vsp-saved-p* t)
5605 (when stack-consed-rest
5606 (x862-open-undo $undostkblk))
5607 (setq *x862-entry-vstack* *x862-vstack*)
5608 (setq reserved-lcells (x862-collect-lcells :reserved))
5609 (x862-bind-lambda seg reserved-lcells req opt rest keys auxen optsupvloc arg-regs lexprp inherited-vars))
5610 (when method-var (x862-heap-cons-next-method-var seg method-var))
5611 (x862-form seg vreg xfer body)
5612 (x862-close-lambda seg req opt rest keys auxen)
5613 (dolist (v inherited-vars)
5614 (x862-close-var seg v))
5615 (when method-var
5616 (x862-close-var seg method-var))
5617 (let* ((bits 0))
5618 (when (%i> num-inh (ldb $lfbits-numinh -1))
5619 (setq num-inh (ldb $lfbits-numinh -1)))
5620 (setq bits (dpb num-inh $lfbits-numinh bits))
5621 (unless lap-p
5622 (when (%i> num-req (ldb $lfbits-numreq -1))
5623 (setq num-req (ldb $lfbits-numreq -1)))
5624 (setq bits (dpb num-req $lfbits-numreq bits))
5625 (when (%i> num-opt (ldb $lfbits-numopt -1))
5626 (setq num-opt (ldb $lfbits-numopt -1)))
5627 (setq bits (dpb num-opt $lfbits-numopt bits))
5628 (when hardopt (setq bits (%ilogior (%ilsl $lfbits-optinit-bit 1) bits)))
5629 (when rest (setq bits (%ilogior (if lexprp (%ilsl $lfbits-restv-bit 1) (%ilsl $lfbits-rest-bit 1)) bits)))
5630 (when keys (setq bits (%ilogior (%ilsl $lfbits-keys-bit 1) bits)))
5631 (when allow-other-keys-p (setq bits (%ilogior (%ilsl $lfbits-aok-bit 1) bits)))
5632 (when (%ilogbitp $fbitnextmethargsp (afunc-bits afunc))
5633 (if methodp
5634 (setq bits (%ilogior (%ilsl $lfbits-nextmeth-with-args-bit 1) bits))
5635 (let ((parent (afunc-parent afunc)))
5636 (when parent
5637 (setf (afunc-bits parent) (bitset $fbitnextmethargsp (afunc-bits parent)))))))
5638 (when methodp
5639 (setq bits (logior (ash 1 $lfbits-method-bit) bits))
5640 (when next-method-p
5641 (setq bits (logior (%ilsl $lfbits-nextmeth-bit 1) bits)))))
5642 bits)))))
5643
5644
5645(defx862 x862-progn progn (seg vreg xfer forms)
5646 (declare (list forms))
5647 (if (null forms)
5648 (x862-nil seg vreg xfer)
5649 (loop
5650 (let* ((form (pop forms)))
5651 (if forms
5652 (x862-form seg nil nil form)
5653 (return (x862-form seg vreg xfer form)))))))
5654
5655
5656
5657(defx862 x862-prog1 prog1 (seg vreg xfer forms)
5658 (if (eq (list-length forms) 1)
5659 (x862-use-operator (%nx1-operator values) seg vreg xfer forms)
5660 (if (null vreg)
5661 (x862-use-operator (%nx1-operator progn) seg vreg xfer forms)
5662 (let* ((float-p (= (hard-regspec-class vreg) hard-reg-class-fpr))
5663 (crf-p (= (hard-regspec-class vreg) hard-reg-class-crf))
5664 (node-p (unless (or float-p crf-p)
5665 (= (get-regspec-mode vreg) hard-reg-class-gpr-mode-node)))
5666 (first (pop forms)))
5667 (x862-push-register seg
5668 (if (or node-p crf-p)
5669 (x862-one-untargeted-reg-form seg first x8664::arg_z)
5670 (x862-one-targeted-reg-form seg first vreg)))
5671 (dolist (form forms)
5672 (x862-form seg nil nil form))
5673 (if crf-p
5674 (progn
5675 (x862-vpop-register seg x8664::arg_z)
5676 (<- x8664::arg_z))
5677 (x862-pop-register seg vreg))
5678 (^)))))
5679
5680(defx862 x862-free-reference free-reference (seg vreg xfer sym)
5681 (x862-ref-symbol-value seg vreg xfer sym t))
5682
5683(defx862 x862-special-ref special-ref (seg vreg xfer sym)
5684 (x862-ref-symbol-value seg vreg xfer sym t))
5685
5686(defx862 x862-bound-special-ref bound-special-ref (seg vreg xfer sym)
5687 (x862-ref-symbol-value seg vreg xfer sym t))
5688
5689(defx862 x862-%slot-ref %slot-ref (seg vreg xfer instance idx)
5690 (ensuring-node-target (target (or vreg ($ x8664::arg_z)))
5691 (multiple-value-bind (v i)
5692 (x862-two-untargeted-reg-forms seg instance x8664::arg_y idx x8664::arg_z)
5693 (unless *x862-reckless*
5694 (! check-misc-bound i v))
5695 (with-node-temps (v) (temp)
5696 (! %slot-ref temp v i)
5697 (x862-copy-register seg target temp))))
5698 (^))
5699
5700(pushnew (%nx1-operator %svref) *x862-operator-supports-push*)
5701(defx862 x862-%svref %svref (seg vreg xfer vector index)
5702 (x862-vref seg vreg xfer :simple-vector vector index nil))
5703
5704(pushnew (%nx1-operator svref) *x862-operator-supports-push*)
5705(defx862 x862-svref svref (seg vreg xfer vector index)
5706 (x862-vref seg vreg xfer :simple-vector vector index (unless *x862-reckless* (nx-lookup-target-uvector-subtag :simple-vector))))
5707
5708;;; It'd be nice if this didn't box the result. Worse things happen ...
5709;;; Once there's a robust mechanism, adding a CHARCODE storage class shouldn't be hard.
5710(defx862 x862-%sbchar %sbchar (seg vreg xfer string index)
5711 (x862-vref seg vreg xfer :simple-string string index (unless *x862-reckless* (nx-lookup-target-uvector-subtag :simple-string))))
5712
5713
5714(defx862 x862-%svset %svset (seg vreg xfer vector index value)
5715 (x862-vset seg vreg xfer :simple-vector vector index value nil))
5716
5717(defx862 x862-svset svset (seg vreg xfer vector index value)
5718 (x862-vset seg vreg xfer :simple-vector vector index value (nx-lookup-target-uvector-subtag :simple-vector)))
5719
5720(defx862 x862-typed-form typed-form (seg vreg xfer typespec form)
5721 (declare (ignore typespec)) ; Boy, do we ever !
5722 (x862-form seg vreg xfer form))
5723
5724(defx862 x862-%primitive %primitive (seg vreg xfer &rest ignore)
5725 (declare (ignore seg vreg xfer ignore))
5726 (error "You're probably losing big: using %primitive ..."))
5727
5728(defx862 x862-consp consp (seg vreg xfer cc form)
5729 (if (null vreg)
5730 (x862-form seg vreg xfer form)
5731 (let* ((tagreg x8664::imm0))
5732 (multiple-value-bind (cr-bit true-p) (acode-condition-to-x86-cr-bit cc)
5733 (! extract-fulltag tagreg (x862-one-untargeted-reg-form seg form x8664::arg_z))
5734 (! compare-u8-constant tagreg x8664::fulltag-cons)
5735 (regspec-crf-gpr-case
5736 (vreg dest)
5737 (^ cr-bit true-p)
5738 (progn
5739 (ensuring-node-target (target dest)
5740 (if (not true-p)
5741 (setq cr-bit (logxor 1 cr-bit)))
5742 (! cr-bit->boolean target cr-bit))
5743 (^)))))))
5744
5745(defx862 x862-cons cons (seg vreg xfer y z)
5746 (if (null vreg)
5747 (progn
5748 (x862-form seg nil nil y)
5749 (x862-form seg nil xfer z))
5750 (multiple-value-bind (yreg zreg) (x862-two-untargeted-reg-forms seg y x8664::arg_y z x8664::arg_z)
5751 (ensuring-node-target (target vreg)
5752 (! cons target yreg zreg))
5753 (^))))
5754
5755
5756
5757(defx862 x862-%rplaca %rplaca (seg vreg xfer ptr val)
5758 (x862-modify-cons seg vreg xfer ptr val nil nil t))
5759
5760(defx862 x862-%rplacd %rplacd (seg vreg xfer ptr val)
5761 (x862-modify-cons seg vreg xfer ptr val nil t t))
5762
5763(defx862 x862-rplaca rplaca (seg vreg xfer ptr val)
5764 (x862-modify-cons seg vreg xfer ptr val t nil t))
5765
5766(defx862 x862-set-car set-car (seg vreg xfer ptr val)
5767 (x862-modify-cons seg vreg xfer ptr val t nil nil))
5768
5769(defx862 x862-rplacd rplacd (seg vreg xfer ptr val)
5770 (x862-modify-cons seg vreg xfer ptr val t t t))
5771
5772(defx862 x862-set-cdr set-cdr (seg vreg xfer ptr val)
5773 (x862-modify-cons seg vreg xfer ptr val t t nil))
5774
5775(pushnew (%nx1-operator %car) *x862-operator-supports-push*)
5776(defx862 x862-%car %car (seg vreg xfer form)
5777 (x862-reference-list seg vreg xfer form nil nil))
5778
5779(pushnew (%nx1-operator %cdr) *x862-operator-supports-push*)
5780(defx862 x862-%cdr %cdr (seg vreg xfer form)
5781 (x862-reference-list seg vreg xfer form nil t))
5782
5783(pushnew (%nx1-operator car) *x862-operator-supports-push*)
5784(defx862 x862-car car (seg vreg xfer form)
5785 (x862-reference-list seg vreg xfer form t nil))
5786
5787(pushnew (%nx1-operator cdr) *x862-operator-supports-push*)
5788(defx862 x862-cdr cdr (seg vreg xfer form)
5789 (x862-reference-list seg vreg xfer form t t))
5790
5791(defx862 x862-vector vector (seg vreg xfer arglist)
5792 (x862-allocate-initialized-gvector seg vreg xfer
5793 (nx-lookup-target-uvector-subtag
5794 :simple-vector) arglist))
5795
5796(defx862 x862-%gvector %gvector (seg vreg xfer arglist)
5797 (let* ((all-on-stack (append (car arglist) (reverse (cadr arglist))))
5798 (subtag-form (car all-on-stack))
5799 (subtag (acode-fixnum-form-p subtag-form)))
5800 (if (null vreg)
5801 (dolist (form all-on-stack (^)) (x862-form seg nil nil form))
5802 (if (null subtag)
5803 (progn ; Vpush everything and call subprim
5804 (let* ((*x862-vstack* *x862-vstack*)
5805 (*x862-top-vstack-lcell* *x862-top-vstack-lcell*))
5806 (x862-set-nargs seg (x862-formlist seg all-on-stack nil))
5807 (! gvector))
5808 (<- x8664::arg_z)
5809 (^))
5810 (x862-allocate-initialized-gvector seg vreg xfer subtag (cdr all-on-stack))))))
5811
5812;;; Should be less eager to box result
5813(defx862 x862-%char-code %char-code (seg vreg xfer c)
5814 (x862-extract-charcode seg vreg xfer c nil))
5815
5816(defx862 x862-char-code char-code (seg vreg xfer c)
5817 (x862-extract-charcode seg vreg xfer c (not (x862-form-typep c 'character))))
5818
5819(defx862 x862-%ilogior2 %ilogior2 (seg vreg xfer form1 form2)
5820 (let* ((fix1 (acode-fixnum-form-p form1))
5821 (fix2 (acode-fixnum-form-p form2)))
5822 (if (and fix1 fix2)
5823 (x862-use-operator (%nx1-operator fixnum) seg vreg xfer (logior fix1 fix2)))
5824 (let* ((fixval (or fix1 fix2))
5825 (fiximm (if fixval (<= (integer-length fixval)
5826 (- 31 *x862-target-fixnum-shift*))))
5827 (otherform (when fiximm (if fix1 form2 form1))))
5828 (if otherform
5829 (if (null vreg)
5830 (x862-form seg nil xfer otherform)
5831 (ensuring-node-target (target vreg)
5832 (x862-one-targeted-reg-form seg otherform target)
5833 (! %logior-c target target (ash fixval *x862-target-fixnum-shift*))))
5834 (multiple-value-bind (r1 r2) (x862-two-untargeted-reg-forms seg form1 x8664::arg_y form2 x8664::arg_z)
5835 (if vreg (ensuring-node-target (target vreg) (! %logior2 target r1 r2)))))
5836 (^))))
5837
5838;;; in a lot of (typical ?) cases, it might be possible to use a
5839;;; rotate-and-mask instead of andi./andis.
5840
5841(defx862 x862-%ilogand2 %ilogand2 (seg vreg xfer form1 form2)
5842 (let* ((fix1 (acode-fixnum-form-p form1))
5843 (fix2 (acode-fixnum-form-p form2)))
5844 (if (and fix1 fix2)
5845 (x862-use-operator (%nx1-operator fixnum) seg vreg xfer (logand fix1 fix2)))
5846 (let* ((fixval (or fix1 fix2))
5847 (fiximm (if fixval (<= (integer-length fixval)
5848 (- 31 *x862-target-fixnum-shift*))))
5849 (otherform (when fiximm (if fix1 form2 form1))))
5850 (if otherform
5851 (if (null vreg)
5852 (x862-form seg nil xfer otherform)
5853 (ensuring-node-target (target vreg)
5854 (x862-one-targeted-reg-form seg otherform target)
5855 (! %logand-c target target (ash fixval *x862-target-fixnum-shift*))))
5856 (multiple-value-bind (r1 r2) (x862-two-untargeted-reg-forms seg form1 x8664::arg_y form2 x8664::arg_z)
5857 (if vreg (ensuring-node-target (target vreg) (! %logand2 target r1 r2)))))
5858 (^))))
5859
5860(defx862 x862-%ilogxor2 %ilogxor2 (seg vreg xfer form1 form2)
5861 (let* ((fix1 (acode-fixnum-form-p form1))
5862 (fix2 (acode-fixnum-form-p form2)))
5863 (if (and fix1 fix2)
5864 (x862-use-operator (%nx1-operator fixnum) seg vreg xfer (logxor fix1 fix2)))
5865 (let* ((fixval (or fix1 fix2))
5866 (fiximm (if fixval (<= (integer-length fixval)
5867 (- 31 *x862-target-fixnum-shift*))))
5868 (otherform (when fiximm (if fix1 form2 form1))))
5869 (if otherform
5870 (if (null vreg)
5871 (x862-form seg nil xfer otherform)
5872 (ensuring-node-target (target vreg)
5873 (x862-one-targeted-reg-form seg otherform target)
5874 (! %logxor-c target target (ash fixval *x862-target-fixnum-shift*))))
5875 (multiple-value-bind (r1 r2) (x862-two-untargeted-reg-forms seg form1 x8664::arg_y form2 x8664::arg_z)
5876 (if vreg (ensuring-node-target (target vreg) (! %logxor2 target r1 r2)))))
5877 (^))))
5878
5879(defx862 x862-%ineg %ineg (seg vreg xfer n)
5880 (if (null vreg)
5881 (x862-form seg vreg xfer n)
5882 (progn
5883 (ensuring-node-target (target vreg)
5884 (x862-one-targeted-reg-form seg n target)
5885 (! negate-fixnum target)
5886 (x862-check-fixnum-overflow seg target))
5887 (^ ))))
5888
5889(defx862 x862-%%ineg %%ineg (seg vreg xfer n)
5890 (if (null vreg)
5891 (x862-form seg vreg xfer n)
5892 (progn
5893 (ensuring-node-target (target vreg)
5894 (x862-one-targeted-reg-form seg n target)
5895 (when vreg
5896 (! negate-fixnum target)))
5897 (^))))
5898
5899(defx862 x862-characterp characterp (seg vreg xfer cc form)
5900 (x862-char-p seg vreg xfer cc form))
5901
5902(pushnew (%nx1-operator struct-ref) *x862-operator-supports-push*)
5903(defx862 x862-struct-ref struct-ref (seg vreg xfer struct offset)
5904 (x862-vref seg vreg xfer :struct struct offset (unless *x862-reckless* (nx-lookup-target-uvector-subtag :struct))))
5905
5906(defx862 x862-struct-set struct-set (seg vreg xfer struct offset value)
5907 (x862-vset seg vreg xfer :struct struct offset value (unless *x862-reckless* (nx-lookup-target-uvector-subtag :struct))))
5908
5909(defx862 x862-istruct-typep istruct-typep (seg vreg xfer cc form type)
5910 (multiple-value-bind (cr-bit true-p) (acode-condition-to-x86-cr-bit cc)
5911 (multiple-value-bind (r1 r2) (x862-two-untargeted-reg-forms seg form x8664::arg_y type x8664::arg_z)
5912 (! set-z-flag-if-istruct-typep r1 r2)
5913 (regspec-crf-gpr-case
5914 (vreg dest)
5915 (^ cr-bit true-p)
5916 (progn
5917 (ensuring-node-target (target dest)
5918 (if (not true-p)
5919 (setq cr-bit (logxor 1 cr-bit)))
5920 (! cr-bit->boolean target cr-bit))
5921 (^))))))
5922
5923
5924(pushnew (%nx1-operator lisptag) *x862-operator-supports-u8-target*)
5925(defx862 x862-lisptag lisptag (seg vreg xfer node)
5926 (if (null vreg)
5927 (x862-form seg vreg xfer node)
5928 (progn
5929 (unboxed-other-case (vreg :u8)
5930 (! extract-tag vreg (x862-one-untargeted-reg-form seg node x8664::arg_z))
5931 (ensuring-node-target (target vreg)
5932 (! extract-tag-fixnum target (x862-one-untargeted-reg-form seg node x8664::arg_z))))
5933 (^))))
5934
5935(pushnew (%nx1-operator fulltag) *x862-operator-supports-u8-target*)
5936(defx862 x862-fulltag fulltag (seg vreg xfer node)
5937 (if (null vreg)
5938 (x862-form seg vreg xfer node)
5939 (progn
5940 (unboxed-other-case (vreg :u8)
5941 (! extract-fulltag vreg (x862-one-untargeted-reg-form seg node x8664::arg_z))
5942 (ensuring-node-target (target vreg)
5943 (! extract-fulltag-fixnum target (x862-one-untargeted-reg-form seg node x8664::arg_z))))
5944 (^))))
5945
5946(pushnew (%nx1-operator typecode) *x862-operator-supports-u8-target*)
5947(defx862 x862-typecode typecode (seg vreg xfer node)
5948 (if (null vreg)
5949 (x862-form seg vreg xfer node)
5950 (progn
5951 (unboxed-other-case (vreg :u8)
5952 (! extract-typecode vreg (x862-one-untargeted-reg-form seg node x8664::arg_z))
5953 (let* ((reg (x862-one-untargeted-reg-form seg node (if (eq (hard-regspec-value vreg) x8664::arg_z)
5954 x8664::arg_y x8664::arg_z))))
5955 (ensuring-node-target (target vreg)
5956 (! extract-typecode-fixnum target reg ))))
5957 (^))))
5958
5959(defx862 x862-setq-special setq-special (seg vreg xfer sym val)
5960 (let* ((symreg ($ x8664::arg_y))
5961 (valreg ($ x8664::arg_z)))
5962 (x862-one-targeted-reg-form seg val valreg)
5963 (x862-store-immediate seg (x862-symbol-value-cell sym) symreg)
5964 (! setq-special symreg valreg)
5965 (<- valreg))
5966 (^))
5967
5968
5969(defx862 x862-local-go local-go (seg vreg xfer tag)
5970 (declare (ignorable xfer))
5971 (let* ((curstack (x862-encode-stack))
5972 (label (cadr tag))
5973 (deststack (caddr tag)))
5974 (if (not (x862-equal-encodings-p curstack deststack))
5975 (multiple-value-bind (catch cstack vstack)
5976 (x862-decode-stack deststack)
5977 (x862-unwind-stack seg nil catch cstack vstack)))
5978 (-> label)
5979 (x862-unreachable-store vreg)))
5980
5981(defx862 x862-local-block local-block (seg vreg xfer blocktag body)
5982 (let* ((curstack (x862-encode-stack))
5983 (compound (x862-cd-compound-p xfer))
5984 (mvpass-p (x862-mvpass-p xfer))
5985 (need-label (if xfer (or compound mvpass-p) t))
5986 end-of-block
5987 last-cd
5988 (dest (if (backend-crf-p vreg) x8664::arg_z vreg)))
5989 (if need-label
5990 (setq end-of-block (backend-get-next-label)))
5991 (setq last-cd (if need-label (%ilogior2 (if mvpass-p $backend-mvpass-mask 0) end-of-block) xfer))
5992 (%rplaca blocktag (cons (cons dest last-cd) curstack))
5993 (if mvpass-p
5994 (x862-multiple-value-body seg body)
5995 (x862-form seg dest (if xfer last-cd) body))
5996 (when need-label
5997 (@ end-of-block)
5998 (if compound
5999 (<- dest))
6000 (x862-branch seg (logand (lognot $backend-mvpass-mask) (or xfer 0))))))
6001
6002(defx862 x862-%izerop %izerop (seg vreg xfer cc form)
6003 (multiple-value-bind (cr-bit true-p) (acode-condition-to-x86-cr-bit cc)
6004 (x862-test-%izerop seg vreg xfer form cr-bit true-p)))
6005
6006
6007(defx862 x862-uvsize uvsize (seg vreg xfer v)
6008 (let* ((misc-reg (x862-one-untargeted-reg-form seg v x8664::arg_z)))
6009 (unless *x862-reckless* (! trap-unless-uvector misc-reg))
6010 (if vreg
6011 (ensuring-node-target (target vreg)
6012 (! misc-element-count-fixnum target misc-reg)))
6013 (^)))
6014
6015(defx862 x862-%ilsl %ilsl (seg vreg xfer form1 form2)
6016 (if (null vreg)
6017 (progn
6018 (x862-form seg nil nil form1)
6019 (x862-form seg nil xfer form2))
6020 (let* ((const (acode-fixnum-form-p form1))
6021 (max (target-arch-case (:x8664 63))))
6022 (ensuring-node-target (target vreg)
6023 (if const
6024 (let* ((src (x862-one-untargeted-reg-form seg form2 x8664::arg_z)))
6025 (if (<= const max)
6026 (! %ilsl-c target const src)
6027 (! lri target 0)))
6028 (multiple-value-bind (count src) (x862-two-untargeted-reg-forms seg form1 x8664::arg_y form2 x8664::arg_z)
6029 (! %ilsl target count src))))
6030 (^))))
6031
6032(defx862 x862-endp endp (seg vreg xfer cc form)
6033 (let* ((formreg (x862-one-untargeted-reg-form seg form x8664::arg_z)))
6034 (! trap-unless-list formreg)
6035 (multiple-value-bind (cr-bit true-p) (acode-condition-to-x86-cr-bit cc)
6036 (x862-compare-register-to-nil seg vreg xfer formreg cr-bit true-p))))
6037
6038
6039
6040(defx862 x862-%code-char %code-char (seg vreg xfer c)
6041 (if (null vreg)
6042 (x862-form seg nil xfer c)
6043 (progn
6044 (ensuring-node-target (target vreg)
6045 (with-imm-target () (dest :u8)
6046 (! u32->char target (x862-one-untargeted-reg-form seg c dest))))
6047 (^))))
6048
6049(defx862 x862-%schar %schar (seg vreg xfer str idx)
6050 (multiple-value-bind (src unscaled-idx)
6051 (x862-two-untargeted-reg-forms seg str x8664::arg_y idx x8664::arg_z)
6052 (if vreg
6053 (ensuring-node-target (target vreg)
6054 (case (arch::target-char-code-limit (backend-target-arch *target-backend*))
6055 (256 (! %schar8 target src unscaled-idx))
6056 (t (! %schar32 target src unscaled-idx)))))
6057 (^)))
6058
6059(defx862 x862-%set-schar %set-schar (seg vreg xfer str idx char)
6060 (multiple-value-bind (src unscaled-idx char)
6061 (x862-three-untargeted-reg-forms seg
6062 str x8664::arg_x
6063 idx x8664::arg_y
6064 char x8664::arg_z)
6065 (case (arch::target-char-code-limit (backend-target-arch *target-backend*))
6066 (256 (! %set-schar8 src unscaled-idx char))
6067 (t (! %set-schar32 src unscaled-idx char)))
6068 (when vreg (<- char))
6069 (^)))
6070
6071(defx862 x862-%set-scharcode %set-scharcode (seg vreg xfer str idx char)
6072 (multiple-value-bind (src unscaled-idx char)
6073 (x862-three-untargeted-reg-forms seg str x8664::arg_x idx x8664::arg_y
6074 char x8664::arg_z)
6075 (case (arch::target-char-code-limit (backend-target-arch *target-backend*))
6076 (256 (! %set-scharcode8 src unscaled-idx char))
6077 (t (! %set-scharcode32 src unscaled-idx char)))
6078 (when vreg (<- char))
6079 (^)))
6080
6081(defx862 x862-%scharcode %scharcode (seg vreg xfer str idx)
6082 (multiple-value-bind (src unscaled-idx)
6083 (x862-two-untargeted-reg-forms seg str x8664::arg_y idx x8664::arg_z)
6084 (if vreg
6085 (ensuring-node-target (target vreg)
6086 (case (arch::target-char-code-limit (backend-target-arch *target-backend*))
6087 (256 (! %scharcode8 target src unscaled-idx))
6088 (t (! %scharcode32 target src unscaled-idx)))))
6089 (^)))
6090
6091
6092
6093(defx862 x862-code-char code-char (seg vreg xfer c)
6094 (let* ((reg (x862-one-untargeted-reg-form seg c x8664::arg_z)))
6095 ;; Typecheck even if result unused.
6096 (! require-char-code reg)
6097 (if vreg
6098 (ensuring-node-target (target vreg)
6099 (! fixnum->char target reg)))
6100 (^)))
6101
6102(defx862 x862-eq eq (seg vreg xfer cc form1 form2)
6103 (multiple-value-bind (cr-bit true-p) (acode-condition-to-x86-cr-bit cc)
6104 (x862-compare seg vreg xfer form1 form2 cr-bit true-p)))
6105
6106(defx862 x862-neq neq (seg vreg xfer cc form1 form2)
6107 (multiple-value-bind (cr-bit true-p) (acode-condition-to-x86-cr-bit cc)
6108 (x862-compare seg vreg xfer form1 form2 cr-bit true-p)))
6109
6110(defx862 x862-numcmp numcmp (seg vreg xfer cc form1 form2)
6111 (let* ((name (ecase (cadr cc)
6112 (:eq '=-2)
6113 (:ne '/=-2)
6114 (:lt '<-2)
6115 (:le '<=-2)
6116 (:gt '>-2)
6117 (:ge '>=-2))))
6118 (if (or (x862-explicit-non-fixnum-type-p form1)
6119 (x862-explicit-non-fixnum-type-p form2))
6120 (x862-binary-builtin seg vreg xfer name form1 form2)
6121 (let* ((fix1 (acode-fixnum-form-p form1))
6122 (fix2 (acode-fixnum-form-p form2)))
6123 (if (and fix1 fix2)
6124 (if (funcall name fix1 fix2)
6125 (x862-t seg vreg xfer)
6126 (x862-nil seg vreg xfer))
6127 (x862-inline-numcmp seg vreg xfer cc name form1 form2))))))
6128
6129(defun x862-inline-numcmp (seg vreg xfer cc name form1 form2)
6130 (with-x86-local-vinsn-macros (seg vreg xfer)
6131 (let* ((fix1 (acode-fixnum-form-p form1))
6132 (fix2 (acode-fixnum-form-p form2))
6133 (fixval (or fix1 fix2))
6134 (fiximm (if fixval (<= (integer-length fixval)
6135 (- 31 *x862-target-fixnum-shift*))))
6136 (otherform (when fiximm (if fix1 form2 form1)))
6137 (out-of-line (backend-get-next-label))
6138 (done (backend-get-next-label)))
6139 (if otherform
6140 (x862-one-targeted-reg-form seg otherform ($ x8664::arg_y))
6141 (x862-two-targeted-reg-forms seg form1 ($ x8664::arg_y) form2 ($ x8664::arg_z)))
6142 (if otherform
6143 (unless (acode-fixnum-form-p otherform)
6144 (! branch-unless-arg-fixnum ($ x8664::arg_y) (aref *backend-labels* out-of-line)))
6145 (if (acode-fixnum-form-p form1)
6146 (! branch-unless-arg-fixnum ($ x8664::arg_z) (aref *backend-labels* out-of-line))
6147 (if (acode-fixnum-form-p form2)
6148 (! branch-unless-arg-fixnum ($ x8664::arg_y) (aref *backend-labels* out-of-line))
6149 (! branch-unless-both-args-fixnums ($ x8664::arg_y) ($ x8664::arg_z) (aref *backend-labels* out-of-line)))))
6150 (if otherform
6151 (if (zerop fixval)
6152 (! compare-reg-to-zero ($ x8664::arg_y))
6153 (! compare-s32-constant ($ x8664::arg_y) (ash fixval x8664::fixnumshift)))
6154 (! compare ($ x8664::arg_y) ($ x8664::arg_z)))
6155 (multiple-value-bind (cr-bit true-p) (acode-condition-to-x86-cr-bit cc)
6156 (when otherform
6157 (unless (or (and fix2 (not fix1)) (eq cr-bit x86::x86-e-bits))
6158 (setq cr-bit (x862-reverse-cr-bit cr-bit))))
6159 (if (not true-p)
6160 (setq cr-bit (logxor 1 cr-bit)))
6161 (! cr-bit->boolean ($ x8664::arg_z) cr-bit)
6162 (-> done)
6163 (@ out-of-line)
6164 (when otherform
6165 (x862-lri seg ($ x8664::arg_z) (ash fixval x8664::fixnumshift))
6166 (unless (or fix2 (eq cr-bit x86::x86-e-bits))
6167 (! xchg-registers ($ x8664::arg_z) ($ x8664::arg_y))))
6168 (let* ((index (arch::builtin-function-name-offset name))
6169 (idx-subprim (x862-builtin-index-subprim index)))
6170 (! call-subprim-2 ($ x8664::arg_z) idx-subprim ($ x8664::arg_y) ($ x8664::arg_z)))
6171 (@ done)
6172 (<- ($ x8664::arg_z))
6173 (^)))))
6174
6175
6176
6177
6178(defx862 x862-%word-to-int %word-to-int (seg vreg xfer form)
6179 (if (null vreg)
6180 (x862-form seg nil xfer form)
6181 (progn
6182 (ensuring-node-target (target vreg)
6183 (! sign-extend-halfword target (x862-one-untargeted-reg-form seg form x8664::arg_z)))
6184 (^))))
6185
6186(defx862 x862-multiple-value-list multiple-value-list (seg vreg xfer form)
6187 (x862-multiple-value-body seg form)
6188 (! list)
6189 (when vreg
6190 (<- x8664::arg_z))
6191 (^))
6192
6193(defx862 x862-immform immediate (seg vreg xfer form)
6194 (x862-immediate seg vreg xfer form))
6195
6196(pushnew (%nx1-operator lexical-reference) *x862-operator-supports-push*)
6197(defx862 x862-lexical-reference lexical-reference (seg vreg xfer varnode)
6198 (let* ((ea-or-form (var-ea varnode)))
6199 (if (and (acode-punted-var-p varnode) (not (fixnump ea-or-form)))
6200 (if (or (not (eq vreg :push))
6201 (x862-acode-operator-supports-push ea-or-form))
6202 (x862-form seg vreg xfer ea-or-form)
6203 (ensuring-node-target (target vreg)
6204 (x862-form seg target xfer ea-or-form)
6205 (! vpush-register target)))
6206 (let* ((cell (x862-lookup-var-cell varnode)))
6207 (if (and cell (typep cell 'lcell))
6208 (if (x862-ensure-lcell-offset cell (logand ea-or-form #xffff))
6209 (and nil (format t "~& could use cell ~s for var ~s" cell (var-name varnode)))
6210 (if (logbitp x862-debug-verbose-bit *x862-debug-mask*)
6211 (break "wrong ea for lcell for var ~s: got ~d, expected ~d"
6212 (var-name varnode) (calc-lcell-offset cell) (logand ea-or-form #xffff))))
6213 (if (not cell)
6214 (when (memory-spec-p ea-or-form)
6215 (if (logbitp x862-debug-verbose-bit *x862-debug-mask*)
6216 (format t "~& no lcell for ~s." (var-name varnode))))))
6217
6218 (unless (or (typep ea-or-form 'lreg) (fixnump ea-or-form))
6219 (break "bogus ref to var ~s (~s) : ~s " varnode (var-name varnode) ea-or-form))
6220 (x862-do-lexical-reference seg vreg ea-or-form)
6221 (^)))))
6222
6223(defx862 x862-setq-lexical setq-lexical (seg vreg xfer varspec form)
6224 (let* ((ea (var-ea varspec)))
6225 ;(unless (fixnump ea) (break "setq lexical is losing BIG"))
6226 (let* ((valreg (x862-one-untargeted-reg-form seg form (if (and (register-spec-p ea)
6227 (or (null vreg) (eq ea vreg)))
6228 ea
6229 x8664::arg_z))))
6230 (x862-do-lexical-setq seg vreg ea valreg))
6231 (^)))
6232
6233(pushnew (%nx1-operator fixnum) *x862-operator-supports-push*)
6234(defx862 x862-fixnum fixnum (seg vreg xfer value)
6235 (if (null vreg)
6236 (^)
6237 (if (eq vreg :push)
6238 (let* ((boxed (ash value *x862-target-fixnum-shift*)))
6239 (if (typep boxed '(signed-byte 32))
6240 (! vpush-fixnum boxed)
6241 (with-node-target () target
6242 (x862-absolute-natural seg target nil boxed)
6243 (! vpush-register target)))
6244 (^))
6245 (let* ((class (hard-regspec-class vreg))
6246 (mode (get-regspec-mode vreg))
6247 (unboxed (if (= class hard-reg-class-gpr)
6248 (not (or (= hard-reg-class-gpr-mode-node mode)
6249 (= hard-reg-class-gpr-mode-address mode))))))
6250 (if unboxed
6251 (x862-absolute-natural seg vreg xfer value)
6252 (if (= class hard-reg-class-crf)
6253 (progn
6254 ;(break "Would have clobbered a GPR!")
6255 (x862-branch seg (x862-cd-true xfer)))
6256 (progn
6257 (ensuring-node-target (target vreg)
6258 (x862-absolute-natural seg target nil (ash value *x862-target-fixnum-shift*)))
6259 (^))))))))
6260
6261(defx862 x862-%ilogbitp %ilogbitp (seg vreg xfer cc bitnum form)
6262 (if (null vreg)
6263 (progn
6264 (x862-form seg nil nil bitnum)
6265 (x862-form seg vreg xfer form))
6266 (multiple-value-bind (cr-bit true-p) (acode-condition-to-x86-cr-bit cc)
6267 (unless (eq cr-bit x86::x86-e-bits)
6268 (bug "bad cr-bit"))
6269 (setq cr-bit x86::x86-b-bits true-p (not true-p))
6270 (let* ((fixbit (acode-fixnum-form-p bitnum)))
6271 (if fixbit
6272 (let* ((reg (x862-one-untargeted-reg-form seg form x8664::arg_z))
6273 (x86-bit (min (+ fixbit *x862-target-fixnum-shift*) (1- *x862-target-bits-in-word*))))
6274 (! set-c-flag-if-constant-logbitp x86-bit reg))
6275 (multiple-value-bind (rbit rform) (x862-two-untargeted-reg-forms seg bitnum x8664::arg_y form x8664::arg_z)
6276 (! set-c-flag-if-variable-logbitp rbit rform)))
6277 (regspec-crf-gpr-case
6278 (vreg dest)
6279 (^ cr-bit true-p)
6280 (progn
6281 (ensuring-node-target (target dest)
6282 (if (not true-p)
6283 (setq cr-bit (logxor 1 cr-bit)))
6284 (! cr-bit->boolean target cr-bit))
6285 (^)))))))
6286
6287
6288(defx862 x862-uvref uvref (seg vreg xfer vector index)
6289 (x862-two-targeted-reg-forms seg vector ($ x8664::arg_y) index ($ x8664::arg_z))
6290 (! misc-ref)
6291 (<- ($ x8664::arg_z))
6292 (^))
6293
6294(defx862 x862-uvset uvset (seg vreg xfer vector index value)
6295 (x862-three-targeted-reg-forms seg vector ($ x8664::arg_x) index ($ x8664::arg_y) value ($ x8664::arg_z))
6296 (! misc-set)
6297 (<- ($ x8664::arg_z))
6298 (^))
6299
6300(defx862 x862-%decls-body %decls-body (seg vreg xfer form p2decls)
6301 (with-x86-p2-declarations p2decls
6302 (x862-form seg vreg xfer form)))
6303
6304
6305
6306(defx862 x862-%err-disp %err-disp (seg vreg xfer arglist)
6307 (x862-set-nargs seg (x862-arglist seg arglist))
6308 (! ksignalerr)
6309 (x862-nil seg vreg xfer))
6310
6311
6312(defx862 x862-local-tagbody local-tagbody (seg vreg xfer taglist body)
6313 (let* ((encstack (x862-encode-stack))
6314 (tagop (%nx1-operator tag-label)))
6315 (dolist (tag taglist)
6316 (rplacd tag (cons (backend-get-next-label) (cons encstack (cadr (cddr (cddr tag)))))))
6317 (dolist (form body)
6318 (if (eq (acode-operator form) tagop)
6319 (let ((tag (cddr form)))
6320 (@ (car tag)))
6321 (x862-form seg nil nil form)))
6322 (x862-nil seg vreg xfer)))
6323
6324(defx862 x862-call call (seg vreg xfer fn arglist &optional spread-p)
6325 (x862-call-fn seg vreg xfer fn arglist spread-p))
6326
6327(defx862 x862-self-call self-call (seg vreg xfer arglist &optional spread-p)
6328 (setq arglist (x862-augment-arglist *x862-cur-afunc* arglist (if spread-p 1 *x862-target-num-arg-regs*)))
6329 (x862-call-fn seg vreg xfer -2 arglist spread-p))
6330
6331
6332(defx862 x862-lexical-function-call lexical-function-call (seg vreg xfer afunc arglist &optional spread-p)
6333 (x862-call-fn seg vreg xfer (list (%nx1-operator simple-function) afunc)
6334 (x862-augment-arglist afunc arglist (if spread-p 1 *x862-target-num-arg-regs*))
6335 spread-p))
6336
6337(defx862 x862-builtin-call builtin-call (seg vreg xfer index arglist)
6338 (let* ((nargs (x862-arglist seg arglist))
6339 (tail-p (and (x862-tailcallok xfer) (<= nargs *x862-target-num-arg-regs*)))
6340 (idx (acode-fixnum-form-p index))
6341 (idx-subprim (x862-builtin-index-subprim idx))
6342 (subprim
6343 (or idx-subprim
6344 (case nargs
6345 (0 (subprim-name->offset '.SPcallbuiltin0))
6346 (1 (subprim-name->offset '.SPcallbuiltin1))
6347 (2 (subprim-name->offset '.SPcallbuiltin2))
6348 (3 (subprim-name->offset '.SPcallbuiltin3))
6349 (t (subprim-name->offset '.SPcallbuiltin))))))
6350 (when tail-p
6351 (x862-restore-nvrs seg *x862-register-restore-ea* *x862-register-restore-count*)
6352 (x862-restore-full-lisp-context seg))
6353 (unless idx-subprim
6354 (! lri x8664::imm0 (ash idx *x862-target-fixnum-shift*))
6355 (when (eql subprim (subprim-name->offset '.SPcallbuiltin))
6356 (x862-set-nargs seg nargs)))
6357 (if tail-p
6358 (! jump-subprim subprim)
6359 (progn
6360 (! call-subprim subprim)
6361 (<- x8664::arg_z)
6362 (^)))))
6363
6364
6365(defx862 x862-if if (seg vreg xfer testform true false)
6366 (if (nx-constant-form-p (acode-unwrapped-form testform))
6367 (x862-form seg vreg xfer (if (nx-null (acode-unwrapped-form testform)) false true))
6368 (let* ((cstack *x862-cstack*)
6369 (vstack *x862-vstack*)
6370 (top-lcell *x862-top-vstack-lcell*)
6371 (entry-stack (x862-encode-stack))
6372 (true-stack nil)
6373 (false-stack nil)
6374 (true-cleanup-label nil)
6375 (same-stack-effects nil)
6376 (true-is-goto (x862-go-label true))
6377 (false-is-goto (and (not true-is-goto) (x862-go-label false)))
6378 (endlabel (backend-get-next-label))
6379 (falselabel (backend-get-next-label))
6380 (need-else (unless false-is-goto (or (not (nx-null false)) (x862-for-value-p vreg))))
6381 (both-single-valued (and (not *x862-open-code-inline*)
6382 (eq xfer $backend-return)
6383 (x862-for-value-p vreg)
6384 need-else
6385 (x862-single-valued-form-p true)
6386 (x862-single-valued-form-p false))))
6387 (if (eq 0 xfer)
6388 (setq xfer nil))
6389 (if both-single-valued ; it's implied that we're returning
6390 (let* ((result x8664::arg_z))
6391 (let ((merge-else-branch-label (if (nx-null false) (x862-find-nilret-label))))
6392 (x862-conditional-form seg (x862-make-compound-cd 0 falselabel) testform)
6393 (x862-form seg result endlabel true)
6394 (if (and merge-else-branch-label (neq -1 (aref *backend-labels* merge-else-branch-label)))
6395 (backend-copy-label merge-else-branch-label falselabel)
6396 (progn
6397 (@ falselabel)
6398 (if (nx-null false) (@ (x862-record-nilret-label)))
6399 (x862-form seg result nil false)))
6400 (@ endlabel)
6401 (<- result)
6402 (^)))
6403 (progn
6404 (if (and need-else (x862-mvpass-p xfer))
6405 (setq true-cleanup-label (backend-get-next-label)))
6406 (x862-conditional-form
6407 seg
6408 (x862-make-compound-cd
6409 (or true-is-goto 0)
6410 (or false-is-goto
6411 (if need-else
6412 (if true-is-goto 0 falselabel)
6413 (if true-is-goto xfer (x862-cd-merge xfer falselabel)))))
6414 testform)
6415 (if true-is-goto
6416 (x862-unreachable-store)
6417 (if true-cleanup-label
6418 (progn
6419 (x862-open-undo $undomvexpect)
6420 (x862-form seg vreg (logior $backend-mvpass-mask true-cleanup-label) true))
6421 (x862-form seg vreg (if need-else (x862-cd-merge xfer endlabel) xfer) true)))
6422 (setq true-stack (x862-encode-stack))
6423 (setq *x862-cstack* cstack)
6424 (x862-set-vstack vstack)
6425 (setq *x862-top-vstack-lcell* top-lcell)
6426 (if false-is-goto (x862-unreachable-store))
6427 (let ((merge-else-branch-label (if (and (nx-null false) (eq xfer $backend-return)) (x862-find-nilret-label))))
6428 (if (and merge-else-branch-label (neq -1 (aref *backend-labels* merge-else-branch-label)))
6429 (backend-copy-label merge-else-branch-label falselabel)
6430 (progn
6431 (@ falselabel)
6432 (when need-else
6433 (if true-cleanup-label
6434 (x862-mvpass seg false)
6435 (x862-form seg vreg xfer false))
6436 (setq false-stack (x862-encode-stack))))))
6437 (when true-cleanup-label
6438 (if (setq same-stack-effects (x862-equal-encodings-p true-stack false-stack)) ; can share cleanup code
6439 (@ true-cleanup-label))
6440 (let* ((*x862-returning-values* :pass))
6441 (x862-nlexit seg xfer 1)
6442 (x862-branch seg (if (and xfer (neq xfer $backend-mvpass-mask)) xfer (if (not same-stack-effects) endlabel))))
6443 (unless same-stack-effects
6444 (@ true-cleanup-label)
6445 (multiple-value-setq (true *x862-cstack* *x862-vstack* *x862-top-vstack-lcell*)
6446 (x862-decode-stack true-stack))
6447 (let* ((*x862-returning-values* :pass))
6448 (x862-nlexit seg xfer 1)
6449 (^)))
6450 (x862-close-undo)
6451 (multiple-value-setq (*x862-undo-count* *x862-cstack* *x862-vstack* *x862-top-vstack-lcell*)
6452 (x862-decode-stack entry-stack)))
6453 (@ endlabel))))))
6454
6455(defx862 x862-or or (seg vreg xfer forms)
6456 (let* ((mvpass (x862-mvpass-p xfer))
6457 (tag1 (backend-get-next-label))
6458 (tag2 (backend-get-next-label))
6459 (vstack *x862-vstack*)
6460 (cstack *x862-cstack*)
6461 (dest (if (backend-crf-p vreg) vreg (if vreg x8664::arg_z (available-crf-temp *available-backend-crf-temps*))))
6462 (cd1 (x862-make-compound-cd
6463 (if (eq dest x8664::arg_z) tag1 (x862-cd-merge (x862-cd-true xfer) tag1)) 0)))
6464 (while (cdr forms)
6465 (x862-form seg dest (if (eq dest x8664::arg_z) nil cd1) (car forms))
6466 (when (eq dest x8664::arg_z)
6467 (with-crf-target () val-crf
6468 (x862-copy-register seg val-crf dest)
6469 (x862-branch seg cd1)))
6470 (setq forms (%cdr forms)))
6471 (if mvpass
6472 (progn (x862-multiple-value-body seg (car forms))
6473 (let* ((*x862-returning-values* t)) (x862-branch seg (x862-cd-merge xfer tag2))))
6474 (x862-form seg vreg (if (eq dest x8664::arg_z) (x862-cd-merge xfer tag2) xfer) (car forms)))
6475 (setq *x862-vstack* vstack *x862-cstack* cstack)
6476 (@ tag1)
6477 (when (eq dest x8664::arg_z)
6478 (<- x8664::arg_z)
6479 (^))
6480 (@ tag2)))
6481
6482(defx862 x862-simple-function simple-function (seg vreg xfer afunc)
6483 (x862-immediate seg vreg xfer (x862-afunc-lfun-ref afunc)))
6484
6485(defx862 x862-list list (seg vreg xfer arglist)
6486 (if (null vreg)
6487 (dolist (form arglist)
6488 (x862-form seg vreg nil form))
6489 (let* ((*x862-vstack* *x862-vstack*)
6490 (*x862-top-vstack-lcell* *x862-top-vstack-lcell*)
6491 (nargs (x862-formlist seg arglist nil)))
6492 (x862-set-nargs seg nargs)
6493 (! list)
6494 (<- x8664::arg_z)))
6495 (^))
6496
6497(defx862 x862-list* list* (seg vreg xfer arglist)
6498 (if (null vreg)
6499 (dolist (arg (apply #'append arglist))
6500 (x862-form seg nil nil arg))
6501 (let* ((*x862-vstack* *x862-vstack*)
6502 (*x862-top-vstack-lcell* *x862-top-vstack-lcell*)
6503 (nargs (x862-formlist seg (car arglist) (cadr arglist))))
6504 (declare (fixnum args))
6505 (when (> nargs 1)
6506 (x862-set-nargs seg (1- nargs))
6507 (! list*))
6508 (<- x8664::arg_z)))
6509 (^))
6510
6511(defx862 x862-minus1 minus1 (seg vreg xfer form)
6512 (x862-unary-builtin seg vreg xfer '%negate form))
6513
6514;;; Return T if form is declare to be something that couldn't be a fixnum.
6515(defun x862-explicit-non-fixnum-type-p (form)
6516 (let* ((type (x862-form-type form))
6517 (target-fixnum-type (nx-target-type 'fixnum)))
6518 (and (not (subtypep type target-fixnum-type))
6519 (not (subtypep target-fixnum-type type)))))
6520
6521(defun x862-inline-sub2 (seg vreg xfer form1 form2)
6522 (let* ((v2 (acode-fixnum-form-p form2)))
6523 (if (and v2 (not (eql v2 most-negative-fixnum)))
6524 (x862-inline-add2 seg vreg xfer form1 (make-acode (%nx1-operator fixnum) (- v2)))
6525 (with-x86-local-vinsn-macros (seg vreg xfer)
6526 (x862-two-targeted-reg-forms seg form1 ($ x8664::arg_y) form2 ($ x8664::arg_z))
6527 (let* ((out-of-line (backend-get-next-label))
6528 (done (backend-get-next-label)))
6529 (ensuring-node-target (target vreg)
6530 (if (acode-fixnum-form-p form1)
6531 (! branch-unless-arg-fixnum ($ x8664::arg_z) (aref *backend-labels* out-of-line))
6532 (if (acode-fixnum-form-p form2)
6533 (! branch-unless-arg-fixnum ($ x8664::arg_y) (aref *backend-labels* out-of-line))
6534 (! branch-unless-both-args-fixnums ($ x8664::arg_y) ($ x8664::arg_z) (aref *backend-labels* out-of-line))))
6535 (! fixnum-sub2 ($ x8664::arg_z) ($ x8664::arg_y) ($ x8664::arg_z))
6536 (x862-check-fixnum-overflow seg ($ x8664::arg_z) done)
6537 (@ out-of-line)
6538 (! call-subprim-2 ($ x8664::arg_z) (subprim-name->offset '.SPbuiltin-minus) ($ x8664::arg_y) ($ x8664::arg_z))
6539 (@ done)
6540 (x862-copy-register seg target ($ x8664::arg_z)))
6541 (^))))))
6542
6543(defun x862-inline-add2 (seg vreg xfer form1 form2)
6544 (with-x86-local-vinsn-macros (seg vreg xfer)
6545 (let* ((fix1 (acode-fixnum-form-p form1))
6546 (fix2 (acode-fixnum-form-p form2))
6547 (otherform (if (and fix1
6548 (typep (ash fix1 *x862-target-fixnum-shift*)
6549 '(signed-byte 32)))
6550 form2
6551 (if (and fix2
6552 (typep (ash fix2 *x862-target-fixnum-shift*)
6553 '(signed-byte 32)))
6554 form1))))
6555 (if otherform
6556 (x862-one-targeted-reg-form seg otherform ($ x8664::arg_z))
6557 (x862-two-targeted-reg-forms seg form1 ($ x8664::arg_y) form2 ($ x8664::arg_z)))
6558 (let* ((out-of-line (backend-get-next-label))
6559 (done (backend-get-next-label)))
6560
6561 (ensuring-node-target (target vreg)
6562 (if otherform
6563 (unless (acode-fixnum-form-p otherform)
6564 (! branch-unless-arg-fixnum ($ x8664::arg_z) (aref *backend-labels* out-of-line)))
6565 (if (acode-fixnum-form-p form1)
6566 (! branch-unless-arg-fixnum ($ x8664::arg_z) (aref *backend-labels* out-of-line))
6567 (if (acode-fixnum-form-p form2)
6568 (! branch-unless-arg-fixnum ($ x8664::arg_y) (aref *backend-labels* out-of-line))
6569 (! branch-unless-both-args-fixnums ($ x8664::arg_y) ($ x8664::arg_z) (aref *backend-labels* out-of-line)))))
6570 (if otherform
6571 (! add-constant ($ x8664::arg_z) (ash (or fix1 fix2) *x862-target-fixnum-shift*))
6572 (! fixnum-add2 ($ x8664::arg_z) ($ x8664::arg_y)))
6573 (x862-check-fixnum-overflow seg ($ x8664::arg_z) done)
6574 (@ out-of-line)
6575 (if otherform
6576 (x862-lri seg ($ x8664::arg_y) (ash (or fix1 fix2) *x862-target-fixnum-shift*)))
6577 (! call-subprim-2 ($ x8664::arg_z) (subprim-name->offset '.SPbuiltin-plus) ($ x8664::arg_y) ($ x8664::arg_z))
6578 (@ done)
6579 (x862-copy-register seg target ($ x8664::arg_z)))
6580 (^)))))
6581
6582(defx862 x862-add2 add2 (seg vreg xfer form1 form2)
6583 (multiple-value-bind (form1 form2)
6584 (nx-binop-numeric-contagion form1 form2 *x862-trust-declarations*)
6585 (if (and (x862-form-typep form1 'double-float)
6586 (x862-form-typep form2 'double-float))
6587 (x862-use-operator (%nx1-operator %double-float+-2)
6588 seg
6589 vreg
6590 xfer
6591 form1
6592 form2)
6593 (if (and (x862-form-typep form1 'single-float)
6594 (x862-form-typep form2 'single-float))
6595 (x862-use-operator (%nx1-operator %short-float+-2)
6596 seg
6597 vreg
6598 xfer
6599 form1
6600 form2)
6601 (if (and (x862-form-typep form1 'fixnum)
6602 (x862-form-typep form2 'fixnum))
6603 (x862-use-operator (%nx1-operator %i+)
6604 seg
6605 vreg
6606 xfer
6607 form1
6608 form2
6609 t)
6610 (if (or (x862-explicit-non-fixnum-type-p form1)
6611 (x862-explicit-non-fixnum-type-p form2))
6612 (x862-binary-builtin seg vreg xfer '+-2 form1 form2)
6613 (x862-inline-add2 seg vreg xfer form1 form2)))))))
6614
6615(defx862 x862-sub2 sub2 (seg vreg xfer form1 form2)
6616 (multiple-value-bind (form1 form2)
6617 (nx-binop-numeric-contagion form1 form2 *x862-trust-declarations*)
6618 (if (and (x862-form-typep form1 'double-float)
6619 (x862-form-typep form2 'double-float))
6620 (x862-use-operator (%nx1-operator %double-float--2)
6621 seg
6622 vreg
6623 xfer
6624 form1
6625 form2)
6626 (if (and (x862-form-typep form1 'single-float)
6627 (x862-form-typep form2 'single-float))
6628 (x862-use-operator (%nx1-operator %short-float--2)
6629 seg
6630 vreg
6631 xfer
6632 form1
6633 form2)
6634 (if (and (x862-form-typep form1 'fixnum)
6635 (x862-form-typep form2 'fixnum))
6636 (x862-use-operator (%nx1-operator %i-)
6637 seg
6638 vreg
6639 xfer
6640 form1
6641 form2
6642 t)
6643 (if (or (x862-explicit-non-fixnum-type-p form1)
6644 (x862-explicit-non-fixnum-type-p form2))
6645 (x862-binary-builtin seg vreg xfer '--2 form1 form2)
6646 (x862-inline-sub2 seg vreg xfer form1 form2)))))))
6647
6648(defx862 x862-mul2 mul2 (seg vreg xfer form1 form2)
6649 (multiple-value-bind (form1 form2)
6650 (nx-binop-numeric-contagion form1 form2 *x862-trust-declarations*)
6651 (if (and (x862-form-typep form1 'double-float)
6652 (x862-form-typep form2 'double-float))
6653 (x862-use-operator (%nx1-operator %double-float*-2)
6654 seg
6655 vreg
6656 xfer
6657 form1
6658 form2)
6659 (if (and (x862-form-typep form1 'single-float)
6660 (x862-form-typep form2 'single-float))
6661 (x862-use-operator (%nx1-operator %short-float*-2)
6662 seg
6663 vreg
6664 xfer
6665 form1
6666 form2)
6667 (x862-binary-builtin seg vreg xfer '*-2 form1 form2)))))
6668
6669(defx862 x862-div2 div2 (seg vreg xfer form1 form2)
6670 (multiple-value-bind (form1 form2)
6671 (nx-binop-numeric-contagion form1 form2 *x862-trust-declarations*)
6672 (if (and (x862-form-typep form1 'double-float)
6673 (x862-form-typep form2 'double-float))
6674 (x862-use-operator (%nx1-operator %double-float/-2)
6675 seg
6676 vreg
6677 xfer
6678 form1
6679 form2)
6680 (if (and (x862-form-typep form1 'single-float)
6681 (x862-form-typep form2 'single-float))
6682 (x862-use-operator (%nx1-operator %short-float/-2)
6683 seg
6684 vreg
6685 xfer
6686 form1
6687 form2)
6688 (let* ((f2 (acode-fixnum-form-p form2))
6689 (unwrapped (acode-unwrapped-form form1))
6690 (f1 nil)
6691 (f1/f2 nil))
6692 (if (and f2
6693 (not (zerop f2))
6694 (acode-p unwrapped)
6695 (or (eq (acode-operator unwrapped) (%nx1-operator mul2))
6696 (eq (acode-operator unwrapped) (%nx1-operator %i*)))
6697 (setq f1 (acode-fixnum-form-p (cadr unwrapped)))
6698 (typep (setq f1/f2 (/ f1 f2)) 'fixnum))
6699 (x862-use-operator (%nx1-operator mul2)
6700 seg
6701 vreg
6702 xfer
6703 (make-acode (%nx1-operator fixnum) f1/f2)
6704 (caddr unwrapped))
6705 (x862-binary-builtin seg vreg xfer '/-2 form1 form2)))))))
6706
6707(defx862 x862-logbitp logbitp (seg vreg xfer bitnum int)
6708 (x862-binary-builtin seg vreg xfer 'logbitp bitnum int))
6709
6710(defun x862-inline-logior2 (seg vreg xfer form1 form2)
6711 (with-x86-local-vinsn-macros (seg vreg xfer)
6712 (let* ((fix1 (acode-fixnum-form-p form1))
6713 (fix2 (acode-fixnum-form-p form2)))
6714 (if (and fix1 fix2)
6715 (x862-use-operator (%nx1-operator fixnum) seg vreg xfer (logior fix1 fix2))
6716 (let* ((fixval (or fix1 fix2))
6717 (fiximm (if fixval (<= (integer-length fixval)
6718 (- 31 *x862-target-fixnum-shift*))))
6719 (otherform (when fiximm (if fix1 form2 form1))))
6720 (let* ((out-of-line (backend-get-next-label))
6721 (done (backend-get-next-label)))
6722 (ensuring-node-target (target vreg)
6723 (if otherform
6724 (x862-one-targeted-reg-form seg otherform ($ x8664::arg_z))
6725 (x862-two-targeted-reg-forms seg form1 ($ x8664::arg_y) form2 ($ x8664::arg_z)))
6726 (if otherform
6727 (unless (acode-fixnum-form-p otherform)
6728 (! branch-unless-arg-fixnum ($ x8664::arg_z) (aref *backend-labels* out-of-line)))
6729 (if (acode-fixnum-form-p form1)
6730 (! branch-unless-arg-fixnum ($ x8664::arg_z) (aref *backend-labels* out-of-line))
6731 (if (acode-fixnum-form-p form2)
6732 (! branch-unless-arg-fixnum ($ x8664::arg_y) (aref *backend-labels* out-of-line))
6733 (! branch-unless-both-args-fixnums ($ x8664::arg_y) ($ x8664::arg_z) (aref *backend-labels* out-of-line)))))
6734 (if otherform
6735 (! %logior-c ($ x8664::arg_z) ($ x8664::arg_z) (ash fixval x8664::fixnumshift))
6736 (! %logior2 ($ x8664::arg_z) ($ x8664::arg_z) ($ x8664::arg_y)))
6737 (-> done)
6738 (@ out-of-line)
6739 (if otherform
6740 (x862-lri seg ($ x8664::arg_y) (ash fixval x8664::fixnumshift)))
6741 (! call-subprim-2 ($ x8664::arg_z) (subprim-name->offset '.SPbuiltin-logior) ($ x8664::arg_y) ($ x8664::arg_z))
6742 (@ done)
6743 (x862-copy-register seg target ($ x8664::arg_z)))
6744 (^)))))))
6745
6746(defx862 x862-logior2 logior2 (seg vreg xfer form1 form2)
6747 (if (or (x862-explicit-non-fixnum-type-p form1)
6748 (x862-explicit-non-fixnum-type-p form2))
6749 (x862-binary-builtin seg vreg xfer 'logior-2 form1 form2)
6750 (x862-inline-logior2 seg vreg xfer form1 form2)))
6751
6752(defx862 x862-logxor2 logxor2 (seg vreg xfer form1 form2)
6753 (x862-binary-builtin seg vreg xfer 'logxor-2 form1 form2))
6754
6755(defun x862-inline-logand2 (seg vreg xfer form1 form2)
6756 (with-x86-local-vinsn-macros (seg vreg xfer)
6757 (let* ((fix1 (acode-fixnum-form-p form1))
6758 (fix2 (acode-fixnum-form-p form2)))
6759 (if (and fix1 fix2)
6760 (x862-use-operator (%nx1-operator fixnum) seg vreg xfer (logand fix1 fix2))
6761 (let* ((fixval (or fix1 fix2))
6762 (fiximm (if fixval (<= (integer-length fixval)
6763 (- 31 *x862-target-fixnum-shift*))))
6764 (otherform (when fiximm (if fix1 form2 form1))))
6765 (let* ((out-of-line (backend-get-next-label))
6766 (done (backend-get-next-label)))
6767 (ensuring-node-target (target vreg)
6768 (if otherform
6769 (x862-one-targeted-reg-form seg otherform ($ x8664::arg_z))
6770 (x862-two-targeted-reg-forms seg form1 ($ x8664::arg_y) form2 ($ x8664::arg_z)))
6771 (if otherform
6772 (unless (acode-fixnum-form-p otherform)
6773 (! branch-unless-arg-fixnum ($ x8664::arg_z) (aref *backend-labels* out-of-line)))
6774 (if (acode-fixnum-form-p form1)
6775 (! branch-unless-arg-fixnum ($ x8664::arg_z) (aref *backend-labels* out-of-line))
6776 (if (acode-fixnum-form-p form2)
6777 (! branch-unless-arg-fixnum ($ x8664::arg_y) (aref *backend-labels* out-of-line))
6778 (! branch-unless-both-args-fixnums ($ x8664::arg_y) ($ x8664::arg_z) (aref *backend-labels* out-of-line)))))
6779 (if otherform
6780 (! %logand-c ($ x8664::arg_z) ($ x8664::arg_z) (ash fixval x8664::fixnumshift))
6781 (! %logand2 ($ x8664::arg_z) ($ x8664::arg_z) ($ x8664::arg_y)))
6782 (-> done)
6783 (@ out-of-line)
6784 (if otherform
6785 (x862-lri seg ($ x8664::arg_y) (ash fixval x8664::fixnumshift)))
6786 (! call-subprim-2 ($ x8664::arg_z) (subprim-name->offset '.SPbuiltin-logand) ($ x8664::arg_y) ($ x8664::arg_z))
6787 (@ done)
6788 (x862-copy-register seg target ($ x8664::arg_z)))
6789 (^)))))))
6790
6791(defx862 x862-logand2 logand2 (seg vreg xfer form1 form2)
6792
6793 (if (or (x862-explicit-non-fixnum-type-p form1)
6794 (x862-explicit-non-fixnum-type-p form2))
6795 (x862-binary-builtin seg vreg xfer 'logand-2 form1 form2)
6796 (x862-inline-logand2 seg vreg xfer form1 form2)))
6797
6798(defx862 x862-%quo2 %quo2 (seg vreg xfer form1 form2)
6799 (x862-binary-builtin seg vreg xfer '/-2 form1 form2))
6800
6801(defx862 x862-%aref1 %aref1 (seg vreg xfer v i)
6802 (let* ((vtype (acode-form-type v t))
6803 (ctype (if vtype (specifier-type vtype)))
6804 (atype (if (array-ctype-p ctype) ctype))
6805 (keyword (if (and atype
6806 (let* ((dims (array-ctype-dimensions atype)))
6807 (and (not (atom dims))
6808 (= (length dims) 1)))
6809 (not (array-ctype-complexp atype)))
6810 (funcall
6811 (arch::target-array-type-name-from-ctype-function
6812 (backend-target-arch *target-backend*))
6813 atype))))
6814 (if keyword
6815 (x862-vref seg vreg xfer keyword v i (unless *x862-reckless*
6816 (nx-lookup-target-uvector-subtag keyword)))
6817 (x862-binary-builtin seg vreg xfer '%aref1 v i))))
6818
6819(defx862 x862-%aset1 aset1 (seg vreg xfer v i n)
6820 (let* ((vtype (acode-form-type v t))
6821 (atype (if vtype (specifier-type vtype)))
6822 (keyword (if (and atype
6823 (let* ((dims (array-ctype-dimensions atype)))
6824 (and (not (atom dims))
6825 (= (length dims) 1)))
6826 (not (array-ctype-complexp atype)))
6827 (funcall
6828 (arch::target-array-type-name-from-ctype-function
6829 (backend-target-arch *target-backend*))
6830 atype))))
6831 (if keyword
6832 (x862-vset seg vreg xfer keyword v i n (not *x862-reckless*))
6833 (x862-ternary-builtin seg vreg xfer '%aset1 v i n))))
6834
6835(defx862 x862-%i+ %i+ (seg vreg xfer form1 form2 &optional overflow)
6836 (when overflow
6837 (let* ((type *x862-target-half-fixnum-type*))
6838 (when (and (x862-form-typep form1 type)
6839 (x862-form-typep form2 type))
6840 (setq overflow nil))))
6841 (cond ((null vreg)
6842 (x862-form seg nil nil form1)
6843 (x862-form seg nil xfer form2))
6844
6845 (t
6846 (let* ((fix1 (acode-fixnum-form-p form1))
6847 (fix2 (acode-fixnum-form-p form2))
6848 (other (if (and fix1
6849 (typep (ash fix1 *x862-target-fixnum-shift*)
6850 '(signed-byte 32)))
6851 form2
6852 (if (and fix2
6853 (typep (ash fix2 *x862-target-fixnum-shift*)
6854 '(signed-byte 32)))
6855 form1))))
6856 (if (and fix1 fix2)
6857 (x862-lri seg vreg (ash (+ fix1 fix2) *x862-target-fixnum-shift*))
6858 (if other
6859 (let* ((constant (ash (or fix1 fix2) *x862-target-fixnum-shift*)))
6860 (if (zerop constant)
6861 (x862-form seg vreg nil other)
6862 (if overflow
6863 (ensuring-node-target (target vreg)
6864 (x862-one-targeted-reg-form seg other target)
6865 (! add-constant target constant)
6866 (x862-check-fixnum-overflow seg target))
6867 (ensuring-node-target (target vreg)
6868 (let* ((reg (x862-one-untargeted-reg-form seg other target)))
6869 (! add-constant3 target reg constant))))))
6870 (if (not overflow)
6871 (multiple-value-bind (r1 r2) (x862-two-untargeted-reg-forms seg form1 x8664::arg_y form2 x8664::arg_z)
6872 ;; This isn't guaranteed to set the overflow flag,
6873 ;; but may do so.
6874 (ensuring-node-target (target vreg)
6875 (! fixnum-add3 target r1 r2)))
6876 (ensuring-node-target (target vreg)
6877 (multiple-value-bind (r1 r2) (x862-two-untargeted-reg-forms seg form1 x8664::arg_y form2 x8664::arg_z)
6878 (cond ((= (hard-regspec-value target)
6879 (hard-regspec-value r1))
6880 (! fixnum-add2 target r2))
6881 ((= (hard-regspec-value target)
6882 (hard-regspec-value r2))
6883 (! fixnum-add2 target r1))
6884 (t
6885 (x862-copy-register seg target r1)
6886 (! fixnum-add2 target r2)))
6887 (x862-check-fixnum-overflow seg target))))))
6888 (^)))))
6889
6890(defx862 x862-%i- %i- (seg vreg xfer num1 num2 &optional overflow)
6891 (when overflow
6892 (let* ((type *x862-target-half-fixnum-type*))
6893 (when (and (x862-form-typep num1 type)
6894 (x862-form-typep num2 type))
6895 (setq overflow nil))))
6896 (let* ((v1 (acode-fixnum-form-p num1))
6897 (v2 (acode-fixnum-form-p num2)))
6898 (if (and v1 v2)
6899 (x862-use-operator (%nx1-operator fixnum) seg vreg xfer (%i- v1 v2))
6900 (if (and v2 (neq v2 most-negative-fixnum))
6901 (x862-use-operator (%nx1-operator %i+) seg vreg xfer num1 (make-acode (%nx1-operator fixnum) (- v2)) overflow)
6902 (cond
6903 ((null vreg)
6904 (x862-form seg nil nil num1)
6905 (x862-form seg nil xfer num2))
6906 (t
6907 (let* ((fix1 (acode-fixnum-form-p num1))
6908 (fix2 (acode-fixnum-form-p num2)))
6909 (if (and fix1 fix2 (not overflow))
6910 (x862-lri seg vreg (ash (- fix1 fix2) *x862-target-fixnum-shift*))
6911 (multiple-value-bind (r1 r2) (x862-two-untargeted-reg-forms seg num1 x8664::arg_y num2 x8664::arg_z)
6912 ;; This isn't guaranteed to set the overflow flag,
6913 ;; but may do so.
6914 (ensuring-node-target (target vreg)
6915 (! fixnum-sub2 target r1 r2)
6916 (if overflow
6917 (x862-check-fixnum-overflow seg target))))))
6918 (^)))))))
6919
6920(defx862 x862-%i* %i* (seg vreg xfer num1 num2)
6921 (if (null vreg)
6922 (progn
6923 (x862-form seg nil nil num1)
6924 (x862-form seg nil xfer num2))
6925 (let* ((fix1 (acode-fixnum-form-p num1))
6926 (fix2 (acode-fixnum-form-p num2))
6927 (other (if (typep fix1 '(signed-byte 32)) num2 (if (typep fix2 '(signed-byte 32)) num1))))
6928 (if (and fix1 fix2)
6929 (x862-lri seg vreg (ash (* fix1 fix2) *x862-target-fixnum-shift*))
6930 (if other
6931 (! multiply-immediate vreg (x862-one-untargeted-reg-form seg other x8664::arg_z) (or fix1 fix2))
6932 (multiple-value-bind (rx ry) (x862-two-untargeted-reg-forms seg num1 x8664::arg_y num2 x8664::arg_z)
6933 (ensuring-node-target (target vreg)
6934 (! multiply-fixnums target rx ry)))))
6935 (^))))
6936
6937(defx862 x862-nth-value nth-value (seg vreg xfer n form)
6938 (let* ((*x862-vstack* *x862-vstack*)
6939 (*x862-top-vstack-lcell* *x862-top-vstack-lcell*))
6940 (let* ((nreg (x862-one-untargeted-reg-form seg n x8664::arg_z)))
6941 (unless (acode-fixnum-form-p n)
6942 (! trap-unless-fixnum nreg))
6943 (x862-vpush-register seg nreg))
6944 (x862-multiple-value-body seg form) ; sets nargs
6945 (! nth-value x8664::arg_z))
6946 (<- x8664::arg_z)
6947 (^))
6948
6949(defx862 x862-values values (seg vreg xfer forms)
6950 (if (eq (list-length forms) 1)
6951 (if (x862-cd-compound-p xfer)
6952 (x862-form seg vreg xfer (%car forms))
6953 (progn
6954 (x862-form seg vreg nil (%car forms))
6955 (^)))
6956 (if (not (x862-mv-p xfer))
6957 (if forms
6958 (x862-use-operator (%nx1-operator prog1) seg vreg xfer forms)
6959 (x862-nil seg vreg xfer))
6960 (progn
6961 (let* ((*x862-vstack* *x862-vstack*)
6962 (*x862-top-vstack-lcell* *x862-top-vstack-lcell*))
6963 (x862-set-nargs seg (x862-formlist seg forms nil)))
6964 (let* ((*x862-returning-values* t))
6965 (^))))))
6966
6967(defx862 x862-base-char-p base-char-p (seg vreg xfer cc form)
6968 (x862-char-p seg vreg xfer cc form))
6969
6970(defun x862-char-p (seg vreg xfer cc form)
6971 (with-x86-local-vinsn-macros (seg vreg xfer)
6972 (multiple-value-bind (cr-bit true-p) (acode-condition-to-x86-cr-bit cc)
6973 (! mask-base-char x8664::imm0 (x862-one-untargeted-reg-form seg form x8664::arg_z))
6974 (x862-test-reg-%izerop seg vreg xfer x8664::imm0 cr-bit true-p
6975 (target-arch-case
6976
6977 (:x8664 x8664::subtag-character))))))
6978
6979
6980(defx862 x862-let* let* (seg vreg xfer vars vals body p2decls &aux
6981 (old-stack (x862-encode-stack)))
6982 (x862-check-lcell-depth)
6983 (with-x86-p2-declarations p2decls
6984 (x862-seq-bind seg vars vals)
6985 (x862-undo-body seg vreg xfer body old-stack))
6986 (dolist (v vars) (x862-close-var seg v)))
6987
6988(defx862 x862-multiple-value-bind multiple-value-bind (seg vreg xfer vars valform body p2decls)
6989 (let* ((n (list-length vars))
6990 (vloc *x862-vstack*)
6991 (nbytes (* n *x862-target-node-size*))
6992 (old-stack (x862-encode-stack)))
6993 (with-x86-p2-declarations p2decls
6994 (x862-multiple-value-body seg valform)
6995 (! fitvals n)
6996 (x862-set-vstack (%i+ vloc nbytes))
6997 (let* ((old-top *x862-top-vstack-lcell*)
6998 (lcells (progn (x862-reserve-vstack-lcells n) (x862-collect-lcells :reserved old-top))))
6999 (dolist (var vars)
7000 (let* ((lcell (pop lcells))
7001 (reg (x862-assign-register-var var)))
7002 (if reg
7003 (x862-init-regvar seg var reg (x862-vloc-ea vloc))
7004 (x862-bind-var seg var vloc lcell))
7005 (setq vloc (%i+ vloc *x862-target-node-size*)))))
7006 (x862-undo-body seg vreg xfer body old-stack)
7007 (dolist (var vars)
7008 (x862-close-var seg var)))))
7009
7010(defx862 x862-debind debind (seg vreg xfer lambda-list bindform req opt rest keys auxen whole body p2decls cdr-p)
7011 (declare (ignore lambda-list))
7012 (let* ((old-stack (x862-encode-stack))
7013 (*x862-top-vstack-lcell* *x862-top-vstack-lcell*)
7014 (vloc *x862-vstack*))
7015 (with-x86-p2-declarations p2decls
7016 (x862-bind-structured-lambda
7017 seg
7018 (x862-spread-lambda-list seg bindform whole req opt rest keys nil cdr-p)
7019 vloc (x862-vloc-ea vloc) whole req opt rest keys auxen)
7020 (x862-undo-body seg vreg xfer body old-stack)
7021 (x862-close-structured-lambda seg whole req opt rest keys auxen))))
7022
7023(defx862 x862-multiple-value-prog1 multiple-value-prog1 (seg vreg xfer forms)
7024 (if (or (not (x862-mv-p xfer)) (x862-single-valued-form-p (%car forms)))
7025 (x862-use-operator (%nx1-operator prog1) seg vreg xfer forms)
7026 (progn
7027 (let* ((*x862-vstack* *x862-vstack*)
7028 (*x862-top-vstack-lcell* *x862-top-vstack-lcell*))
7029 (x862-multiple-value-body seg (%car forms))
7030 (x862-open-undo $undostkblk)
7031 (! save-values))
7032 (dolist (form (cdr forms))
7033 (x862-form seg nil nil form))
7034 (x862-set-nargs seg 0)
7035 (! recover-values)
7036 (x862-close-undo)
7037 (let* ((*x862-returning-values* t))
7038 (^)))))
7039
7040(defx862 x862-not not (seg vreg xfer cc form)
7041 (multiple-value-bind (cr-bit true-p) (acode-condition-to-x86-cr-bit cc)
7042 (let* ((ea (x862-lexical-reference-ea form nil)))
7043 (if (and ea (memory-spec-p ea))
7044 (x862-compare-ea-to-nil
7045 seg
7046 vreg
7047 xfer
7048 ea
7049 cr-bit
7050 true-p)
7051 (x862-compare-register-to-nil
7052 seg
7053 vreg
7054 xfer
7055 (x862-one-untargeted-reg-form seg form x8664::arg_z)
7056 cr-bit
7057 true-p)))))
7058
7059
7060(defx862 x862-%alloc-misc %make-uvector (seg vreg xfer element-count st &optional initval)
7061 (if (null vreg)
7062 (progn
7063 (x862-form seg nil nil element-count)
7064 (x862-form seg nil xfer st))
7065 (let* ((subtag (acode-fixnum-form-p st))
7066 (nelements (acode-fixnum-form-p element-count))
7067 (nbytes (if (and subtag nelements) (x862-misc-byte-count subtag nelements))))
7068 (if (and nbytes (null initval)
7069 (< (logand
7070 (lognot (1- *x862-target-dnode-size*))
7071 (+ nbytes *x862-target-node-size*
7072 (1- *x862-target-dnode-size*))) #x8000))
7073 (let* ((header x8664::imm0)
7074 (physsize x8664::imm1))
7075 (x862-lri seg header (arch::make-vheader nelements subtag))
7076 (x862-lri seg physsize (- (* (ceiling (+ nbytes *x862-target-node-size*) *x862-target-dnode-size*) *x862-target-dnode-size*) (target-arch-case (:x8664 x8664::fulltag-misc))))
7077 (ensuring-node-target (target vreg)
7078 (! %allocate-uvector target)))
7079 (progn
7080 (if initval
7081 (progn
7082 (x862-three-targeted-reg-forms seg element-count ($ x8664::arg_x) st ($ x8664::arg_y) initval ($ x8664::arg_z))
7083 (! misc-alloc-init)
7084 (<- ($ x8664::arg_z)))
7085 (progn
7086 (x862-two-targeted-reg-forms seg element-count ($ x8664::arg_y) st ($ x8664::arg_z))
7087 (! misc-alloc)
7088 (<- ($ x8664::arg_z))))))
7089 (^))))
7090
7091(defx862 x862-%iasr %iasr (seg vreg xfer form1 form2)
7092 (if (null vreg)
7093 (progn
7094 (x862-form seg nil nil form1)
7095 (x862-form seg vreg xfer form2))
7096 (let* ((count (acode-fixnum-form-p form1))
7097 (max (target-arch-case (:x8664 63))))
7098 (declare (fixnum max))
7099 (ensuring-node-target (target vreg)
7100 (if count
7101 (! %iasr-c target (if (> count max) max count)
7102 (x862-one-untargeted-reg-form seg form2 x8664::arg_z))
7103 (multiple-value-bind (cnt src) (x862-two-targeted-reg-forms seg form1 ($ x8664::arg_y) form2 ($ x8664::arg_z))
7104 (! %iasr target cnt src))))
7105 (^))))
7106
7107(defx862 x862-%ilsr %ilsr (seg vreg xfer form1 form2)
7108 (if (null vreg)
7109 (progn
7110 (x862-form seg nil nil form1)
7111 (x862-form seg vreg xfer form2))
7112 (let* ((count (acode-fixnum-form-p form1)))
7113 (ensuring-node-target (target vreg)
7114 (if count
7115 (let ((src (x862-one-untargeted-reg-form seg form2 ($ x8664::arg_z))))
7116 (if (<= count 31)
7117 (! %ilsr-c target count src)
7118 (! lri target 0)))
7119 (multiple-value-bind (cnt src) (x862-two-targeted-reg-forms seg form1 ($ x8664::arg_y) form2 ($ x8664::arg_z))
7120 (! %ilsr target cnt src))))
7121 (^))))
7122
7123
7124(defx862 x862-%i<> %i<> (seg vreg xfer cc form1 form2)
7125 (multiple-value-bind (cr-bit true-p) (acode-condition-to-x86-cr-bit cc)
7126 (x862-compare seg vreg xfer form1 form2 cr-bit true-p)))
7127
7128(defx862 x862-%natural<> %natural<> (seg vreg xfer cc form1 form2)
7129 (multiple-value-bind (cr-bit true-p) (acode-condition-to-x86-cr-bit cc)
7130 (x862-natural-compare seg vreg xfer form1 form2 cr-bit true-p)))
7131
7132(defx862 x862-double-float-compare double-float-compare (seg vreg xfer cc form1 form2)
7133 (multiple-value-bind (cr-bit true-p) (acode-condition-to-x86-cr-bit cc)
7134 (with-fp-target () (r1 :double-float)
7135 (with-fp-target (r1) (r2 :double-float)
7136 (multiple-value-bind (r1 r2) (x862-two-untargeted-reg-forms seg form1 r1 form2 r2)
7137 (x862-compare-double-float-registers seg vreg xfer r1 r2 cr-bit true-p))))))
7138
7139(defx862 x862-short-float-compare short-float-compare (seg vreg xfer cc form1 form2)
7140 (multiple-value-bind (cr-bit true-p) (acode-condition-to-x86-cr-bit cc)
7141 (with-fp-target () (r1 :single-float)
7142 (with-fp-target (r1) (r2 :single-float)
7143 (multiple-value-bind (r1 r2) (x862-two-untargeted-reg-forms seg form1 r1 form2 r2)
7144 (x862-compare-single-float-registers seg vreg xfer r1 r2 cr-bit true-p))))))
7145
7146(eval-when (:compile-toplevel :execute)
7147 (defmacro defx862-df-op (fname opname vinsn)
7148 `(defx862 ,fname ,opname (seg vreg xfer f0 f1)
7149 (if (null vreg)
7150 (progn
7151 (x862-form seg nil nil f0)
7152 (x862-form seg vreg xfer f1))
7153 (with-fp-target () (r1 :double-float)
7154 (with-fp-target (r1) (r2 :double-float)
7155 (multiple-value-bind (r1 r2) (x862-two-untargeted-reg-forms seg f0 r1 f1 r2)
7156 (if (and (= (hard-regspec-class vreg) hard-reg-class-fpr)
7157 (or (not (= (hard-regspec-value vreg)
7158 (hard-regspec-value r2)))
7159 ,(and
7160 (not (eq opname '%double-float--2))
7161 (not (eq opname '%double-float/-2)))))
7162 (! ,vinsn vreg r1 r2)
7163 (with-fp-target (r2) (result :double-float)
7164 (! ,vinsn result r1 r2)
7165 (if (= (hard-regspec-class vreg) hard-reg-class-fpr)
7166 (<- result)
7167 (ensuring-node-target (target vreg)
7168 (x862-copy-register seg target result)))))
7169 (^)))))))
7170
7171 (defmacro defx862-sf-op (fname opname vinsn)
7172 `(defx862 ,fname ,opname (seg vreg xfer f0 f1)
7173 (if (null vreg)
7174 (progn
7175 (x862-form seg nil nil f0)
7176 (x862-form seg vreg xfer f1))
7177 (with-fp-target () (r1 :single-float)
7178 (with-fp-target (r1) (r2 :single-float)
7179 (multiple-value-bind (r1 r2) (x862-two-untargeted-reg-forms seg f0 r1 f1 r2)
7180 (if (and (= (hard-regspec-class vreg) hard-reg-class-fpr)
7181 (or (not (= (hard-regspec-value vreg)
7182 (hard-regspec-value r2)))
7183 ,(and
7184 (not (eq opname '%short-float--2))
7185 (not (eq opname '%short-float/-2)))))
7186 (! ,vinsn vreg r1 r2)
7187 (with-fp-target (r2) (result :single-float)
7188 (! ,vinsn result r1 r2)
7189 (if (= (hard-regspec-class vreg) hard-reg-class-fpr)
7190 (<- result)
7191 (ensuring-node-target (target vreg)
7192 (x862-copy-register seg target result)))))
7193 (^)))))))
7194 )
7195
7196(defx862-df-op x862-%double-float+-2 %double-float+-2 double-float+-2)
7197(defx862-df-op x862-%double-float--2 %double-float--2 double-float--2)
7198(defx862-df-op x862-%double-float*-2 %double-float*-2 double-float*-2)
7199(defx862-df-op x862-%double-float/-2 %double-float/-2 double-float/-2)
7200
7201(defx862-sf-op x862-%short-float+-2 %short-float+-2 single-float+-2)
7202(defx862-sf-op x862-%short-float--2 %short-float--2 single-float--2)
7203(defx862-sf-op x862-%short-float*-2 %short-float*-2 single-float*-2)
7204(defx862-sf-op x862-%short-float/-2 %short-float/-2 single-float/-2)
7205
7206(defun x862-get-float (seg vreg xfer ptr offset double-p fp-reg)
7207 (with-x86-local-vinsn-macros (seg vreg xfer)
7208 (cond ((null vreg)
7209 (x862-form seg nil nil ptr)
7210 (x862-form seg nil xfer offset))
7211 (t
7212 (let* ((fixoffset (acode-fixnum-form-p offset)))
7213 (if (typep fixoffset '(signed-byte 32))
7214 (with-imm-target () (ptrreg :address)
7215 (x862-form seg ptrreg nil ptr)
7216 (if double-p
7217 (! mem-ref-c-double-float fp-reg ptrreg fixoffset)
7218 (! mem-ref-c-single-float fp-reg ptrreg fixoffset)))
7219 (with-imm-target () (ptrreg :address)
7220 (with-imm-target (ptrreg) (offsetreg :s64)
7221 (x862-two-targeted-reg-forms seg
7222 ptr ptrreg
7223 offset ($ x8664::arg_z))
7224 (! fixnum->signed-natural offsetreg x8664::arg_z)
7225 (if double-p
7226 (! mem-ref-double-float fp-reg ptrreg offsetreg)
7227 (! mem-ref-single-float fp-reg ptrreg offsetreg)))))
7228 (<- fp-reg))
7229 (^)))))
7230
7231
7232(defx862 x862-%get-double-float %get-double-float (seg vreg xfer ptr offset)
7233 (with-fp-target () (fp-reg :double-float)
7234 (x862-get-float seg vreg xfer ptr offset t fp-reg)))
7235
7236(defx862 x862-%get-single-float %get-single-float (seg vreg xfer ptr offset)
7237 (with-fp-target () (fp-reg :single-float)
7238 (x862-get-float seg vreg xfer ptr offset nil fp-reg)))
7239
7240(defun x862-set-float (seg vreg xfer ptr offset newval double-p fp-reg)
7241 (with-x86-local-vinsn-macros (seg vreg xfer)
7242 (let* ((fixoffset (acode-fixnum-form-p offset))
7243 (immoffset (typep fixoffset '(unsigned-byte 15))))
7244 (with-imm-target () (ptr-reg :address)
7245 (cond ((or (null vreg)
7246 (= (hard-regspec-class vreg) hard-reg-class-fpr))
7247 (cond (immoffset
7248 (x862-push-register
7249 seg
7250 (x862-one-untargeted-reg-form seg
7251 ptr
7252 ptr-reg))
7253 (x862-one-targeted-reg-form seg newval fp-reg)
7254 (x862-pop-register seg ptr-reg)
7255 (if double-p
7256 (! mem-set-c-double-float fp-reg ptr-reg fixoffset)
7257 (! mem-set-c-single-float fp-reg ptr-reg fixoffset)))
7258 (t
7259 (with-imm-target (ptr-reg) (offset-reg :s32)
7260 (x862-push-register
7261 seg
7262 (x862-one-untargeted-reg-form seg
7263 ptr
7264 ptr-reg))
7265 (x862-push-register
7266 seg
7267 (x862-one-untargeted-reg-form seg
7268 offset
7269 x8664::arg_z))
7270 (x862-one-targeted-reg-form seg newval fp-reg)
7271 (x862-pop-register seg x8664::arg_z)
7272 (x862-pop-register seg ptr-reg)
7273 (! fixnum->signed-natural offset-reg x8664::arg_z)
7274 (if double-p
7275 (! mem-set-double-float fp-reg ptr-reg offset-reg)
7276 (! mem-set-single-float fp-reg ptr-reg offset-reg)))))
7277 (<- fp-reg))
7278 (t
7279 (cond (immoffset
7280 (let* ((rnew ($ x8664::arg_z)))
7281 (x862-push-register
7282 seg
7283 (x862-one-untargeted-reg-form seg
7284 ptr
7285 ptr-reg))
7286 (x862-one-targeted-reg-form seg newval rnew)
7287 (x862-pop-register seg ptr-reg)
7288 (with-imm-temps (ptr-reg) ()
7289 (x862-copy-register seg fp-reg rnew)
7290 (if double-p
7291 (! mem-set-c-double-float fp-reg ptr-reg fixoffset)
7292 (! mem-set-c-single-float fp-reg ptr-reg fixoffset)))))
7293 (t
7294 (let* ((roffset ($ x8664::arg_y))
7295 (rnew ($ x8664::arg_z)))
7296 (x862-push-register
7297 seg
7298 (x862-one-untargeted-reg-form
7299 seg
7300 ptr ptr-reg))
7301 (x862-two-targeted-reg-forms seg
7302 offset roffset
7303 newval rnew)
7304 (x862-pop-register seg ptr-reg)
7305 (with-imm-target (ptr-reg) (offset-reg :s32)
7306 (with-imm-temps (ptr-reg) ()
7307 (x862-copy-register seg fp-reg rnew)
7308 (! fixnum->signed-natural offset-reg roffset))
7309 (if double-p
7310 (! mem-set-double-float fp-reg ptr-reg offset-reg)
7311 (! mem-set-single-float fp-reg ptr-reg offset-reg))))))
7312 (<- x8664::arg_z)))
7313 (^)))))
7314
7315(defx862 x862-%set-double-float %set-double-float (seg vreg xfer ptr offset newval)
7316 (with-fp-target () (fp-reg :double-float)
7317 (x862-set-float seg vreg xfer ptr offset newval t fp-reg)))
7318
7319(defx862 x862-%set-single-float %set-single-float (seg vreg xfer ptr offset newval)
7320 (with-fp-target () (fp-reg :single-float)
7321 (x862-set-float seg vreg xfer ptr offset newval nil fp-reg)))
7322
7323(defx862 x862-immediate-get-ptr immediate-get-ptr (seg vreg xfer ptr offset)
7324 (let* ((absptr (acode-absolute-ptr-p ptr))
7325 (triv-p (x862-trivial-p offset))
7326 (dest vreg)
7327 (offval (acode-fixnum-form-p offset)))
7328 (cond ((not vreg)
7329 (x862-form seg nil nil ptr)
7330 (x862-form seg nil xfer offset))
7331 (t
7332 (if (and absptr offval)
7333 (setq absptr (+ absptr offval) offval 0)
7334 (setq absptr nil))
7335 (and offval (%i> (integer-length offval) 15) (setq offval nil))
7336 (and absptr (%i> (integer-length absptr) 15) (setq absptr nil))
7337 (target-arch-case
7338
7339 (:x8664 (progn
7340 (and offval (logtest 3 offval) (setq offval nil))
7341 (and absptr (logtest 3 absptr) (setq absptr nil)))))
7342 (if absptr
7343 (! mem-ref-c-absolute-natural dest absptr)
7344 (if offval
7345 (let* ((src (x862-macptr-arg-to-reg seg ptr ($ x8664::imm0 :mode :address))))
7346 (! mem-ref-c-natural dest src offval))
7347 (let* ((src (x862-macptr-arg-to-reg seg ptr ($ x8664::imm0 :mode :address))))
7348 (if triv-p
7349 (with-imm-temps (src) (x)
7350 (if (acode-fixnum-form-p offset)
7351 (x862-lri seg x (acode-fixnum-form-p offset))
7352 (! fixnum->signed-natural x (x862-one-untargeted-reg-form seg offset x8664::arg_z)))
7353 (! mem-ref-natural dest src x))
7354 (progn
7355 (! temp-push-unboxed-word src)
7356 (x862-open-undo $undostkblk)
7357 (let* ((oreg (x862-one-untargeted-reg-form seg offset x8664::arg_z)))
7358 (with-imm-temps () (src x)
7359 (! temp-pop-unboxed-word src)
7360 (x862-close-undo)
7361 (! fixnum->signed-natural x oreg)
7362 (! mem-ref-natural dest src x))))))))
7363 (^)))))
7364
7365(defx862 x862-get-bit %get-bit (seg vreg xfer ptr offset)
7366 (if (null vreg)
7367 (progn
7368 (x862-form seg nil nil ptr)
7369 (x862-form seg nil xfer offset))
7370 (let* ((offval (acode-fixnum-form-p offset)))
7371 (if (typep offval '(signed-byte 32)) ; or thereabouts
7372 (with-imm-target () (src-reg :address)
7373 (x862-one-targeted-reg-form seg ptr src-reg)
7374 (if (node-reg-p vreg)
7375 (! mem-ref-c-bit-fixnum vreg src-reg offval)
7376 (with-imm-target () ;OK if src-reg & dest overlap
7377 (dest :u8)
7378 (! mem-ref-c-bit dest src-reg offval)
7379 (<- dest))))
7380 (with-imm-target () (src-reg :address)
7381 (x862-two-targeted-reg-forms seg ptr src-reg offset ($ x8664::arg_z))
7382 (if (node-reg-p vreg)
7383 (! mem-ref-bit-fixnum vreg src-reg ($ x8664::arg_z))
7384 (with-imm-target () ;OK if src-reg & dest overlap
7385 (dest :u8)
7386 (! mem-ref-bit dest src-reg offset)
7387 (<- dest)))))
7388 (^))))
7389
7390
7391
7392
7393;;; This returns an unboxed object, unless the caller wants to box it.
7394(defx862 x862-immediate-get-xxx immediate-get-xxx (seg vreg xfer bits ptr offset)
7395 (declare (fixnum bits))
7396 (let* ((fixnump (logbitp 6 bits))
7397 (signed (logbitp 5 bits))
7398 (size (logand 15 bits))
7399 (absptr (acode-absolute-ptr-p ptr))
7400 (triv-p (x862-trivial-p offset))
7401 (offval (acode-fixnum-form-p offset)))
7402 (declare (fixnum size))
7403 (cond ((null vreg)
7404 (x862-form seg nil nil ptr)
7405 (x862-form seg nil xfer offset))
7406 (t
7407 (if (and absptr offval)
7408 (setq absptr (+ absptr offval) offval 0)
7409 (setq absptr nil))
7410 (and offval (%i> (integer-length offval) 31) (setq offval nil))
7411 (and absptr (%i> (integer-length absptr) 31) (setq absptr nil))
7412 (target-arch-case
7413
7414 (:x8664 (when (or fixnump (eql size 8) (and (eql size 8) signed))
7415 (and offval (logtest 3 offval) (setq offval nil))
7416 (and absptr (logtest 3 absptr) (setq absptr nil)))))
7417 (cond
7418 (fixnump
7419 (with-imm-target () (dest :signed-natural)
7420 (cond
7421 (absptr
7422 (target-arch-case
7423
7424 (:x8664 (! mem-ref-c-absolute-doubleword dest absptr))))
7425 (offval
7426 (with-imm-target () (src-reg :address)
7427 (x862-one-targeted-reg-form seg ptr src-reg)
7428 (target-arch-case
7429
7430 (:x8664 (! mem-ref-c-doubleword dest src-reg offval)))))
7431 (t
7432 (with-imm-target () (src-reg :address)
7433 (with-imm-target (src-reg) (offset-reg :signed-natural)
7434 (x862-one-targeted-reg-form seg ptr src-reg)
7435 (if triv-p
7436 (if (acode-fixnum-form-p offset)
7437 (x862-lri seg offset-reg (acode-fixnum-form-p offset))
7438 (! fixnum->signed-natural offset-reg (x862-one-untargeted-reg-form seg offset x8664::arg_z)))
7439 (progn
7440 (! temp-push-unboxed-word src-reg)
7441 (x862-open-undo $undostkblk)
7442 (! fixnum->signed-natural offset-reg (x862-one-untargeted-reg-form seg offset x8664::arg_z))
7443 (! temp-pop-unboxed-word src-reg)
7444 (x862-close-undo)))
7445 (target-arch-case
7446
7447 (:x8664 (! mem-ref-doubleword dest src-reg offset-reg)))))))
7448 (if (node-reg-p vreg)
7449 (! box-fixnum vreg dest)
7450 (<- dest))))
7451 (signed
7452 (with-imm-target () (dest :signed-natural)
7453 (cond
7454 (absptr
7455 (case size
7456 (8 (! mem-ref-c-absolute-signed-doubleword dest absptr))
7457 (4 (! mem-ref-c-absolute-signed-fullword dest absptr))
7458 (2 (! mem-ref-c-absolute-s16 dest absptr))
7459 (1 (! mem-ref-c-absolute-s8 dest absptr))))
7460 (offval
7461 (with-imm-target (dest) (src-reg :address)
7462 (x862-one-targeted-reg-form seg ptr src-reg)
7463 (case size
7464 (8 (! mem-ref-c-signed-doubleword dest src-reg offval))
7465 (4 (! mem-ref-c-signed-fullword dest src-reg offval))
7466 (2 (! mem-ref-c-s16 dest src-reg offval))
7467 (1 (! mem-ref-c-s8 dest src-reg offval)))))
7468 (t
7469 (with-imm-target () (src-reg :address)
7470 (with-imm-target (src-reg) (offset-reg :signed-natural)
7471 (x862-one-targeted-reg-form seg ptr src-reg)
7472 (if triv-p
7473 (if (acode-fixnum-form-p offset)
7474 (x862-lri seg offset-reg (acode-fixnum-form-p offset))
7475 (! fixnum->signed-natural offset-reg (x862-one-untargeted-reg-form seg offset x8664::arg_z)))
7476 (progn
7477 (! temp-push-unboxed-word src-reg)
7478 (x862-open-undo $undostkblk)
7479 (! fixnum->signed-natural offset-reg (x862-one-untargeted-reg-form seg offset x8664::arg_z))
7480 (! temp-pop-unboxed-word src-reg)
7481 (x862-close-undo)))
7482 (case size
7483 (8 (! mem-ref-signed-doubleword dest src-reg offset-reg))
7484 (4 (! mem-ref-signed-fullword dest src-reg offset-reg))
7485 (2 (! mem-ref-s16 dest src-reg offset-reg))
7486 (1 (! mem-ref-s8 dest src-reg offset-reg)))))))
7487 (if (node-reg-p vreg)
7488 (case size
7489 ((1 2) (! box-fixnum vreg dest))
7490 (4 (target-arch-case
7491
7492 (:x8664 (! box-fixnum vreg dest))))
7493 (8 (<- dest)))
7494 (<- dest))))
7495 (t
7496 (with-imm-target () (dest :natural)
7497 (cond
7498 (absptr
7499 (case size
7500 (8 (! mem-ref-c-absolute-doubleword dest absptr))
7501 (4 (! mem-ref-c-absolute-fullword dest absptr))
7502 (2 (! mem-ref-c-absolute-u16 dest absptr))
7503 (1 (! mem-ref-c-absolute-u8 dest absptr))))
7504 (offval
7505 (with-imm-target (dest) (src-reg :address)
7506 (x862-one-targeted-reg-form seg ptr src-reg)
7507 (case size
7508 (8 (! mem-ref-c-doubleword dest src-reg offval))
7509 (4 (! mem-ref-c-fullword dest src-reg offval))
7510 (2 (! mem-ref-c-u16 dest src-reg offval))
7511 (1 (! mem-ref-c-u8 dest src-reg offval)))))
7512 (t
7513 (with-imm-target () (src-reg :address)
7514 (with-imm-target (src-reg) (offset-reg :signed-natural)
7515 (x862-one-targeted-reg-form seg ptr src-reg)
7516 (if triv-p
7517 (if (acode-fixnum-form-p offset)
7518 (x862-lri seg offset-reg (acode-fixnum-form-p offset))
7519 (! fixnum->signed-natural offset-reg (x862-one-untargeted-reg-form seg offset x8664::arg_z)))
7520 (progn
7521 (! temp-push-unboxed-word src-reg)
7522 (x862-open-undo $undostkblk)
7523 (! fixnum->signed-natural offset-reg (x862-one-untargeted-reg-form seg offset x8664::arg_z))
7524 (! temp-pop-unboxed-word src-reg)
7525 (x862-close-undo)))
7526 (case size
7527 (8 (! mem-ref-doubleword dest src-reg offset-reg))
7528 (4 (! mem-ref-fullword dest src-reg offset-reg))
7529 (2 (! mem-ref-u16 dest src-reg offset-reg))
7530 (1 (! mem-ref-u8 dest src-reg offset-reg)))))))
7531 (<- (set-regspec-mode
7532 dest
7533 (gpr-mode-name-value
7534 (case size
7535 (8 :u64)
7536 (4 :u32)
7537 (2 :u16)
7538 (1 :u8))))))))
7539 (^)))))
7540
7541(defx862 x862-let let (seg vreg xfer vars vals body p2decls)
7542 (let* ((old-stack (x862-encode-stack))
7543 (val nil)
7544 (bits nil)
7545 (valcopy vals))
7546 (with-x86-p2-declarations p2decls
7547 (dolist (var vars)
7548 (setq val (%car valcopy))
7549 (cond ((or (%ilogbitp $vbitspecial (setq bits (nx-var-bits var)))
7550 (and (%ilogbitp $vbitreg bits)
7551 (dolist (val (%cdr valcopy))
7552 (unless (x862-trivial-p val) (return t)))))
7553 (let* ((pair (cons (x862-vloc-ea *x862-vstack*) nil)))
7554 (%rplaca valcopy pair)
7555 (if (and (%ilogbitp $vbitdynamicextent bits)
7556 (progn
7557 (setq val
7558 (x862-dynamic-extent-form seg (x862-encode-stack) val))
7559 (x862-load-ea-p val)))
7560 (progn
7561 (%rplaca pair (x862-vloc-ea *x862-vstack*))
7562 (x862-vpush-register seg val :reserved))
7563 (x862-vpush-register seg (x862-one-untargeted-reg-form seg val x8664::arg_z) :reserved))
7564 (%rplacd pair *x862-top-vstack-lcell*)))
7565 (t (x862-seq-bind-var seg var val)
7566 (%rplaca valcopy nil)))
7567 (setq valcopy (%cdr valcopy)))
7568 (dolist (var vars)
7569 (declare (list val))
7570 (when (setq val (pop vals))
7571 (if (%ilogbitp $vbitspecial (nx-var-bits var))
7572 (progn
7573 (x862-dbind seg (car val) (var-name var))
7574 (x862-set-var-ea seg var (x862-vloc-ea (- *x862-vstack* *x862-target-node-size*)))
7575 )
7576 (x862-seq-bind-var seg var (car val)))))
7577 (x862-undo-body seg vreg xfer body old-stack)
7578 (dolist (var vars)
7579 (x862-close-var seg var)))))
7580
7581(defx862 x862-closed-function closed-function (seg vreg xfer afunc)
7582 (x862-make-closure seg afunc nil)
7583 (when vreg (<- x8664::arg_z))
7584 (^))
7585
7586(defx862 x862-flet flet (seg vreg xfer vars afuncs body p2decls)
7587 (x862-seq-fbind seg vreg xfer vars afuncs body p2decls))
7588
7589(defx862 x862-labels labels (seg vreg xfer vars afuncs body p2decls)
7590 (let* ((fwd-refs nil)
7591 (func nil)
7592 (togo vars)
7593 (real-vars ())
7594 (real-funcs ())
7595 (funs afuncs))
7596 (dolist (v vars)
7597 (when (neq 0 (afunc-fn-refcount (setq func (pop funs))))
7598 (push v real-vars)
7599 (push func real-funcs)
7600 (let* ((i 5) ; skip 4 words of code, inner function
7601 (our-var nil)
7602 (item nil))
7603 (declare (fixnum i))
7604 (dolist (ref (afunc-inherited-vars func))
7605 (when (memq (setq our-var (var-bits ref)) togo)
7606 (setq item (cons i our-var))
7607 (let* ((refs (assq v fwd-refs)))
7608 (if refs
7609 (push item (cdr refs))
7610 (push (list v item) fwd-refs))))
7611 (incf i)))
7612 (setq togo (%cdr togo))))
7613 (if (null fwd-refs)
7614 (x862-seq-fbind seg vreg xfer (nreverse real-vars) (nreverse real-funcs) body p2decls)
7615 (let* ((old-stack (x862-encode-stack)))
7616 (setq real-vars (nreverse real-vars) real-funcs (nreverse real-funcs))
7617 (with-x86-p2-declarations p2decls
7618 (dolist (var real-vars)
7619 (x862-seq-bind-var seg var (nx1-afunc-ref (pop real-funcs))))
7620 (dolist (ref fwd-refs)
7621 (let ((ea (var-ea (pop ref))))
7622 (x862-addrspec-to-reg seg ea x8664::temp0)
7623 (dolist (r ref)
7624 (let* ((v-ea (var-ea (cdr r))))
7625 (let* ((val-reg (if (eq v-ea ea)
7626 x8664::temp0
7627 (progn
7628 (x862-addrspec-to-reg seg v-ea x8664::temp1)
7629 x8664::temp1))))
7630 (! set-closure-forward-reference val-reg x8664::temp0 (car r)))))))
7631 (x862-undo-body seg vreg xfer body old-stack)
7632 (dolist (var real-vars)
7633 (x862-close-var seg var)))))))
7634
7635;;; Make a function call (e.g., to mapcar) with some of the toplevel arguments
7636;;; stack-consed (downward) closures. Bind temporaries to these closures so
7637;;; that tail-recursion/non-local exits work right.
7638;;; (all of the closures are distinct: FLET and LABELS establish dynamic extent themselves.)
7639(defx862 x862-with-downward-closures with-downward-closures (seg vreg xfer tempvars closures callform)
7640 (let* ((old-stack (x862-encode-stack)))
7641 (x862-seq-bind seg tempvars closures)
7642 (x862-undo-body seg vreg xfer callform old-stack)
7643 (dolist (v tempvars) (x862-close-var seg v))))
7644
7645
7646(defx862 x862-local-return-from local-return-from (seg vreg xfer blocktag value)
7647 (declare (ignorable vreg xfer))
7648 (let* ((*x862-undo-count* *x862-undo-count*)
7649 (tagdata (car blocktag))
7650 (cur-stack (x862-encode-stack))
7651 (dest-vd (caar tagdata))
7652 (dest-cd (cdar tagdata))
7653 (mv-p (x862-mvpass-p dest-cd))
7654 (dest-stack (cdr tagdata))
7655 (need-break (neq cur-stack dest-stack)))
7656 (let* ((*x862-vstack* *x862-vstack*)
7657 (*x862-top-vstack-lcell* *x862-top-vstack-lcell*)
7658 (*x862-cstack* *x862-cstack*))
7659 (if
7660 (or
7661 (eq dest-cd $backend-return)
7662 (and mv-p
7663 (eq (x862-encoding-undo-count cur-stack)
7664 (x862-encoding-undo-count dest-stack))
7665 (eq (x862-encoding-cstack-depth cur-stack)
7666 (x862-encoding-cstack-depth dest-stack))))
7667 (x862-form seg dest-vd dest-cd value)
7668 (if mv-p
7669 (progn
7670 (x862-multiple-value-body seg value)
7671 (let* ((*x862-returning-values* :pass))
7672 (x862-nlexit seg dest-cd (%i- *x862-undo-count* (x862-encoding-undo-count dest-stack)))
7673 (x862-branch seg dest-cd)))
7674 (progn
7675 (x862-form
7676 seg
7677 (if need-break (if dest-vd x8664::arg_z) dest-vd)
7678 (if need-break nil dest-cd)
7679 value)
7680 (when need-break
7681 (x862-unwind-set seg dest-cd dest-stack)
7682 (when dest-vd (x862-copy-register seg dest-vd x8664::arg_z))
7683 (x862-branch seg dest-cd))))))
7684 (x862-unreachable-store)))
7685
7686(defx862 x862-inherited-arg inherited-arg (seg vreg xfer arg)
7687 (when vreg
7688 (x862-addrspec-to-reg seg (x862-ea-open (var-ea arg)) vreg))
7689 (^))
7690
7691
7692(defx862 x862-%lisp-word-ref %lisp-word-ref (seg vreg xfer base offset)
7693 (let* ((fixoffset (acode-fixnum-form-p offset)))
7694 (cond ((null vreg)
7695 (x862-form seg nil nil base)
7696 (x862-form seg nil xfer offset))
7697 ((target-arch-case
7698
7699 (:x8664 (typep fixoffset '(signed-byte 13))))
7700 (ensuring-node-target (target vreg)
7701 (! lisp-word-ref-c target
7702 (x862-one-untargeted-reg-form seg base x8664::arg_z)
7703 (ash fixoffset *x862-target-fixnum-shift*)))
7704 (^))
7705 (t (multiple-value-bind (breg oreg)
7706 (x862-two-untargeted-reg-forms seg base x8664::arg_y offset x8664::arg_z)
7707 (ensuring-node-target (target vreg)
7708 (! lisp-word-ref target breg oreg))
7709 (^))))))
7710
7711(defx862 x862-%fixnum-ref %fixnum-ref (seg vreg xfer base offset)
7712 (let* ((fixoffset (acode-fixnum-form-p offset)))
7713 (cond ((null vreg)
7714 (x862-form seg nil nil base)
7715 (x862-form seg nil xfer offset))
7716 ((typep fixoffset '(signed-byte 16))
7717 (ensuring-node-target (target vreg)
7718 (! lisp-word-ref-c target
7719 (x862-one-untargeted-reg-form seg base x8664::arg_z)
7720 fixoffset))
7721 (^))
7722 (t (multiple-value-bind (breg oreg)
7723 (x862-two-untargeted-reg-forms seg base x8664::arg_y offset x8664::arg_z)
7724 (with-imm-target () (otemp :s32)
7725 (! fixnum->signed-natural otemp oreg)
7726 (ensuring-node-target (target vreg)
7727 (! lisp-word-ref target breg otemp)))
7728 (^))))))
7729
7730(defx862 x862-%fixnum-ref-natural %fixnum-ref-natural (seg vreg xfer base offset)
7731 (let* ((fixoffset (acode-fixnum-form-p offset)))
7732 (cond ((null vreg)
7733 (x862-form seg nil nil base)
7734 (x862-form seg nil xfer offset))
7735 ((typep fixoffset '(signed-byte 16))
7736 (with-imm-target () (val :natural)
7737 (! lisp-word-ref-c val
7738 (x862-one-untargeted-reg-form seg base x8664::arg_z)
7739 fixoffset)
7740 (<- val))
7741 (^))
7742 (t (multiple-value-bind (breg oreg)
7743 (x862-two-untargeted-reg-forms seg base x8664::arg_y offset x8664::arg_z)
7744 (with-imm-target () (otemp :s32)
7745 (! fixnum->signed-natural otemp oreg)
7746 (with-imm-target () (val :natural)
7747 (! lisp-word-ref val breg otemp)
7748 (<- val)))
7749 (^))))))
7750
7751(defx862 x862-int>0-p int>0-p (seg vreg xfer cc form)
7752 (multiple-value-bind (cr-bit true-p) (acode-condition-to-x86-cr-bit cc)
7753 (x862-one-targeted-reg-form seg form ($ x8664::arg_z))
7754 (! integer-sign)
7755 (x862-test-reg-%izerop seg vreg xfer x8664::imm0 cr-bit true-p 0)))
7756
7757
7758(defx862 x862-throw throw (seg vreg xfer tag valform )
7759 (declare (ignorable vreg xfer))
7760 (let* ((*x862-vstack* *x862-vstack*)
7761 (*x862-top-vstack-lcell* *x862-top-vstack-lcell*))
7762 (x862-vpush-register seg (x862-one-untargeted-reg-form seg tag x8664::arg_z))
7763 (if (x862-trivial-p valform)
7764 (progn
7765 (x862-vpush-register seg (x862-one-untargeted-reg-form seg valform x8664::arg_z))
7766 (x862-set-nargs seg 1))
7767 (x862-multiple-value-body seg valform))
7768 (! throw)))
7769
7770;;; This (and unwind-protect and things like that) are a little funky in that
7771;;; they have no good way of specifying the exit-point. The bad way is to
7772;;; follow the call to the catch-frame-creating subprim with a branch to that
7773;;; exit-point; the subprim returns to the following instruction.
7774;;; If the compiler ever gets smart about eliminating dead code, it has to
7775;;; be careful not to consider the block following the jump to be dead.
7776;;; Use a vinsn other than JUMP to reference the label.
7777(defx862 x862-catch catch (seg vreg xfer tag valform)
7778 (let* ((tag-label (backend-get-next-label))
7779 (tag-label-value (aref *backend-labels* tag-label))
7780 (mv-pass (x862-mv-p xfer)))
7781 (x862-one-targeted-reg-form seg tag ($ x8664::arg_z))
7782 (if mv-pass
7783 (! nmkcatchmv tag-label-value)
7784 (! nmkcatch1v tag-label-value))
7785 (x862-open-undo)
7786 (if mv-pass
7787 (x862-multiple-value-body seg valform)
7788 (x862-one-targeted-reg-form seg valform ($ x8664::arg_z)))
7789 (x862-lri seg x8664::imm0 (ash 1 *x862-target-fixnum-shift*))
7790 (if mv-pass
7791 (! nthrowvalues tag-label-value)
7792 (! nthrow1value tag-label-value))
7793 (x862-close-undo)
7794 (@= tag-label)
7795 (unless mv-pass (if vreg (<- x8664::arg_z)))
7796 (let* ((*x862-returning-values* mv-pass)) ; nlexit keeps values on stack
7797 (^))))
7798
7799
7800(defx862 x862-fixnum-overflow fixnum-overflow (seg vreg xfer form)
7801 (destructuring-bind (op n0 n1) (acode-unwrapped-form form)
7802 (x862-use-operator op seg vreg xfer n0 n1 *nx-t*)))
7803
7804(defx862 x862-%aref2 simple-typed-aref2 (seg vreg xfer typename arr i j &optional dim0 dim1)
7805 (if (null vreg)
7806 (progn
7807 (x862-form seg nil nil arr)
7808 (x862-form seg nil nil i)
7809 (x862-form seg nil xfer j)))
7810 (let* ((type-keyword (x862-immediate-operand typename))
7811 (fixtype (nx-lookup-target-uvector-subtag type-keyword ))
7812 (safe (unless *x862-reckless* fixtype))
7813 (dim0 (acode-fixnum-form-p dim0))
7814 (dim1 (acode-fixnum-form-p dim1)))
7815 (x862-aref2 seg vreg xfer arr i j safe type-keyword dim0 dim1)))
7816
7817(defx862 x862-generic-aref2 general-aref2 (seg vreg xfer arr i j)
7818 (let* ((atype0 (acode-form-type arr t))
7819 (ctype (if atype0 (specifier-type atype0)))
7820 (atype (if (array-ctype-p ctype) ctype))
7821 (keyword (and atype
7822 (let* ((dims (array-ctype-dimensions atype)))
7823 (and (typep dims 'list)
7824 (= 2 (length dims))))
7825 (not (array-ctype-complexp atype))
7826 (funcall
7827 (arch::target-array-type-name-from-ctype-function
7828 (backend-target-arch *target-backend*))
7829 atype))))
7830 (cond (keyword
7831 (let* ((dims (array-ctype-dimensions atype))
7832 (dim0 (car dims))
7833 (dim1 (cadr dims)))
7834 (x862-aref2 seg
7835 vreg
7836 xfer
7837 arr
7838 i
7839 j
7840 (if *x862-reckless*
7841 nil
7842 (nx-lookup-target-uvector-subtag keyword ))
7843 keyword ;(make-acode (%nx1-operator immediate) )
7844 (if (typep dim0 'fixnum) dim0) (if (typep dim1 'fixnum) dim1))))
7845 (t
7846 (x862-three-targeted-reg-forms seg
7847 arr ($ x8664::arg_x)
7848 i ($ x8664::arg_y)
7849 j ($ x8664::arg_z))
7850 (x862-fixed-call-builtin seg vreg xfer nil (subprim-name->offset '.SParef2))))))
7851
7852(defx862 x862-%aref3 simple-typed-aref3 (seg vreg xfer typename arr i j k &optional dim0 dim1 dim2)
7853 (if (null vreg)
7854 (progn
7855 (x862-form seg nil nil arr)
7856 (x862-form seg nil nil i)
7857 (x862-form seg nil nil j)
7858 (x862-form seg nil xfer k)))
7859 (let* ((type-keyword (x862-immediate-operand typename))
7860 (fixtype (nx-lookup-target-uvector-subtag type-keyword ))
7861 (safe (unless *x862-reckless* fixtype))
7862 (dim0 (acode-fixnum-form-p dim0))
7863 (dim1 (acode-fixnum-form-p dim1))
7864 (dim2 (acode-fixnum-form-p dim2)))
7865 (x862-aref3 seg vreg xfer arr i j k safe type-keyword dim0 dim1 dim2)))
7866
7867
7868(defx862 x862-general-aref3 general-aref3 (seg vreg xfer arr i j k)
7869 (let* ((atype0 (acode-form-type arr t))
7870 (ctype (if atype0 (specifier-type atype0)))
7871 (atype (if (array-ctype-p ctype) ctype))
7872 (keyword (and atype
7873 (let* ((dims (array-ctype-dimensions atype)))
7874 (and (typep dims 'list)
7875 (= 3 (length dims))))
7876 (not (array-ctype-complexp atype))
7877 (funcall
7878 (arch::target-array-type-name-from-ctype-function
7879 (backend-target-arch *target-backend*))
7880 atype))))
7881 (cond (keyword
7882 (let* ((dims (array-ctype-dimensions atype))
7883 (dim0 (car dims))
7884 (dim1 (cadr dims))
7885 (dim2 (caddr dims)))
7886 (x862-aref3 seg
7887 vreg
7888 xfer
7889 arr
7890 i
7891 j
7892 k
7893 (if *x862-reckless*
7894 nil
7895 (nx-lookup-target-uvector-subtag keyword ))
7896 keyword ;(make-acode (%nx1-operator immediate) )
7897 (if (typep dim0 'fixnum) dim0)
7898 (if (typep dim1 'fixnum) dim1)
7899 (if (typep dim2 'fixnum) dim2))))
7900 (t
7901 (x862-four-targeted-reg-forms seg
7902 arr ($ x8664::temp0)
7903 i ($ x8664::arg_x)
7904 j ($ x8664::arg_y)
7905 k ($ x8664::arg_z))
7906 (x862-fixed-call-builtin seg vreg xfer nil (subprim-name->offset '.SParef3))))))
7907
7908(defx862 x862-general-aset2 general-aset2 (seg vreg xfer arr i j new)
7909 (let* ((atype0 (acode-form-type arr t))
7910 (ctype (if atype0 (specifier-type atype0)))
7911 (atype (if (array-ctype-p ctype) ctype))
7912 (keyword (and atype
7913 (let* ((dims (array-ctype-dimensions atype)))
7914 (and (typep dims 'list)
7915 (= 2 (length dims))))
7916 (not (array-ctype-complexp atype))
7917 (funcall
7918 (arch::target-array-type-name-from-ctype-function
7919 (backend-target-arch *target-backend*))
7920 atype))))
7921 (cond (keyword
7922 (let* ((dims (array-ctype-dimensions atype))
7923 (dim0 (car dims))
7924 (dim1 (cadr dims)))
7925 (x862-aset2 seg
7926 vreg
7927 xfer
7928 arr
7929 i
7930 j
7931 new
7932 (unless *x862-reckless*
7933 (nx-lookup-target-uvector-subtag keyword ))
7934 keyword
7935 (if (typep dim0 'fixnum) dim0)
7936 (if (typep dim1 'fixnum) dim1))))
7937 (t
7938 (x862-four-targeted-reg-forms seg
7939 arr ($ x8664::temp0)
7940 i ($ x8664::arg_x)
7941 j ($ x8664::arg_y)
7942 new ($ x8664::arg_z))
7943 (x862-fixed-call-builtin seg vreg xfer nil (subprim-name->offset '.SPaset2))))))
7944
7945(defx862 x862-general-aset3 general-aset3 (seg vreg xfer arr i j k new)
7946 (let* ((atype0 (acode-form-type arr t))
7947 (ctype (if atype0 (specifier-type atype0)))
7948 (atype (if (array-ctype-p ctype) ctype))
7949 (keyword (and atype
7950 (let* ((dims (array-ctype-dimensions atype)))
7951 (unless (atom dims)
7952 (= 3 (length dims))))
7953 (not (array-ctype-complexp atype))
7954 (funcall
7955 (arch::target-array-type-name-from-ctype-function
7956 (backend-target-arch *target-backend*))
7957 atype))))
7958 (cond (keyword
7959 (let* ((dims (array-ctype-dimensions atype))
7960 (dim0 (car dims))
7961 (dim1 (cadr dims))
7962 (dim2 (caddr dims)))
7963 (x862-aset3 seg
7964 vreg
7965 xfer
7966 arr
7967 i
7968 j
7969 k
7970 new
7971 (unless *x862-reckless*
7972 (nx-lookup-target-uvector-subtag keyword ))
7973 keyword
7974 (if (typep dim0 'fixnum) dim0)
7975 (if (typep dim1 'fixnum) dim1)
7976 (if (typep dim2 'fixnum) dim2))))
7977 (t
7978 (x862-push-register seg (x862-one-untargeted-reg-form seg arr ($ x8664::arg_z)))
7979 (x862-four-targeted-reg-forms seg
7980 i ($ x8664::temp0)
7981 j ($ x8664::arg_x)
7982 k ($ x8664::arg_y)
7983 new ($ x8664::arg_z))
7984 (x862-pop-register seg ($ x8664::temp1))
7985 (x862-fixed-call-builtin seg vreg xfer nil (subprim-name->offset '.SPaset3))))))
7986
7987
7988(defx862 x862-%aset2 simple-typed-aset2 (seg vreg xfer typename arr i j new &optional dim0 dim1)
7989 (let* ((type-keyword (x862-immediate-operand typename))
7990 (fixtype (nx-lookup-target-uvector-subtag type-keyword))
7991 (safe (unless *x862-reckless* fixtype))
7992 (dim0 (acode-fixnum-form-p dim0))
7993 (dim1 (acode-fixnum-form-p dim1)))
7994 (x862-aset2 seg vreg xfer arr i j new safe type-keyword dim0 dim1)))
7995
7996
7997(defx862 x862-%aset3 simple-typed-aset3 (seg vreg xfer typename arr i j k new &optional dim0 dim1 dim2)
7998 (let* ((type-keyword (x862-immediate-operand typename))
7999 (fixtype (nx-lookup-target-uvector-subtag type-keyword))
8000 (safe (unless *x862-reckless* fixtype))
8001 (dim0 (acode-fixnum-form-p dim0))
8002 (dim1 (acode-fixnum-form-p dim1))
8003 (dim2 (acode-fixnum-form-p dim2)))
8004 (x862-aset3 seg vreg xfer arr i j k new safe type-keyword dim0 dim1 dim2)))
8005
8006(defx862 x862-%typed-uvref %typed-uvref (seg vreg xfer subtag uvector index)
8007 (let* ((type-keyword
8008 (let* ((fixtype (acode-fixnum-form-p subtag)))
8009 (if fixtype
8010 (nx-target-uvector-subtag-name fixtype)
8011 (x862-immediate-operand subtag)))))
8012 (if type-keyword
8013 (x862-vref seg vreg xfer type-keyword uvector index (unless *x862-reckless* (nx-lookup-target-uvector-subtag type-keyword)))
8014 (progn
8015 (x862-three-targeted-reg-forms seg subtag ($ x8664::arg_x) uvector ($ x8664::arg_y) index ($ x8664::arg_z))
8016 (! subtag-misc-ref)
8017 (when vreg (<- ($ x8664::arg_z)))
8018 (^)) )))
8019
8020(defx862 x862-%typed-uvset %typed-uvset (seg vreg xfer subtag uvector index newval)
8021 (let* ((type-keyword
8022 (let* ((fixtype (acode-fixnum-form-p subtag)))
8023 (if fixtype
8024 (nx-target-uvector-subtag-name fixtype)
8025 (x862-immediate-operand subtag)))))
8026 (if type-keyword
8027 (x862-vset seg vreg xfer type-keyword uvector index newval (unless *x862-reckless* (nx-lookup-target-uvector-subtag type-keyword)))
8028 (progn
8029 (x862-four-targeted-reg-forms seg subtag ($ x8664::temp0) uvector ($ x8664::arg_x) index ($ x8664::arg_y) newval ($ x8664::arg_z))
8030 (! subtag-misc-set)
8031 (when vreg (<- ($ x8664::arg_z)))
8032 (^)))))
8033
8034(defx862 x862-%macptrptr% %macptrptr% (seg vreg xfer form)
8035 (with-imm-target () (target :address)
8036 (x862-one-targeted-reg-form seg form (or vreg target)))
8037 (^))
8038
8039
8040;;; cons a macptr, unless "vreg" is an immediate register of mode :address.
8041(defx862 x862-%consmacptr% %consmacptr% (seg vreg xfer form)
8042 (cond ((null vreg) (x862-form seg nil xfer form))
8043 ((eql (get-regspec-mode vreg) hard-reg-class-gpr-mode-address)
8044 (x862-form seg vreg xfer form))
8045 (t
8046 (with-imm-target () (temp :address)
8047 (<- (x862-one-targeted-reg-form seg form temp))
8048 (^)))))
8049
8050(defx862 x862-%immediate-ptr-to-int %immediate-ptr-to-int (seg vreg xfer form)
8051 (if (null vreg)
8052 (x862-form seg nil xfer form)
8053 (with-imm-target () (address-reg :address)
8054 (x862-form seg address-reg nil form)
8055 (<- (set-regspec-mode address-reg (gpr-mode-name-value :natural)))
8056 (^))))
8057
8058(defx862 x862-%immediate-int-to-ptr %immediate-int-to-ptr (seg vreg xfer form)
8059 (if (null vreg)
8060 (x862-form seg nil xfer form)
8061 (progn
8062 (unless (logbitp (hard-regspec-value vreg) *backend-imm-temps*)
8063 (error "I give up. When will I get this right ?"))
8064 (let* ((natural-reg (x862-one-targeted-reg-form seg
8065 form
8066 ($ vreg :mode :natural))))
8067 (<- natural-reg)
8068 (^)))))
8069
8070
8071(defx862 x862-%function %function (seg vreg xfer sym)
8072 (when vreg
8073 (let* ((symreg (x862-one-untargeted-reg-form seg (make-acode (%nx1-operator immediate)
8074 (x862-symbol-entry-locative sym)) x8664::arg_z)))
8075 (with-node-temps (vreg symreg) (val)
8076 (! symbol-function val symreg)
8077 (<- val))))
8078 (^))
8079
8080(defx862 x862-%unbound-marker %unbound-marker (seg vreg xfer)
8081 (when vreg
8082 (ensuring-node-target (target vreg)
8083 (x862-lri seg target (target-arch-case
8084
8085 (:x8664 x8664::unbound-marker)))))
8086 (^))
8087
8088(defx862 x862-slot-unbound-marker %slot-unbound-marker (seg vreg xfer)
8089 (when vreg
8090 (ensuring-node-target (target vreg)
8091 (x862-lri seg target (target-arch-case
8092 (:x8664 x8664::slot-unbound-marker)))))
8093 (^))
8094
8095(defx862 x862-illegal-marker %illegal-marker (seg vreg xfer)
8096 (when vreg
8097 (ensuring-node-target (target vreg)
8098 (x862-lri seg target (target-arch-case
8099 (:x8664 x8664::illegal-marker)))))
8100 (^))
8101
8102(defx862 x862-lambda-bind lambda-bind (seg vreg xfer vals req rest keys-p auxen body p2decls)
8103 (let* ((old-stack (x862-encode-stack))
8104 (nreq (list-length req))
8105 (rest-arg (nthcdr nreq vals))
8106 (apply-body (x862-eliminate-&rest body rest keys-p auxen rest-arg)))
8107 (x862-seq-bind seg req vals)
8108 (when apply-body (setq rest nil body apply-body))
8109 (let*
8110 ((vloc *x862-vstack*)
8111 (restloc vloc)
8112 (nvloc (progn (if (or rest keys-p) (x862-formlist seg rest-arg)) *x862-vstack*)))
8113 (with-x86-p2-declarations p2decls
8114 (when rest
8115 (when keys-p
8116 (until (eq restloc nvloc)
8117 (with-node-temps () (temp)
8118 (x862-stack-to-register seg (x862-vloc-ea restloc) temp)
8119 (x862-vpush-register seg temp))
8120 (setq restloc (%i+ restloc *x862-target-node-size*))))
8121 (x862-set-nargs seg (length rest-arg))
8122 (x862-set-vstack restloc)
8123 (if (%ilogbitp $vbitdynamicextent (nx-var-bits rest))
8124 (progn
8125 (! stack-cons-list)
8126 (x862-open-undo $undostkblk))
8127 (! list))
8128 (x862-vpush-register seg x8664::arg_z))
8129 (when rest (x862-bind-var seg rest restloc))
8130 (destructuring-bind (vars inits) auxen
8131 (while vars
8132 (let ((val (%car inits)))
8133 (if (fixnump val)
8134 (progn
8135 (when rest (setq val (%i+ (%i+ val val) 1)))
8136 (x862-bind-var seg (%car vars) (%i+ vloc (* val *x862-target-node-size*))))
8137 (x862-seq-bind-var seg (%car vars) val)))
8138 (setq vars (%cdr vars) inits (%cdr inits))))
8139 (x862-undo-body seg vreg xfer body old-stack)
8140 (dolist (var req) (x862-close-var seg var))
8141 (when rest (x862-close-var seg rest))
8142 (dolist (var (%car auxen)) (x862-close-var seg var))))))
8143
8144(macrolet
8145 ((def-x862-require (function op &optional (vinsn op))
8146 `(defx862 ,function ,op (seg vreg xfer val)
8147 (let* ((val-reg (x862-one-untargeted-reg-form
8148 seg
8149 val
8150 (if (eq vreg x8664::arg_z) x8664::arg_y x8664::arg_z))))
8151 (! ,vinsn val-reg)
8152 (when vreg (<- val-reg))
8153 (^)))))
8154 (def-x862-require x862-require-simple-vector require-simple-vector)
8155 (def-x862-require x862-require-simple-string require-simple-string)
8156 (def-x862-require x862-require-integer require-integer)
8157 (def-x862-require x862-require-fixnum require-fixnum)
8158 (def-x862-require x862-require-real require-real)
8159 (def-x862-require x862-require-list require-list)
8160 (def-x862-require x862-require-character require-character)
8161 (def-x862-require x862-require-number require-number)
8162 (def-x862-require x862-require-symbol require-symbol)
8163 (def-x862-require x862-require-s8 require-s8)
8164 (def-x862-require x862-require-s8 require-u8)
8165 (def-x862-require x862-require-s8 require-s16)
8166 (def-x862-require x862-require-s8 require-u16)
8167 (def-x862-require x862-require-s8 require-s32)
8168 (def-x862-require x862-require-s8 require-u32)
8169 (def-x862-require x862-require-s8 require-s64)
8170 (def-x862-require x862-require-s8 require-u64))
8171
8172(defx862 x862-%badarg2 %badarg2 (seg vreg xfer badthing goodthing)
8173 (x862-two-targeted-reg-forms seg badthing ($ x8664::arg_y) goodthing ($ x8664::arg_z))
8174 (x862-lri seg ($ x8664::arg_x) (ash $XWRONGTYPE *x862-target-fixnum-shift*))
8175 (x862-set-nargs seg 3)
8176 (! ksignalerr)
8177 (<- nil)
8178 (^))
8179
8180(defx862 x862-%set-sbchar %set-sbchar (seg vreg xfer string index value)
8181 (x862-vset
8182 seg
8183 vreg
8184 xfer
8185 :simple-string
8186 string
8187 index
8188 value
8189 (unless *x862-reckless* (nx-lookup-target-uvector-subtag :simple-string))))
8190
8191
8192;;; If we didn't use this for stack consing, turn it into a call. Ugh.
8193
8194(defx862 x862-make-list make-list (seg vreg xfer size initial-element)
8195 (x862-form seg vreg xfer (make-acode (%nx1-operator call)
8196 (make-acode (%nx1-operator immediate) 'make-list)
8197 (list nil
8198 (list initial-element
8199 (make-acode (%nx1-operator immediate)
8200 :initial-element)
8201 size)))))
8202
8203
8204(defx862 x862-setq-free setq-free (seg vreg xfer sym val)
8205 (let* ((rsym ($ x8664::arg_y))
8206 (rval ($ x8664::arg_z)))
8207 (x862-one-targeted-reg-form seg val rval)
8208 (x862-immediate seg rsym nil (x862-symbol-value-cell sym))
8209 (! setqsym)
8210 (<- rval)
8211 (^)))
8212
8213(defx862 x862-%setf-macptr %setf-macptr (seg vreg xfer x y)
8214 (x862-vpush-register seg (x862-one-untargeted-reg-form seg x x8664::arg_z))
8215 (with-imm-target () (src-reg :address)
8216 (x862-one-targeted-reg-form seg y src-reg)
8217 (x862-vpop-register seg x8664::arg_z)
8218 (unless (or *x862-reckless* (x862-form-typep x 'macptr))
8219 (with-imm-temps (src-reg) ()
8220 (! trap-unless-macptr x8664::arg_z)))
8221 (! set-macptr-address src-reg x8664::arg_z)
8222 (<- x8664::arg_z)
8223 (^)))
8224
8225(defx862 x862-%setf-double-float %setf-double-float (seg vref xfer fnode fval)
8226 (x862-vpush-register seg (x862-one-untargeted-reg-form seg fnode x8664::arg_z))
8227 (let* ((target ($ x8664::fp1 :class :fpr :mode :double-float))
8228 (node ($ x8664::arg_z)))
8229 (x862-one-targeted-reg-form seg fval target)
8230 (x862-vpop-register seg node)
8231 (unless (or *x862-reckless* (x862-form-typep fnode 'double-float))
8232 (! trap-unless-double-float node))
8233 (! store-double node target)
8234 (<- node)
8235 (^)))
8236
8237
8238
8239(defx862 x862-unwind-protect unwind-protect (seg vreg xfer protected-form cleanup-form)
8240 (let* ((cleanup-label (backend-get-next-label))
8241 (protform-label (backend-get-next-label))
8242 (old-stack (x862-encode-stack))
8243 (ilevel '*interrupt-level*))
8244 (! nmkunwind
8245 (aref *backend-labels* protform-label)
8246 (aref *backend-labels* cleanup-label))
8247 (x862-open-undo $undointerruptlevel)
8248 (x862-new-vstack-lcell :special-value *x862-target-lcell-size* 0 ilevel)
8249 (x862-new-vstack-lcell :special *x862-target-lcell-size* (ash 1 $vbitspecial) ilevel)
8250 (x862-new-vstack-lcell :special-link *x862-target-lcell-size* 0 ilevel)
8251 (x862-adjust-vstack (* 3 *x862-target-node-size*))
8252 (@= cleanup-label)
8253 (let* ((*x862-vstack* *x862-vstack*)
8254 (*x862-top-vstack-lcell* *x862-top-vstack-lcell*))
8255 (x862-open-undo $undostkblk) ; tsp frame created by nthrow.
8256 (x862-new-vstack-lcell :cleanup-return *x862-target-lcell-size* 0 nil)
8257 (x862-adjust-vstack *x862-target-node-size*)
8258 (x862-form seg nil nil cleanup-form)
8259 (x862-close-undo)
8260 (! jump-return-pc))
8261 (x862-open-undo)
8262 (@= protform-label)
8263 (x862-open-undo $undointerruptlevel)
8264 (x862-new-vstack-lcell :special-value *x862-target-lcell-size* 0 ilevel)
8265 (x862-new-vstack-lcell :special *x862-target-lcell-size* (ash 1 $vbitspecial) ilevel)
8266 (x862-new-vstack-lcell :special-link *x862-target-lcell-size* 0 ilevel)
8267 (x862-adjust-vstack (* 3 *x862-target-node-size*))
8268 (x862-undo-body seg vreg xfer protected-form old-stack)))
8269
8270(defx862 x862-progv progv (seg vreg xfer symbols values body)
8271 (let* ((cleanup-label (backend-get-next-label))
8272 (protform-label (backend-get-next-label))
8273 (old-stack (x862-encode-stack)))
8274 (x862-two-targeted-reg-forms seg symbols ($ x8664::arg_y) values ($ x8664::arg_z))
8275 (! progvsave)
8276 (x862-open-undo $undostkblk)
8277 (! mkunwind
8278 (aref *backend-labels* protform-label)
8279 (aref *backend-labels* cleanup-label))
8280 (@= cleanup-label)
8281 (! progvrestore)
8282 (x862-open-undo)
8283 (@= protform-label)
8284 (x862-undo-body seg vreg xfer body old-stack)))
8285
8286(defx862 x862-%ptr-eql %ptr-eql (seg vreg xfer cc x y )
8287 (if (null vreg)
8288 (progn
8289 (x862-form seg nil nil x)
8290 (x862-form seg nil xfer y))
8291 (let* ((x-abs (acode-absolute-ptr-p x t))
8292 (y-abs (acode-absolute-ptr-p y t))
8293 (abs (or x-abs y-abs))
8294 (other (if abs (if x-abs y x))))
8295 (multiple-value-bind (cr-bit true-p) (acode-condition-to-x86-cr-bit cc)
8296 (if other
8297 (with-imm-target () (other-target :address)
8298 (x862-one-targeted-reg-form seg other other-target)
8299 (if (typep abs '(signed-byte 16))
8300 (x862-test-reg-%izerop seg vreg xfer other-target cr-bit true-p abs)
8301 (with-imm-temps (other-target) ((abs-target :address))
8302 (use-imm-temp other-target)
8303 (x862-lri seg abs-target abs)
8304 (x862-compare-registers seg vreg xfer other-target abs-target cr-bit true-p))))
8305 ;; Neither expression is obviously a constant-valued macptr.
8306 (with-imm-target () (target-a :address)
8307 (x862-one-targeted-reg-form seg x target-a)
8308 (! temp-push-unboxed-word target-a)
8309 (x862-open-undo $undostkblk)
8310 (x862-one-targeted-reg-form seg y target-a)
8311 (with-imm-target (target-a) (target-b :address)
8312 (! temp-pop-unboxed-word target-b)
8313 (x862-close-undo)
8314 (x862-compare-registers seg vreg xfer target-b target-a cr-bit true-p))))))))
8315
8316(defx862 x862-set-bit %set-bit (seg vreg xfer ptr offset newval)
8317 (let* ((offval (acode-fixnum-form-p offset))
8318 (constval (acode-fixnum-form-p newval)))
8319 (if (typep offval '(signed-byte 32))
8320 (with-imm-target () (src :address)
8321 (x862-one-targeted-reg-form seg ptr src)
8322 (if constval
8323 (progn
8324 (if (eql constval 0)
8325 (! mem-set-c-bit-0 src offval)
8326 (! mem-set-c-bit-1 src offval))
8327 (when vreg
8328 (x862-form seg vreg nil newval)))
8329 (with-imm-target () (src :address)
8330 (x862-two-targeted-reg-forms seg ptr src newval ($ x8664::arg_z))
8331 (! mem-set-c-bit-variable-value src offval ($ x8664::arg_z))
8332 (<- ($ x8664::arg_z)))))
8333 (if constval
8334 (with-imm-target () (src :address)
8335 (x862-two-targeted-reg-forms seg ptr src offset ($ x8664::arg_z))
8336 (if (eql constval 0)
8337 (! mem-set-bit-0 src ($ x8664::arg_z))
8338 (! mem-set-bit-1 src ($ x8664::arg_z)))
8339 (when vreg
8340 (x862-form seg vreg nil newval)))
8341 (with-imm-target () (src :address)
8342 (x862-three-targeted-reg-forms seg ptr src offset ($ x8664::arg_y) newval ($ x8664::arg_z))
8343 (! mem-set-bit-variable-value src ($ x8664::arg_y) ($ x8664::arg_z))
8344 (<- ($ x8664::arg_z)))))
8345 (^)))
8346
8347(defx862 x862-%immediate-set-xxx %immediate-set-xxx (seg vreg xfer bits ptr offset val)
8348 (x862-%immediate-store seg vreg xfer bits ptr offset val))
8349
8350
8351
8352(defx862 x862-%immediate-inc-ptr %immediate-inc-ptr (seg vreg xfer ptr by)
8353 (let* ((triv-by (x862-trivial-p by))
8354 (fixnum-by (acode-fixnum-form-p by)))
8355 (if (and fixnum-by (eql 0 fixnum-by))
8356 (x862-form seg vreg xfer ptr)
8357 (let* ((ptr-reg (with-imm-target () (ptr-reg :address)
8358 (x862-one-targeted-reg-form seg ptr ptr-reg))))
8359 (if fixnum-by
8360 (let* ((result ptr-reg))
8361 (! add-constant result fixnum-by)
8362 (<- result))
8363 (progn
8364 (unless triv-by
8365 (x862-push-register seg ptr-reg))
8366 (let* ((boxed-by (x862-one-targeted-reg-form seg by x8664::arg_z)))
8367 (unless triv-by
8368 (x862-pop-register seg ptr-reg))
8369 (with-imm-target (ptr-reg) (by-reg :signed-natural)
8370 (! fixnum->signed-natural by-reg boxed-by)
8371 (let* ((result ptr-reg))
8372 (! fixnum-add2 result by-reg)
8373 (<- result))))))
8374 (^)))))
8375
8376
8377
8378(defx862 x862-multiple-value-call multiple-value-call (seg vreg xfer fn arglist)
8379 (x862-mvcall seg vreg xfer fn arglist))
8380
8381
8382
8383(defx862 x862-syscall syscall (seg vreg xfer idx argspecs argvals resultspec &optional monitor-exception-ports)
8384 (declare (ignore monitor-exception-ports))
8385 (let* ((*x862-vstack* *x862-vstack*)
8386 (*x862-top-vstack-lcell* *x862-top-vstack-lcell*)
8387 (*x862-cstack* *x862-cstack*)
8388 (gpr-offset 0)
8389 (other-offset 6)
8390 (nother-words 0)
8391 (ngpr-args 0)
8392 (simple-foreign-args nil))
8393 (declare (fixnum ngpr-args narg-words
8394 gpr-offset other-offset))
8395 (dolist (argspec argspecs)
8396 (declare (ignorable argspec))
8397 (incf ngpr-args)
8398 (if (> ngpr-args 6)
8399 (incf nother-words)))
8400 (let* ((total-words nother-words))
8401 (when (zerop total-words)
8402 (setq simple-foreign-args nil))
8403 (! alloc-c-frame total-words))
8404 (x862-open-undo $undo-x86-c-frame)
8405 (setq ngpr-args 0)
8406 (unless simple-foreign-args
8407 (x862-vpush-register seg (x862-one-untargeted-reg-form seg idx x8664::arg_z)))
8408 ;; Evaluate each form into the C frame, according to the
8409 ;; matching argspec.
8410 (do* ((specs argspecs (cdr specs))
8411 (vals argvals (cdr vals)))
8412 ((null specs))
8413 (declare (list specs vals))
8414 (let* ((valform (car vals))
8415 (spec (car specs))
8416 (absptr (acode-absolute-ptr-p valform)))
8417 (case spec
8418 (:address
8419 (with-imm-target () (ptr :address)
8420 (if absptr
8421 (x862-lri seg ptr absptr)
8422 (x862-form seg ptr nil valform))
8423 (incf ngpr-args)
8424 (cond ((<= ngpr-args 6)
8425 (! set-c-arg ptr gpr-offset)
8426 (incf gpr-offset))
8427 (t
8428 (! set-c-arg ptr other-offset)
8429 (incf other-offset)))))
8430 (t
8431 (with-imm-target () (valreg :natural)
8432 (let* ((reg (x862-unboxed-integer-arg-to-reg seg valform valreg spec)))
8433 (incf ngpr-args)
8434 (cond ((<= ngpr-args 8)
8435 (! set-c-arg reg gpr-offset)
8436 (incf gpr-offset))
8437 (t
8438 (! set-c-arg reg other-offset)
8439 (incf other-offset)))))))))
8440 (unless simple-foreign-args
8441 (x862-vpop-register seg ($ x8664::arg_z)))
8442 (! syscall)
8443 (x862-close-undo)
8444 (when vreg
8445 (cond ((eq resultspec :void) (<- nil))
8446 ((eq resultspec :unsigned-doubleword)
8447 (ensuring-node-target (target vreg)
8448 (! makeu64)
8449 (x862-copy-register seg target ($ x8664::arg_z))))
8450 ((eq resultspec :signed-doubleword)
8451 (ensuring-node-target (target vreg)
8452 (! makes64)
8453 (x862-copy-register seg target ($ x8664::arg_z))))
8454 (t
8455 (case resultspec
8456 (:signed-byte (! sign-extend-s8 x8664::imm0 x8664::imm0))
8457 (:signed-halfword (! sign-extend-s16 x8664::imm0 x8664::imm0))
8458 (:signed-fullword (! sign-extend-s32 x8664::imm0 x8664::imm0))
8459 (:unsigned-byte (! zero-extend-u8 x8664::imm0 x8664::imm0))
8460 (:unsigned-halfword (! zero-extend-u16 x8664::imm0 x8664::imm0))
8461 (:unsigned-fullword (! zero-extend-u32 x8664::imm0 x8664::imm0)))
8462 (<- (make-wired-lreg x8664::imm0
8463 :mode
8464 (gpr-mode-name-value
8465 (case resultspec
8466 (:address :address)
8467 (:signed-byte :s8)
8468 (:unsigned-byte :u8)
8469 (:signed-halfword :s16)
8470 (:unsigned-halfword :u16)
8471 (:signed-fullword :s32)
8472 (t :u32))))))))
8473 (^)))
8474
8475
8476(defx862 x862-ff-call ff-call (seg vreg xfer address argspecs argvals resultspec &optional monitor)
8477 (declare (ignore monitor))
8478 (let* ((*x862-vstack* *x862-vstack*)
8479 (*x862-top-vstack-lcell* *x862-top-vstack-lcell*)
8480 (*x862-cstack* *x862-cstack*)
8481 (gpr-offset 0)
8482 (other-offset 6)
8483 (single-float-offset 6)
8484 (double-float-offset 6)
8485 (nsingle-floats 0) ; F
8486 (ndouble-floats 0) ; D
8487 (nother-words 0)
8488 (nfpr-args 0)
8489 (ngpr-args 0)
8490 (simple-foreign-args nil)
8491 (fp-loads ())
8492 (return-registers ()))
8493 (declare (fixnum nshort-floats ndouble-floats nfpr-args ngpr-args narg-words
8494 gpr-offset other-offset single-float-offset double-float-offset))
8495 (dolist (argspec argspecs)
8496 (case argspec
8497 (:double-float (incf nfpr-args)
8498 (if (<= nfpr-args 8)
8499 (incf ndouble-floats)
8500 (incf nother-words)))
8501 (:single-float (incf nfpr-args)
8502 (if (<= nfpr-args 8)
8503 (incf nsingle-floats)
8504 (incf nother-words)))
8505 (:registers (setq return-registers t))
8506 (t
8507 (if (typep argspec 'unsigned-byte)
8508 (incf nother-words argspec)
8509 (progn
8510 (incf ngpr-args)
8511 (if (> ngpr-args 6)
8512 (incf nother-words)))))))
8513 (let* ((total-words (+ nother-words nsingle-floats ndouble-floats)))
8514 (when (null argspecs)
8515 (setq simple-foreign-args t))
8516 (! alloc-c-frame total-words))
8517 (x862-open-undo $undo-x86-c-frame)
8518 (setq single-float-offset (+ other-offset nother-words))
8519 (setq double-float-offset
8520 (+ single-float-offset nsingle-floats))
8521 (setq ngpr-args 0 nfpr-args 0)
8522 (unless simple-foreign-args
8523 (x862-vpush-register seg (x862-one-untargeted-reg-form seg address x8664::arg_z)))
8524 ;; Evaluate each form into the C frame, according to the
8525 ;; matching argspec. Remember type and arg offset of any FP
8526 ;; args, since FP regs will have to be loaded later.
8527 (do* ((specs argspecs (cdr specs))
8528 (vals argvals (cdr vals)))
8529 ((null specs))
8530 (declare (list specs vals))
8531 (let* ((valform (car vals))
8532 (spec (car specs))
8533 (absptr (acode-absolute-ptr-p valform)))
8534 (case spec
8535 (:registers
8536 (let* ((reg (x862-one-untargeted-reg-form seg valform x8664::arg_z)))
8537 (unless *x862-reckless*
8538 (! trap-unless-macptr reg))
8539 (x862-vpush-register seg reg)))
8540 (:double-float
8541 (let* ((df ($ x8664::fp1 :class :fpr :mode :double-float)))
8542 (incf nfpr-args)
8543 (x862-one-targeted-reg-form seg valform df )
8544 (cond ((<= nfpr-args 8)
8545 (! set-double-c-arg df double-float-offset)
8546 (push (cons :double-float double-float-offset) fp-loads)
8547 (incf double-float-offset))
8548 (t
8549 (! set-double-c-arg df other-offset)
8550 (incf other-offset)))))
8551 (:single-float
8552 (let* ((sf ($ x8664::fp1 :class :fpr :mode :single-float)))
8553 (incf nfpr-args)
8554 (x862-one-targeted-reg-form
8555 seg valform sf)
8556 (cond ((<= nfpr-args 8)
8557 (! set-single-c-arg sf single-float-offset)
8558 (push (cons :single-float single-float-offset) fp-loads)
8559 (incf single-float-offset))
8560 (t
8561 (! set-single-c-arg sf other-offset)
8562 (incf other-offset)))))
8563 (:address
8564 (with-imm-target () (ptr :address)
8565 (if absptr
8566 (x862-lri seg ptr absptr)
8567 (x862-form seg ptr nil valform))
8568 (incf ngpr-args)
8569 (cond ((<= ngpr-args 6)
8570 (! set-c-arg ptr gpr-offset)
8571 (incf gpr-offset))
8572 (t
8573 (! set-c-arg ptr other-offset)
8574 (incf other-offset)))))
8575 (t
8576 (if (typep spec 'unsigned-byte)
8577 (progn
8578 (with-imm-target () (ptr :address)
8579 (x862-one-targeted-reg-form seg valform ptr)
8580 (with-imm-target (ptr) (r :natural)
8581 (dotimes (i spec)
8582 (! mem-ref-c-doubleword r ptr (ash i x8664::word-shift))
8583 (! set-c-arg r other-offset)
8584 (incf other-offset)))))
8585 (with-imm-target () (valreg :natural)
8586 (let* ((reg (x862-unboxed-integer-arg-to-reg seg valform valreg spec)))
8587 (incf ngpr-args)
8588 (cond ((<= ngpr-args 6)
8589 (! set-c-arg reg gpr-offset)
8590 (incf gpr-offset))
8591 (t
8592 (! set-c-arg reg other-offset)
8593 (incf other-offset))))))))))
8594 (do* ((fpreg x8664::fp0 (1+ fpreg))
8595 (reloads (nreverse fp-loads) (cdr reloads)))
8596 ((or (null reloads) (= fpreg x8664::fp8)))
8597 (declare (list reloads) (fixnum fpreg))
8598 (let* ((reload (car reloads))
8599 (size (car reload))
8600 (from (cdr reload)))
8601 (if (eq size :double-float)
8602 (! reload-double-c-arg ($ fpreg :class :fpr :mode :double-float) from)
8603 (! reload-single-c-arg ($ fpreg :class :fpr :mode :single-float) from))))
8604 (if return-registers
8605 (x862-vpop-register seg ($ x8664::arg_y)))
8606 (if simple-foreign-args
8607 (x862-one-targeted-reg-form seg address x8664::arg_z)
8608 (x862-vpop-register seg ($ x8664::arg_z)))
8609 (x862-lri seg x8664::rax (min 8 nfpr-args))
8610 (if return-registers
8611 (! ff-call-return-registers)
8612 (! ff-call) )
8613 (x862-close-undo)
8614 (when vreg
8615 (cond ((eq resultspec :void) (<- nil))
8616 ((eq resultspec :double-float)
8617 (<- ($ x8664::fp0 :class :fpr :mode :double-float)))
8618 ((eq resultspec :single-float)
8619 (<- ($ x8664::fp0 :class :fpr :mode :single-float)))
8620 ((eq resultspec :unsigned-doubleword)
8621 (if (node-reg-p vreg)
8622 (progn
8623 (! makeu64)
8624 (<- ($ x8664::arg_z)))
8625 (<- ($ x8664::rax :class :gpr :mode :u64))))
8626 ((eq resultspec :signed-doubleword)
8627 (if (node-reg-p vreg)
8628 (progn
8629 (! makes64)
8630 (<- ($ x8664::arg_z)))
8631 (<- ($ x8664::rax :class :gpr :mode :s64))))
8632 (t
8633 (case resultspec
8634 (:signed-byte (! sign-extend-s8 x8664::imm0 x8664::imm0))
8635 (:signed-halfword (! sign-extend-s16 x8664::imm0 x8664::imm0))
8636 (:signed-fullword (! sign-extend-s32 x8664::imm0 x8664::imm0))
8637 (:unsigned-byte (! zero-extend-u8 x8664::imm0 x8664::imm0))
8638 (:unsigned-halfword (! zero-extend-u16 x8664::imm0 x8664::imm0))
8639 (:unsigned-fullword (! zero-extend-u32 x8664::imm0 x8664::imm0)))
8640 (<- (make-wired-lreg x8664::imm0
8641 :mode
8642 (gpr-mode-name-value
8643 (case resultspec
8644 (:address :address)
8645 (:signed-byte :s8)
8646 (:unsigned-byte :u8)
8647 (:signed-halfword :s16)
8648 (:unsigned-halfword :u16)
8649 (:signed-fullword :s32)
8650 (t :u32))))))))
8651 (^)))
8652
8653
8654
8655(defx862 x862-%temp-list %temp-list (seg vreg xfer arglist)
8656 (x862-use-operator (%nx1-operator list) seg vreg xfer arglist))
8657
8658(defx862 x862-%temp-cons %temp-cons (seg vreg xfer car cdr)
8659 (x862-use-operator (%nx1-operator cons) seg vreg xfer car cdr))
8660
8661
8662
8663(defx862 x862-%debug-trap %debug-trap (seg vreg xfer arg)
8664 (x862-one-targeted-reg-form seg arg ($ x8664::arg_z))
8665 (! %debug-trap)
8666 (<- ($ x8664::arg_z))
8667 (^))
8668
8669(defx862 x862-%reference-external-entry-point %reference-external-entry-point
8670 (seg vreg xfer arg)
8671 (ensuring-node-target (target vreg)
8672 (let* ((reg (if (eq (hard-regspec-value target) x8664::arg_z) ($ x8664::arg_y) ($ x8664::arg_z))))
8673 (x862-one-targeted-reg-form seg arg reg)
8674 (! eep.address target reg)))
8675 (^))
8676
8677(defx862 x862-%natural+ %natural+ (seg vreg xfer x y)
8678 (if (null vreg)
8679 (progn
8680 (x862-form seg nil nil x)
8681 (x862-form seg nil xfer y))
8682 (let* ((fix-x (acode-fixnum-form-p x))
8683 (fix-y (acode-fixnum-form-p y)))
8684 (if (and fix-x fix-y)
8685 (x862-absolute-natural seg vreg xfer (+ fix-x fix-y))
8686 (let* ((u31x (and (typep fix-x '(unsigned-byte 31)) fix-x))
8687 (u31y (and (typep fix-y '(unsigned-byte 31)) fix-y)))
8688 (if (not (or u31x u31y))
8689 (with-imm-target () (xreg :natural)
8690 (with-imm-target (xreg) (yreg :natural)
8691 (x862-two-targeted-reg-forms seg x xreg y yreg)
8692 (! %natural+ xreg yreg))
8693 (<- xreg))
8694 (let* ((other (if u31x y x)))
8695 (with-imm-target () (other-reg :natural)
8696 (x862-one-targeted-reg-form seg other other-reg)
8697 (! %natural+-c other-reg (or u31x u31y))
8698 (<- other-reg))))
8699 (^))))))
8700
8701(defx862 x862-%natural- %natural- (seg vreg xfer x y)
8702 (if (null vreg)
8703 (progn
8704 (x862-form seg nil nil x)
8705 (x862-form seg nil xfer y))
8706 (let* ((fix-x (acode-fixnum-form-p x))
8707 (fix-y (acode-fixnum-form-p y)))
8708 (if (and fix-x fix-y)
8709 (x862-absolute-natural seg vreg xfer (- fix-x fix-y))
8710 (let* ((u31y (and (typep fix-y '(unsigned-byte 31)) fix-y)))
8711 (if (not u31y)
8712 (with-imm-target () (xreg :natural)
8713 (with-imm-target (xreg) (yreg :natural)
8714 (x862-two-targeted-reg-forms seg x xreg y yreg)
8715 (! %natural- xreg yreg))
8716 (<- xreg))
8717 (progn
8718 (with-imm-target () (xreg :natural)
8719 (x862-one-targeted-reg-form seg x xreg)
8720 (! %natural--c xreg u31y)
8721 (<- xreg))))
8722 (^))))))
8723
8724(defx862 x862-%natural-logior %natural-logior (seg vreg xfer x y)
8725 (if (null vreg)
8726 (progn
8727 (x862-form seg nil nil x)
8728 (x862-form seg nil xfer y))
8729 (let* ((naturalx (nx-natural-constant-p x))
8730 (naturaly (nx-natural-constant-p y)))
8731 (if (and naturalx naturaly)
8732 (x862-absolute-natural seg vreg xfer (logior naturalx naturaly))
8733 (let* ((u31x (nx-u31-constant-p x))
8734 (u31y (nx-u31-constant-p y))
8735 (constant (or u31x u31y)))
8736 (if (not constant)
8737 (with-imm-target () (xreg :natural)
8738 (with-imm-target (xreg) (yreg :natural)
8739 (x862-two-targeted-reg-forms seg x xreg y yreg)
8740 (! %natural-logior xreg yreg))
8741 (<- xreg))
8742 (let* ((other (if u31x y x)))
8743 (with-imm-target () (other-reg :natural)
8744 (x862-one-targeted-reg-form seg other other-reg)
8745 (! %natural-logior-c other-reg constant)
8746 (<- other-reg))))
8747 (^))))))
8748
8749(defx862 x862-%natural-logxor %natural-logxor (seg vreg xfer x y)
8750 (if (null vreg)
8751 (progn
8752 (x862-form seg nil nil x)
8753 (x862-form seg nil xfer y))
8754 (let* ((naturalx (nx-natural-constant-p x))
8755 (naturaly (nx-natural-constant-p y)))
8756 (if (and naturalx naturaly)
8757 (x862-absolute-natural seg vreg xfer (logxor naturalx naturaly))
8758 (let* ((u32x (nx-u32-constant-p x))
8759 (u32y (nx-u32-constant-p y))
8760 (constant (or u32x u32y)))
8761 (if (not constant)
8762 (with-imm-target () (xreg :natural)
8763 (with-imm-target (xreg) (yreg :natural)
8764 (x862-two-targeted-reg-forms seg x xreg y yreg)
8765 (! %natural-logxor xreg yreg))
8766 (<- xreg))
8767 (let* ((other (if u32x y x)))
8768 (with-imm-target () (other-reg :natural)
8769 (x862-one-targeted-reg-form seg other other-reg)
8770 (! %natural-logxor-c other-reg constant)
8771 (<- other-reg))))
8772 (^))))))
8773
8774(defx862 x862-%natural-logand %natural-logand (seg vreg xfer x y)
8775 (if (null vreg)
8776 (progn
8777 (x862-form seg nil nil x)
8778 (x862-form seg nil xfer y))
8779 (let* ((naturalx (nx-natural-constant-p x))
8780 (naturaly (nx-natural-constant-p y)))
8781 (if (and naturalx naturaly)
8782 (x862-absolute-natural seg vreg xfer (logand naturalx naturaly))
8783 (let* ((u31x (nx-u31-constant-p x))
8784 (u31y (nx-u31-constant-p y))
8785 (constant (or u31x u31y)))
8786 (if (not constant)
8787 (with-imm-target () (xreg :natural)
8788 (with-imm-target (xreg) (yreg :natural)
8789 (x862-two-targeted-reg-forms seg x xreg y yreg)
8790 (! %natural-logand xreg yreg))
8791 (<- xreg))
8792 (let* ((other (if u31x y x)))
8793 (with-imm-target () (other-reg :natural)
8794 (x862-one-targeted-reg-form seg other other-reg)
8795 (! %natural-logand-c other-reg constant)
8796 (<- other-reg))))
8797 (^))))))
8798
8799(defx862 x862-natural-shift-right natural-shift-right (seg vreg xfer num amt)
8800 (with-imm-target () (dest :natural)
8801 (x862-one-targeted-reg-form seg num dest)
8802 (! natural-shift-right dest (acode-fixnum-form-p amt))
8803 (<- dest)
8804 (^)))
8805
8806(defx862 x862-natural-shift-left natural-shift-left (seg vreg xfer num amt)
8807 (with-imm-target () (dest :natural)
8808 (x862-one-targeted-reg-form seg num dest)
8809 (! natural-shift-left dest (acode-fixnum-form-p amt))
8810 (<- dest)
8811 (^)))
8812
8813;;; This assumes that "global" variables are always boundp.
8814(defx862 x862-global-ref global-ref (seg vreg xfer sym)
8815 (when vreg
8816 (ensuring-node-target (target vreg)
8817 (with-node-temps () (symreg)
8818 (setq symreg (or (x862-register-constant-p sym)
8819 (x862-store-immediate seg sym symreg)))
8820 (! symbol-ref target symreg (target-arch-case
8821 (:x8664 x8664::symbol.vcell-cell))))))
8822 (^))
8823
8824(defx862 x862-global-setq global-setq (seg vreg xfer sym val)
8825 (x862-vset seg
8826 vreg
8827 xfer
8828 :symbol
8829 (make-acode (%nx1-operator %symptr->symvector)
8830 (make-acode (%nx1-operator immediate) sym))
8831 (make-acode (%nx1-operator fixnum)
8832 (target-arch-case
8833 (:x8664 x8664::symbol.vcell-cell)))
8834 val
8835 nil))
8836
8837(defx862 x862-%current-frame-ptr %current-frame-ptr (seg vreg xfer)
8838 (cond ((x862-tailcallok xfer)
8839 (x862-restore-nvrs seg *x862-register-restore-ea* *x862-register-restore-count*)
8840 (x862-restore-full-lisp-context seg)
8841 (! %current-frame-ptr ($ x8664::arg_z))
8842 (! jump-return-pc))
8843 (t
8844 (when vreg
8845 (ensuring-node-target (target vreg)
8846 (! %current-frame-ptr target)))
8847 (^))))
8848
8849(defx862 x862-%foreign-stack-pointer %foreign-stack-pointer (seg vreg xfer)
8850 (when vreg
8851 (ensuring-node-target (target vreg)
8852 (! %foreign-stack-pointer target)))
8853 (^))
8854
8855
8856(defx862 x862-%current-tcr %current-tcr (seg vreg xfer)
8857 (when vreg
8858 (ensuring-node-target (target vreg)
8859 (! %current-tcr target)))
8860 (^))
8861
8862
8863
8864(defx862 x862-%interrupt-poll %interrupt-poll (seg vreg xfer)
8865 (! event-poll)
8866 (x862-nil seg vreg xfer))
8867
8868
8869(defx862 x862-with-c-frame with-c-frame (seg vreg xfer body &aux
8870 (old-stack (x862-encode-stack)))
8871 (! alloc-c-frame 0)
8872 (x862-open-undo $undo-x86-c-frame)
8873 (x862-undo-body seg vreg xfer body old-stack))
8874
8875(defx862 x862-with-variable-c-frame with-variable-c-frame (seg vreg xfer size body &aux
8876 (old-stack (x862-encode-stack)))
8877 (let* ((reg (x862-one-untargeted-reg-form seg size x8664::arg_z)))
8878 (! alloc-variable-c-frame reg)
8879 (x862-open-undo $undo-x86-c-frame)
8880 (x862-undo-body seg vreg xfer body old-stack)))
8881
8882(defx862 x862-%symbol->symptr %symbol->symptr (seg vreg xfer sym)
8883 (let* ((src (x862-one-untargeted-reg-form seg sym x8664::arg_z)))
8884 (ensuring-node-target (target vreg)
8885 (! %symbol->symptr target src))
8886 (^)))
8887
8888(defx862 x862-%double-to-single %double-to-single (seg vreg xfer arg)
8889 (if (null vreg)
8890 (x862-form seg vreg xfer arg)
8891 (if (and (= (hard-regspec-class vreg) hard-reg-class-fpr)
8892 (= (get-regspec-mode vreg) hard-reg-class-fpr-mode-single))
8893 (let* ((dreg (x862-one-untargeted-reg-form
8894 seg arg
8895 (make-wired-lreg (hard-regspec-value vreg)
8896 :class hard-reg-class-fpr
8897 :mode hard-reg-class-fpr-mode-double))))
8898 (! double-to-single vreg dreg)
8899 (^))
8900 (with-fp-target () (argreg :double-float)
8901 (x862-one-targeted-reg-form seg arg argreg)
8902 (with-fp-target () (sreg :single-float)
8903 (! double-to-single sreg argreg)
8904 (<- sreg)
8905 (^))))))
8906
8907(defx862 x862-%single-to-double %single-to-double (seg vreg xfer arg)
8908 (if (null vreg)
8909 (x862-form seg vreg xfer arg)
8910 (if (and (= (hard-regspec-class vreg) hard-reg-class-fpr)
8911 (= (get-regspec-mode vreg) hard-reg-class-fpr-mode-double))
8912 (let* ((sreg (x862-one-untargeted-reg-form
8913 seg arg
8914 (make-wired-lreg (hard-regspec-value vreg)
8915 :class hard-reg-class-fpr
8916 :mode hard-reg-class-fpr-mode-double))))
8917 (! single-to-double vreg sreg)
8918 (^))
8919 (with-fp-target () (sreg :single-float)
8920 (x862-one-targeted-reg-form seg arg sreg)
8921 (with-fp-target () (dreg :double-float)
8922 (! single-to-double dreg sreg)
8923 (<- dreg)
8924 (^))))))
8925
8926(defx862 x862-%symptr->symvector %symptr->symvector (seg vreg xfer arg)
8927 (if (null vreg)
8928 (x862-form seg vreg xfer arg)
8929 (progn
8930 (ensuring-node-target (target vreg)
8931 (x862-one-targeted-reg-form seg arg target)
8932 (! %symptr->symvector target))
8933 (^))))
8934
8935(defx862 x862-%symvector->symptr %symvector->symptr (seg vreg xfer arg)
8936 (if (null vreg)
8937 (x862-form seg vreg xfer arg)
8938 (progn
8939 (ensuring-node-target (target vreg)
8940 (x862-one-targeted-reg-form seg arg target)
8941 (! %symvector->symptr target))
8942 (^))))
8943
8944(defx862 x862-%fixnum-to-single %fixnum-to-single (seg vreg xfer arg)
8945 (with-fp-target () (sreg :single-float)
8946 (let* ((r (x862-one-untargeted-reg-form seg arg x8664::arg_z)))
8947 (unless (or (acode-fixnum-form-p arg)
8948 *x862-reckless*)
8949 (! trap-unless-fixnum r))
8950 (! fixnum->single-float sreg r)
8951 (<- sreg)
8952 (^))))
8953
8954(defx862 x862-%fixnum-to-double %fixnum-to-double (seg vreg xfer arg)
8955 (with-fp-target () (dreg :double-float)
8956 (let* ((r (x862-one-untargeted-reg-form seg arg x8664::arg_z)))
8957 (unless (or (acode-fixnum-form-p arg)
8958 *x862-reckless*)
8959 (! trap-unless-fixnum r))
8960 (! fixnum->double-float dreg r)
8961 (<- dreg)
8962 (^))))
8963
8964(defx862 x862-%double-float %double-float (seg vreg xfer arg)
8965 (let* ((real (or (acode-fixnum-form-p arg)
8966 (let* ((form (acode-unwrapped-form arg)))
8967 (if (and (acode-p form)
8968 (eq (acode-operator form)
8969 (%nx1-operator immediate))
8970 (typep (cadr form) 'real))
8971 (cadr form))))))
8972 (if real
8973 (x862-immediate seg vreg xfer (float real 0.0d0))
8974 (if (x862-form-typep arg 'single-float)
8975 (x862-use-operator (%nx1-operator %single-to-double)
8976 seg
8977 vreg
8978 xfer
8979 arg)
8980 (if (x862-form-typep arg 'fixnum)
8981 (x862-use-operator (%nx1-operator %fixnum-to-double)
8982 seg
8983 vreg
8984 xfer
8985 arg)
8986 (x862-use-operator (%nx1-operator call)
8987 seg
8988 vreg
8989 xfer
8990 (make-acode (%nx1-operator immediate)
8991 '%double-float)
8992 (list nil (list arg))))))))
8993
8994(defx862 x862-%single-float %single-float (seg vreg xfer arg)
8995 (let* ((real (or (acode-fixnum-form-p arg)
8996 (let* ((form (acode-unwrapped-form arg)))
8997 (if (and (acode-p form)
8998 (eq (acode-operator form)
8999 (%nx1-operator immediate))
9000 (typep (cadr form) 'real))
9001 (cadr form))))))
9002 (if real
9003 (x862-immediate seg vreg xfer (float real 0.0f0))
9004 (if (x862-form-typep arg 'double-float)
9005 (x862-use-operator (%nx1-operator %double-to-single)
9006 seg
9007 vreg
9008 xfer
9009 arg)
9010 (if (x862-form-typep arg 'fixnum)
9011 (x862-use-operator (%nx1-operator %fixnum-to-single)
9012 seg
9013 vreg
9014 xfer
9015 arg)
9016 (x862-use-operator (%nx1-operator call)
9017 seg
9018 vreg
9019 xfer
9020 (make-acode (%nx1-operator immediate)
9021 '%short-float)
9022 (list nil (list arg))))))))
9023
9024
9025;------
9026
9027#+not-yet
9028(progn
9029
9030
9031;Make a gcable macptr.
9032(defx862 x862-%new-ptr %new-ptr (b vreg xfer size clear-p )
9033 (declare (ignore b vreg xfer size clear-p))
9034 (error "%New-ptr is a waste of precious silicon."))
9035
9036
9037
9038)
9039
9040#-x86-target
9041(defun x8664-xcompile-lambda (def &key show-vinsns (symbolic-names t)
9042 (target :linuxx8664)
9043 (disassemble t))
9044 (let* ((*x862-debug-mask* (if show-vinsns
9045 (ash 1 x862-debug-vinsns-bit)
9046 0))
9047 (backend (find-backend target))
9048 (*target-ftd* (if backend
9049 (backend-target-foreign-type-data backend)
9050 *target-ftd*)))
9051 (multiple-value-bind (xlfun warnings)
9052 (compile-named-function def nil
9053 nil
9054 nil
9055 nil
9056 nil
9057 nil
9058 target)
9059 (signal-or-defer-warnings warnings nil)
9060 (when disassemble
9061 (format t "~%~%")
9062 (apply #'x8664-disassemble-xfunction
9063 xlfun
9064 (unless symbolic-names (list nil))))
9065 xlfun)))
9066
9067
9068
9069
Note: See TracBrowser for help on using the repository browser.