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 "X8632ENV") |
---|
22 | (require "X8664ENV")) |
---|
23 | |
---|
24 | (eval-when (:load-toplevel :execute :compile-toplevel) |
---|
25 | (require "X86-BACKEND")) |
---|
26 | |
---|
27 | (defparameter *x862-debug-mask* 0) |
---|
28 | (defconstant x862-debug-verbose-bit 0) |
---|
29 | (defconstant x862-debug-vinsns-bit 1) |
---|
30 | (defconstant x862-debug-lcells-bit 2) |
---|
31 | (defparameter *x862-target-lcell-size* 0) |
---|
32 | (defparameter *x862-target-node-size* 0) |
---|
33 | (defparameter *x862-target-dnode-size* 0) |
---|
34 | (defparameter *x862-target-fixnum-shift* 0) |
---|
35 | (defparameter *x862-target-node-shift* 0) |
---|
36 | (defparameter *x862-target-bits-in-word* 0) |
---|
37 | (defparameter *x862-target-num-arg-regs* 0) |
---|
38 | (defparameter *x862-target-num-save-regs* 0) |
---|
39 | (defparameter *x862-target-half-fixnum-type* nil) |
---|
40 | |
---|
41 | (defparameter *x862-operator-supports-u8-target* ()) |
---|
42 | (defparameter *x862-operator-supports-push* ()) |
---|
43 | (defparameter *x862-tos-reg* ()) |
---|
44 | |
---|
45 | ;; probably should be elsewhere |
---|
46 | |
---|
47 | (defmacro with-additional-imm-reg ((&rest reserved) &body body) |
---|
48 | (let ((node (gensym)) |
---|
49 | (bit (gensym))) |
---|
50 | `(target-arch-case |
---|
51 | (:x8632 |
---|
52 | (with-node-target (,@reserved) ,node |
---|
53 | (let* ((,bit (ash 1 (hard-regspec-value ,node))) |
---|
54 | (*backend-node-temps* (logandc2 *backend-node-temps* ,bit)) |
---|
55 | (*available-backend-node-temps* (logandc2 *available-backend-node-temps* ,bit)) |
---|
56 | (*backend-imm-temps* (logior *backend-imm-temps* ,bit)) |
---|
57 | (*available-backend-imm-temps* (logior *available-backend-imm-temps* ,bit))) |
---|
58 | (! mark-as-imm ,node) |
---|
59 | ,@body |
---|
60 | (! mark-as-node ,node)))) |
---|
61 | (:x8664 |
---|
62 | (progn |
---|
63 | ,@body))))) |
---|
64 | |
---|
65 | |
---|
66 | (defun x862-immediate-operand (x) |
---|
67 | (if (eq (acode-operator x) (%nx1-operator immediate)) |
---|
68 | (cadr x) |
---|
69 | (if (eq (acode-operator x) (%nx1-operator with-code-note)) |
---|
70 | (x862-immediate-operand (caddr x)) |
---|
71 | (compiler-bug "not an immediate: ~s" x)))) |
---|
72 | |
---|
73 | (defmacro with-x86-p2-declarations (declsform &body body) |
---|
74 | `(let* ((*x862-tail-allow* *x862-tail-allow*) |
---|
75 | (*x862-reckless* *x862-reckless*) |
---|
76 | (*x862-open-code-inline* *x862-open-code-inline*) |
---|
77 | (*x862-trust-declarations* *x862-trust-declarations*) |
---|
78 | (*x862-full-safety* *x862-full-safety*)) |
---|
79 | (x862-decls ,declsform) |
---|
80 | ,@body)) |
---|
81 | |
---|
82 | |
---|
83 | (defmacro with-x86-local-vinsn-macros ((segvar &optional vreg-var xfer-var) &body body) |
---|
84 | (declare (ignorable xfer-var)) |
---|
85 | (let* ((template-name-var (gensym)) |
---|
86 | (template-temp (gensym)) |
---|
87 | (args-var (gensym)) |
---|
88 | (labelnum-var (gensym)) |
---|
89 | (retvreg-var (gensym)) |
---|
90 | (label-var (gensym))) |
---|
91 | `(macrolet ((! (,template-name-var &rest ,args-var) |
---|
92 | (let* ((,template-temp (get-vinsn-template-cell ,template-name-var (backend-p2-vinsn-templates *target-backend*)))) |
---|
93 | (unless ,template-temp |
---|
94 | (warn "VINSN \"~A\" not defined" ,template-name-var)) |
---|
95 | `(prog1 |
---|
96 | (%emit-vinsn ,',segvar ',,template-name-var (backend-p2-vinsn-templates *target-backend*) ,@,args-var) |
---|
97 | (setq *x862-tos-reg* nil))))) |
---|
98 | (macrolet ((<- (,retvreg-var) |
---|
99 | `(x862-copy-register ,',segvar ,',vreg-var ,,retvreg-var)) |
---|
100 | (@ (,labelnum-var) |
---|
101 | `(backend-gen-label ,',segvar ,,labelnum-var)) |
---|
102 | (@= (,labelnum-var) |
---|
103 | `(x862-emit-aligned-label ,',segvar ,,labelnum-var)) |
---|
104 | (-> (,label-var) |
---|
105 | `(! jump (aref *backend-labels* ,,label-var))) |
---|
106 | (^ (&rest branch-args) |
---|
107 | `(x862-branch ,',segvar ,',xfer-var ,@branch-args)) |
---|
108 | (? (&key (class :gpr) |
---|
109 | (mode :lisp)) |
---|
110 | (let* ((class-val |
---|
111 | (ecase class |
---|
112 | (:gpr hard-reg-class-gpr) |
---|
113 | (:fpr hard-reg-class-fpr) |
---|
114 | (:crf hard-reg-class-crf))) |
---|
115 | (mode-val-or-form |
---|
116 | (if (eq class :gpr) |
---|
117 | (if (member mode '(:natural :signed-natural)) |
---|
118 | `(gpr-mode-name-value ,mode) |
---|
119 | (gpr-mode-name-value mode)) |
---|
120 | (if (eq class :fpr) |
---|
121 | (if (eq mode :single-float) |
---|
122 | hard-reg-class-fpr-mode-single |
---|
123 | hard-reg-class-fpr-mode-double) |
---|
124 | 0)))) |
---|
125 | `(make-unwired-lreg nil |
---|
126 | :class ,class-val |
---|
127 | :mode ,mode-val-or-form))) |
---|
128 | ($ (reg &key (class :gpr) (mode :lisp)) |
---|
129 | (let* ((class-val |
---|
130 | (ecase class |
---|
131 | (:gpr hard-reg-class-gpr) |
---|
132 | (:fpr hard-reg-class-fpr) |
---|
133 | (:crf hard-reg-class-crf))) |
---|
134 | (mode-val-or-form |
---|
135 | (if (eq class :gpr) |
---|
136 | (if (member mode '(:natural :signed-natural)) |
---|
137 | `(gpr-mode-name-value ,mode) |
---|
138 | (gpr-mode-name-value mode)) |
---|
139 | (if (eq class :fpr) |
---|
140 | (if (eq mode :single-float) |
---|
141 | hard-reg-class-fpr-mode-single |
---|
142 | hard-reg-class-fpr-mode-double) |
---|
143 | 0)))) |
---|
144 | `(make-wired-lreg ,reg |
---|
145 | :class ,class-val |
---|
146 | :mode ,mode-val-or-form)))) |
---|
147 | ,@body)))) |
---|
148 | |
---|
149 | |
---|
150 | |
---|
151 | (defvar *x86-current-context-annotation* nil) |
---|
152 | (defvar *x862-woi* nil) |
---|
153 | (defvar *x862-open-code-inline* nil) |
---|
154 | (defvar *x862-register-restore-count* 0) |
---|
155 | (defvar *x862-register-restore-ea* nil) |
---|
156 | (defvar *x862-compiler-register-save-label* nil) |
---|
157 | (defvar *x862-valid-register-annotations* 0) |
---|
158 | (defvar *x862-register-annotation-types* nil) |
---|
159 | (defvar *x862-register-ea-annotations* nil) |
---|
160 | (defvar *x862-constant-alist* nil) |
---|
161 | (defvar *x862-double-float-constant-alist* nil) |
---|
162 | (defvar *x862-single-float-constant-alist* nil) |
---|
163 | |
---|
164 | (defparameter *x862-tail-call-aliases* |
---|
165 | () |
---|
166 | #| '((%call-next-method . (%tail-call-next-method . 1))) |# |
---|
167 | |
---|
168 | ) |
---|
169 | |
---|
170 | (defvar *x862-popreg-labels* nil) |
---|
171 | (defvar *x862-popj-labels* nil) |
---|
172 | (defvar *x862-valret-labels* nil) |
---|
173 | (defvar *x862-nilret-labels* nil) |
---|
174 | |
---|
175 | (defvar *x862-icode* nil) |
---|
176 | (defvar *x862-undo-stack* nil) |
---|
177 | (defvar *x862-undo-because* nil) |
---|
178 | |
---|
179 | |
---|
180 | (defvar *x862-cur-afunc* nil) |
---|
181 | (defvar *x862-vstack* 0) |
---|
182 | (defvar *x862-cstack* 0) |
---|
183 | (defvar *x862-undo-count* 0) |
---|
184 | (defvar *x862-returning-values* nil) |
---|
185 | (defvar *x862-vcells* nil) |
---|
186 | (defvar *x862-fcells* nil) |
---|
187 | (defvar *x862-entry-vsp-saved-p* nil) |
---|
188 | |
---|
189 | (defvar *x862-entry-label* nil) |
---|
190 | (defvar *x862-tail-label* nil) |
---|
191 | (defvar *x862-tail-vsp* nil) |
---|
192 | (defvar *x862-tail-nargs* nil) |
---|
193 | (defvar *x862-tail-allow* t) |
---|
194 | (defvar *x862-reckless* nil) |
---|
195 | (defvar *x862-full-safety* nil) |
---|
196 | (defvar *x862-trust-declarations* nil) |
---|
197 | (defvar *x862-entry-vstack* nil) |
---|
198 | (defvar *x862-fixed-nargs* nil) |
---|
199 | (defvar *x862-need-nargs* t) |
---|
200 | |
---|
201 | (defparameter *x862-inhibit-register-allocation* nil) |
---|
202 | (defvar *x862-record-symbols* nil) |
---|
203 | (defvar *x862-recorded-symbols* nil) |
---|
204 | (defvar *x862-emitted-source-notes* '() |
---|
205 | "List of all the :source-location-begin notes we've emitted during this compile.") |
---|
206 | |
---|
207 | (defvar *x862-result-reg* x8664::arg_z) |
---|
208 | |
---|
209 | (defvar *x862-arg-z* nil) |
---|
210 | (defvar *x862-arg-y* nil) |
---|
211 | (defvar *x862-imm0* nil) |
---|
212 | (defvar *x862-temp0* nil) |
---|
213 | (defvar *x862-temp1* nil) |
---|
214 | (defvar *x862-fn* nil) |
---|
215 | (defvar *x862-fname* nil) |
---|
216 | (defvar *x862-ra0* nil) |
---|
217 | |
---|
218 | (defvar *x862-allocptr* nil) |
---|
219 | |
---|
220 | (defvar *x862-fp0* nil) |
---|
221 | (defvar *x862-fp1* nil) |
---|
222 | |
---|
223 | (declaim (fixnum *x862-vstack* *x862-cstack*)) |
---|
224 | |
---|
225 | |
---|
226 | |
---|
227 | |
---|
228 | |
---|
229 | (defvar *x862-all-lcells* ()) |
---|
230 | |
---|
231 | (defun x86-immediate-label (imm) |
---|
232 | (or (cdr (assoc imm *x862-constant-alist* :test #'eq)) |
---|
233 | (let* ((lab (aref *backend-labels* (backend-get-next-label)))) |
---|
234 | (push (cons imm lab) *x862-constant-alist*) |
---|
235 | lab))) |
---|
236 | |
---|
237 | (defun x86-double-float-constant-label (imm) |
---|
238 | (or (cdr (assoc imm *x862-double-float-constant-alist*)) |
---|
239 | (let* ((lab (aref *backend-labels* (backend-get-next-label)))) |
---|
240 | (push (cons imm lab) *x862-double-float-constant-alist*) |
---|
241 | lab))) |
---|
242 | |
---|
243 | (defun x86-single-float-constant-label (imm) |
---|
244 | (or (cdr (assoc imm *x862-single-float-constant-alist*)) |
---|
245 | (let* ((lab (aref *backend-labels* (backend-get-next-label)))) |
---|
246 | (push (cons imm lab) *x862-single-float-constant-alist*) |
---|
247 | lab))) |
---|
248 | |
---|
249 | |
---|
250 | (defun x862-free-lcells () |
---|
251 | (without-interrupts |
---|
252 | (let* ((prev (pool.data *lcell-freelist*))) |
---|
253 | (dolist (r *x862-all-lcells*) |
---|
254 | (setf (lcell-kind r) prev |
---|
255 | prev r)) |
---|
256 | (setf (pool.data *lcell-freelist*) prev) |
---|
257 | (setq *x862-all-lcells* nil)))) |
---|
258 | |
---|
259 | (defun x862-note-lcell (c) |
---|
260 | (push c *x862-all-lcells*) |
---|
261 | c) |
---|
262 | |
---|
263 | (defvar *x862-top-vstack-lcell* ()) |
---|
264 | (defvar *x862-bottom-vstack-lcell* ()) |
---|
265 | |
---|
266 | (defun x862-new-lcell (kind parent width attributes info) |
---|
267 | (x862-note-lcell (make-lcell kind parent width attributes info))) |
---|
268 | |
---|
269 | (defun x862-new-vstack-lcell (kind width attributes info) |
---|
270 | (setq *x862-top-vstack-lcell* (x862-new-lcell kind *x862-top-vstack-lcell* width attributes info))) |
---|
271 | |
---|
272 | (defun x862-reserve-vstack-lcells (n) |
---|
273 | (dotimes (i n) (x862-new-vstack-lcell :reserved *x862-target-lcell-size* 0 nil))) |
---|
274 | |
---|
275 | (defun x862-vstack-mark-top () |
---|
276 | (x862-new-lcell :tos *x862-top-vstack-lcell* 0 0 nil)) |
---|
277 | |
---|
278 | ;;; Alist mapping VARs to lcells/lregs |
---|
279 | (defvar *x862-var-cells* ()) |
---|
280 | |
---|
281 | (defun x862-note-var-cell (var cell) |
---|
282 | ;(format t "~& ~s -> ~s" (var-name var) cell) |
---|
283 | (push (cons var cell) *x862-var-cells*)) |
---|
284 | |
---|
285 | (defun x862-note-top-cell (var) |
---|
286 | (x862-note-var-cell var *x862-top-vstack-lcell*)) |
---|
287 | |
---|
288 | (defun x862-lookup-var-cell (var) |
---|
289 | (or (cdr (assq var *x862-var-cells*)) |
---|
290 | (and nil (warn "Cell not found for ~s" (var-name var))))) |
---|
291 | |
---|
292 | (defun x862-collect-lcells (kind &optional (bottom *x862-bottom-vstack-lcell*) (top *x862-top-vstack-lcell*)) |
---|
293 | (do* ((res ()) |
---|
294 | (cell top (lcell-parent cell))) |
---|
295 | ((eq cell bottom) res) |
---|
296 | (if (null cell) |
---|
297 | (compiler-bug "Horrible compiler bug.") |
---|
298 | (if (eq (lcell-kind cell) kind) |
---|
299 | (push cell res))))) |
---|
300 | |
---|
301 | |
---|
302 | |
---|
303 | ;;; ensure that lcell's offset matches what we expect it to. |
---|
304 | ;;; For bootstrapping. |
---|
305 | |
---|
306 | (defun x862-ensure-lcell-offset (c expected) |
---|
307 | (if c (= (calc-lcell-offset c) expected) (zerop expected))) |
---|
308 | |
---|
309 | (defun x862-check-lcell-depth (&optional (context "wherever")) |
---|
310 | (when (logbitp x862-debug-verbose-bit *x862-debug-mask*) |
---|
311 | (let* ((depth (calc-lcell-depth *x862-top-vstack-lcell*))) |
---|
312 | (or (= depth *x862-vstack*) |
---|
313 | (warn "~a: lcell depth = ~d, vstack = ~d" context depth *x862-vstack*))))) |
---|
314 | |
---|
315 | (defun x862-do-lexical-reference (seg vreg ea) |
---|
316 | (when vreg |
---|
317 | (with-x86-local-vinsn-macros (seg vreg) |
---|
318 | (if (eq vreg :push) |
---|
319 | (if (memory-spec-p ea) |
---|
320 | (if (addrspec-vcell-p ea) |
---|
321 | (with-node-target () target |
---|
322 | (x862-stack-to-register seg ea target) |
---|
323 | (! vcell-ref target target) |
---|
324 | (! vpush-register target)) |
---|
325 | (! vframe-push (memspec-frame-address-offset ea) *x862-vstack*)) |
---|
326 | (! vpush-register ea)) |
---|
327 | (if (memory-spec-p ea) |
---|
328 | (ensuring-node-target (target vreg) |
---|
329 | (progn |
---|
330 | (x862-stack-to-register seg ea target) |
---|
331 | (if (addrspec-vcell-p ea) |
---|
332 | (! vcell-ref target target)))) |
---|
333 | (<- ea)))))) |
---|
334 | |
---|
335 | (defun x862-do-lexical-setq (seg vreg ea valreg) |
---|
336 | (with-x86-local-vinsn-macros (seg vreg) |
---|
337 | (cond ((typep ea 'lreg) |
---|
338 | (x862-copy-register seg ea valreg)) |
---|
339 | ((addrspec-vcell-p ea) ; closed-over vcell |
---|
340 | (x862-copy-register seg *x862-arg-z* valreg) |
---|
341 | (let* ((gvector (target-arch-case (:x8632 x8632::temp0) |
---|
342 | (:x8664 x8664::arg_x)))) |
---|
343 | (x862-stack-to-register seg ea gvector) |
---|
344 | (x862-lri seg *x862-arg-y* 0) |
---|
345 | (! call-subprim-3 *x862-arg-z* (subprim-name->offset '.SPgvset) gvector *x862-arg-y* *x862-arg-z*))) |
---|
346 | ((memory-spec-p ea) ; vstack slot |
---|
347 | (x862-register-to-stack seg valreg ea)) |
---|
348 | (t |
---|
349 | (x862-copy-register seg ea valreg))) |
---|
350 | (when vreg |
---|
351 | (<- valreg)))) |
---|
352 | |
---|
353 | ;;; ensure that next-method-var is heap-consed (if it's closed over.) |
---|
354 | ;;; it isn't ever setqed, is it ? |
---|
355 | (defun x862-heap-cons-next-method-var (seg var) |
---|
356 | (with-x86-local-vinsn-macros (seg) |
---|
357 | (when (eq (ash 1 $vbitclosed) |
---|
358 | (logand (logior (ash 1 $vbitclosed) |
---|
359 | (ash 1 $vbitcloseddownward)) |
---|
360 | (the fixnum (nx-var-bits var)))) |
---|
361 | (let* ((ea (var-ea var)) |
---|
362 | (arg ($ *x862-arg-z*)) |
---|
363 | (result ($ *x862-arg-z*))) |
---|
364 | (x862-do-lexical-reference seg arg ea) |
---|
365 | (x862-set-nargs seg 1) |
---|
366 | (! ref-constant ($ *x862-fname*) (x86-immediate-label (x862-symbol-entry-locative '%cons-magic-next-method-arg))) |
---|
367 | (! call-known-symbol arg) |
---|
368 | (x862-do-lexical-setq seg nil ea result))))) |
---|
369 | |
---|
370 | ;;; If we change the order of operands in a binary comparison operation, |
---|
371 | ;;; what should the operation change to ? (eg., (< X Y) means the same |
---|
372 | ;;; thing as (> Y X)). |
---|
373 | (defparameter *x862-reversed-cr-bits* |
---|
374 | (vector |
---|
375 | nil ;o ? |
---|
376 | nil ;no ? |
---|
377 | x86::x86-a-bits ;b -> a |
---|
378 | x86::x86-be-bits ;ae -> be |
---|
379 | x86::x86-e-bits ;e->e |
---|
380 | x86::x86-ne-bits ;ne->ne |
---|
381 | x86::x86-ae-bits ;be->ae |
---|
382 | x86::x86-b-bits ;a->b |
---|
383 | nil ;s ? |
---|
384 | nil ;ns ? |
---|
385 | nil ;pe ? |
---|
386 | nil ;po ? |
---|
387 | x86::x86-g-bits ;l->g |
---|
388 | x86::x86-le-bits ;ge->le |
---|
389 | x86::x86-ge-bits ;le->ge |
---|
390 | x86::x86-l-bits ;g->l |
---|
391 | )) |
---|
392 | |
---|
393 | (defun x862-reverse-cr-bit (cr-bit) |
---|
394 | (or (svref *x862-reversed-cr-bits* cr-bit) |
---|
395 | (compiler-bug "Can't reverse CR bit ~d" cr-bit))) |
---|
396 | |
---|
397 | |
---|
398 | (defun acode-condition-to-x86-cr-bit (cond) |
---|
399 | (condition-to-x86-cr-bit (cadr cond))) |
---|
400 | |
---|
401 | (defun condition-to-x86-cr-bit (cond) |
---|
402 | (case cond |
---|
403 | (:EQ (values x86::x86-e-bits t)) |
---|
404 | (:NE (values x86::x86-e-bits nil)) |
---|
405 | (:GT (values x86::x86-le-bits nil)) |
---|
406 | (:LE (values x86::x86-le-bits t)) |
---|
407 | (:LT (values x86::x86-l-bits t)) |
---|
408 | (:GE (values x86::x86-l-bits nil)))) |
---|
409 | |
---|
410 | ;;; Generate the start and end bits for a RLWINM instruction that |
---|
411 | ;;; would be equivalent to to LOGANDing the constant with some value. |
---|
412 | ;;; Return (VALUES NIL NIL) if the constant contains more than one |
---|
413 | ;;; sequence of consecutive 1-bits, else bit indices. |
---|
414 | ;;; The caller generally wants to treat the constant as an (UNSIGNED-BYTE 32); |
---|
415 | ;;; since this uses LOGCOUNT and INTEGER-LENGTH to find the significant |
---|
416 | ;;; bits, it ensures that the constant is a (SIGNED-BYTE 32) that has |
---|
417 | ;;; the same least-significant 32 bits. |
---|
418 | (defun x862-mask-bits (constant) |
---|
419 | (if (< constant 0) (setq constant (logand #xffffffff constant))) |
---|
420 | (if (= constant #xffffffff) |
---|
421 | (values 0 31) |
---|
422 | (if (zerop constant) |
---|
423 | (values nil nil) |
---|
424 | (let* ((signed (if (and (logbitp 31 constant) |
---|
425 | (> constant 0)) |
---|
426 | (- constant (ash 1 32)) |
---|
427 | constant)) |
---|
428 | (count (logcount signed)) |
---|
429 | (len (integer-length signed)) |
---|
430 | (highbit (logbitp (the fixnum (1- len)) constant))) |
---|
431 | (declare (fixnum count len)) |
---|
432 | (do* ((i 1 (1+ i)) |
---|
433 | (pos (- len 2) (1- pos))) |
---|
434 | ((= i count) |
---|
435 | (let* ((start (- 32 len)) |
---|
436 | (end (+ count start))) |
---|
437 | (declare (fixnum start end)) |
---|
438 | (if highbit |
---|
439 | (values start (the fixnum (1- end))) |
---|
440 | (values (logand 31 end) |
---|
441 | (the fixnum (1- start)))))) |
---|
442 | (declare (fixnum i pos)) |
---|
443 | (unless (eq (logbitp pos constant) highbit) |
---|
444 | (return (values nil nil)))))))) |
---|
445 | |
---|
446 | |
---|
447 | (defun x862-ensure-binding-indices-for-vcells (vcells) |
---|
448 | (dolist (cell vcells) |
---|
449 | (ensure-binding-index (car cell))) |
---|
450 | vcells) |
---|
451 | |
---|
452 | (defun x862-register-mask-byte (count) |
---|
453 | (if (> count 0) |
---|
454 | (logior |
---|
455 | (ash 1 (- x8664::save0 8)) |
---|
456 | (if (> count 1) |
---|
457 | (logior |
---|
458 | (ash 1 (- x8664::save1 8)) |
---|
459 | (if (> count 2) |
---|
460 | (logior |
---|
461 | (ash 1 (- x8664::save2 8)) |
---|
462 | (if (> count 3) |
---|
463 | (ash 1 (- x8664::save3 8)) |
---|
464 | 0)) |
---|
465 | 0)) |
---|
466 | 0)) |
---|
467 | 0)) |
---|
468 | |
---|
469 | (defun x862-encode-register-save-ea (ea count) |
---|
470 | (if (zerop count) |
---|
471 | 0 |
---|
472 | (min (- (ash ea (- *x862-target-node-shift*)) count) #xff))) |
---|
473 | |
---|
474 | |
---|
475 | (defun x862-compile (afunc &optional lambda-form *x862-record-symbols*) |
---|
476 | (progn |
---|
477 | (dolist (a (afunc-inner-functions afunc)) |
---|
478 | (unless (afunc-lfun a) |
---|
479 | (x862-compile a |
---|
480 | (if lambda-form (afunc-lambdaform a)) |
---|
481 | *x862-record-symbols*))) ; always compile inner guys |
---|
482 | (let* ((*x862-cur-afunc* afunc) |
---|
483 | (*x862-returning-values* nil) |
---|
484 | (*x86-current-context-annotation* nil) |
---|
485 | (*x862-woi* nil) |
---|
486 | (*next-lcell-id* -1) |
---|
487 | (*x862-open-code-inline* nil) |
---|
488 | (*x862-register-restore-count* nil) |
---|
489 | (*x862-compiler-register-save-label* nil) |
---|
490 | (*x862-valid-register-annotations* 0) |
---|
491 | (*x862-register-ea-annotations* (x862-make-stack 16)) |
---|
492 | (*x862-register-restore-ea* nil) |
---|
493 | (*x862-constant-alist* nil) |
---|
494 | (*x862-double-float-constant-alist* nil) |
---|
495 | (*x862-single-float-constant-alist* nil) |
---|
496 | (*x862-vstack* 0) |
---|
497 | (*x862-cstack* 0) |
---|
498 | (*x86-lap-entry-offset* (target-arch-case |
---|
499 | (:x8632 x8632::fulltag-misc) |
---|
500 | (:x8664 x8664::fulltag-function))) |
---|
501 | (*x862-result-reg* (target-arch-case |
---|
502 | (:x8632 x8632::arg_z) |
---|
503 | (:x8664 x8664::arg_z))) |
---|
504 | (*x862-imm0* (target-arch-case (:x8632 x8632::imm0) |
---|
505 | (:x8664 x8664::imm0))) |
---|
506 | (*x862-arg-z* (target-arch-case (:x8632 x8632::arg_z) |
---|
507 | (:x8664 x8664::arg_z))) |
---|
508 | (*x862-arg-y* (target-arch-case (:x8632 x8632::arg_y) |
---|
509 | (:x8664 x8664::arg_y))) |
---|
510 | (*x862-temp0* (target-arch-case (:x8632 x8632::temp0) |
---|
511 | (:x8664 x8664::temp0))) |
---|
512 | (*x862-temp1* (target-arch-case (:x8632 x8632::temp1) |
---|
513 | (:x8664 x8664::temp1))) |
---|
514 | (*x862-fn* (target-arch-case (:x8632 x8632::fn) |
---|
515 | (:x8664 x8664::fn))) |
---|
516 | (*x862-fname* (target-arch-case (:x8632 x8632::fname) |
---|
517 | (:x8664 x8664::fname))) |
---|
518 | (*x862-ra0* (target-arch-case (:x8632 x8632::ra0) |
---|
519 | (:x8664 x8664::ra0))) |
---|
520 | (*x862-allocptr* (target-arch-case (:x8632 x8632::allocptr) |
---|
521 | (:x8664 x8664::allocptr))) |
---|
522 | (*x862-fp0* (target-arch-case (:x8632 x8632::fp0) |
---|
523 | (:x8664 x8664::fp0))) |
---|
524 | (*x862-fp1* (target-arch-case (:x8632 x8632::fp1) |
---|
525 | (:x8664 x8664::fp1))) |
---|
526 | (*x862-target-num-arg-regs* (target-arch-case |
---|
527 | (:x8632 $numx8632argregs) |
---|
528 | (:x8664 $numx8664argregs))) |
---|
529 | (*x862-target-num-save-regs* (target-arch-case |
---|
530 | (:x8632 $numx8632saveregs) |
---|
531 | (:x8664 $numx8664saveregs))) |
---|
532 | (*x862-target-lcell-size* (arch::target-lisp-node-size (backend-target-arch *target-backend*))) |
---|
533 | (*x862-target-fixnum-shift* (arch::target-fixnum-shift (backend-target-arch *target-backend*))) |
---|
534 | (*x862-target-node-shift* (arch::target-word-shift (backend-target-arch *target-backend*))) |
---|
535 | (*x862-target-bits-in-word* (arch::target-nbits-in-word (backend-target-arch *target-backend*))) |
---|
536 | (*x862-target-node-size* *x862-target-lcell-size*) |
---|
537 | (*x862-target-half-fixnum-type* `(signed-byte ,(- *x862-target-bits-in-word* |
---|
538 | (1+ *x862-target-fixnum-shift*)))) |
---|
539 | (*x862-target-dnode-size* (* 2 *x862-target-lcell-size*)) |
---|
540 | (*x862-tos-reg* nil) |
---|
541 | (*x862-all-lcells* ()) |
---|
542 | (*x862-top-vstack-lcell* nil) |
---|
543 | (*x862-bottom-vstack-lcell* (x862-new-vstack-lcell :bottom 0 0 nil)) |
---|
544 | (*x862-var-cells* nil) |
---|
545 | (*backend-vinsns* (backend-p2-vinsn-templates *target-backend*)) |
---|
546 | (*backend-node-regs* (target-arch-case |
---|
547 | (:x8632 x8632-node-regs) |
---|
548 | (:x8664 x8664-node-regs))) |
---|
549 | (*backend-node-temps* (target-arch-case |
---|
550 | (:x8632 x8632-temp-node-regs) |
---|
551 | (:x8664 x8664-temp-node-regs))) |
---|
552 | (*available-backend-node-temps* (target-arch-case |
---|
553 | (:x8632 x8632-temp-node-regs) |
---|
554 | (:x8664 x8664-temp-node-regs))) |
---|
555 | (*backend-imm-temps* (target-arch-case |
---|
556 | (:x8632 x8632-imm-regs) |
---|
557 | (:x8664 x8664-imm-regs))) |
---|
558 | (*available-backend-imm-temps* (target-arch-case |
---|
559 | (:x8632 x8632-imm-regs) |
---|
560 | (:x8664 x8664-imm-regs))) |
---|
561 | (*backend-crf-temps* (target-arch-case |
---|
562 | (:x8632 x8632-cr-fields) |
---|
563 | (:x8664 x8664-cr-fields))) |
---|
564 | (*available-backend-crf-temps* (target-arch-case |
---|
565 | (:x8632 x8632-cr-fields) |
---|
566 | (:x8664 x8664-cr-fields))) |
---|
567 | (*backend-fp-temps* (target-arch-case |
---|
568 | (:x8632 x8632-temp-fp-regs) |
---|
569 | (:x8664 x8664-temp-fp-regs))) |
---|
570 | (*available-backend-fp-temps* (target-arch-case |
---|
571 | (:x8632 x8632-temp-fp-regs) |
---|
572 | (:x8664 x8664-temp-fp-regs))) |
---|
573 | (bits 0) |
---|
574 | (*logical-register-counter* -1) |
---|
575 | (*backend-all-lregs* ()) |
---|
576 | (*x862-popj-labels* nil) |
---|
577 | (*x862-popreg-labels* nil) |
---|
578 | (*x862-valret-labels* nil) |
---|
579 | (*x862-nilret-labels* nil) |
---|
580 | (*x862-undo-count* 0) |
---|
581 | (*backend-labels* (x862-make-stack 64 target::subtag-simple-vector)) |
---|
582 | (*x862-undo-stack* (x862-make-stack 64 target::subtag-simple-vector)) |
---|
583 | (*x862-undo-because* (x862-make-stack 64)) |
---|
584 | (*x862-entry-label* nil) |
---|
585 | (*x862-tail-label* nil) |
---|
586 | (*x862-tail-vsp* nil) |
---|
587 | (*x862-tail-nargs* nil) |
---|
588 | (*x862-inhibit-register-allocation* nil) |
---|
589 | (*x862-tail-allow* t) |
---|
590 | (*x862-reckless* nil) |
---|
591 | (*x862-full-safety* nil) |
---|
592 | (*x862-trust-declarations* t) |
---|
593 | (*x862-entry-vstack* nil) |
---|
594 | (*x862-fixed-nargs* nil) |
---|
595 | (*x862-need-nargs* t) |
---|
596 | (fname (afunc-name afunc)) |
---|
597 | (*x862-entry-vsp-saved-p* nil) |
---|
598 | (*x862-vcells* (x862-ensure-binding-indices-for-vcells (afunc-vcells afunc))) |
---|
599 | (*x862-fcells* (afunc-fcells afunc)) |
---|
600 | *x862-recorded-symbols* |
---|
601 | (*x862-emitted-source-notes* '())) |
---|
602 | (set-fill-pointer |
---|
603 | *backend-labels* |
---|
604 | (set-fill-pointer |
---|
605 | *x862-undo-stack* |
---|
606 | (set-fill-pointer |
---|
607 | *x862-undo-because* |
---|
608 | 0))) |
---|
609 | (backend-get-next-label) ; start @ label 1, 0 is confused with NIL in compound cd |
---|
610 | (with-dll-node-freelist (vinsns *vinsn-freelist*) |
---|
611 | (unwind-protect |
---|
612 | (progn |
---|
613 | (setq bits (x862-form vinsns (make-wired-lreg *x862-result-reg*) $backend-return (afunc-acode afunc))) |
---|
614 | (do* ((constants *x862-constant-alist* (cdr constants))) |
---|
615 | ((null constants)) |
---|
616 | (let* ((imm (caar constants))) |
---|
617 | (when (x862-symbol-locative-p imm) |
---|
618 | (setf (caar constants) (car imm))))) |
---|
619 | (optimize-vinsns vinsns) |
---|
620 | (when (logbitp x862-debug-vinsns-bit *x862-debug-mask*) |
---|
621 | (format t "~% vinsns for ~s (after generation)" (afunc-name afunc)) |
---|
622 | (do-dll-nodes (v vinsns) (format t "~&~s" v)) |
---|
623 | (format t "~%~%")) |
---|
624 | |
---|
625 | (with-dll-node-freelist ((frag-list make-frag-list) *frag-freelist*) |
---|
626 | (with-dll-node-freelist ((uuo-frag-list make-frag-list) *frag-freelist*) |
---|
627 | (let* ((*x86-lap-labels* nil) |
---|
628 | (instruction (x86::make-x86-instruction)) |
---|
629 | (end-code-tag (gensym)) |
---|
630 | (start-tag (gensym)) |
---|
631 | (srt-tag (gensym)) |
---|
632 | debug-info) |
---|
633 | (make-x86-lap-label end-code-tag) |
---|
634 | (target-arch-case |
---|
635 | (:x8664 |
---|
636 | (x86-lap-directive frag-list :long `(ash (+ (- (:^ ,end-code-tag ) 8) |
---|
637 | *x86-lap-entry-offset*) -3)) |
---|
638 | (x86-lap-directive frag-list :byte 0) ;regsave PC |
---|
639 | (x86-lap-directive frag-list :byte 0) ;regsave ea |
---|
640 | (x86-lap-directive frag-list :byte 0)) ;regsave mask |
---|
641 | (:x8632 |
---|
642 | (make-x86-lap-label start-tag) |
---|
643 | (make-x86-lap-label srt-tag) |
---|
644 | (x86-lap-directive frag-list :short `(ash (+ (- (:^ ,end-code-tag) 4) |
---|
645 | *x86-lap-entry-offset*) -2)) |
---|
646 | (emit-x86-lap-label frag-list start-tag))) |
---|
647 | (x862-expand-vinsns vinsns frag-list instruction uuo-frag-list) |
---|
648 | (when (or *x862-double-float-constant-alist* |
---|
649 | *x862-single-float-constant-alist*) |
---|
650 | (x86-lap-directive frag-list :align 3) |
---|
651 | (dolist (double-pair *x862-double-float-constant-alist*) |
---|
652 | (destructuring-bind (dfloat . lab) double-pair |
---|
653 | (setf (vinsn-label-info lab) (emit-x86-lap-label frag-list lab)) |
---|
654 | (multiple-value-bind (high low) |
---|
655 | (x862-double-float-bits dfloat) |
---|
656 | (x86-lap-directive frag-list :long low) |
---|
657 | (x86-lap-directive frag-list :long high)))) |
---|
658 | (dolist (single-pair *x862-single-float-constant-alist*) |
---|
659 | (destructuring-bind (sfloat . lab) single-pair |
---|
660 | (setf (vinsn-label-info lab) (emit-x86-lap-label frag-list lab)) |
---|
661 | (let* ((val (single-float-bits sfloat))) |
---|
662 | (x86-lap-directive frag-list :long val))))) |
---|
663 | (target-arch-case |
---|
664 | (:x8632 |
---|
665 | (x86-lap-directive frag-list :align 2) |
---|
666 | ;; start of self reference table |
---|
667 | (x86-lap-directive frag-list :long 0) |
---|
668 | (emit-x86-lap-label frag-list srt-tag) |
---|
669 | ;; make space for self-reference offsets |
---|
670 | (do-dll-nodes (frag frag-list) |
---|
671 | (dolist (reloc (frag-relocs frag)) |
---|
672 | (when (eq (reloc-type reloc) :self) |
---|
673 | (x86-lap-directive frag-list :long 0)))) |
---|
674 | (x86-lap-directive frag-list :long x8632::function-boundary-marker)) |
---|
675 | (:x8664 |
---|
676 | (x86-lap-directive frag-list :align 3) |
---|
677 | (x86-lap-directive frag-list :quad x8664::function-boundary-marker))) |
---|
678 | |
---|
679 | (emit-x86-lap-label frag-list end-code-tag) |
---|
680 | |
---|
681 | (dolist (c (reverse *x862-constant-alist*)) |
---|
682 | (let* ((vinsn-label (cdr c))) |
---|
683 | (or (vinsn-label-info vinsn-label) |
---|
684 | (setf (vinsn-label-info vinsn-label) |
---|
685 | (find-or-create-x86-lap-label |
---|
686 | vinsn-label))) |
---|
687 | (emit-x86-lap-label frag-list vinsn-label) |
---|
688 | (target-arch-case |
---|
689 | (:x8632 |
---|
690 | (x86-lap-directive frag-list :long 0)) |
---|
691 | (:x8664 |
---|
692 | (x86-lap-directive frag-list :quad 0))))) |
---|
693 | |
---|
694 | (if (logbitp $fbitnonnullenv (the fixnum (afunc-bits afunc))) |
---|
695 | (setq bits (+ bits (ash 1 $lfbits-nonnullenv-bit)))) |
---|
696 | (when (logbitp $fbitccoverage (the fixnum (afunc-bits afunc))) |
---|
697 | (setq bits (+ bits (ash 1 $lfbits-code-coverage-bit)))) |
---|
698 | (setq debug-info (afunc-lfun-info afunc)) |
---|
699 | (when lambda-form |
---|
700 | (setq debug-info |
---|
701 | (list* 'function-lambda-expression lambda-form debug-info))) |
---|
702 | (when *x862-record-symbols* |
---|
703 | (setq debug-info |
---|
704 | (list* 'function-symbol-map *x862-recorded-symbols* debug-info))) |
---|
705 | (when (and (getf debug-info 'function-source-note) *x862-emitted-source-notes*) |
---|
706 | (setq debug-info ;; Compressed below |
---|
707 | (list* 'pc-source-map *x862-emitted-source-notes* debug-info))) |
---|
708 | (when debug-info |
---|
709 | (setq bits (logior (ash 1 $lfbits-info-bit) bits))) |
---|
710 | (unless (or fname lambda-form *x862-recorded-symbols*) |
---|
711 | (setq bits (logior (ash 1 $lfbits-noname-bit) bits))) |
---|
712 | (unless (afunc-parent afunc) |
---|
713 | (x862-fixup-fwd-refs afunc)) |
---|
714 | (setf (afunc-all-vars afunc) nil) |
---|
715 | (setf (afunc-argsword afunc) bits) |
---|
716 | (let* ((regsave-label (if (typep *x862-compiler-register-save-label* 'vinsn-note) |
---|
717 | (vinsn-label-info (vinsn-note-label *x862-compiler-register-save-label*)))) |
---|
718 | (regsave-mask (if regsave-label (x862-register-mask-byte |
---|
719 | *x862-register-restore-count*))) |
---|
720 | (regsave-addr (if regsave-label (x862-encode-register-save-ea |
---|
721 | *x862-register-restore-ea* |
---|
722 | *x862-register-restore-count*)))) |
---|
723 | (target-arch-case |
---|
724 | (:x8632 |
---|
725 | (when debug-info |
---|
726 | (x86-lap-directive frag-list :long 0)) |
---|
727 | (when fname |
---|
728 | (x86-lap-directive frag-list :long 0)) |
---|
729 | (x86-lap-directive frag-list :long 0)) |
---|
730 | (:x8664 |
---|
731 | (when debug-info |
---|
732 | (x86-lap-directive frag-list :quad 0)) |
---|
733 | (when fname |
---|
734 | (x86-lap-directive frag-list :quad 0)) |
---|
735 | (x86-lap-directive frag-list :quad 0))) |
---|
736 | |
---|
737 | (relax-frag-list frag-list) |
---|
738 | (apply-relocs frag-list) |
---|
739 | (fill-for-alignment frag-list) |
---|
740 | (target-arch-case |
---|
741 | (:x8632 |
---|
742 | (let* ((label (find-x86-lap-label srt-tag)) |
---|
743 | (srt-frag (x86-lap-label-frag label)) |
---|
744 | (srt-index (x86-lap-label-offset label))) |
---|
745 | ;; fill in self-reference offsets |
---|
746 | (do-dll-nodes (frag frag-list) |
---|
747 | (dolist (reloc (frag-relocs frag)) |
---|
748 | (when (eq (reloc-type reloc) :self) |
---|
749 | (setf (frag-ref-32 srt-frag srt-index) |
---|
750 | (+ (frag-address frag) (reloc-pos reloc))) |
---|
751 | (incf srt-index 4))))) |
---|
752 | ;;(show-frag-bytes frag-list) |
---|
753 | )) |
---|
754 | |
---|
755 | (x862-lap-process-regsave-info frag-list regsave-label regsave-mask regsave-addr) |
---|
756 | |
---|
757 | (when (getf debug-info 'pc-source-map) |
---|
758 | (setf (getf debug-info 'pc-source-map) (x862-generate-pc-source-map debug-info))) |
---|
759 | (when (getf debug-info 'function-symbol-map) |
---|
760 | (setf (getf debug-info 'function-symbol-map) (x862-digest-symbols))) |
---|
761 | (let ((source-note (getf debug-info 'function-source-note))) |
---|
762 | (when source-note |
---|
763 | (setf (getf debug-info 'function-source-note) |
---|
764 | (source-note-for-%lfun-info source-note)))) |
---|
765 | |
---|
766 | (setf (afunc-lfun afunc) |
---|
767 | #+x86-target |
---|
768 | (if (eq *host-backend* *target-backend*) |
---|
769 | (create-x86-function fname frag-list *x862-constant-alist* bits debug-info) |
---|
770 | (cross-create-x86-function fname frag-list *x862-constant-alist* bits debug-info)) |
---|
771 | #-x86-target |
---|
772 | (cross-create-x86-function fname frag-list *x862-constant-alist* bits debug-info))))))) |
---|
773 | (backend-remove-labels)))) |
---|
774 | afunc)) |
---|
775 | |
---|
776 | |
---|
777 | |
---|
778 | |
---|
779 | (defun x862-make-stack (size &optional (subtype target::subtag-s16-vector)) |
---|
780 | (make-uarray-1 subtype size t 0 nil nil nil nil t nil)) |
---|
781 | |
---|
782 | (defun x862-fixup-fwd-refs (afunc) |
---|
783 | (dolist (f (afunc-inner-functions afunc)) |
---|
784 | (x862-fixup-fwd-refs f)) |
---|
785 | (let ((fwd-refs (afunc-fwd-refs afunc))) |
---|
786 | (when fwd-refs |
---|
787 | (let* ((native-x86-functions #-x86-target nil |
---|
788 | #+x86-target (eq *target-backend* |
---|
789 | *host-backend*)) |
---|
790 | (v (if native-x86-functions |
---|
791 | (function-to-function-vector (afunc-lfun afunc)) |
---|
792 | (afunc-lfun afunc))) |
---|
793 | (vlen (uvsize v))) |
---|
794 | (declare (fixnum vlen)) |
---|
795 | (dolist (ref fwd-refs) |
---|
796 | (let* ((ref-fun (afunc-lfun ref))) |
---|
797 | (do* ((i (if native-x86-functions |
---|
798 | (%function-code-words |
---|
799 | (function-vector-to-function v)) |
---|
800 | 1) |
---|
801 | (1+ i))) |
---|
802 | ((= i vlen)) |
---|
803 | (declare (fixnum i)) |
---|
804 | (if (eq (%svref v i) ref) |
---|
805 | (setf (%svref v i) ref-fun))))))))) |
---|
806 | |
---|
807 | (defun x862-generate-pc-source-map (debug-info) |
---|
808 | (let* ((definition-source-note (getf debug-info 'function-source-note)) |
---|
809 | (emitted-source-notes (getf debug-info 'pc-source-map)) |
---|
810 | (def-start (source-note-start-pos definition-source-note)) |
---|
811 | (n (length emitted-source-notes)) |
---|
812 | (nvalid 0) |
---|
813 | (max 0) |
---|
814 | (pc-starts (make-array n)) |
---|
815 | (pc-ends (make-array n)) |
---|
816 | (text-starts (make-array n)) |
---|
817 | (text-ends (make-array n))) |
---|
818 | (declare (fixnum n nvalid) |
---|
819 | (dynamic-extent pc-starts pc-ends text-starts text-ends)) |
---|
820 | (dolist (start emitted-source-notes) |
---|
821 | (let* ((pc-start (x862-vinsn-note-label-address start t)) |
---|
822 | (pc-end (x862-vinsn-note-label-address (vinsn-note-peer start) nil)) |
---|
823 | (source-note (aref (vinsn-note-info start) 0)) |
---|
824 | (text-start (- (source-note-start-pos source-note) def-start)) |
---|
825 | (text-end (- (source-note-end-pos source-note) def-start))) |
---|
826 | (declare (fixnum pc-start pc-end text-start text-end)) |
---|
827 | (when (and (plusp pc-start) |
---|
828 | (plusp pc-end) |
---|
829 | (plusp text-start) |
---|
830 | (plusp text-end)) |
---|
831 | (if (> pc-start max) (setq max pc-start)) |
---|
832 | (if (> pc-end max) (setq max pc-end)) |
---|
833 | (if (> text-start max) (setq max text-start)) |
---|
834 | (if (> text-end max) (setq max text-end)) |
---|
835 | (setf (svref pc-starts nvalid) pc-start |
---|
836 | (svref pc-ends nvalid) pc-end |
---|
837 | (svref text-starts nvalid) text-start |
---|
838 | (svref text-ends nvalid) text-end) |
---|
839 | (incf nvalid)))) |
---|
840 | (let* ((nentries (* nvalid 4)) |
---|
841 | (vec (cond ((< max #x100) (make-array nentries :element-type '(unsigned-byte 8))) |
---|
842 | ((< max #x10000) (make-array nentries :element-type '(unsigned-byte 16))) |
---|
843 | (t (make-array nentries :element-type '(unsigned-byte 32)))))) |
---|
844 | (declare (fixnum nentries)) |
---|
845 | (do* ((i 0 (+ i 4)) |
---|
846 | (j 1 (+ j 4)) |
---|
847 | (k 2 (+ k 4)) |
---|
848 | (l 3 (+ l 4)) |
---|
849 | (idx 0 (1+ idx))) |
---|
850 | ((= i nentries) vec) |
---|
851 | (declare (fixnum i j k l idx)) |
---|
852 | (setf (aref vec i) (svref pc-starts idx) |
---|
853 | (aref vec j) (svref pc-ends idx) |
---|
854 | (aref vec k) (svref text-starts idx) |
---|
855 | (aref vec l) (svref text-ends idx)))))) |
---|
856 | |
---|
857 | (defun x862-vinsn-note-label-address (note &optional start-p sym) |
---|
858 | (- |
---|
859 | (let* ((label (vinsn-note-label note)) |
---|
860 | (lap-label (if label (vinsn-label-info label)))) |
---|
861 | (if lap-label |
---|
862 | (x86-lap-label-address lap-label) |
---|
863 | (compiler-bug "Missing or bad ~s label~@[: ~s~]" |
---|
864 | (if start-p 'start 'end) |
---|
865 | sym))) |
---|
866 | (target-arch-case |
---|
867 | (:x8632 x8632::fulltag-misc) ;xxx? |
---|
868 | (:x8664 x8664::fulltag-function)))) |
---|
869 | |
---|
870 | (defun x862-digest-symbols () |
---|
871 | (when *x862-recorded-symbols* |
---|
872 | (let* ((symlist *x862-recorded-symbols*) |
---|
873 | (len (length symlist)) |
---|
874 | (syms (make-array len)) |
---|
875 | (ptrs (make-array (%i+ (%i+ len len) len))) |
---|
876 | (i -1) |
---|
877 | (j -1)) |
---|
878 | (declare (fixnum i j)) |
---|
879 | (dolist (info symlist (progn (%rplaca symlist syms) |
---|
880 | (%rplacd symlist ptrs))) |
---|
881 | (destructuring-bind (var sym startlab endlab) info |
---|
882 | (let* ((ea (var-ea var)) |
---|
883 | (ea-val (ldb (byte 16 0) ea))) |
---|
884 | (setf (aref ptrs (incf i)) (if (memory-spec-p ea) |
---|
885 | (logior (ash ea-val 6) #o77) |
---|
886 | ea-val))) |
---|
887 | (setf (aref syms (incf j)) sym) |
---|
888 | (setf (aref ptrs (incf i)) (x862-vinsn-note-label-address startlab t sym)) |
---|
889 | (setf (aref ptrs (incf i)) (x862-vinsn-note-label-address endlab nil sym)))) |
---|
890 | *x862-recorded-symbols*))) |
---|
891 | |
---|
892 | (defun x862-decls (decls) |
---|
893 | (if (fixnump decls) |
---|
894 | (locally (declare (fixnum decls)) |
---|
895 | (setq *x862-tail-allow* (neq 0 (%ilogand2 $decl_tailcalls decls)) |
---|
896 | *x862-open-code-inline* (neq 0 (%ilogand2 $decl_opencodeinline decls)) |
---|
897 | *x862-full-safety* (neq 0 (%ilogand2 $decl_full_safety decls)) |
---|
898 | *x862-reckless* (neq 0 (%ilogand2 $decl_unsafe decls)) |
---|
899 | *x862-trust-declarations* (neq 0 (%ilogand2 $decl_trustdecls decls)))))) |
---|
900 | |
---|
901 | |
---|
902 | (defun %x862-bigger-cdr-than (x y) |
---|
903 | (declare (cons x y)) |
---|
904 | (> (the fixnum (cdr x)) (the fixnum (cdr y)))) |
---|
905 | |
---|
906 | ;;; Return an unordered list of "varsets": each var in a varset can be |
---|
907 | ;;; assigned a register and all vars in a varset can be assigned the |
---|
908 | ;;; same register (e.g., no scope conflicts.) |
---|
909 | |
---|
910 | (defun x862-partition-vars (vars) |
---|
911 | (labels ((var-weight (var) |
---|
912 | (let* ((bits (nx-var-bits var))) |
---|
913 | (declare (fixnum bits)) |
---|
914 | (if (eql 0 (logand bits (logior |
---|
915 | (ash 1 $vbitpuntable) |
---|
916 | (ash -1 $vbitspecial) |
---|
917 | (ash 1 $vbitnoreg)))) |
---|
918 | (if (eql (logior (ash 1 $vbitclosed) (ash 1 $vbitsetq)) |
---|
919 | (logand bits (logior (ash 1 $vbitclosed) (ash 1 $vbitsetq)))) |
---|
920 | 0 |
---|
921 | (%i+ (%ilogand $vrefmask bits) (%ilsr 8 (%ilogand $vsetqmask bits)))) |
---|
922 | 0))) |
---|
923 | (sum-weights (varlist) |
---|
924 | (let ((sum 0)) |
---|
925 | (dolist (v varlist sum) (incf sum (var-weight v))))) |
---|
926 | (vars-disjoint-p (v1 v2) |
---|
927 | (if (eq v1 v2) |
---|
928 | nil |
---|
929 | (if (memq v1 (var-binding-info v2)) |
---|
930 | nil |
---|
931 | (if (memq v2 (var-binding-info v1)) |
---|
932 | nil |
---|
933 | t))))) |
---|
934 | (setq vars (%sort-list-no-key |
---|
935 | ;(delete-if #'(lambda (v) (eql (var-weight v) 0)) vars) |
---|
936 | (do* ((handle (cons nil vars)) |
---|
937 | (splice handle)) |
---|
938 | ((null (cdr splice)) (cdr handle)) |
---|
939 | (declare (dynamic-extent handle) (type cons handle splice)) |
---|
940 | (if (eql 0 (var-weight (%car (cdr splice)))) |
---|
941 | (rplacd splice (%cdr (cdr splice))) |
---|
942 | (setq splice (cdr splice)))) |
---|
943 | #'(lambda (v1 v2) (%i> (var-weight v1) (var-weight v2))))) |
---|
944 | ;; This isn't optimal. It partitions all register-allocatable |
---|
945 | ;; variables into sets such that |
---|
946 | ;; 1) no variable is a member of more than one set and |
---|
947 | ;; 2) all variables in a given set are disjoint from each other |
---|
948 | ;; A set might have exactly one member. |
---|
949 | ;; If a register is allocated for any member of a set, it's |
---|
950 | ;; allocated for all members of that set. |
---|
951 | (let* ((varsets nil)) |
---|
952 | (do* ((all vars (cdr all))) |
---|
953 | ((null all)) |
---|
954 | (let* ((var (car all))) |
---|
955 | (when (dolist (already varsets t) |
---|
956 | (when (memq var (car already)) (return))) |
---|
957 | (let* ((varset (cons var nil))) |
---|
958 | (dolist (v (cdr all)) |
---|
959 | (when (dolist (already varsets t) |
---|
960 | (when (memq v (car already)) (return))) |
---|
961 | (when (dolist (d varset t) |
---|
962 | (unless (vars-disjoint-p v d) (return))) |
---|
963 | (push v varset)))) |
---|
964 | (let* ((weight (sum-weights varset))) |
---|
965 | (declare (fixnum weight)) |
---|
966 | (if (>= weight 3) |
---|
967 | (push (cons (nreverse varset) weight) varsets))))))) |
---|
968 | varsets))) |
---|
969 | |
---|
970 | ;;; Maybe globally allocate registers to symbols naming functions & variables, |
---|
971 | ;;; and to simple lexical variables. |
---|
972 | (defun x862-allocate-global-registers (fcells vcells all-vars no-regs) |
---|
973 | (if (or no-regs (target-arch-case (:x8632 t))) |
---|
974 | (progn |
---|
975 | (dolist (c fcells) (%rplacd c nil)) |
---|
976 | (dolist (c vcells) (%rplacd c nil)) |
---|
977 | (values 0 nil)) |
---|
978 | (let* ((maybe (x862-partition-vars all-vars))) |
---|
979 | (dolist (c fcells) |
---|
980 | (if (>= (the fixnum (cdr c)) 3) (push c maybe))) |
---|
981 | (dolist (c vcells) |
---|
982 | (if (>= (the fixnum (cdr c)) 3) (push c maybe))) |
---|
983 | (do* ((things (%sort-list-no-key maybe #'%x862-bigger-cdr-than) (cdr things)) |
---|
984 | (n 0 (1+ n)) |
---|
985 | (registers (target-arch-case |
---|
986 | (:x8632 (error "no nvrs on x8632")) |
---|
987 | (:x8664 |
---|
988 | (if (= (backend-lisp-context-register *target-backend*) x8664::save3) |
---|
989 | (list x8664::save0 x8664::save1 x8664::save2) |
---|
990 | (list x8664::save0 x8664::save1 x8664::save2 x8664::save3))))) |
---|
991 | (regno (pop registers) (pop registers)) |
---|
992 | (constant-alist ())) |
---|
993 | ((or (null things) (null regno)) |
---|
994 | (dolist (cell fcells) (%rplacd cell nil)) |
---|
995 | (dolist (cell vcells) (%rplacd cell nil)) |
---|
996 | (values n constant-alist)) |
---|
997 | (declare (list things) |
---|
998 | (fixnum n #|regno|#)) |
---|
999 | (let* ((thing (car things))) |
---|
1000 | (if (or (memq thing fcells) |
---|
1001 | (memq thing vcells)) |
---|
1002 | (push (cons thing regno) constant-alist) |
---|
1003 | (dolist (var (car thing)) |
---|
1004 | (nx-set-var-bits var |
---|
1005 | (%ilogior (%ilogand (%ilognot $vrefmask) (nx-var-bits var)) |
---|
1006 | regno |
---|
1007 | (%ilsl $vbitreg 1)))))))))) |
---|
1008 | |
---|
1009 | |
---|
1010 | |
---|
1011 | ;;; Vpush the last N non-volatile-registers. |
---|
1012 | (defun x862-save-nvrs (seg n) |
---|
1013 | (declare (fixnum n)) |
---|
1014 | (target-arch-case |
---|
1015 | ;; no nvrs on x8632 |
---|
1016 | (:x8664 |
---|
1017 | (when (> n 0) |
---|
1018 | (setq *x862-compiler-register-save-label* (x862-emit-note seg :regsave)) |
---|
1019 | (with-x86-local-vinsn-macros (seg) |
---|
1020 | (let* ((mask x8664-nonvolatile-node-regs)) |
---|
1021 | (dotimes (i n) |
---|
1022 | (let* ((reg (1- (integer-length mask)))) |
---|
1023 | (x862-vpush-register seg reg :regsave reg 0) |
---|
1024 | (setq mask (logandc2 mask (ash 1 reg))))))) |
---|
1025 | (setq *x862-register-restore-ea* *x862-vstack* |
---|
1026 | *x862-register-restore-count* n))))) |
---|
1027 | |
---|
1028 | |
---|
1029 | ;;; If there are an indefinite number of args/values on the vstack, |
---|
1030 | ;;; we have to restore from a register that matches the compiler's |
---|
1031 | ;;; notion of the vstack depth. This can be computed by the caller |
---|
1032 | ;;; (sum of vsp & nargs, or copy of vsp before indefinite number of |
---|
1033 | ;;; args pushed, etc.) |
---|
1034 | |
---|
1035 | |
---|
1036 | (defun x862-restore-nvrs (seg ea nregs &optional (can-pop t)) |
---|
1037 | (target-arch-case |
---|
1038 | ;; no nvrs on x8632 |
---|
1039 | (:x8664 |
---|
1040 | (when (and ea nregs) |
---|
1041 | (with-x86-local-vinsn-macros (seg) |
---|
1042 | (let* ((mask x8664-nonvolatile-node-regs) |
---|
1043 | (regs ())) |
---|
1044 | (dotimes (i nregs) |
---|
1045 | (let* ((reg (1- (integer-length mask)))) |
---|
1046 | (push reg regs) |
---|
1047 | (setq mask (logandc2 mask (ash 1 reg))))) |
---|
1048 | (cond (can-pop |
---|
1049 | (let* ((diff-in-bytes (- *x862-vstack* ea))) |
---|
1050 | (unless (zerop diff-in-bytes) |
---|
1051 | (x862-adjust-vstack diff-in-bytes) |
---|
1052 | (! vstack-discard (floor diff-in-bytes *x862-target-node-size*))) |
---|
1053 | (dolist (reg regs) |
---|
1054 | (! vpop-register reg)))) |
---|
1055 | (t |
---|
1056 | (dolist (reg regs) |
---|
1057 | (! vframe-load reg (- ea *x862-target-node-size*) ea) |
---|
1058 | (decf ea *x862-target-node-size*)))))))))) |
---|
1059 | |
---|
1060 | |
---|
1061 | (defun x862-bind-lambda (seg lcells req opt rest keys auxen optsupvloc passed-in-regs lexpr &optional inherited |
---|
1062 | &aux (vloc 0) (numopt (list-length (%car opt))) |
---|
1063 | (nkeys (list-length (%cadr keys))) |
---|
1064 | reg) |
---|
1065 | (declare (fixnum vloc)) |
---|
1066 | (x862-check-lcell-depth) |
---|
1067 | (dolist (arg inherited) |
---|
1068 | (if (memq arg passed-in-regs) |
---|
1069 | (x862-set-var-ea seg arg (var-ea arg)) |
---|
1070 | (let* ((lcell (pop lcells))) |
---|
1071 | (if (setq reg (x862-assign-register-var arg)) |
---|
1072 | (x862-init-regvar seg arg reg (x862-vloc-ea vloc)) |
---|
1073 | (x862-bind-var seg arg vloc lcell)) |
---|
1074 | (setq vloc (%i+ vloc *x862-target-node-size*))))) |
---|
1075 | (dolist (arg req) |
---|
1076 | (if (memq arg passed-in-regs) |
---|
1077 | (x862-set-var-ea seg arg (var-ea arg)) |
---|
1078 | (let* ((lcell (pop lcells))) |
---|
1079 | (if (setq reg (x862-assign-register-var arg)) |
---|
1080 | (x862-init-regvar seg arg reg (x862-vloc-ea vloc)) |
---|
1081 | (x862-bind-var seg arg vloc lcell)) |
---|
1082 | (setq vloc (%i+ vloc *x862-target-node-size*))))) |
---|
1083 | (when opt |
---|
1084 | (if (x862-hard-opt-p opt) |
---|
1085 | (setq vloc (apply #'x862-initopt seg vloc optsupvloc lcells (nthcdr (- (length lcells) numopt) lcells) opt) |
---|
1086 | lcells (nthcdr numopt lcells)) |
---|
1087 | |
---|
1088 | (dolist (var (%car opt)) |
---|
1089 | (if (memq var passed-in-regs) |
---|
1090 | (x862-set-var-ea seg var (var-ea var)) |
---|
1091 | (let* ((lcell (pop lcells))) |
---|
1092 | (if (setq reg (x862-assign-register-var var)) |
---|
1093 | (x862-init-regvar seg var reg (x862-vloc-ea vloc)) |
---|
1094 | (x862-bind-var seg var vloc lcell)) |
---|
1095 | (setq vloc (+ vloc *x862-target-node-size*))))))) |
---|
1096 | |
---|
1097 | (when rest |
---|
1098 | (if lexpr |
---|
1099 | (progn |
---|
1100 | (if (setq reg (x862-assign-register-var rest)) |
---|
1101 | (progn |
---|
1102 | (x862-copy-register seg reg *x862-arg-z*) |
---|
1103 | (x862-set-var-ea seg rest reg)) |
---|
1104 | (let* ((loc *x862-vstack*)) |
---|
1105 | (x862-vpush-register seg *x862-arg-z* :reserved) |
---|
1106 | (x862-note-top-cell rest) |
---|
1107 | (x862-bind-var seg rest loc *x862-top-vstack-lcell*)))) |
---|
1108 | (let* ((rvloc (+ vloc (* 2 *x862-target-node-size* nkeys)))) |
---|
1109 | (if (setq reg (x862-assign-register-var rest)) |
---|
1110 | (x862-init-regvar seg rest reg (x862-vloc-ea rvloc)) |
---|
1111 | (x862-bind-var seg rest rvloc (pop lcells)))))) |
---|
1112 | (when keys |
---|
1113 | (apply #'x862-init-keys seg vloc lcells keys)) |
---|
1114 | (x862-seq-bind seg (%car auxen) (%cadr auxen))) |
---|
1115 | |
---|
1116 | |
---|
1117 | (defun x862-initopt (seg vloc spvloc lcells splcells vars inits spvars) |
---|
1118 | (with-x86-local-vinsn-macros (seg) |
---|
1119 | (dolist (var vars vloc) |
---|
1120 | (let* ((initform (pop inits)) |
---|
1121 | (spvar (pop spvars)) |
---|
1122 | (lcell (pop lcells)) |
---|
1123 | (splcell (pop splcells)) |
---|
1124 | (reg (x862-assign-register-var var)) |
---|
1125 | (regloadedlabel (if reg (backend-get-next-label)))) |
---|
1126 | (unless (nx-null initform) |
---|
1127 | (let ((skipinitlabel (backend-get-next-label))) |
---|
1128 | (with-crf-target () crf |
---|
1129 | (x862-compare-ea-to-nil seg crf (x862-make-compound-cd 0 skipinitlabel) (x862-vloc-ea spvloc) x86::x86-e-bits t)) |
---|
1130 | (if reg |
---|
1131 | (x862-form seg reg regloadedlabel initform) |
---|
1132 | (x862-register-to-stack seg (x862-one-untargeted-reg-form seg initform ($ *x862-arg-z*)) (x862-vloc-ea vloc))) |
---|
1133 | (@ skipinitlabel))) |
---|
1134 | (if reg |
---|
1135 | (progn |
---|
1136 | (x862-init-regvar seg var reg (x862-vloc-ea vloc)) |
---|
1137 | (@ regloadedlabel)) |
---|
1138 | (x862-bind-var seg var vloc lcell)) |
---|
1139 | (when spvar |
---|
1140 | (if (setq reg (x862-assign-register-var spvar)) |
---|
1141 | (x862-init-regvar seg spvar reg (x862-vloc-ea spvloc)) |
---|
1142 | (x862-bind-var seg spvar spvloc splcell)))) |
---|
1143 | (setq vloc (%i+ vloc *x862-target-node-size*)) |
---|
1144 | (if spvloc (setq spvloc (%i+ spvloc *x862-target-node-size*)))))) |
---|
1145 | |
---|
1146 | (defun x862-init-keys (seg vloc lcells allow-others keyvars keysupp keyinits keykeys) |
---|
1147 | (declare (ignore keykeys allow-others)) |
---|
1148 | (with-x86-local-vinsn-macros (seg) |
---|
1149 | (dolist (var keyvars) |
---|
1150 | (let* ((spvar (pop keysupp)) |
---|
1151 | (initform (pop keyinits)) |
---|
1152 | (reg (x862-assign-register-var var)) |
---|
1153 | (regloadedlabel (if reg (backend-get-next-label))) |
---|
1154 | (var-lcell (pop lcells)) |
---|
1155 | (sp-lcell (pop lcells)) |
---|
1156 | (sploc (%i+ vloc *x862-target-node-size*))) |
---|
1157 | (unless (nx-null initform) |
---|
1158 | (let ((skipinitlabel (backend-get-next-label))) |
---|
1159 | (with-crf-target () crf |
---|
1160 | (x862-compare-ea-to-nil seg crf (x862-make-compound-cd 0 skipinitlabel) (x862-vloc-ea sploc) x86::x86-e-bits t)) |
---|
1161 | (if reg |
---|
1162 | (x862-form seg reg regloadedlabel initform) |
---|
1163 | (x862-register-to-stack seg (x862-one-untargeted-reg-form seg initform ($ *x862-arg-z*)) (x862-vloc-ea vloc))) |
---|
1164 | (@ skipinitlabel))) |
---|
1165 | (if reg |
---|
1166 | (progn |
---|
1167 | (x862-init-regvar seg var reg (x862-vloc-ea vloc)) |
---|
1168 | (@ regloadedlabel)) |
---|
1169 | (x862-bind-var seg var vloc var-lcell)) |
---|
1170 | (when spvar |
---|
1171 | (if (setq reg (x862-assign-register-var spvar)) |
---|
1172 | (x862-init-regvar seg spvar reg (x862-vloc-ea sploc)) |
---|
1173 | (x862-bind-var seg spvar sploc sp-lcell)))) |
---|
1174 | (setq vloc (%i+ vloc (* 2 *x862-target-node-size*)))))) |
---|
1175 | |
---|
1176 | ;;; Vpush register r, unless var gets a globally-assigned register. |
---|
1177 | ;;; Return NIL if register was vpushed, else var. |
---|
1178 | (defun x862-vpush-arg-register (seg reg var) |
---|
1179 | (when var |
---|
1180 | (let* ((bits (nx-var-bits var))) |
---|
1181 | (declare (fixnum bits)) |
---|
1182 | (if (logbitp $vbitreg bits) |
---|
1183 | var |
---|
1184 | (progn |
---|
1185 | (x862-vpush-register seg reg :reserved) |
---|
1186 | nil))))) |
---|
1187 | |
---|
1188 | |
---|
1189 | ;;; nargs has been validated, arguments defaulted and canonicalized. |
---|
1190 | ;;; Save caller's context, then vpush any argument registers that |
---|
1191 | ;;; didn't get global registers assigned to their variables. |
---|
1192 | ;;; Return a list of vars/nils for each argument register |
---|
1193 | ;;; (nil if vpushed, var if still in arg_reg). |
---|
1194 | (defun x862-argregs-entry (seg revargs &optional variable-args-entry) |
---|
1195 | (with-x86-local-vinsn-macros (seg) |
---|
1196 | (let* ((nargs (length revargs)) |
---|
1197 | (reg-vars ())) |
---|
1198 | (declare (type (unsigned-byte 16) nargs)) |
---|
1199 | (unless variable-args-entry |
---|
1200 | (if (<= nargs *x862-target-num-arg-regs*) ; caller didn't vpush anything |
---|
1201 | (! save-lisp-context-no-stack-args) |
---|
1202 | (let* ((offset (* (the fixnum (- nargs *x862-target-num-arg-regs*)) *x862-target-node-size*))) |
---|
1203 | (declare (fixnum offset)) |
---|
1204 | (! save-lisp-context-offset offset)))) |
---|
1205 | (target-arch-case |
---|
1206 | (:x8632 |
---|
1207 | (destructuring-bind (&optional zvar yvar &rest stack-args) revargs |
---|
1208 | (let* ((nstackargs (length stack-args))) |
---|
1209 | (x862-set-vstack (* nstackargs *x862-target-node-size*)) |
---|
1210 | (dotimes (i nstackargs) |
---|
1211 | (x862-new-vstack-lcell :reserved *x862-target-lcell-size* 0 nil)) |
---|
1212 | (if (>= nargs 2) |
---|
1213 | (push (x862-vpush-arg-register seg ($ *x862-arg-y*) yvar) reg-vars)) |
---|
1214 | (if (>= nargs 1) |
---|
1215 | (push (x862-vpush-arg-register seg ($ *x862-arg-z*) zvar) reg-vars))))) |
---|
1216 | (:x8664 |
---|
1217 | (destructuring-bind (&optional zvar yvar xvar &rest stack-args) revargs |
---|
1218 | (let* ((nstackargs (length stack-args))) |
---|
1219 | (x862-set-vstack (* nstackargs *x862-target-node-size*)) |
---|
1220 | (dotimes (i nstackargs) |
---|
1221 | (x862-new-vstack-lcell :reserved *x862-target-lcell-size* 0 nil)) |
---|
1222 | (if (>= nargs 3) |
---|
1223 | (push (x862-vpush-arg-register seg ($ x8664::arg_x) xvar) reg-vars)) |
---|
1224 | (if (>= nargs 2) |
---|
1225 | (push (x862-vpush-arg-register seg ($ *x862-arg-y*) yvar) reg-vars)) |
---|
1226 | (if (>= nargs 1) |
---|
1227 | (push (x862-vpush-arg-register seg ($ *x862-arg-z*) zvar) reg-vars)))))) |
---|
1228 | reg-vars))) |
---|
1229 | |
---|
1230 | ;;; Just required args. |
---|
1231 | ;;; Since this is just a stupid bootstrapping port, always save |
---|
1232 | ;;; lisp context. |
---|
1233 | (defun x862-req-nargs-entry (seg rev-fixed-args) |
---|
1234 | (let* ((nargs (length rev-fixed-args))) |
---|
1235 | (declare (type (unsigned-byte 16) nargs)) |
---|
1236 | (with-x86-local-vinsn-macros (seg) |
---|
1237 | (unless *x862-reckless* |
---|
1238 | (! check-exact-nargs nargs)) |
---|
1239 | (x862-argregs-entry seg rev-fixed-args)))) |
---|
1240 | |
---|
1241 | ;;; No more &optional args than register args; all &optionals default |
---|
1242 | ;;; to NIL and none have supplied-p vars. No &key/&rest. |
---|
1243 | (defun x862-simple-opt-entry (seg rev-opt-args rev-req-args) |
---|
1244 | (let* ((min (length rev-req-args)) |
---|
1245 | (nopt (length rev-opt-args)) |
---|
1246 | (max (+ min nopt))) |
---|
1247 | (declare (type (unsigned-byte 16) min nopt max)) |
---|
1248 | (with-x86-local-vinsn-macros (seg) |
---|
1249 | (unless *x862-reckless* |
---|
1250 | (if rev-req-args |
---|
1251 | (! check-min-max-nargs min max) |
---|
1252 | (! check-max-nargs max))) |
---|
1253 | (if (> min *x862-target-num-arg-regs*) |
---|
1254 | (! save-lisp-context-in-frame) |
---|
1255 | (if (<= max *x862-target-num-arg-regs*) |
---|
1256 | (! save-lisp-context-no-stack-args) |
---|
1257 | (! save-lisp-context-variable-arg-count))) |
---|
1258 | (if (= nopt 1) |
---|
1259 | (! default-1-arg min) |
---|
1260 | (if (= nopt 2) |
---|
1261 | (! default-2-args min) |
---|
1262 | (! default-3-args min))) |
---|
1263 | (x862-argregs-entry seg (append rev-opt-args rev-req-args) t)))) |
---|
1264 | |
---|
1265 | ;;; if "num-fixed" is > 0, we've already ensured that at least that many args |
---|
1266 | ;;; were provided; that may enable us to generate better code for saving the |
---|
1267 | ;;; argument registers. |
---|
1268 | ;;; We're responsible for computing the caller's VSP and saving |
---|
1269 | ;;; caller's state. |
---|
1270 | (defun x862-lexpr-entry (seg num-fixed) |
---|
1271 | (with-x86-local-vinsn-macros (seg) |
---|
1272 | (! save-lexpr-argregs num-fixed) |
---|
1273 | ;; The "lexpr" (address of saved nargs register, basically |
---|
1274 | ;; is now in arg_z |
---|
1275 | (! build-lexpr-frame) |
---|
1276 | (dotimes (i num-fixed) |
---|
1277 | (! copy-lexpr-argument (- num-fixed i))))) |
---|
1278 | |
---|
1279 | |
---|
1280 | (defun x862-structured-initopt (seg lcells vloc context vars inits spvars) |
---|
1281 | (with-x86-local-vinsn-macros (seg) |
---|
1282 | (dolist (var vars vloc) |
---|
1283 | (let* ((initform (pop inits)) |
---|
1284 | (spvar (pop spvars)) |
---|
1285 | (spvloc (%i+ vloc *x862-target-node-size*)) |
---|
1286 | (var-lcell (pop lcells)) |
---|
1287 | (sp-lcell (pop lcells))) |
---|
1288 | (unless (nx-null initform) |
---|
1289 | (let ((skipinitlabel (backend-get-next-label))) |
---|
1290 | (with-crf-target () crf |
---|
1291 | (x862-compare-ea-to-nil seg crf (x862-make-compound-cd 0 skipinitlabel) (x862-vloc-ea spvloc) x86::x86-e-bits t)) |
---|
1292 | (x862-register-to-stack seg (x862-one-untargeted-reg-form seg initform ($ *x862-arg-z*)) (x862-vloc-ea vloc)) |
---|
1293 | (@ skipinitlabel))) |
---|
1294 | (x862-bind-structured-var seg var vloc var-lcell context) |
---|
1295 | (when spvar |
---|
1296 | (x862-bind-var seg spvar spvloc sp-lcell))) |
---|
1297 | (setq vloc (%i+ vloc (* 2 *x862-target-node-size*)))))) |
---|
1298 | |
---|
1299 | |
---|
1300 | |
---|
1301 | (defun x862-structured-init-keys (seg lcells vloc context allow-others keyvars keysupp keyinits keykeys) |
---|
1302 | (declare (ignore keykeys allow-others)) |
---|
1303 | (with-x86-local-vinsn-macros (seg) |
---|
1304 | (dolist (var keyvars) |
---|
1305 | (let* ((spvar (pop keysupp)) |
---|
1306 | (initform (pop keyinits)) |
---|
1307 | (sploc (%i+ vloc *x862-target-node-size*)) |
---|
1308 | (var-lcell (pop lcells)) |
---|
1309 | (sp-reg ($ *x862-arg-z*)) |
---|
1310 | (sp-lcell (pop lcells))) |
---|
1311 | (unless (nx-null initform) |
---|
1312 | (x862-stack-to-register seg (x862-vloc-ea sploc) sp-reg) |
---|
1313 | (let ((skipinitlabel (backend-get-next-label))) |
---|
1314 | (with-crf-target () crf |
---|
1315 | (x862-compare-register-to-nil seg crf (x862-make-compound-cd 0 skipinitlabel) sp-reg x86::x86-e-bits t)) |
---|
1316 | (x862-register-to-stack seg (x862-one-untargeted-reg-form seg initform ($ *x862-arg-z*)) (x862-vloc-ea vloc)) |
---|
1317 | (@ skipinitlabel))) |
---|
1318 | (x862-bind-structured-var seg var vloc var-lcell context) |
---|
1319 | (when spvar |
---|
1320 | (x862-bind-var seg spvar sploc sp-lcell))) |
---|
1321 | (setq vloc (%i+ vloc (* 2 *x862-target-node-size*)))))) |
---|
1322 | |
---|
1323 | (defun x862-vloc-ea (n &optional vcell-p) |
---|
1324 | (setq n (make-memory-spec (dpb memspec-frame-address memspec-type-byte n))) |
---|
1325 | (if vcell-p |
---|
1326 | (make-vcell-memory-spec n) |
---|
1327 | n)) |
---|
1328 | |
---|
1329 | (defun x862-form (seg vreg xfer form &aux (note (acode-note form))) |
---|
1330 | (flet ((main (seg vreg xfer form) |
---|
1331 | (if (nx-null form) |
---|
1332 | (x862-nil seg vreg xfer) |
---|
1333 | (if (nx-t form) |
---|
1334 | (x862-t seg vreg xfer) |
---|
1335 | (let* ((op nil) |
---|
1336 | (fn nil)) |
---|
1337 | (if (and (consp form) |
---|
1338 | (setq fn (svref *x862-specials* (%ilogand #.operator-id-mask (setq op (acode-operator form)))))) |
---|
1339 | (if (and (null vreg) |
---|
1340 | (%ilogbitp operator-acode-subforms-bit op) |
---|
1341 | (%ilogbitp operator-assignment-free-bit op)) |
---|
1342 | (dolist (f (%cdr form) (x862-branch seg xfer)) |
---|
1343 | (x862-form seg nil nil f )) |
---|
1344 | (apply fn seg vreg xfer (%cdr form))) |
---|
1345 | (compiler-bug "x862-form ? ~s" form))))))) |
---|
1346 | (if note |
---|
1347 | (let* ((start (x862-emit-note seg :source-location-begin note)) |
---|
1348 | (bits (main seg vreg xfer form)) |
---|
1349 | (end (x862-emit-note seg :source-location-end))) |
---|
1350 | (setf (vinsn-note-peer start) end |
---|
1351 | (vinsn-note-peer end) start) |
---|
1352 | (push start *x862-emitted-source-notes*) |
---|
1353 | bits) |
---|
1354 | (main seg vreg xfer form)))) |
---|
1355 | |
---|
1356 | ;;; dest is a float reg - form is acode |
---|
1357 | (defun x862-form-float (seg freg xfer form) |
---|
1358 | (declare (ignore xfer)) |
---|
1359 | (when (or (nx-null form)(nx-t form))(compiler-bug "x862-form to freg ~s" form)) |
---|
1360 | (when (and (= (get-regspec-mode freg) hard-reg-class-fpr-mode-double) |
---|
1361 | (x862-form-typep form 'double-float)) |
---|
1362 | ;; kind of screwy - encoding the source type in the dest register spec |
---|
1363 | (set-node-regspec-type-modes freg hard-reg-class-fpr-type-double)) |
---|
1364 | (let* ((fn nil)) |
---|
1365 | (if (and (consp form) |
---|
1366 | (setq fn (svref *x862-specials* (%ilogand #.operator-id-mask (acode-operator form))))) |
---|
1367 | (apply fn seg freg nil (%cdr form)) |
---|
1368 | (compiler-bug "x862-form ? ~s" form)))) |
---|
1369 | |
---|
1370 | |
---|
1371 | |
---|
1372 | (defun x862-form-typep (form type) |
---|
1373 | (acode-form-typep form type *x862-trust-declarations*) |
---|
1374 | ) |
---|
1375 | |
---|
1376 | (defun x862-form-type (form) |
---|
1377 | (acode-form-type form *x862-trust-declarations*)) |
---|
1378 | |
---|
1379 | (defun x862-use-operator (op seg vreg xfer &rest forms) |
---|
1380 | (declare (dynamic-extent forms)) |
---|
1381 | (apply (svref *x862-specials* (%ilogand operator-id-mask op)) seg vreg xfer forms)) |
---|
1382 | |
---|
1383 | ;;; Returns true iff lexical variable VAR isn't setq'ed in FORM. |
---|
1384 | ;;; Punts a lot ... |
---|
1385 | (defun x862-var-not-set-by-form-p (var form) |
---|
1386 | (or (not (%ilogbitp $vbitsetq (nx-var-bits var))) |
---|
1387 | (x862-setqed-var-not-set-by-form-p var form))) |
---|
1388 | |
---|
1389 | (defun x862-setqed-var-not-set-by-form-p (var form) |
---|
1390 | (setq form (acode-unwrapped-form form)) |
---|
1391 | (or (atom form) |
---|
1392 | (x86-constant-form-p form) |
---|
1393 | (x862-lexical-reference-p form) |
---|
1394 | (let ((op (acode-operator form)) |
---|
1395 | (subforms nil)) |
---|
1396 | (if (eq op (%nx1-operator setq-lexical)) |
---|
1397 | (and (neq var (cadr form)) |
---|
1398 | (x862-setqed-var-not-set-by-form-p var (caddr form))) |
---|
1399 | (and (%ilogbitp operator-side-effect-free-bit op) |
---|
1400 | (flet ((not-set-in-formlist (formlist) |
---|
1401 | (dolist (subform formlist t) |
---|
1402 | (unless (x862-setqed-var-not-set-by-form-p var subform) (return))))) |
---|
1403 | (if |
---|
1404 | (cond ((%ilogbitp operator-acode-subforms-bit op) (setq subforms (%cdr form))) |
---|
1405 | ((%ilogbitp operator-acode-list-bit op) (setq subforms (cadr form)))) |
---|
1406 | (not-set-in-formlist subforms) |
---|
1407 | (and (or (eq op (%nx1-operator call)) |
---|
1408 | (eq op (%nx1-operator lexical-function-call))) |
---|
1409 | (x862-setqed-var-not-set-by-form-p var (cadr form)) |
---|
1410 | (setq subforms (caddr form)) |
---|
1411 | (not-set-in-formlist (car subforms)) |
---|
1412 | (not-set-in-formlist (cadr subforms)))))))))) |
---|
1413 | |
---|
1414 | (defun x862-check-fixnum-overflow (seg target &optional labelno) |
---|
1415 | (with-x86-local-vinsn-macros (seg) |
---|
1416 | (if *x862-open-code-inline* |
---|
1417 | (let* ((no-overflow (backend-get-next-label))) |
---|
1418 | (! set-bigits-and-header-for-fixnum-overflow target (aref *backend-labels* (or labelno no-overflow))) |
---|
1419 | (! %allocate-uvector target) |
---|
1420 | (! set-bigits-after-fixnum-overflow target) |
---|
1421 | (when labelno |
---|
1422 | (-> labelno)) |
---|
1423 | (@ no-overflow)) |
---|
1424 | (if labelno |
---|
1425 | (! fix-fixnum-overflow-ool-and-branch target (aref *backend-labels* labelno)) |
---|
1426 | (! fix-fixnum-overflow-ool target))))) |
---|
1427 | |
---|
1428 | (defun x862-nil (seg vreg xfer) |
---|
1429 | (with-x86-local-vinsn-macros (seg vreg xfer) |
---|
1430 | (if (eq vreg :push) |
---|
1431 | (progn |
---|
1432 | (! vpush-fixnum (target-nil-value)) |
---|
1433 | (^)) |
---|
1434 | (progn |
---|
1435 | (if (x862-for-value-p vreg) |
---|
1436 | (ensuring-node-target (target vreg) |
---|
1437 | (! load-nil target))) |
---|
1438 | (x862-branch seg (x862-cd-false xfer)))))) |
---|
1439 | |
---|
1440 | (defun x862-t (seg vreg xfer) |
---|
1441 | (with-x86-local-vinsn-macros (seg vreg xfer) |
---|
1442 | (if (eq vreg :push) |
---|
1443 | (progn |
---|
1444 | (! vpush-fixnum (target-t-value)) |
---|
1445 | (^)) |
---|
1446 | (progn |
---|
1447 | (if (x862-for-value-p vreg) |
---|
1448 | (ensuring-node-target (target vreg) |
---|
1449 | (! load-t target))) |
---|
1450 | (x862-branch seg (x862-cd-true xfer)))))) |
---|
1451 | |
---|
1452 | (defun x862-for-value-p (vreg) |
---|
1453 | (and vreg (not (backend-crf-p vreg)))) |
---|
1454 | |
---|
1455 | (defun x862-mvpass (seg form &optional xfer) |
---|
1456 | (with-x86-local-vinsn-macros (seg) |
---|
1457 | (x862-form seg ($ *x862-arg-z*) (logior (or xfer 0) $backend-mvpass-mask) form))) |
---|
1458 | |
---|
1459 | (defun x862-adjust-vstack (delta) |
---|
1460 | (x862-set-vstack (%i+ *x862-vstack* delta))) |
---|
1461 | |
---|
1462 | (defun x862-set-vstack (new) |
---|
1463 | (setq *x862-vstack* (or new 0))) |
---|
1464 | |
---|
1465 | |
---|
1466 | ;;; Emit a note at the end of the segment. |
---|
1467 | (defun x862-emit-note (seg class &rest info) |
---|
1468 | (declare (dynamic-extent info)) |
---|
1469 | (let* ((note (make-vinsn-note class info))) |
---|
1470 | (append-dll-node (vinsn-note-label note) seg) |
---|
1471 | note)) |
---|
1472 | |
---|
1473 | ;;; Emit a note immediately before the target vinsn. |
---|
1474 | (defun x86-prepend-note (vinsn class &rest info) |
---|
1475 | (declare (dynamic-extent info)) |
---|
1476 | (let* ((note (make-vinsn-note class info))) |
---|
1477 | (insert-dll-node-before (vinsn-note-label note) vinsn) |
---|
1478 | note)) |
---|
1479 | |
---|
1480 | (defun x862-close-note (seg note) |
---|
1481 | (let* ((end (close-vinsn-note note))) |
---|
1482 | (append-dll-node (vinsn-note-label end) seg) |
---|
1483 | end)) |
---|
1484 | |
---|
1485 | |
---|
1486 | |
---|
1487 | |
---|
1488 | |
---|
1489 | |
---|
1490 | (defun x862-stack-to-register (seg memspec reg) |
---|
1491 | (with-x86-local-vinsn-macros (seg) |
---|
1492 | (let* ((offset (memspec-frame-address-offset memspec))) |
---|
1493 | (if (and *x862-tos-reg* |
---|
1494 | (= offset (- *x862-vstack* *x862-target-node-size*))) |
---|
1495 | (x862-copy-register seg reg *x862-tos-reg*) |
---|
1496 | (! vframe-load reg offset *x862-vstack*))))) |
---|
1497 | |
---|
1498 | (defun x862-lcell-to-register (seg lcell reg) |
---|
1499 | (with-x86-local-vinsn-macros (seg) |
---|
1500 | (! lcell-load reg lcell (x862-vstack-mark-top)))) |
---|
1501 | |
---|
1502 | (defun x862-register-to-lcell (seg reg lcell) |
---|
1503 | (with-x86-local-vinsn-macros (seg) |
---|
1504 | (! lcell-store reg lcell (x862-vstack-mark-top)))) |
---|
1505 | |
---|
1506 | (defun x862-register-to-stack (seg reg memspec) |
---|
1507 | (with-x86-local-vinsn-macros (seg) |
---|
1508 | (! vframe-store reg (memspec-frame-address-offset memspec) *x862-vstack*))) |
---|
1509 | |
---|
1510 | |
---|
1511 | (defun x862-ea-open (ea) |
---|
1512 | (if (and ea (not (typep ea 'lreg)) (addrspec-vcell-p ea)) |
---|
1513 | (make-memory-spec (memspec-frame-address-offset ea)) |
---|
1514 | ea)) |
---|
1515 | |
---|
1516 | (defun x862-set-NARGS (seg n) |
---|
1517 | (if (> n call-arguments-limit) |
---|
1518 | (error "~s exceeded." call-arguments-limit) |
---|
1519 | (with-x86-local-vinsn-macros (seg) |
---|
1520 | (! set-nargs n)))) |
---|
1521 | |
---|
1522 | (defun x862-assign-register-var (v) |
---|
1523 | (let ((bits (nx-var-bits v))) |
---|
1524 | (when (%ilogbitp $vbitreg bits) |
---|
1525 | (%ilogand bits $vrefmask)))) |
---|
1526 | |
---|
1527 | (defun x862-single-float-bits (the-sf) |
---|
1528 | (single-float-bits the-sf)) |
---|
1529 | |
---|
1530 | (defun x862-double-float-bits (the-df) |
---|
1531 | (double-float-bits the-df)) |
---|
1532 | |
---|
1533 | (defun x862-push-immediate (seg xfer form) |
---|
1534 | (with-x86-local-vinsn-macros (seg) |
---|
1535 | (if (typep form 'character) |
---|
1536 | (! vpush-fixnum (logior (ash (char-code form) 8) |
---|
1537 | (arch::target-subtag-char (backend-target-arch *target-backend*)))) |
---|
1538 | (let* ((reg (x862-register-constant-p form))) |
---|
1539 | (if reg |
---|
1540 | (! vpush-register reg) |
---|
1541 | (let* ((lab (x86-immediate-label form))) |
---|
1542 | (! vpush-constant lab))))) |
---|
1543 | (x862-branch seg xfer))) |
---|
1544 | |
---|
1545 | |
---|
1546 | (pushnew (%nx1-operator immediate) *x862-operator-supports-push*) |
---|
1547 | (defun x862-immediate (seg vreg xfer form) |
---|
1548 | (if (eq vreg :push) |
---|
1549 | (x862-push-immediate seg xfer form) |
---|
1550 | (with-x86-local-vinsn-macros (seg vreg xfer) |
---|
1551 | (if vreg |
---|
1552 | (if (and (= (hard-regspec-class vreg) hard-reg-class-fpr) |
---|
1553 | (or (and (typep form 'double-float) (= (get-regspec-mode vreg) hard-reg-class-fpr-mode-double)) |
---|
1554 | (and (typep form 'short-float)(= (get-regspec-mode vreg) hard-reg-class-fpr-mode-single)))) |
---|
1555 | (if (zerop form) |
---|
1556 | (if (eql form 0.0d0) |
---|
1557 | (! zero-double-float-register vreg) |
---|
1558 | (! zero-single-float-register vreg)) |
---|
1559 | (if (typep form 'short-float) |
---|
1560 | (let* ((lab (x86-single-float-constant-label form))) |
---|
1561 | (! load-single-float-constant vreg lab)) |
---|
1562 | (let* ((lab (x86-double-float-constant-label form))) |
---|
1563 | (! load-double-float-constant vreg lab)))) |
---|
1564 | (target-arch-case |
---|
1565 | (:x8632 |
---|
1566 | (if (and (= (hard-regspec-class vreg) hard-reg-class-gpr) |
---|
1567 | (member (get-regspec-mode vreg) |
---|
1568 | '(hard-reg-class-gpr-mode-u32 |
---|
1569 | hard-reg-class-gpr-mode-s32 |
---|
1570 | hard-reg-class-gpr-mode-address)) |
---|
1571 | (or (typep form '(unsigned-byte 32)) |
---|
1572 | (typep form '(signed-byte 32)))) |
---|
1573 | ;; The bits fit. Get them in the register somehow. |
---|
1574 | (if (typep form '(signed-byte 32)) |
---|
1575 | (x862-lri seg vreg form) |
---|
1576 | (x862-lriu seg vreg form)) |
---|
1577 | (ensuring-node-target (target vreg) |
---|
1578 | (if (characterp form) |
---|
1579 | (! load-character-constant target (char-code form)) |
---|
1580 | (x862-store-immediate seg form target))))) |
---|
1581 | (:x8664 |
---|
1582 | (if (and (typep form '(unsigned-byte 32)) |
---|
1583 | (= (hard-regspec-class vreg) hard-reg-class-gpr) |
---|
1584 | (= (get-regspec-mode vreg) |
---|
1585 | hard-reg-class-gpr-mode-u32)) |
---|
1586 | (x862-lri seg vreg form) |
---|
1587 | (ensuring-node-target |
---|
1588 | (target vreg) |
---|
1589 | (if (characterp form) |
---|
1590 | (! load-character-constant target (char-code form)) |
---|
1591 | (x862-store-immediate seg form target))))))) |
---|
1592 | (if (and (listp form) *load-time-eval-token* (eq (car form) *load-time-eval-token*)) |
---|
1593 | (x862-store-immediate seg form ($ *x862-temp0*)))) |
---|
1594 | (^)))) |
---|
1595 | |
---|
1596 | (defun x862-register-constant-p (form) |
---|
1597 | (and (consp form) |
---|
1598 | (or (memq form *x862-vcells*) |
---|
1599 | (memq form *x862-fcells*)) |
---|
1600 | (%cdr form))) |
---|
1601 | |
---|
1602 | (defun x862-store-immediate (seg imm dest) |
---|
1603 | (with-x86-local-vinsn-macros (seg) |
---|
1604 | (let* ((reg (x862-register-constant-p imm))) |
---|
1605 | (if reg |
---|
1606 | (x862-copy-register seg dest reg) |
---|
1607 | (let* ((lab (x86-immediate-label imm))) |
---|
1608 | (! ref-constant dest lab))) |
---|
1609 | dest))) |
---|
1610 | |
---|
1611 | |
---|
1612 | ;;; Returns label iff form is (local-go <tag>) and can go without adjusting stack. |
---|
1613 | (defun x862-go-label (form) |
---|
1614 | (let ((current-stack (x862-encode-stack))) |
---|
1615 | (while (and (acode-p form) (or (eq (acode-operator form) (%nx1-operator progn)) |
---|
1616 | (eq (acode-operator form) (%nx1-operator local-tagbody)))) |
---|
1617 | (setq form (caadr form))) |
---|
1618 | (when (acode-p form) |
---|
1619 | (let ((op (acode-operator form))) |
---|
1620 | (if (and (eq op (%nx1-operator local-go)) |
---|
1621 | (x862-equal-encodings-p (%caddr (%cadr form)) current-stack)) |
---|
1622 | (%cadr (%cadr form)) |
---|
1623 | (if (and (eq op (%nx1-operator local-return-from)) |
---|
1624 | (nx-null (caddr form))) |
---|
1625 | (let ((tagdata (car (cadr form)))) |
---|
1626 | (and (x862-equal-encodings-p (cdr tagdata) current-stack) |
---|
1627 | (null (caar tagdata)) |
---|
1628 | (< 0 (cdar tagdata) $backend-mvpass) |
---|
1629 | (cdar tagdata))))))))) |
---|
1630 | |
---|
1631 | (defun x862-single-valued-form-p (form) |
---|
1632 | (setq form (acode-unwrapped-form-value form)) |
---|
1633 | (or (nx-null form) |
---|
1634 | (nx-t form) |
---|
1635 | (if (acode-p form) |
---|
1636 | (let ((op (acode-operator form))) |
---|
1637 | (or (%ilogbitp operator-single-valued-bit op) |
---|
1638 | (and (eql op (%nx1-operator values)) |
---|
1639 | (let ((values (cadr form))) |
---|
1640 | (and values (null (cdr values))))) |
---|
1641 | nil ; Learn about functions someday |
---|
1642 | ))))) |
---|
1643 | |
---|
1644 | (defun x862-box-s32 (seg node-dest s32-src) |
---|
1645 | (with-x86-local-vinsn-macros (seg) |
---|
1646 | (if (target-arch-case |
---|
1647 | (:x8632 nil) |
---|
1648 | (:x8664 t)) |
---|
1649 | (! box-fixnum node-dest s32-src) |
---|
1650 | (let* ((arg_z ($ *x862-arg-z*)) |
---|
1651 | (imm0 ($ *x862-imm0* :mode :s32))) |
---|
1652 | (x862-copy-register seg imm0 s32-src) |
---|
1653 | (! call-subprim (subprim-name->offset '.SPmakes32)) |
---|
1654 | (x862-copy-register seg node-dest arg_z))))) |
---|
1655 | |
---|
1656 | (defun x862-box-s64 (seg node-dest s64-src) |
---|
1657 | (with-x86-local-vinsn-macros (seg) |
---|
1658 | (if (target-arch-case |
---|
1659 | (:x8632 (error "bug")) |
---|
1660 | (:x8664 *x862-open-code-inline*)) |
---|
1661 | (let* ((no-overflow (backend-get-next-label))) |
---|
1662 | (! %set-z-flag-if-s64-fits-in-fixnum node-dest s64-src) |
---|
1663 | (! cbranch-true (aref *backend-labels* no-overflow) x86::x86-e-bits) |
---|
1664 | (! setup-bignum-alloc-for-s64-overflow s64-src) |
---|
1665 | (! %allocate-uvector node-dest) |
---|
1666 | (! set-bigits-after-fixnum-overflow node-dest) |
---|
1667 | (@ no-overflow)) |
---|
1668 | (let* ((arg_z ($ *x862-arg-z*)) |
---|
1669 | (imm0 (make-wired-lreg *x862-imm0* :mode (get-regspec-mode s64-src)))) |
---|
1670 | (x862-copy-register seg imm0 s64-src) |
---|
1671 | (! call-subprim (subprim-name->offset '.SPmakes64)) |
---|
1672 | (x862-copy-register seg node-dest arg_z))))) |
---|
1673 | |
---|
1674 | (defun x862-box-u32 (seg node-dest u32-src) |
---|
1675 | (with-x86-local-vinsn-macros (seg) |
---|
1676 | (target-arch-case |
---|
1677 | (:x8632 |
---|
1678 | (let* ((arg_z ($ *x862-arg-z*)) |
---|
1679 | (imm0 ($ *x862-imm0* :mode :u32))) |
---|
1680 | (x862-copy-register seg imm0 u32-src) |
---|
1681 | (! call-subprim (subprim-name->offset '.SPmakeu32)) |
---|
1682 | (x862-copy-register seg node-dest arg_z))) |
---|
1683 | (:x8664 |
---|
1684 | (! box-fixnum node-dest u32-src))))) |
---|
1685 | |
---|
1686 | (defun x862-box-u64 (seg node-dest u64-src) |
---|
1687 | (with-x86-local-vinsn-macros (seg) |
---|
1688 | (if (target-arch-case |
---|
1689 | (:x8632 (error "bug")) |
---|
1690 | (:x8664 *x862-open-code-inline*)) |
---|
1691 | (let* ((no-overflow (backend-get-next-label))) |
---|
1692 | (! %set-z-flag-if-u64-fits-in-fixnum node-dest u64-src) |
---|
1693 | (! cbranch-true (aref *backend-labels* no-overflow) x86::x86-e-bits) |
---|
1694 | (! setup-bignum-alloc-for-u64-overflow u64-src) |
---|
1695 | (! %allocate-uvector node-dest) |
---|
1696 | (! set-bigits-after-fixnum-overflow node-dest) |
---|
1697 | (@ no-overflow)) |
---|
1698 | (let* ((arg_z ($ *x862-arg-z*)) |
---|
1699 | (imm0 ($ *x862-imm0* :mode :u64))) |
---|
1700 | (x862-copy-register seg imm0 u64-src) |
---|
1701 | (! call-subprim (subprim-name->offset '.SPmakeu64)) |
---|
1702 | (x862-copy-register seg node-dest arg_z))))) |
---|
1703 | |
---|
1704 | (defun x862-single->heap (seg dest src) |
---|
1705 | (with-x86-local-vinsn-macros (seg) |
---|
1706 | (! setup-single-float-allocation) |
---|
1707 | (! %allocate-uvector dest) |
---|
1708 | (! set-single-float-value dest src))) |
---|
1709 | |
---|
1710 | (defun x862-double->heap (seg dest src) |
---|
1711 | (with-x86-local-vinsn-macros (seg) |
---|
1712 | (! setup-double-float-allocation) |
---|
1713 | (! %allocate-uvector dest) |
---|
1714 | (! set-double-float-value dest src))) |
---|
1715 | |
---|
1716 | |
---|
1717 | (defun x862-vref1 (seg vreg xfer type-keyword src unscaled-idx index-known-fixnum) |
---|
1718 | (with-x86-local-vinsn-macros (seg vreg xfer) |
---|
1719 | (when vreg |
---|
1720 | (let* ((arch (backend-target-arch *target-backend*)) |
---|
1721 | (is-node (member type-keyword (arch::target-gvector-types arch))) |
---|
1722 | (is-1-bit (member type-keyword (arch::target-1-bit-ivector-types arch))) |
---|
1723 | |
---|
1724 | (is-8-bit (member type-keyword (arch::target-8-bit-ivector-types arch))) |
---|
1725 | (is-16-bit (member type-keyword (arch::target-16-bit-ivector-types arch))) |
---|
1726 | (is-32-bit (member type-keyword (arch::target-32-bit-ivector-types arch))) |
---|
1727 | (is-64-bit (member type-keyword (arch::target-64-bit-ivector-types arch))) |
---|
1728 | (is-signed (member type-keyword '(:signed-8-bit-vector :signed-16-bit-vector :signed-32-bit-vector :signed-64-bit-vector :fixnum-vector))) |
---|
1729 | (vreg-class (and (not (eq vreg :push)) (hard-regspec-class vreg))) |
---|
1730 | (vreg-mode |
---|
1731 | (if (eql vreg-class hard-reg-class-gpr) |
---|
1732 | (get-regspec-mode vreg) |
---|
1733 | hard-reg-class-gpr-mode-invalid))) |
---|
1734 | (cond |
---|
1735 | (is-node |
---|
1736 | (if (eq vreg :push) |
---|
1737 | (if (and index-known-fixnum (<= index-known-fixnum (arch::target-max-64-bit-constant-index arch))) |
---|
1738 | (! push-misc-ref-c-node src index-known-fixnum) |
---|
1739 | (! push-misc-ref-node src unscaled-idx)) |
---|
1740 | (ensuring-node-target (target vreg) |
---|
1741 | (if (and index-known-fixnum (<= index-known-fixnum (arch::target-max-64-bit-constant-index arch))) |
---|
1742 | (! misc-ref-c-node target src index-known-fixnum) |
---|
1743 | (! misc-ref-node target src unscaled-idx))))) |
---|
1744 | (is-32-bit |
---|
1745 | (if (and index-known-fixnum (<= index-known-fixnum (arch::target-max-32-bit-constant-index arch))) |
---|
1746 | (cond ((eq type-keyword :single-float-vector) |
---|
1747 | (with-fp-target () (fp-val :single-float) |
---|
1748 | (if (and (eql vreg-class hard-reg-class-fpr) |
---|
1749 | (eql vreg-mode hard-reg-class-fpr-mode-single)) |
---|
1750 | (setq fp-val vreg)) |
---|
1751 | (! misc-ref-c-single-float fp-val src index-known-fixnum) |
---|
1752 | (if (eql vreg-class hard-reg-class-fpr) |
---|
1753 | (<- fp-val) |
---|
1754 | (ensuring-node-target (target vreg) |
---|
1755 | (target-arch-case |
---|
1756 | (:x8632 (x862-single->heap seg target fp-val)) |
---|
1757 | (:x8664 (! single->node target fp-val))))))) |
---|
1758 | (t |
---|
1759 | (with-additional-imm-reg () |
---|
1760 | (with-imm-target () temp |
---|
1761 | (if is-signed |
---|
1762 | (! misc-ref-c-s32 temp src index-known-fixnum) |
---|
1763 | (! misc-ref-c-u32 temp src index-known-fixnum)) |
---|
1764 | (ensuring-node-target (target vreg) |
---|
1765 | (if (eq type-keyword :simple-string) |
---|
1766 | (! u32->char target temp) |
---|
1767 | (target-arch-case |
---|
1768 | (:x8632 |
---|
1769 | (if is-signed |
---|
1770 | (x862-box-s32 seg target temp) |
---|
1771 | (x862-box-u32 seg target temp))) |
---|
1772 | (:x8664 |
---|
1773 | (! box-fixnum target temp))))))))) |
---|
1774 | (with-imm-target () idx-reg |
---|
1775 | (if index-known-fixnum |
---|
1776 | (x862-absolute-natural seg idx-reg nil (+ (arch::target-misc-data-offset arch) (ash index-known-fixnum 2))) |
---|
1777 | (! scale-32bit-misc-index idx-reg unscaled-idx)) |
---|
1778 | (cond ((eq type-keyword :single-float-vector) |
---|
1779 | (with-fp-target () (fp-val :single-float) |
---|
1780 | (if (and (eql vreg-class hard-reg-class-fpr) |
---|
1781 | (eql vreg-mode hard-reg-class-fpr-mode-single)) |
---|
1782 | (setq fp-val vreg)) |
---|
1783 | (! misc-ref-single-float fp-val src idx-reg) |
---|
1784 | (if (eq vreg-class hard-reg-class-fpr) |
---|
1785 | (<- fp-val) |
---|
1786 | (ensuring-node-target (target vreg) |
---|
1787 | (target-arch-case |
---|
1788 | (:x8632 (x862-single->heap seg target fp-val)) |
---|
1789 | (:x8664 (! single->node target fp-val))))))) |
---|
1790 | (t |
---|
1791 | (with-imm-target () temp |
---|
1792 | (if is-signed |
---|
1793 | (! misc-ref-s32 temp src idx-reg) |
---|
1794 | (! misc-ref-u32 temp src idx-reg)) |
---|
1795 | (ensuring-node-target (target vreg) |
---|
1796 | (if (eq type-keyword :simple-string) |
---|
1797 | (! u32->char target temp) |
---|
1798 | (target-arch-case |
---|
1799 | (:x8632 (if is-signed |
---|
1800 | (x862-box-s32 seg target temp) |
---|
1801 | (x862-box-u32 seg target temp))) |
---|
1802 | (:x8664 (! box-fixnum target temp))))))))))) |
---|
1803 | (is-8-bit |
---|
1804 | (with-imm-target () temp |
---|
1805 | (if (and index-known-fixnum (<= index-known-fixnum (arch::target-max-8-bit-constant-index arch))) |
---|
1806 | (if is-signed |
---|
1807 | (! misc-ref-c-s8 temp src index-known-fixnum) |
---|
1808 | (! misc-ref-c-u8 temp src index-known-fixnum)) |
---|
1809 | (with-additional-imm-reg () |
---|
1810 | (with-imm-target () idx-reg |
---|
1811 | (if index-known-fixnum |
---|
1812 | (x862-absolute-natural seg idx-reg nil (+ (arch::target-misc-data-offset arch) index-known-fixnum)) |
---|
1813 | (! scale-8bit-misc-index idx-reg unscaled-idx)) |
---|
1814 | (if is-signed |
---|
1815 | (! misc-ref-s8 temp src idx-reg) |
---|
1816 | (! misc-ref-u8 temp src idx-reg))))) |
---|
1817 | (if (eq type-keyword :simple-string) |
---|
1818 | (ensuring-node-target (target vreg) |
---|
1819 | (! u32->char target temp)) |
---|
1820 | (if (and (= vreg-mode hard-reg-class-gpr-mode-u8) |
---|
1821 | (eq type-keyword :unsigned-8-bit-vector)) |
---|
1822 | (x862-copy-register seg vreg temp) |
---|
1823 | (ensuring-node-target (target vreg) |
---|
1824 | (! box-fixnum target temp)))))) |
---|
1825 | (is-16-bit |
---|
1826 | (with-imm-target () temp |
---|
1827 | (ensuring-node-target (target vreg) |
---|
1828 | (if (and index-known-fixnum |
---|
1829 | (<= index-known-fixnum (arch::target-max-16-bit-constant-index arch))) |
---|
1830 | (if is-signed |
---|
1831 | (! misc-ref-c-s16 temp src index-known-fixnum) |
---|
1832 | (! misc-ref-c-u16 temp src index-known-fixnum)) |
---|
1833 | (with-imm-target () idx-reg |
---|
1834 | (if index-known-fixnum |
---|
1835 | (x862-absolute-natural seg idx-reg nil (+ (arch::target-misc-data-offset arch) (ash index-known-fixnum 1))) |
---|
1836 | (! scale-16bit-misc-index idx-reg unscaled-idx)) |
---|
1837 | (if is-signed |
---|
1838 | (! misc-ref-s16 temp src idx-reg) |
---|
1839 | (! misc-ref-u16 temp src idx-reg)))) |
---|
1840 | (! box-fixnum target temp)))) |
---|
1841 | ;; Down to the dregs. |
---|
1842 | (is-64-bit |
---|
1843 | (case type-keyword |
---|
1844 | (:double-float-vector |
---|
1845 | (with-fp-target () (fp-val :double-float) |
---|
1846 | (if (and (eql vreg-class hard-reg-class-fpr) |
---|
1847 | (eql vreg-mode hard-reg-class-fpr-mode-double)) |
---|
1848 | (setq fp-val vreg)) |
---|
1849 | (if (and index-known-fixnum (<= index-known-fixnum (arch::target-max-64-bit-constant-index arch))) |
---|
1850 | (! misc-ref-c-double-float fp-val src index-known-fixnum) |
---|
1851 | (progn |
---|
1852 | (if index-known-fixnum |
---|
1853 | (x862-absolute-natural seg unscaled-idx nil (+ (arch::target-misc-data-offset arch) (ash index-known-fixnum 3)))) |
---|
1854 | (! misc-ref-double-float fp-val src unscaled-idx))) |
---|
1855 | (if (eq vreg-class hard-reg-class-fpr) |
---|
1856 | (<- fp-val) |
---|
1857 | (ensuring-node-target (target vreg) |
---|
1858 | (x862-double->heap seg target fp-val))))) |
---|
1859 | ((:signed-64-bit-vector :fixnum-vector) |
---|
1860 | (ensuring-node-target (target vreg) |
---|
1861 | |
---|
1862 | (with-imm-target () (s64-reg :s64) |
---|
1863 | (if (and index-known-fixnum (<= index-known-fixnum (arch::target-max-64-bit-constant-index arch))) |
---|
1864 | (! misc-ref-c-s64 s64-reg src index-known-fixnum) |
---|
1865 | (progn |
---|
1866 | (if index-known-fixnum |
---|
1867 | (x862-absolute-natural seg unscaled-idx nil (+ (arch::target-misc-data-offset arch) (ash index-known-fixnum 3)))) |
---|
1868 | (! misc-ref-s64 s64-reg src unscaled-idx))) |
---|
1869 | (if (eq type-keyword :fixnum-vector) |
---|
1870 | (! box-fixnum target s64-reg) |
---|
1871 | (x862-box-s64 seg target s64-reg))))) |
---|
1872 | (t |
---|
1873 | (with-imm-target () (u64-reg :u64) |
---|
1874 | (if (eql vreg-mode hard-reg-class-gpr-mode-u64) |
---|
1875 | (setq u64-reg vreg)) |
---|
1876 | (if (and index-known-fixnum (<= index-known-fixnum (arch::target-max-64-bit-constant-index arch))) |
---|
1877 | (! misc-ref-c-u64 u64-reg src index-known-fixnum) |
---|
1878 | (progn |
---|
1879 | (if index-known-fixnum |
---|
1880 | (x862-absolute-natural seg unscaled-idx nil (+ (arch::target-misc-data-offset arch) (ash index-known-fixnum 3)))) |
---|
1881 | (! misc-ref-u64 u64-reg src unscaled-idx))) |
---|
1882 | (unless (eq u64-reg vreg) |
---|
1883 | (ensuring-node-target (target vreg) |
---|
1884 | (x862-box-u64 seg target u64-reg))))))) |
---|
1885 | (t |
---|
1886 | (unless is-1-bit |
---|
1887 | (nx-error "~& unsupported vector type: ~s" |
---|
1888 | type-keyword)) |
---|
1889 | (ensuring-node-target (target vreg) |
---|
1890 | (if (and index-known-fixnum (<= index-known-fixnum (arch::target-max-1-bit-constant-index arch))) |
---|
1891 | (! misc-ref-c-bit-fixnum target src index-known-fixnum) |
---|
1892 | (with-imm-target () bitnum |
---|
1893 | (if index-known-fixnum |
---|
1894 | (x862-lri seg bitnum index-known-fixnum) |
---|
1895 | (! scale-1bit-misc-index bitnum unscaled-idx)) |
---|
1896 | (! nref-bit-vector-fixnum target bitnum src)))))))) |
---|
1897 | (^))) |
---|
1898 | |
---|
1899 | |
---|
1900 | |
---|
1901 | ;;; safe = T means assume "vector" is miscobj, do bounds check. |
---|
1902 | ;;; safe = fixnum means check that subtag of vector = "safe" and do |
---|
1903 | ;;; bounds check. |
---|
1904 | ;;; safe = nil means crash&burn. |
---|
1905 | ;;; This mostly knows how to reference the elements of an immediate miscobj. |
---|
1906 | (defun x862-vref (seg vreg xfer type-keyword vector index safe) |
---|
1907 | (with-x86-local-vinsn-macros (seg vreg xfer) |
---|
1908 | (when *x862-full-safety* |
---|
1909 | (unless vreg (setq vreg *x862-arg-z*))) |
---|
1910 | (if (null vreg) |
---|
1911 | (progn |
---|
1912 | (x862-form seg nil nil vector) |
---|
1913 | (x862-form seg nil xfer index)) |
---|
1914 | (let* ((index-known-fixnum (acode-fixnum-form-p index)) |
---|
1915 | (unscaled-idx nil) |
---|
1916 | (src nil)) |
---|
1917 | (if (or safe (not index-known-fixnum)) |
---|
1918 | (multiple-value-setq (src unscaled-idx) |
---|
1919 | (x862-two-untargeted-reg-forms seg vector *x862-arg-y* index *x862-arg-z*)) |
---|
1920 | (setq src (x862-one-untargeted-reg-form seg vector *x862-arg-z*))) |
---|
1921 | (when safe |
---|
1922 | (if (typep safe 'fixnum) |
---|
1923 | (! trap-unless-typecode= src safe)) |
---|
1924 | (unless index-known-fixnum |
---|
1925 | (! trap-unless-fixnum unscaled-idx)) |
---|
1926 | (! check-misc-bound unscaled-idx src)) |
---|
1927 | (x862-vref1 seg vreg xfer type-keyword src unscaled-idx index-known-fixnum))))) |
---|
1928 | |
---|
1929 | |
---|
1930 | |
---|
1931 | (defun x862-aset2 (seg vreg xfer array i j new safe type-keyword dim0 dim1) |
---|
1932 | (target-arch-case |
---|
1933 | (:x8632 (error "not for x8632 yet"))) |
---|
1934 | (with-x86-local-vinsn-macros (seg target) |
---|
1935 | (let* ((i-known-fixnum (acode-fixnum-form-p i)) |
---|
1936 | (j-known-fixnum (acode-fixnum-form-p j)) |
---|
1937 | (arch (backend-target-arch *target-backend*)) |
---|
1938 | (is-node (member type-keyword (arch::target-gvector-types arch))) |
---|
1939 | (constval (x862-constant-value-ok-for-type-keyword type-keyword new)) |
---|
1940 | (needs-memoization (and is-node (x862-acode-needs-memoization new))) |
---|
1941 | (src) |
---|
1942 | (unscaled-i) |
---|
1943 | (unscaled-j) |
---|
1944 | (val-reg (x862-target-reg-for-aset vreg type-keyword)) |
---|
1945 | (constidx |
---|
1946 | (and dim0 dim1 i-known-fixnum j-known-fixnum |
---|
1947 | (>= i-known-fixnum 0) |
---|
1948 | (>= j-known-fixnum 0) |
---|
1949 | (< i-known-fixnum dim0) |
---|
1950 | (< j-known-fixnum dim1) |
---|
1951 | (+ (* i-known-fixnum dim1) j-known-fixnum)))) |
---|
1952 | (progn |
---|
1953 | (if constidx |
---|
1954 | (multiple-value-setq (src val-reg) |
---|
1955 | (x862-two-targeted-reg-forms seg array ($ *x862-temp0*) new val-reg)) |
---|
1956 | (multiple-value-setq (src unscaled-i unscaled-j val-reg) |
---|
1957 | (if needs-memoization |
---|
1958 | (progn |
---|
1959 | (x862-four-targeted-reg-forms seg |
---|
1960 | array ($ *x862-temp0*) |
---|
1961 | i ($ x8664::arg_x) |
---|
1962 | j ($ *x862-arg-y*) |
---|
1963 | new val-reg) |
---|
1964 | (values ($ *x862-temp0*) ($ x8664::arg_x) ($ *x862-arg-y*) ($ *x862-arg-z*))) |
---|
1965 | (x862-four-untargeted-reg-forms seg |
---|
1966 | array ($ *x862-temp0*) |
---|
1967 | i ($ x8664::arg_x) |
---|
1968 | j ($ *x862-arg-y*) |
---|
1969 | new val-reg)))) |
---|
1970 | (let* ((*available-backend-imm-temps* *available-backend-imm-temps*)) |
---|
1971 | (when (and (= (hard-regspec-class val-reg) hard-reg-class-gpr) |
---|
1972 | (logbitp (hard-regspec-value val-reg) |
---|
1973 | *backend-imm-temps*)) |
---|
1974 | (use-imm-temp (hard-regspec-value val-reg))) |
---|
1975 | (when safe |
---|
1976 | (when (typep safe 'fixnum) |
---|
1977 | (! trap-unless-simple-array-2 |
---|
1978 | src |
---|
1979 | (dpb safe target::arrayH.flags-cell-subtag-byte |
---|
1980 | (ash 1 $arh_simple_bit)) |
---|
1981 | (nx-error-for-simple-2d-array-type type-keyword))) |
---|
1982 | (unless i-known-fixnum |
---|
1983 | (! trap-unless-fixnum unscaled-i)) |
---|
1984 | (unless j-known-fixnum |
---|
1985 | (! trap-unless-fixnum unscaled-j))) |
---|
1986 | (with-imm-target () dim1 |
---|
1987 | (let* ((idx-reg ($ *x862-arg-y*))) |
---|
1988 | (if constidx |
---|
1989 | (if needs-memoization |
---|
1990 | (x862-lri seg *x862-arg-y* (ash constidx *x862-target-fixnum-shift*))) |
---|
1991 | (progn |
---|
1992 | (if safe |
---|
1993 | (! check-2d-bound dim1 unscaled-i unscaled-j src) |
---|
1994 | (! 2d-dim1 dim1 src)) |
---|
1995 | (! 2d-unscaled-index idx-reg dim1 unscaled-i unscaled-j))) |
---|
1996 | (let* ((v ($ x8664::arg_x))) |
---|
1997 | (! array-data-vector-ref v src) |
---|
1998 | (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))))))))) |
---|
1999 | |
---|
2000 | |
---|
2001 | (defun x862-aset3 (seg vreg xfer array i j k new safe type-keyword dim0 dim1 dim2) |
---|
2002 | (target-arch-case |
---|
2003 | (:x8632 (error "not for x8632 yet"))) |
---|
2004 | (with-x86-local-vinsn-macros (seg target) |
---|
2005 | (let* ((i-known-fixnum (acode-fixnum-form-p i)) |
---|
2006 | (j-known-fixnum (acode-fixnum-form-p j)) |
---|
2007 | (k-known-fixnum (acode-fixnum-form-p k)) |
---|
2008 | (arch (backend-target-arch *target-backend*)) |
---|
2009 | (is-node (member type-keyword (arch::target-gvector-types arch))) |
---|
2010 | (constval (x862-constant-value-ok-for-type-keyword type-keyword new)) |
---|
2011 | (needs-memoization (and is-node (x862-acode-needs-memoization new))) |
---|
2012 | (src) |
---|
2013 | (unscaled-i) |
---|
2014 | (unscaled-j) |
---|
2015 | (unscaled-k) |
---|
2016 | (val-reg (x862-target-reg-for-aset vreg type-keyword)) |
---|
2017 | (constidx |
---|
2018 | (and dim0 dim1 dim2 i-known-fixnum j-known-fixnum k-known-fixnum |
---|
2019 | (>= i-known-fixnum 0) |
---|
2020 | (>= j-known-fixnum 0) |
---|
2021 | (>= k-known-fixnum 0) |
---|
2022 | (< i-known-fixnum dim0) |
---|
2023 | (< j-known-fixnum dim1) |
---|
2024 | (< k-known-fixnum dim2) |
---|
2025 | (+ (* i-known-fixnum dim1 dim2) |
---|
2026 | (* j-known-fixnum dim2) |
---|
2027 | k-known-fixnum)))) |
---|
2028 | (progn |
---|
2029 | (if constidx |
---|
2030 | (multiple-value-setq (src val-reg) |
---|
2031 | (x862-two-targeted-reg-forms seg array ($ *x862-temp0*) new val-reg)) |
---|
2032 | (progn |
---|
2033 | (setq src ($ x8664::temp1) |
---|
2034 | unscaled-i ($ *x862-temp0*) |
---|
2035 | unscaled-j ($ x8664::arg_x) |
---|
2036 | unscaled-k ($ *x862-arg-y*)) |
---|
2037 | (x862-push-register |
---|
2038 | seg |
---|
2039 | (x862-one-untargeted-reg-form seg array ($ *x862-arg-z*))) |
---|
2040 | (x862-four-targeted-reg-forms seg |
---|
2041 | i ($ *x862-temp0*) |
---|
2042 | j ($ x8664::arg_x) |
---|
2043 | k ($ *x862-arg-y*) |
---|
2044 | new val-reg) |
---|
2045 | (x862-pop-register seg src))) |
---|
2046 | (let* ((*available-backend-imm-temps* *available-backend-imm-temps*)) |
---|
2047 | (when (and (= (hard-regspec-class val-reg) hard-reg-class-gpr) |
---|
2048 | (logbitp (hard-regspec-value val-reg) |
---|
2049 | *backend-imm-temps*)) |
---|
2050 | (use-imm-temp (hard-regspec-value val-reg))) |
---|
2051 | |
---|
2052 | (when safe |
---|
2053 | (when (typep safe 'fixnum) |
---|
2054 | (! trap-unless-simple-array-3 |
---|
2055 | src |
---|
2056 | (dpb safe target::arrayH.flags-cell-subtag-byte |
---|
2057 | (ash 1 $arh_simple_bit)) |
---|
2058 | (nx-error-for-simple-3d-array-type type-keyword))) |
---|
2059 | (unless i-known-fixnum |
---|
2060 | (! trap-unless-fixnum unscaled-i)) |
---|
2061 | (unless j-known-fixnum |
---|
2062 | (! trap-unless-fixnum unscaled-j)) |
---|
2063 | (unless k-known-fixnum |
---|
2064 | (! trap-unless-fixnum unscaled-k))) |
---|
2065 | (with-imm-target () dim1 |
---|
2066 | (with-imm-target (dim1) dim2 |
---|
2067 | (let* ((idx-reg ($ *x862-arg-y*))) |
---|
2068 | (if constidx |
---|
2069 | (when needs-memoization |
---|
2070 | (x862-lri seg idx-reg (ash constidx *x862-target-fixnum-shift*))) |
---|
2071 | (progn |
---|
2072 | (if safe |
---|
2073 | (! check-3d-bound dim1 dim2 unscaled-i unscaled-j unscaled-k src) |
---|
2074 | (! 3d-dims dim1 dim2 src)) |
---|
2075 | (! 3d-unscaled-index idx-reg dim1 dim2 unscaled-i unscaled-j unscaled-k))) |
---|
2076 | (let* ((v ($ x8664::arg_x))) |
---|
2077 | (! array-data-vector-ref v src) |
---|
2078 | (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)))))))))) |
---|
2079 | |
---|
2080 | |
---|
2081 | (defun x862-aref2 (seg vreg xfer array i j safe typekeyword &optional dim0 dim1) |
---|
2082 | (target-arch-case |
---|
2083 | (:x8632 (error "not for x8632 yet"))) |
---|
2084 | (with-x86-local-vinsn-macros (seg vreg xfer) |
---|
2085 | (let* ((i-known-fixnum (acode-fixnum-form-p i)) |
---|
2086 | (j-known-fixnum (acode-fixnum-form-p j)) |
---|
2087 | (src) |
---|
2088 | (unscaled-i) |
---|
2089 | (unscaled-j) |
---|
2090 | (constidx |
---|
2091 | (and dim0 dim1 i-known-fixnum j-known-fixnum |
---|
2092 | (>= i-known-fixnum 0) |
---|
2093 | (>= j-known-fixnum 0) |
---|
2094 | (< i-known-fixnum dim0) |
---|
2095 | (< j-known-fixnum dim1) |
---|
2096 | (+ (* i-known-fixnum dim1) j-known-fixnum)))) |
---|
2097 | (if constidx |
---|
2098 | (setq src (x862-one-targeted-reg-form seg array ($ *x862-arg-z*))) |
---|
2099 | (multiple-value-setq (src unscaled-i unscaled-j) |
---|
2100 | (x862-three-untargeted-reg-forms seg |
---|
2101 | array x8664::arg_x |
---|
2102 | i *x862-arg-y* |
---|
2103 | j *x862-arg-z*))) |
---|
2104 | (when safe |
---|
2105 | (when (typep safe 'fixnum) |
---|
2106 | (! trap-unless-simple-array-2 |
---|
2107 | src |
---|
2108 | (dpb safe target::arrayH.flags-cell-subtag-byte |
---|
2109 | (ash 1 $arh_simple_bit)) |
---|
2110 | (nx-error-for-simple-2d-array-type typekeyword))) |
---|
2111 | (unless i-known-fixnum |
---|
2112 | (! trap-unless-fixnum unscaled-i)) |
---|
2113 | (unless j-known-fixnum |
---|
2114 | (! trap-unless-fixnum unscaled-j))) |
---|
2115 | (with-node-target (src) idx-reg |
---|
2116 | (with-imm-target () dim1 |
---|
2117 | (unless constidx |
---|
2118 | (if safe |
---|
2119 | (! check-2d-bound dim1 unscaled-i unscaled-j src) |
---|
2120 | (! 2d-dim1 dim1 src)) |
---|
2121 | (! 2d-unscaled-index idx-reg dim1 unscaled-i unscaled-j)) |
---|
2122 | (with-node-target (idx-reg) v |
---|
2123 | (! array-data-vector-ref v src) |
---|
2124 | (x862-vref1 seg vreg xfer typekeyword v idx-reg constidx))))))) |
---|
2125 | |
---|
2126 | (defun x862-aref3 (seg vreg xfer array i j k safe typekeyword &optional dim0 dim1 dim2) |
---|
2127 | (target-arch-case |
---|
2128 | (:x8632 (error "not for x8632 yet"))) |
---|
2129 | (with-x86-local-vinsn-macros (seg vreg xfer) |
---|
2130 | (let* ((i-known-fixnum (acode-fixnum-form-p i)) |
---|
2131 | (j-known-fixnum (acode-fixnum-form-p j)) |
---|
2132 | (k-known-fixnum (acode-fixnum-form-p k)) |
---|
2133 | (src) |
---|
2134 | (unscaled-i) |
---|
2135 | (unscaled-j) |
---|
2136 | (unscaled-k) |
---|
2137 | (constidx |
---|
2138 | (and dim0 dim1 i-known-fixnum j-known-fixnum k-known-fixnum |
---|
2139 | (>= i-known-fixnum 0) |
---|
2140 | (>= j-known-fixnum 0) |
---|
2141 | (>= k-known-fixnum 0) |
---|
2142 | (< i-known-fixnum dim0) |
---|
2143 | (< j-known-fixnum dim1) |
---|
2144 | (< k-known-fixnum dim2) |
---|
2145 | (+ (* i-known-fixnum dim1 dim2) |
---|
2146 | (* j-known-fixnum dim2) |
---|
2147 | k-known-fixnum)))) |
---|
2148 | (if constidx |
---|
2149 | (setq src (x862-one-targeted-reg-form seg array ($ *x862-arg-z*))) |
---|
2150 | (multiple-value-setq (src unscaled-i unscaled-j unscaled-k) |
---|
2151 | (x862-four-untargeted-reg-forms seg |
---|
2152 | array *x862-temp0* |
---|
2153 | i x8664::arg_x |
---|
2154 | j *x862-arg-y* |
---|
2155 | k *x862-arg-z*))) |
---|
2156 | (when safe |
---|
2157 | (when (typep safe 'fixnum) |
---|
2158 | (! trap-unless-simple-array-3 |
---|
2159 | src |
---|
2160 | (dpb safe target::arrayH.flags-cell-subtag-byte |
---|
2161 | (ash 1 $arh_simple_bit)) |
---|
2162 | (nx-error-for-simple-3d-array-type typekeyword))) |
---|
2163 | (unless i-known-fixnum |
---|
2164 | (! trap-unless-fixnum unscaled-i)) |
---|
2165 | (unless j-known-fixnum |
---|
2166 | (! trap-unless-fixnum unscaled-j)) |
---|
2167 | (unless k-known-fixnum |
---|
2168 | (! trap-unless-fixnum unscaled-k))) |
---|
2169 | (with-node-target (src) idx-reg |
---|
2170 | (with-imm-target () dim1 |
---|
2171 | (with-imm-target (dim1) dim2 |
---|
2172 | (unless constidx |
---|
2173 | (if safe |
---|
2174 | (! check-3d-bound dim1 dim2 unscaled-i unscaled-j unscaled-k src) |
---|
2175 | (! 3d-dims dim1 dim2 src)) |
---|
2176 | (! 3d-unscaled-index idx-reg dim1 dim2 unscaled-i unscaled-j unscaled-k)))) |
---|
2177 | (with-node-target (idx-reg) v |
---|
2178 | (! array-data-vector-ref v src) |
---|
2179 | (x862-vref1 seg vreg xfer typekeyword v idx-reg constidx)))))) |
---|
2180 | |
---|
2181 | |
---|
2182 | |
---|
2183 | (defun x862-natural-vset (seg vreg xfer vector index value safe) |
---|
2184 | (with-x86-local-vinsn-macros (seg vreg xfer) |
---|
2185 | (let* ((index-known-fixnum (acode-fixnum-form-p index)) |
---|
2186 | (arch (backend-target-arch *target-backend*)) |
---|
2187 | (src nil) |
---|
2188 | (unscaled-idx nil)) |
---|
2189 | (with-imm-target () (target :natural) |
---|
2190 | (if (or safe (not index-known-fixnum)) |
---|
2191 | (multiple-value-setq (src unscaled-idx target) |
---|
2192 | (x862-three-untargeted-reg-forms seg vector *x862-arg-y* index *x862-arg-z* value (or vreg target))) |
---|
2193 | (multiple-value-setq (src target) |
---|
2194 | (x862-two-untargeted-reg-forms seg vector *x862-arg-y* value (or vreg target)))) |
---|
2195 | (when safe |
---|
2196 | (with-imm-temps (target) () ; Don't use target in type/bounds check |
---|
2197 | (if (typep safe 'fixnum) |
---|
2198 | (! trap-unless-typecode= src safe)) |
---|
2199 | (unless index-known-fixnum |
---|
2200 | (! trap-unless-fixnum unscaled-idx)) |
---|
2201 | (! check-misc-bound unscaled-idx src))) |
---|
2202 | (target-arch-case |
---|
2203 | |
---|
2204 | (:x8664 |
---|
2205 | (if (and index-known-fixnum |
---|
2206 | (<= index-known-fixnum (arch::target-max-64-bit-constant-index arch))) |
---|
2207 | (! misc-set-c-u64 target src index-known-fixnum) |
---|
2208 | (progn |
---|
2209 | (if index-known-fixnum |
---|
2210 | (x862-absolute-natural seg unscaled-idx nil (+ (arch::target-misc-data-offset arch) (ash index-known-fixnum 3)))) |
---|
2211 | (! misc-set-u64 target src unscaled-idx))))) |
---|
2212 | (<- target) ; should be a no-op in this case |
---|
2213 | (^))))) |
---|
2214 | |
---|
2215 | |
---|
2216 | (defun x862-constant-value-ok-for-type-keyword (type-keyword form) |
---|
2217 | (let* ((arch (backend-target-arch *target-backend*)) |
---|
2218 | (is-node (member type-keyword (arch::target-gvector-types arch)))) |
---|
2219 | (if is-node |
---|
2220 | (cond ((eq form *nx-nil*) |
---|
2221 | (target-nil-value)) |
---|
2222 | ((eq form *nx-t*) |
---|
2223 | (+ (target-nil-value) (arch::target-t-offset arch))) |
---|
2224 | (t |
---|
2225 | (let* ((fixval (acode-fixnum-form-p form))) |
---|
2226 | (if fixval |
---|
2227 | (ash fixval (arch::target-fixnum-shift arch)))))) |
---|
2228 | (if (and (acode-p form) |
---|
2229 | (or (eq (acode-operator form) (%nx1-operator immediate)) |
---|
2230 | (eq (acode-operator form) (%nx1-operator fixnum)))) |
---|
2231 | (let* ((val (%cadr form)) |
---|
2232 | |
---|
2233 | (typep (cond ((eq type-keyword :signed-32-bit-vector) |
---|
2234 | (typep val '(signed-byte 32))) |
---|
2235 | ((eq type-keyword :single-float-vector) |
---|
2236 | (typep val 'short-float)) |
---|
2237 | ((eq type-keyword :double-float-vector) |
---|
2238 | (typep val 'double-float)) |
---|
2239 | ((eq type-keyword :simple-string) |
---|
2240 | (typep val 'base-char)) |
---|
2241 | ((eq type-keyword :signed-8-bit-vector) |
---|
2242 | (typep val '(signed-byte 8))) |
---|
2243 | ((eq type-keyword :unsigned-8-bit-vector) |
---|
2244 | (typep val '(unsigned-byte 8))) |
---|
2245 | ((eq type-keyword :signed-16-bit-vector) |
---|
2246 | (typep val '(signed-byte 16))) |
---|
2247 | ((eq type-keyword :unsigned-16-bit-vector) |
---|
2248 | (typep val '(unsigned-byte 16))) |
---|
2249 | ((eq type-keyword :bit-vector) |
---|
2250 | (typep val 'bit))))) |
---|
2251 | (if typep val)))))) |
---|
2252 | |
---|
2253 | (defun x862-target-reg-for-aset (vreg type-keyword) |
---|
2254 | (let* ((arch (backend-target-arch *target-backend*)) |
---|
2255 | (is-node (member type-keyword (arch::target-gvector-types arch))) |
---|
2256 | (is-1-bit (member type-keyword (arch::target-1-bit-ivector-types arch))) |
---|
2257 | (is-8-bit (member type-keyword (arch::target-8-bit-ivector-types arch))) |
---|
2258 | (is-16-bit (member type-keyword (arch::target-16-bit-ivector-types arch))) |
---|
2259 | (is-32-bit (member type-keyword (arch::target-32-bit-ivector-types arch))) |
---|
2260 | (is-64-bit (member type-keyword (arch::target-64-bit-ivector-types arch))) |
---|
2261 | (is-signed (member type-keyword '(:signed-8-bit-vector :signed-16-bit-vector :signed-32-bit-vector :signed-64-bit-vector :fixnum-vector))) |
---|
2262 | (vreg-class (if (and vreg (not (eq vreg :push))) (hard-regspec-class vreg))) |
---|
2263 | (vreg-mode (if (or (eql vreg-class hard-reg-class-gpr) |
---|
2264 | (eql vreg-class hard-reg-class-fpr)) |
---|
2265 | (get-regspec-mode vreg))) |
---|
2266 | (next-imm-target (available-imm-temp *available-backend-imm-temps*)) |
---|
2267 | (next-fp-target (available-fp-temp *available-backend-fp-temps*)) |
---|
2268 | (acc (make-wired-lreg *x862-arg-z*))) |
---|
2269 | (cond ((or is-node |
---|
2270 | (eq vreg :push) |
---|
2271 | is-1-bit |
---|
2272 | (eq type-keyword :simple-string) |
---|
2273 | (eq type-keyword :fixnum-vector) |
---|
2274 | (and (eql vreg-class hard-reg-class-gpr) |
---|
2275 | (eql vreg-mode hard-reg-class-gpr-mode-node))) |
---|
2276 | acc) |
---|
2277 | ;; If there's no vreg - if we're setting for effect only, and |
---|
2278 | ;; not for value - we can target an unboxed register directly. |
---|
2279 | ;; Usually. |
---|
2280 | ((null vreg) |
---|
2281 | (cond (is-64-bit |
---|
2282 | (if (eq type-keyword :double-float-vector) |
---|
2283 | (make-unwired-lreg next-fp-target :mode hard-reg-class-fpr-mode-double) |
---|
2284 | (make-unwired-lreg next-imm-target :mode (if is-signed hard-reg-class-gpr-mode-s64 hard-reg-class-gpr-mode-u64)))) |
---|
2285 | (is-32-bit |
---|
2286 | (if (eq type-keyword :single-float-vector) |
---|
2287 | (make-unwired-lreg next-fp-target :mode hard-reg-class-fpr-mode-single) |
---|
2288 | (make-unwired-lreg next-imm-target :mode (if is-signed hard-reg-class-gpr-mode-s32 hard-reg-class-gpr-mode-u32)))) |
---|
2289 | (is-16-bit |
---|
2290 | (make-unwired-lreg next-imm-target :mode (if is-signed hard-reg-class-gpr-mode-s16 hard-reg-class-gpr-mode-u16))) |
---|
2291 | (is-8-bit |
---|
2292 | (make-unwired-lreg next-imm-target :mode (if is-signed hard-reg-class-gpr-mode-s8 hard-reg-class-gpr-mode-u8))) |
---|
2293 | (t "Bug: can't determine operand size for ~s" type-keyword))) |
---|
2294 | ;; Vreg is non-null. We might be able to use it directly. |
---|
2295 | (t |
---|
2296 | (let* ((lreg (if vreg-mode |
---|
2297 | (make-unwired-lreg (lreg-value vreg))))) |
---|
2298 | (if |
---|
2299 | (cond |
---|
2300 | (is-64-bit |
---|
2301 | (if (eq type-keyword :double-float-vector) |
---|
2302 | (and (eql vreg-class hard-reg-class-fpr) |
---|
2303 | (eql vreg-mode hard-reg-class-fpr-mode-double)) |
---|
2304 | (if is-signed |
---|
2305 | (and (eql vreg-class hard-reg-class-gpr) |
---|
2306 | (eql vreg-mode hard-reg-class-gpr-mode-s64)) |
---|
2307 | (and (eql vreg-class hard-reg-class-gpr) |
---|
2308 | (eql vreg-mode hard-reg-class-gpr-mode-u64))))) |
---|
2309 | (is-32-bit |
---|
2310 | (if (eq type-keyword :single-float-vector) |
---|
2311 | (and (eql vreg-class hard-reg-class-fpr) |
---|
2312 | (eql vreg-mode hard-reg-class-fpr-mode-single)) |
---|
2313 | (if is-signed |
---|
2314 | (and (eql vreg-class hard-reg-class-gpr) |
---|
2315 | (or (eql vreg-mode hard-reg-class-gpr-mode-s32) |
---|
2316 | (eql vreg-mode hard-reg-class-gpr-mode-s64))) |
---|
2317 | (and (eql vreg-class hard-reg-class-gpr) |
---|
2318 | (or (eql vreg-mode hard-reg-class-gpr-mode-u32) |
---|
2319 | (eql vreg-mode hard-reg-class-gpr-mode-u64) |
---|
2320 | (eql vreg-mode hard-reg-class-gpr-mode-s64)))))) |
---|
2321 | (is-16-bit |
---|
2322 | (if is-signed |
---|
2323 | (and (eql vreg-class hard-reg-class-gpr) |
---|
2324 | (or (eql vreg-mode hard-reg-class-gpr-mode-s16) |
---|
2325 | (eql vreg-mode hard-reg-class-gpr-mode-s32) |
---|
2326 | (eql vreg-mode hard-reg-class-gpr-mode-s64))) |
---|
2327 | (and (eql vreg-class hard-reg-class-gpr) |
---|
2328 | (or (eql vreg-mode hard-reg-class-gpr-mode-u16) |
---|
2329 | (eql vreg-mode hard-reg-class-gpr-mode-u32) |
---|
2330 | (eql vreg-mode hard-reg-class-gpr-mode-u64) |
---|
2331 | (eql vreg-mode hard-reg-class-gpr-mode-s32) |
---|
2332 | (eql vreg-mode hard-reg-class-gpr-mode-s64))))) |
---|
2333 | (t |
---|
2334 | (if is-signed |
---|
2335 | (and (eql vreg-class hard-reg-class-gpr) |
---|
2336 | (or (eql vreg-mode hard-reg-class-gpr-mode-s8) |
---|
2337 | (eql vreg-mode hard-reg-class-gpr-mode-s16) |
---|
2338 | (eql vreg-mode hard-reg-class-gpr-mode-s32) |
---|
2339 | (eql vreg-mode hard-reg-class-gpr-mode-s64))) |
---|
2340 | (and (eql vreg-class hard-reg-class-gpr) |
---|
2341 | (or (eql vreg-mode hard-reg-class-gpr-mode-u8) |
---|
2342 | (eql vreg-mode hard-reg-class-gpr-mode-u16) |
---|
2343 | (eql vreg-mode hard-reg-class-gpr-mode-u32) |
---|
2344 | (eql vreg-mode hard-reg-class-gpr-mode-u64) |
---|
2345 | (eql vreg-mode hard-reg-class-gpr-mode-s16) |
---|
2346 | (eql vreg-mode hard-reg-class-gpr-mode-s32) |
---|
2347 | (eql vreg-mode hard-reg-class-gpr-mode-s64)))))) |
---|
2348 | lreg |
---|
2349 | acc)))))) |
---|
2350 | |
---|
2351 | (defun x862-unboxed-reg-for-aset (seg type-keyword result-reg safe constval) |
---|
2352 | (with-x86-local-vinsn-macros (seg) |
---|
2353 | (let* ((arch (backend-target-arch *target-backend*)) |
---|
2354 | (is-node (member type-keyword (arch::target-gvector-types arch))) |
---|
2355 | (is-8-bit (member type-keyword (arch::target-8-bit-ivector-types arch))) |
---|
2356 | (is-16-bit (member type-keyword (arch::target-16-bit-ivector-types arch))) |
---|
2357 | (is-32-bit (member type-keyword (arch::target-32-bit-ivector-types arch))) |
---|
2358 | (is-64-bit (member type-keyword (arch::target-64-bit-ivector-types arch))) |
---|
2359 | (is-signed (member type-keyword '(:signed-8-bit-vector :signed-16-bit-vector :signed-32-bit-vector :signed-64-bit-vector :fixnum-vector))) |
---|
2360 | (result-is-node-gpr (and (eql (hard-regspec-class result-reg) |
---|
2361 | hard-reg-class-gpr) |
---|
2362 | (eql (get-regspec-mode result-reg) |
---|
2363 | hard-reg-class-gpr-mode-node))) |
---|
2364 | (next-imm-target (available-imm-temp *available-backend-imm-temps*)) |
---|
2365 | (next-fp-target (available-fp-temp *available-backend-fp-temps*))) |
---|
2366 | (if (or is-node (not result-is-node-gpr)) |
---|
2367 | result-reg |
---|
2368 | (cond (is-64-bit |
---|
2369 | (if (eq type-keyword :double-float-vector) |
---|
2370 | (let* ((reg (make-unwired-lreg next-fp-target :mode hard-reg-class-fpr-mode-double))) |
---|
2371 | (if safe |
---|
2372 | (! get-double? reg result-reg) |
---|
2373 | (! get-double reg result-reg)) |
---|
2374 | reg) |
---|
2375 | (if is-signed |
---|
2376 | (let* ((reg (make-unwired-lreg next-imm-target :mode hard-reg-class-gpr-mode-s64))) |
---|
2377 | (if (eq type-keyword :fixnum-vector) |
---|
2378 | (progn |
---|
2379 | (when safe |
---|
2380 | (! trap-unless-fixnum result-reg)) |
---|
2381 | (! fixnum->signed-natural reg result-reg)) |
---|
2382 | (! unbox-s64 reg result-reg)) |
---|
2383 | reg) |
---|
2384 | (let* ((reg (make-unwired-lreg next-imm-target :mode hard-reg-class-gpr-mode-u64))) |
---|
2385 | (! unbox-u64 reg result-reg) |
---|
2386 | reg)))) |
---|
2387 | (is-32-bit |
---|
2388 | ;; Generally better to use a GPR for the :SINGLE-FLOAT-VECTOR |
---|
2389 | ;; case here. |
---|
2390 | (if is-signed |
---|
2391 | (let* ((reg (make-unwired-lreg next-imm-target :mode hard-reg-class-gpr-mode-s32))) |
---|
2392 | (if (eq type-keyword :fixnum-vector) |
---|
2393 | (progn |
---|
2394 | (when safe |
---|
2395 | (! trap-unless-fixnum result-reg)) |
---|
2396 | (! fixnum->signed-natural reg result-reg)) |
---|
2397 | (! unbox-s32 reg result-reg)) |
---|
2398 | reg) |
---|
2399 | (let* ((reg (make-unwired-lreg next-imm-target :mode hard-reg-class-gpr-mode-u32))) |
---|
2400 | (cond ((eq type-keyword :simple-string) |
---|
2401 | (if (characterp constval) |
---|
2402 | (x862-lri seg reg (char-code constval)) |
---|
2403 | (! unbox-base-char reg result-reg))) |
---|
2404 | ((eq type-keyword :single-float-vector) |
---|
2405 | (if (typep constval 'single-float) |
---|
2406 | (x862-lri seg reg (single-float-bits constval)) |
---|
2407 | (progn |
---|
2408 | (when safe |
---|
2409 | (! trap-unless-single-float result-reg)) |
---|
2410 | (! single-float-bits reg result-reg)))) |
---|
2411 | (t |
---|
2412 | (if (typep constval '(unsigned-byte 32)) |
---|
2413 | (x862-lri seg reg constval) |
---|
2414 | (if *x862-reckless* |
---|
2415 | (target-arch-case |
---|
2416 | (:x8632 (! unbox-u32 reg result-reg)) |
---|
2417 | (:x8664 (! %unbox-u32 reg result-reg))) |
---|
2418 | (! unbox-u32 reg result-reg))))) |
---|
2419 | reg))) |
---|
2420 | (is-16-bit |
---|
2421 | (if is-signed |
---|
2422 | (let* ((reg (make-unwired-lreg next-imm-target :mode hard-reg-class-gpr-mode-s16))) |
---|
2423 | (if (typep constval '(signed-byte 16)) |
---|
2424 | (x862-lri seg reg constval) |
---|
2425 | (if *x862-reckless* |
---|
2426 | (! %unbox-s16 reg result-reg) |
---|
2427 | (! unbox-s16 reg result-reg))) |
---|
2428 | reg) |
---|
2429 | (let* ((reg (make-unwired-lreg next-imm-target :mode hard-reg-class-gpr-mode-u16))) |
---|
2430 | (if (typep constval '(unsigned-byte 16)) |
---|
2431 | (x862-lri seg reg constval) |
---|
2432 | (if *x862-reckless* |
---|
2433 | (! %unbox-u16 reg result-reg) |
---|
2434 | (! unbox-u16 reg result-reg))) |
---|
2435 | reg))) |
---|
2436 | (is-8-bit |
---|
2437 | (if is-signed |
---|
2438 | (let* ((reg (make-unwired-lreg next-imm-target :mode hard-reg-class-gpr-mode-s8))) |
---|
2439 | (if (typep constval '(signed-byte 8)) |
---|
2440 | (x862-lri seg reg constval) |
---|
2441 | (if *x862-reckless* |
---|
2442 | (! %unbox-s8 reg result-reg) |
---|
2443 | (! unbox-s8 reg result-reg))) |
---|
2444 | reg) |
---|
2445 | (let* ((reg (make-unwired-lreg next-imm-target :mode hard-reg-class-gpr-mode-u8))) |
---|
2446 | (if (typep constval '(unsigned-byte 8)) |
---|
2447 | (x862-lri seg reg constval) |
---|
2448 | (if *x862-reckless* |
---|
2449 | (! %unbox-u8 reg result-reg) |
---|
2450 | (! unbox-u8 reg result-reg))) |
---|
2451 | reg))) |
---|
2452 | (t |
---|
2453 | (let* ((reg result-reg)) |
---|
2454 | (unless (typep constval 'bit) |
---|
2455 | (when safe |
---|
2456 | (! trap-unless-bit reg ))) |
---|
2457 | reg))))))) |
---|
2458 | |
---|
2459 | |
---|
2460 | ;;; xxx |
---|
2461 | (defun x862-vset1 (seg vreg xfer type-keyword src unscaled-idx index-known-fixnum val-reg unboxed-val-reg constval node-value-needs-memoization) |
---|
2462 | (with-x86-local-vinsn-macros (seg vreg xfer) |
---|
2463 | (let* ((arch (backend-target-arch *target-backend*)) |
---|
2464 | (is-node (member type-keyword (arch::target-gvector-types arch))) |
---|
2465 | (is-1-bit (member type-keyword (arch::target-1-bit-ivector-types arch))) |
---|
2466 | (is-8-bit (member type-keyword (arch::target-8-bit-ivector-types arch))) |
---|
2467 | (is-16-bit (member type-keyword (arch::target-16-bit-ivector-types arch))) |
---|
2468 | (is-32-bit (member type-keyword (arch::target-32-bit-ivector-types arch))) |
---|
2469 | (is-64-bit (member type-keyword (arch::target-64-bit-ivector-types arch))) |
---|
2470 | (is-signed (member type-keyword '(:signed-8-bit-vector :signed-16-bit-vector :signed-32-bit-vector :signed-64-bit-vector :fixnum-vector)))) |
---|
2471 | (cond ((and is-node node-value-needs-memoization) |
---|
2472 | (unless (and (eql (hard-regspec-value src) (target-arch-case |
---|
2473 | (:x8632 x8632::temp0) |
---|
2474 | (:x8664 x8664::arg_x))) |
---|
2475 | (eql (hard-regspec-value unscaled-idx) *x862-arg-y*) |
---|
2476 | (eql (hard-regspec-value val-reg) *x862-arg-z*)) |
---|
2477 | (compiler-bug "Bug: invalid register targeting for gvset: ~s" (list src unscaled-idx val-reg))) |
---|
2478 | (! call-subprim-3 val-reg (subprim-name->offset '.SPgvset) src unscaled-idx val-reg)) |
---|
2479 | (is-node |
---|
2480 | (if (and index-known-fixnum (<= index-known-fixnum |
---|
2481 | (target-word-size-case |
---|
2482 | (32 (arch::target-max-32-bit-constant-index arch)) |
---|
2483 | (64 (arch::target-max-64-bit-constant-index arch))))) |
---|
2484 | (if (typep constval '(signed-byte 32)) |
---|
2485 | (! misc-set-immediate-c-node constval src index-known-fixnum) |
---|
2486 | (! misc-set-c-node val-reg src index-known-fixnum)) |
---|
2487 | (progn |
---|
2488 | (if index-known-fixnum |
---|
2489 | (x862-absolute-natural seg unscaled-idx nil (+ (arch::target-misc-data-offset arch) (ash index-known-fixnum *x862-target-node-shift*)))) |
---|
2490 | (if (typep constval '(signed-byte 32)) |
---|
2491 | (! misc-set-immediate-node constval src unscaled-idx) |
---|
2492 | (! misc-set-node val-reg src unscaled-idx))))) |
---|
2493 | (t |
---|
2494 | (with-additional-imm-reg (src unscaled-idx val-reg) |
---|
2495 | (with-imm-target (unboxed-val-reg) scaled-idx |
---|
2496 | (cond |
---|
2497 | (is-64-bit |
---|
2498 | (if (and index-known-fixnum |
---|
2499 | (<= index-known-fixnum |
---|
2500 | (arch::target-max-64-bit-constant-index arch))) |
---|
2501 | (if (eq type-keyword :double-float-vector) |
---|
2502 | (! misc-set-c-double-float unboxed-val-reg src index-known-fixnum) |
---|
2503 | (if is-signed |
---|
2504 | (! misc-set-c-s64 unboxed-val-reg src index-known-fixnum) |
---|
2505 | (! misc-set-c-u64 unboxed-val-reg src index-known-fixnum))) |
---|
2506 | (progn |
---|
2507 | (if index-known-fixnum |
---|
2508 | (x862-absolute-natural seg unscaled-idx nil (+ (arch::target-misc-dfloat-offset arch) (ash index-known-fixnum 3)))) |
---|
2509 | (if (eq type-keyword :double-float-vector) |
---|
2510 | (! misc-set-double-float unboxed-val-reg src unscaled-idx) |
---|
2511 | (if is-signed |
---|
2512 | (! misc-set-s64 unboxed-val-reg src unscaled-idx) |
---|
2513 | (! misc-set-u64 unboxed-val-reg src unscaled-idx)))))) |
---|
2514 | (is-32-bit |
---|
2515 | (if (and index-known-fixnum |
---|
2516 | (<= index-known-fixnum |
---|
2517 | (arch::target-max-32-bit-constant-index arch))) |
---|
2518 | (if (eq type-keyword :single-float-vector) |
---|
2519 | (if (eq (hard-regspec-class unboxed-val-reg) |
---|
2520 | hard-reg-class-fpr) |
---|
2521 | (! misc-set-c-single-float unboxed-val-reg src index-known-fixnum) |
---|
2522 | (! misc-set-c-u32 unboxed-val-reg src index-known-fixnum)) |
---|
2523 | (if is-signed |
---|
2524 | (! misc-set-c-s32 unboxed-val-reg src index-known-fixnum) |
---|
2525 | (! misc-set-c-u32 unboxed-val-reg src index-known-fixnum))) |
---|
2526 | (progn |
---|
2527 | (if index-known-fixnum |
---|
2528 | (x862-absolute-natural seg scaled-idx nil (+ (arch::target-misc-data-offset arch) (ash index-known-fixnum 2))) |
---|
2529 | (! scale-32bit-misc-index scaled-idx unscaled-idx)) |
---|
2530 | (if (and (eq type-keyword :single-float-vector) |
---|
2531 | (eql (hard-regspec-class unboxed-val-reg) |
---|
2532 | hard-reg-class-fpr)) |
---|
2533 | (! misc-set-single-float unboxed-val-reg src scaled-idx) |
---|
2534 | (if is-signed |
---|
2535 | (! misc-set-s32 unboxed-val-reg src scaled-idx) |
---|
2536 | (! misc-set-u32 unboxed-val-reg src scaled-idx)))))) |
---|
2537 | (is-16-bit |
---|
2538 | (if (and index-known-fixnum |
---|
2539 | (<= index-known-fixnum |
---|
2540 | (arch::target-max-16-bit-constant-index arch))) |
---|
2541 | (if is-signed |
---|
2542 | (! misc-set-c-s16 unboxed-val-reg src index-known-fixnum) |
---|
2543 | (! misc-set-c-u16 unboxed-val-reg src index-known-fixnum)) |
---|
2544 | (progn |
---|
2545 | (if index-known-fixnum |
---|
2546 | (x862-absolute-natural seg scaled-idx nil (+ (arch::target-misc-data-offset arch) (ash index-known-fixnum 1))) |
---|
2547 | (! scale-16bit-misc-index scaled-idx unscaled-idx)) |
---|
2548 | (if is-signed |
---|
2549 | (! misc-set-s16 unboxed-val-reg src scaled-idx) |
---|
2550 | (! misc-set-u16 unboxed-val-reg src scaled-idx))))) |
---|
2551 | (is-8-bit |
---|
2552 | (if (and index-known-fixnum |
---|
2553 | (<= index-known-fixnum |
---|
2554 | (arch::target-max-8-bit-constant-index arch))) |
---|
2555 | (if is-signed |
---|
2556 | (! misc-set-c-s8 unboxed-val-reg src index-known-fixnum) |
---|
2557 | (! misc-set-c-u8 unboxed-val-reg src index-known-fixnum)) |
---|
2558 | (progn |
---|
2559 | (if index-known-fixnum |
---|
2560 | (x862-absolute-natural seg scaled-idx nil (+ (arch::target-misc-data-offset arch) index-known-fixnum)) |
---|
2561 | (! scale-8bit-misc-index scaled-idx unscaled-idx)) |
---|
2562 | (if is-signed |
---|
2563 | (! misc-set-s8 unboxed-val-reg src scaled-idx) |
---|
2564 | (! misc-set-u8 unboxed-val-reg src scaled-idx))))) |
---|
2565 | (is-1-bit |
---|
2566 | (if (and index-known-fixnum (<= index-known-fixnum (arch::target-max-1-bit-constant-index arch))) |
---|
2567 | (if constval |
---|
2568 | (if (zerop constval) |
---|
2569 | (! set-constant-bit-to-zero src index-known-fixnum) |
---|
2570 | (! set-constant-bit-to-one src index-known-fixnum)) |
---|
2571 | (progn |
---|
2572 | (! set-constant-bit-to-variable-value src index-known-fixnum val-reg))) |
---|
2573 | (progn |
---|
2574 | (if index-known-fixnum |
---|
2575 | (x862-lri seg scaled-idx index-known-fixnum) |
---|
2576 | (! scale-1bit-misc-index scaled-idx unscaled-idx)) |
---|
2577 | (if constval |
---|
2578 | (if (zerop constval) |
---|
2579 | (! nset-variable-bit-to-zero src scaled-idx) |
---|
2580 | (! nset-variable-bit-to-one src scaled-idx)) |
---|
2581 | (progn |
---|
2582 | (! nset-variable-bit-to-variable-value src scaled-idx val-reg))))))))))) |
---|
2583 | (when (and vreg val-reg) (<- val-reg)) |
---|
2584 | (^)))) |
---|
2585 | |
---|
2586 | |
---|
2587 | (defun x862-code-coverage-entry (seg note) |
---|
2588 | (let* ((afunc *x862-cur-afunc*)) |
---|
2589 | (setf (afunc-bits afunc) (%ilogior (afunc-bits afunc) (ash 1 $fbitccoverage))) |
---|
2590 | (with-x86-local-vinsn-macros (seg) |
---|
2591 | (let* ((ccreg ($ x8664::arg_x))) |
---|
2592 | (! vpush-register ccreg) |
---|
2593 | (! ref-constant ccreg (x86-immediate-label note)) |
---|
2594 | (! misc-set-immediate-c-node 0 ccreg 1) |
---|
2595 | (! vpop-register ccreg))))) |
---|
2596 | |
---|
2597 | (defx862 x862-with-code-note with-code-note (seg vreg xfer note form &aux val) |
---|
2598 | (when *record-pc-mapping* |
---|
2599 | (append-dll-node (setf (code-note-start-pc note) (make-vinsn-label nil)) seg)) |
---|
2600 | (when *compile-code-coverage* |
---|
2601 | (with-x86-local-vinsn-macros (seg) |
---|
2602 | (x862-store-immediate seg note *x862-temp0*) |
---|
2603 | (! misc-set-immediate-c-node 0 *x862-temp0* 1))) |
---|
2604 | (setq val (x862-form seg vreg xfer form)) |
---|
2605 | (when *record-pc-mapping* |
---|
2606 | (append-dll-node (setf (code-note-end-pc note) (make-vinsn-label nil)) seg)) |
---|
2607 | val) |
---|
2608 | |
---|
2609 | (defun x862-with-dynamic-extent-code-note (seg curstack note form &aux val) |
---|
2610 | ;; This assumes x862-dynamic-extent-form will actually generate code. The caller |
---|
2611 | ;; must check for that. |
---|
2612 | (when *record-pc-mapping* |
---|
2613 | (append-dll-node (setf (code-note-start-pc note) (make-vinsn-label nil)) seg)) |
---|
2614 | (when *compile-code-coverage* |
---|
2615 | (with-x86-local-vinsn-macros (seg) |
---|
2616 | (x862-store-immediate seg note *x862-temp0*) |
---|
2617 | (! misc-set-immediate-c-node 0 *x862-temp0* 1))) |
---|
2618 | (setq val (x862-dynamic-extent-form seg curstack form)) |
---|
2619 | #+debug 0 (assert (not (eq val form))) |
---|
2620 | (when *record-pc-mapping* |
---|
2621 | (append-dll-node (setf (code-note-end-pc note) (make-vinsn-label nil)) seg)) |
---|
2622 | val) |
---|
2623 | |
---|
2624 | |
---|
2625 | (defun x862-vset (seg vreg xfer type-keyword vector index value safe) |
---|
2626 | (with-x86-local-vinsn-macros (seg) |
---|
2627 | (let* ((arch (backend-target-arch *target-backend*)) |
---|
2628 | (is-node (member type-keyword (arch::target-gvector-types arch))) |
---|
2629 | (constval (x862-constant-value-ok-for-type-keyword type-keyword value)) |
---|
2630 | (needs-memoization (and is-node (x862-acode-needs-memoization value))) |
---|
2631 | (index-known-fixnum (acode-fixnum-form-p index))) |
---|
2632 | (let* ((src (target-arch-case |
---|
2633 | (:x8632 ($ x8632::temp0)) |
---|
2634 | (:x8664 ($ x8664::arg_x)))) |
---|
2635 | (unscaled-idx ($ *x862-arg-y*)) |
---|
2636 | (result-reg ($ *x862-arg-z*))) |
---|
2637 | (cond (needs-memoization |
---|
2638 | (x862-three-targeted-reg-forms seg |
---|
2639 | vector src |
---|
2640 | index unscaled-idx |
---|
2641 | value result-reg)) |
---|
2642 | (t |
---|
2643 | (setq result-reg (x862-target-reg-for-aset vreg type-keyword)) |
---|
2644 | (target-arch-case |
---|
2645 | (:x8632 |
---|
2646 | (with-node-temps (src) () |
---|
2647 | (x862-three-targeted-reg-forms seg |
---|
2648 | vector src |
---|
2649 | index unscaled-idx |
---|
2650 | value result-reg))) |
---|
2651 | (:x8664 |
---|
2652 | (x862-three-targeted-reg-forms seg |
---|
2653 | vector src |
---|
2654 | index unscaled-idx |
---|
2655 | value result-reg))))) |
---|
2656 | (when safe |
---|
2657 | (let* ((*available-backend-imm-temps* *available-backend-imm-temps*) |
---|
2658 | (value (if (eql (hard-regspec-class result-reg) |
---|
2659 | hard-reg-class-gpr) |
---|
2660 | (hard-regspec-value result-reg))) |
---|
2661 | (result-is-imm nil)) |
---|
2662 | (when (and value (logbitp value *available-backend-imm-temps*)) |
---|
2663 | (setq *available-backend-imm-temps* (bitclr value *available-backend-imm-temps*)) |
---|
2664 | (setq result-is-imm t)) |
---|
2665 | (if (typep safe 'fixnum) |
---|
2666 | (if result-is-imm |
---|
2667 | (with-additional-imm-reg (src safe) |
---|
2668 | (! trap-unless-typecode= src safe)) |
---|
2669 | (! trap-unless-typecode= src safe))) |
---|
2670 | (unless index-known-fixnum |
---|
2671 | (! trap-unless-fixnum unscaled-idx)) |
---|
2672 | (if result-is-imm |
---|
2673 | (with-additional-imm-reg (unscaled-idx src) |
---|
2674 | (! check-misc-bound unscaled-idx src)) |
---|
2675 | (! check-misc-bound unscaled-idx src)))) |
---|
2676 | (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))))) |
---|
2677 | |
---|
2678 | |
---|
2679 | |
---|
2680 | (defun x862-tail-call-alias (immref sym &optional arglist) |
---|
2681 | (let ((alias (cdr (assq sym *x862-tail-call-aliases*)))) |
---|
2682 | (if (and alias (or (null arglist) (eq (+ (length (car arglist)) (length (cadr arglist))) (cdr alias)))) |
---|
2683 | (make-acode (%nx1-operator immediate) (car alias)) |
---|
2684 | immref))) |
---|
2685 | |
---|
2686 | ;;; If BODY is essentially an APPLY involving an &rest arg, try to avoid |
---|
2687 | ;;; consing it. |
---|
2688 | (defun x862-eliminate-&rest (body rest key-p auxen rest-values) |
---|
2689 | (when (and rest (not key-p) (not (cadr auxen)) rest-values) |
---|
2690 | (when (eq (logand (the fixnum (nx-var-bits rest)) |
---|
2691 | (logior $vsetqmask (ash -1 $vbitspecial) |
---|
2692 | (ash 1 $vbitclosed) (ash 1 $vbitsetq) (ash 1 $vbitcloseddownward))) |
---|
2693 | 0) ; Nothing but simple references |
---|
2694 | (do* () |
---|
2695 | ((not (acode-p body))) |
---|
2696 | (let* ((op (acode-operator body))) |
---|
2697 | (if (or (eq op (%nx1-operator lexical-function-call)) |
---|
2698 | (eq op (%nx1-operator call))) |
---|
2699 | (destructuring-bind (fn-form (stack-args reg-args) &optional spread-p) (%cdr body) |
---|
2700 | (unless (and (eq spread-p t) |
---|
2701 | (eq (x862-lexical-reference-p (%car reg-args)) rest)) |
---|
2702 | (return nil)) |
---|
2703 | (flet ((independent-of-all-values (form) |
---|
2704 | (setq form (acode-unwrapped-form-value form)) |
---|
2705 | (or (x86-constant-form-p form) |
---|
2706 | (let* ((lexref (x862-lexical-reference-p form))) |
---|
2707 | (and lexref |
---|
2708 | (neq lexref rest) |
---|
2709 | (dolist (val rest-values t) |
---|
2710 | (unless (x862-var-not-set-by-form-p lexref val) |
---|
2711 | (return)))))))) |
---|
2712 | (unless (or (eq op (%nx1-operator lexical-function-call)) |
---|
2713 | (independent-of-all-values fn-form)) |
---|
2714 | (return nil)) |
---|
2715 | (if (dolist (s stack-args t) |
---|
2716 | (unless (independent-of-all-values s) |
---|
2717 | (return nil))) |
---|
2718 | (let* ((arglist (append stack-args rest-values))) |
---|
2719 | (return |
---|
2720 | (make-acode op |
---|
2721 | fn-form |
---|
2722 | (if (<= (length arglist) *x862-target-num-arg-regs*) |
---|
2723 | (list nil (reverse arglist)) |
---|
2724 | (list (butlast arglist *x862-target-num-arg-regs*) |
---|
2725 | (reverse (last arglist *x862-target-num-arg-regs*)))) |
---|
2726 | nil))) |
---|
2727 | (return nil)))) |
---|
2728 | (if (eq op (%nx1-operator local-block)) |
---|
2729 | (setq body (%cadr body)) |
---|
2730 | (if (and (eq op (%nx1-operator if)) |
---|
2731 | (eq (x862-lexical-reference-p (%cadr body)) rest)) |
---|
2732 | (setq body (%caddr body)) |
---|
2733 | (return nil))))))))) |
---|
2734 | |
---|
2735 | (defun x862-call-fn (seg vreg xfer fn arglist spread-p) |
---|
2736 | (with-x86-local-vinsn-macros (seg vreg xfer) |
---|
2737 | (when spread-p |
---|
2738 | (destructuring-bind (stack-args reg-args) arglist |
---|
2739 | (when (and (null (cdr reg-args)) |
---|
2740 | (nx-null (acode-unwrapped-form-value (car reg-args)))) |
---|
2741 | (setq spread-p nil) |
---|
2742 | (let* ((nargs (length stack-args))) |
---|
2743 | (declare (fixnum nargs)) |
---|
2744 | (if (<= nargs *x862-target-num-arg-regs*) |
---|
2745 | (setq arglist (list nil (reverse stack-args))) |
---|
2746 | (setq arglist (list (butlast stack-args *x862-target-num-arg-regs*) (reverse (last stack-args *x862-target-num-arg-regs*))))))))) |
---|
2747 | (let* ((lexref (x862-lexical-reference-p fn)) |
---|
2748 | (simple-case (or (fixnump fn) |
---|
2749 | (typep fn 'lreg) |
---|
2750 | (x862-immediate-function-p fn) |
---|
2751 | (and |
---|
2752 | lexref |
---|
2753 | (not spread-p) |
---|
2754 | (flet ((all-simple (args) |
---|
2755 | (dolist (arg args t) |
---|
2756 | (when (and arg (not (x862-var-not-set-by-form-p lexref arg))) |
---|
2757 | (return))))) |
---|
2758 | (and (all-simple (car arglist)) |
---|
2759 | (all-simple (cadr arglist)) |
---|
2760 | (setq fn (var-ea lexref))))))) |
---|
2761 | (cstack *x862-cstack*) |
---|
2762 | (top *x862-top-vstack-lcell*) |
---|
2763 | (vstack *x862-vstack*)) |
---|
2764 | (setq xfer (or xfer 0)) |
---|
2765 | (when (and (eq xfer $backend-return) |
---|
2766 | (eq 0 *x862-undo-count*) |
---|
2767 | (acode-p fn) |
---|
2768 | (eq (acode-operator fn) (%nx1-operator immediate)) |
---|
2769 | (symbolp (cadr fn))) |
---|
2770 | (setq fn (x862-tail-call-alias fn (%cadr fn) arglist))) |
---|
2771 | |
---|
2772 | (if (and (eq xfer $backend-return) (not (x862-tailcallok xfer))) |
---|
2773 | (progn |
---|
2774 | (x862-call-fn seg vreg $backend-mvpass fn arglist spread-p) |
---|
2775 | (x862-set-vstack (%i+ (if simple-case 0 *x862-target-node-size*) vstack)) |
---|
2776 | (setq *x862-cstack* cstack) |
---|
2777 | (let ((*x862-returning-values* t)) (x862-do-return seg))) |
---|
2778 | (let* ((mv-p (x862-mv-p xfer)) |
---|
2779 | (mv-return-label (if (and mv-p |
---|
2780 | (not (x862-tailcallok xfer))) |
---|
2781 | (backend-get-next-label)))) |
---|
2782 | (unless simple-case |
---|
2783 | (x862-vpush-register seg (x862-one-untargeted-reg-form seg fn *x862-arg-z*)) |
---|
2784 | (setq fn (x862-vloc-ea vstack))) |
---|
2785 | (x862-invoke-fn seg fn (x862-arglist seg arglist mv-return-label) spread-p xfer mv-return-label) |
---|
2786 | (if (and (logbitp $backend-mvpass-bit xfer) |
---|
2787 | (not simple-case)) |
---|
2788 | (progn |
---|
2789 | (! save-values) |
---|
2790 | (! vstack-discard 1) |
---|
2791 | (x862-set-nargs seg 0) |
---|
2792 | (! recover-values)) |
---|
2793 | (unless (or mv-p simple-case) |
---|
2794 | (! vstack-discard 1))) |
---|
2795 | (x862-set-vstack vstack) |
---|
2796 | (setq *x862-top-vstack-lcell* top) |
---|
2797 | (setq *x862-cstack* cstack) |
---|
2798 | (when (or (logbitp $backend-mvpass-bit xfer) (not mv-p)) |
---|
2799 | (<- *x862-arg-z*) |
---|
2800 | (x862-branch seg (logand (lognot $backend-mvpass-mask) xfer))))) |
---|
2801 | nil))) |
---|
2802 | |
---|
2803 | (defun x862-restore-full-lisp-context (seg) |
---|
2804 | (with-x86-local-vinsn-macros (seg) |
---|
2805 | (! restore-full-lisp-context))) |
---|
2806 | |
---|
2807 | (defun x862-emit-aligned-label (seg labelnum) |
---|
2808 | (with-x86-local-vinsn-macros (seg) |
---|
2809 | (! emit-aligned-label (aref *backend-labels* labelnum)) |
---|
2810 | (@ labelnum) |
---|
2811 | (target-arch-case |
---|
2812 | (:x8632 |
---|
2813 | (! recover-fn)) |
---|
2814 | (:x8664 |
---|
2815 | (! recover-fn-from-rip))))) |
---|
2816 | |
---|
2817 | |
---|
2818 | (defun x862-call-symbol (seg jump-p) |
---|
2819 | (with-x86-local-vinsn-macros (seg) |
---|
2820 | (if jump-p |
---|
2821 | (! jump-known-symbol) |
---|
2822 | (! call-known-symbol *x862-arg-z*)))) |
---|
2823 | |
---|
2824 | ;;; Nargs = nil -> multiple-value case. |
---|
2825 | (defun x862-invoke-fn (seg fn nargs spread-p xfer &optional mvpass-label) |
---|
2826 | (with-x86-local-vinsn-macros (seg) |
---|
2827 | (let* ((f-op (acode-unwrapped-form-value fn)) |
---|
2828 | (immp (and (consp f-op) |
---|
2829 | (eq (%car f-op) (%nx1-operator immediate)))) |
---|
2830 | (symp (and immp (symbolp (%cadr f-op)))) |
---|
2831 | (label-p (and (fixnump fn) |
---|
2832 | (locally (declare (fixnum fn)) |
---|
2833 | (and (= fn -2) (- fn))))) |
---|
2834 | (tail-p (eq xfer $backend-return)) |
---|
2835 | (func (if (consp f-op) (%cadr f-op))) |
---|
2836 | (a-reg nil) |
---|
2837 | (lfunp (and (acode-p f-op) |
---|
2838 | (eq (acode-operator f-op) (%nx1-operator simple-function)))) |
---|
2839 | (expression-p (or (typep fn 'lreg) (and (fixnump fn) (not label-p)))) |
---|
2840 | (callable (or symp lfunp label-p)) |
---|
2841 | (destreg (if symp ($ *x862-fname*) (unless label-p ($ *x862-temp0*)))) |
---|
2842 | (alternate-tail-call |
---|
2843 | (and tail-p label-p *x862-tail-label* (eql nargs *x862-tail-nargs*) (not spread-p)))) |
---|
2844 | (when expression-p |
---|
2845 | ;;Have to do this before spread args, since might be vsp-relative. |
---|
2846 | (if nargs |
---|
2847 | (x862-do-lexical-reference seg destreg fn) |
---|
2848 | (x862-copy-register seg destreg fn))) |
---|
2849 | (if (or symp lfunp) |
---|
2850 | (setq func (if symp |
---|
2851 | (x862-symbol-entry-locative func) |
---|
2852 | (x862-afunc-lfun-ref func)) |
---|
2853 | a-reg (x862-register-constant-p func))) |
---|
2854 | (when tail-p |
---|
2855 | #-no-compiler-bugs |
---|
2856 | (unless (or immp symp lfunp (typep fn 'lreg) (fixnump fn)) (compiler-bug "Well, well, well. How could this have happened ?")) |
---|
2857 | (when a-reg |
---|
2858 | (x862-copy-register seg destreg a-reg)) |
---|
2859 | (unless spread-p |
---|
2860 | (unless alternate-tail-call |
---|
2861 | (x862-restore-nvrs seg *x862-register-restore-ea* *x862-register-restore-count* (and nargs (<= nargs *x862-target-num-arg-regs*)))))) |
---|
2862 | (if spread-p |
---|
2863 | (progn |
---|
2864 | (x862-set-nargs seg (%i- nargs 1)) |
---|
2865 | ; .SPspread-lexpr-z & .SPspreadargz preserve temp1 |
---|
2866 | (target-arch-case |
---|
2867 | (:x8632 |
---|
2868 | (! save-node-register-to-spill-area *x862-temp0*))) |
---|
2869 | (if (eq spread-p 0) |
---|
2870 | (! spread-lexpr) |
---|
2871 | (! spread-list)) |
---|
2872 | (target-arch-case |
---|
2873 | (:x8632 |
---|
2874 | (! load-node-register-from-spill-area *x862-temp0*))) |
---|
2875 | |
---|
2876 | (when (and tail-p *x862-register-restore-count*) |
---|
2877 | (x862-restore-nvrs seg *x862-register-restore-ea* *x862-register-restore-count* nil))) |
---|
2878 | (if nargs |
---|
2879 | (unless alternate-tail-call (x862-set-nargs seg nargs)) |
---|
2880 | (! pop-argument-registers))) |
---|
2881 | (if callable |
---|
2882 | (if (not tail-p) |
---|
2883 | (if (x862-mvpass-p xfer) |
---|
2884 | (let* ((call-reg (if symp ($ *x862-fname*) ($ *x862-temp0*)))) |
---|
2885 | (unless mvpass-label (compiler-bug "no label for mvpass")) |
---|
2886 | (if label-p |
---|
2887 | (x862-copy-register seg call-reg ($ *x862-fn*)) |
---|
2888 | (if a-reg |
---|
2889 | (x862-copy-register seg call-reg a-reg) |
---|
2890 | (x862-store-immediate seg func call-reg))) |
---|
2891 | (if symp |
---|
2892 | (! pass-multiple-values-symbol) |
---|
2893 | (! pass-multiple-values)) |
---|
2894 | (when mvpass-label |
---|
2895 | (@= mvpass-label))) |
---|
2896 | (progn |
---|
2897 | (if label-p |
---|
2898 | (progn |
---|
2899 | (! call-label (aref *backend-labels* 2))) |
---|
2900 | (progn |
---|
2901 | (if a-reg |
---|
2902 | (x862-copy-register seg destreg a-reg) |
---|
2903 | (x862-store-immediate seg func destreg)) |
---|
2904 | (if symp |
---|
2905 | (x862-call-symbol seg nil) |
---|
2906 | (! call-known-function)))))) |
---|
2907 | (if alternate-tail-call |
---|
2908 | (progn |
---|
2909 | (x862-unwind-stack seg xfer 0 0 *x862-tail-vsp*) |
---|
2910 | (! jump (aref *backend-labels* *x862-tail-label*))) |
---|
2911 | (progn |
---|
2912 | (x862-unwind-stack seg xfer 0 0 #x7fffff) |
---|
2913 | (if (and (not spread-p) nargs (%i<= nargs *x862-target-num-arg-regs*)) |
---|
2914 | (progn |
---|
2915 | (unless (or label-p a-reg) (x862-store-immediate seg func destreg)) |
---|
2916 | (x862-restore-full-lisp-context seg) |
---|
2917 | (if label-p |
---|
2918 | (! jump (aref *backend-labels* 1)) |
---|
2919 | (progn |
---|
2920 | (if symp |
---|
2921 | (x862-call-symbol seg t) |
---|
2922 | (! jump-known-function))))) |
---|
2923 | (progn |
---|
2924 | (unless (or label-p a-reg) (x862-store-immediate seg func destreg)) |
---|
2925 | (when label-p |
---|
2926 | (x862-copy-register seg *x862-temp0* *x862-fn*)) |
---|
2927 | |
---|
2928 | (cond ((or spread-p (null nargs)) |
---|
2929 | (if symp |
---|
2930 | (! tail-call-sym-gen) |
---|
2931 | (! tail-call-fn-gen))) |
---|
2932 | ((%i> nargs *x862-target-num-arg-regs*) |
---|
2933 | (if symp |
---|
2934 | (! tail-call-sym-slide) |
---|
2935 | (! tail-call-fn-slide))) |
---|
2936 | (t |
---|
2937 | (if symp |
---|
2938 | (! tail-call-sym-vsp) |
---|
2939 | (! tail-call-fn-vsp))))))))) |
---|
2940 | ;; The general (funcall) case: we don't know (at compile-time) |
---|
2941 | ;; for sure whether we've got a symbol or a (local, constant) |
---|
2942 | ;; function. |
---|
2943 | (progn |
---|
2944 | (unless (or (fixnump fn) (typep fn 'lreg)) |
---|
2945 | (x862-one-targeted-reg-form seg fn destreg)) |
---|
2946 | (if (not tail-p) |
---|
2947 | (if (x862-mvpass-p xfer) |
---|
2948 | (progn (! pass-multiple-values) |
---|
2949 | (when mvpass-label |
---|
2950 | (@= mvpass-label))) |
---|
2951 | (! funcall)) |
---|
2952 | (cond ((or (null nargs) spread-p) |
---|
2953 | (! tail-funcall-gen)) |
---|
2954 | ((%i> nargs *x862-target-num-arg-regs*) |
---|
2955 | (! tail-funcall-slide)) |
---|
2956 | (t |
---|
2957 | (! restore-full-lisp-context) |
---|
2958 | (! tail-funcall))))))) |
---|
2959 | nil)) |
---|
2960 | |
---|
2961 | (defun x862-seq-fbind (seg vreg xfer vars afuncs body p2decls) |
---|
2962 | (let* ((old-stack (x862-encode-stack)) |
---|
2963 | (copy afuncs) |
---|
2964 | (func nil)) |
---|
2965 | (with-x86-p2-declarations p2decls |
---|
2966 | (dolist (var vars) |
---|
2967 | (when (neq 0 (afunc-fn-refcount (setq func (pop afuncs)))) |
---|
2968 | (x862-seq-bind-var seg var (nx1-afunc-ref func)))) |
---|
2969 | (x862-undo-body seg vreg xfer body old-stack) |
---|
2970 | (dolist (var vars) |
---|
2971 | (when (neq 0 (afunc-fn-refcount (setq func (pop copy)))) |
---|
2972 | (x862-close-var seg var)))))) |
---|
2973 | |
---|
2974 | (defun x862-make-closure (seg afunc downward-p) |
---|
2975 | (with-x86-local-vinsn-macros (seg) |
---|
2976 | (flet ((var-to-reg (var target) |
---|
2977 | (let* ((ea (var-ea (var-bits var)))) |
---|
2978 | (if ea |
---|
2979 | (x862-addrspec-to-reg seg (x862-ea-open ea) target) |
---|
2980 | (! load-nil target)) |
---|
2981 | target)) |
---|
2982 | (set-some-cells (dest cellno c0 c1 c2 c3) |
---|
2983 | (declare (fixnum cellno)) |
---|
2984 | (! misc-set-c-node c0 dest cellno) |
---|
2985 | (incf cellno) |
---|
2986 | (when c1 |
---|
2987 | (! misc-set-c-node c1 dest cellno) |
---|
2988 | (incf cellno) |
---|
2989 | (when c2 |
---|
2990 | (! misc-set-c-node c2 dest cellno) |
---|
2991 | (incf cellno) |
---|
2992 | (when c3 |
---|
2993 | (! misc-set-c-node c3 dest cellno) |
---|
2994 | (incf cellno)))) |
---|
2995 | cellno)) |
---|
2996 | (let* ((inherited-vars (afunc-inherited-vars afunc)) |
---|
2997 | (arch (backend-target-arch *target-backend*)) |
---|
2998 | (dest ($ *x862-arg-z*)) |
---|
2999 | (vsize (+ (length inherited-vars) |
---|
3000 | (target-arch-case |
---|
3001 | (:x8632 7) |
---|
3002 | (:x8664 5)) ; %closure-code%, afunc |
---|
3003 | 1))) ; lfun-bits |
---|
3004 | (declare (list inherited-vars)) |
---|
3005 | (let* ((cell (target-arch-case (:x8632 6) |
---|
3006 | (:x8664 4)))) |
---|
3007 | (declare (fixnum cell)) |
---|
3008 | (if downward-p |
---|
3009 | (progn |
---|
3010 | (! make-fixed-stack-gvector |
---|
3011 | dest |
---|
3012 | (ash (logandc2 (+ vsize 2) 1) (arch::target-word-shift arch)) |
---|
3013 | (arch::make-vheader vsize (nx-lookup-target-uvector-subtag :function))) |
---|
3014 | (x862-open-undo $undostkblk)) |
---|
3015 | (progn |
---|
3016 | (x862-lri seg |
---|
3017 | *x862-imm0* |
---|
3018 | (arch::make-vheader vsize (nx-lookup-target-uvector-subtag :function))) |
---|
3019 | (target-arch-case |
---|
3020 | (:x8632 |
---|
3021 | (! setup-uvector-allocation *x862-imm0*) |
---|
3022 | (x862-lri seg *x862-imm0* (- (ash (logandc2 (+ vsize 2) 1) (arch::target-word-shift arch)) x8632::fulltag-misc))) |
---|
3023 | (:x8664 |
---|
3024 | (x862-lri seg x8664::imm1 (- (ash (logandc2 (+ vsize 2) 1) (arch::target-word-shift arch)) x8664::fulltag-misc)))) |
---|
3025 | (! %allocate-uvector dest))) |
---|
3026 | (! init-nclosure *x862-arg-z*) |
---|
3027 | ;;; xxx --- x8632 likely to have register conflicts with *x862-ra0* |
---|
3028 | (x862-store-immediate seg (x862-afunc-lfun-ref afunc) *x862-ra0*) |
---|
3029 | (target-arch-case |
---|
3030 | (:x8632 |
---|
3031 | (with-node-temps (*x862-arg-z*) (t0) |
---|
3032 | (do* ((func *x862-ra0* nil)) |
---|
3033 | ((null inherited-vars)) |
---|
3034 | (let* ((t0r (or func (if inherited-vars |
---|
3035 | (var-to-reg (pop inherited-vars) t0))))) |
---|
3036 | (! misc-set-c-node t0r dest cell) |
---|
3037 | (incf cell))))) |
---|
3038 | (:x8664 |
---|
3039 | (with-node-temps (*x862-arg-z*) (t0 t1 t2 t3) |
---|
3040 | (do* ((func *x862-ra0* nil)) |
---|
3041 | ((null inherited-vars)) |
---|
3042 | (let* ((t0r (or func (if inherited-vars (var-to-reg (pop inherited-vars) t0)))) |
---|
3043 | (t1r (if inherited-vars (var-to-reg (pop inherited-vars) t1))) |
---|
3044 | (t2r (if inherited-vars (var-to-reg (pop inherited-vars) t2))) |
---|
3045 | (t3r (if inherited-vars (var-to-reg (pop inherited-vars) t3)))) |
---|
3046 | (setq cell (set-some-cells dest cell t0r t1r t2r t3r))))))) |
---|
3047 | (x862-lri seg *x862-arg-y* (ash (logior (ash -1 $lfbits-noname-bit) (ash 1 $lfbits-trampoline-bit)) *x862-target-fixnum-shift*)) |
---|
3048 | (! misc-set-c-node *x862-arg-y* dest cell)) |
---|
3049 | (! finalize-closure dest) |
---|
3050 | dest)))) |
---|
3051 | |
---|
3052 | (defun x862-symbol-entry-locative (sym) |
---|
3053 | (setq sym (require-type sym 'symbol)) |
---|
3054 | (when (eq sym '%call-next-method-with-args) |
---|
3055 | (setf (afunc-bits *x862-cur-afunc*) |
---|
3056 | (%ilogior (%ilsl $fbitnextmethargsp 1) (afunc-bits *x862-cur-afunc*)))) |
---|
3057 | (or (assq sym *x862-fcells*) |
---|
3058 | (let ((new (list sym))) |
---|
3059 | (push new *x862-fcells*) |
---|
3060 | new))) |
---|
3061 | |
---|
3062 | (defun x862-symbol-value-cell (sym) |
---|
3063 | (setq sym (require-type sym 'symbol)) |
---|
3064 | (or (assq sym *x862-vcells*) |
---|
3065 | (let ((new (list sym))) |
---|
3066 | (push new *x862-vcells*) |
---|
3067 | (ensure-binding-index sym) |
---|
3068 | new))) |
---|
3069 | |
---|
3070 | |
---|
3071 | (defun x862-symbol-locative-p (imm) |
---|
3072 | (and (consp imm) |
---|
3073 | (or (memq imm *x862-vcells*) |
---|
3074 | (memq imm *x862-fcells*)))) |
---|
3075 | |
---|
3076 | |
---|
3077 | |
---|
3078 | |
---|
3079 | (defun x862-immediate-function-p (f) |
---|
3080 | (setq f (acode-unwrapped-form-value f)) |
---|
3081 | (and (acode-p f) |
---|
3082 | (or (eq (%car f) (%nx1-operator immediate)) |
---|
3083 | (eq (%car f) (%nx1-operator simple-function))))) |
---|
3084 | |
---|
3085 | (defun x86-constant-form-p (form) |
---|
3086 | (setq form (nx-untyped-form form)) |
---|
3087 | (if form |
---|
3088 | (or (nx-null form) |
---|
3089 | (nx-t form) |
---|
3090 | (and (consp form) |
---|
3091 | (or (eq (acode-operator form) (%nx1-operator immediate)) |
---|
3092 | (eq (acode-operator form) (%nx1-operator fixnum)) |
---|
3093 | (eq (acode-operator form) (%nx1-operator simple-function))))))) |
---|
3094 | |
---|
3095 | |
---|
3096 | |
---|
3097 | (defun x862-integer-constant-p (form mode) |
---|
3098 | (let* ((val |
---|
3099 | (or (acode-fixnum-form-p (setq form (acode-unwrapped-form form))) |
---|
3100 | (and (acode-p form) |
---|
3101 | (eq (acode-operator form) (%nx1-operator immediate)) |
---|
3102 | (setq form (%cadr form)) |
---|
3103 | (if (typep form 'integer) |
---|
3104 | form))))) |
---|
3105 | (when val |
---|
3106 | (let* ((type (mode-specifier-type mode)) |
---|
3107 | (high (numeric-ctype-high type)) |
---|
3108 | (low (numeric-ctype-low type))) |
---|
3109 | (if (and (>= val low) |
---|
3110 | (<= val high)) |
---|
3111 | val |
---|
3112 | (if (<= (integer-length val) (integer-length (- high low))) |
---|
3113 | (if (eql 0 low) ; type is unsigned, value is negative |
---|
3114 | (logand high val) |
---|
3115 | (- val (1+ (- high low)))))))))) |
---|
3116 | |
---|
3117 | |
---|
3118 | |
---|
3119 | |
---|
3120 | (defun x86-side-effect-free-form-p (form) |
---|
3121 | (when (consp (setq form (acode-unwrapped-form-value form))) |
---|
3122 | (or (x86-constant-form-p form) |
---|
3123 | ;(eq (acode-operator form) (%nx1-operator bound-special-ref)) |
---|
3124 | (if (eq (acode-operator form) (%nx1-operator lexical-reference)) |
---|
3125 | (not (%ilogbitp $vbitsetq (nx-var-bits (%cadr form)))))))) |
---|
3126 | |
---|
3127 | (defun x862-formlist (seg stkargs &optional revregargs) |
---|
3128 | (with-x86-local-vinsn-macros (seg) |
---|
3129 | (let* ((nregs (length revregargs)) |
---|
3130 | (n nregs)) |
---|
3131 | (declare (fixnum n)) |
---|
3132 | (dolist (arg stkargs) |
---|
3133 | (let* ((pushform (x862-acode-operator-supports-push arg))) |
---|
3134 | (if pushform |
---|
3135 | (progn |
---|
3136 | (x862-form seg :push nil pushform) |
---|
3137 | (x862-new-vstack-lcell :outgoing-argument *x862-target-lcell-size* 0 nil) |
---|
3138 | (x862-adjust-vstack *x862-target-node-size*)) |
---|
3139 | |
---|
3140 | (let* ((reg (x862-one-untargeted-reg-form seg arg *x862-arg-z*))) |
---|
3141 | (x862-vpush-register-arg seg reg))) |
---|
3142 | (incf n))) |
---|
3143 | (when revregargs |
---|
3144 | (let* ((zform (%car revregargs)) |
---|
3145 | (yform (%cadr revregargs)) |
---|
3146 | (xform (%caddr revregargs))) |
---|
3147 | (if (eq 3 nregs) |
---|
3148 | (progn |
---|
3149 | (target-arch-case (:x8632 (compiler-bug "3 reg args on x8632?"))) |
---|
3150 | (x862-three-targeted-reg-forms seg xform ($ x8664::arg_x) |
---|
3151 | yform ($ *x862-arg-y*) |
---|
3152 | zform ($ *x862-arg-z*))) |
---|
3153 | (if (eq 2 nregs) |
---|
3154 | (x862-two-targeted-reg-forms seg yform ($ *x862-arg-y*) zform ($ *x862-arg-z*)) |
---|
3155 | (x862-one-targeted-reg-form seg zform ($ *x862-arg-z*)))))) |
---|
3156 | n))) |
---|
3157 | |
---|
3158 | (defun x862-arglist (seg args &optional mv-label) |
---|
3159 | (with-x86-local-vinsn-macros (seg) |
---|
3160 | (when mv-label |
---|
3161 | (x862-vpush-label seg (aref *backend-labels* mv-label))) |
---|
3162 | (when (car args) |
---|
3163 | (! reserve-outgoing-frame) |
---|
3164 | (x862-new-vstack-lcell :reserved *x862-target-lcell-size* 0 nil) |
---|
3165 | (x862-new-vstack-lcell :reserved *x862-target-lcell-size* 0 nil) |
---|
3166 | (setq *x862-vstack* (+ *x862-vstack* (* 2 *x862-target-node-size*)))) |
---|
3167 | (x862-formlist seg (car args) (cadr args)))) |
---|
3168 | |
---|
3169 | |
---|
3170 | (defun x862-unboxed-integer-arg-to-reg (seg form immreg &optional ffi-arg-type) |
---|
3171 | (let* ((mode (ecase ffi-arg-type |
---|
3172 | ((nil) :natural) |
---|
3173 | (:signed-byte :s8) |
---|
3174 | (:unsigned-byte :u8) |
---|
3175 | (:signed-halfword :s16) |
---|
3176 | (:unsigned-halfword :u16) |
---|
3177 | (:signed-fullword :s32) |
---|
3178 | (:unsigned-fullword :u32) |
---|
3179 | (:unsigned-doubleword :u64) |
---|
3180 | (:signed-doubleword :s64))) |
---|
3181 | (modeval (gpr-mode-name-value mode))) |
---|
3182 | (with-x86-local-vinsn-macros (seg) |
---|
3183 | (let* ((value (x862-integer-constant-p form mode))) |
---|
3184 | (if value |
---|
3185 | (progn |
---|
3186 | (unless (typep immreg 'lreg) |
---|
3187 | (setq immreg (make-unwired-lreg immreg :mode modeval))) |
---|
3188 | (if (< value 0) |
---|
3189 | (x862-lri seg immreg value) |
---|
3190 | (x862-lriu seg immreg value)) |
---|
3191 | immreg) |
---|
3192 | (progn |
---|
3193 | (x862-one-targeted-reg-form seg form (make-wired-lreg *x862-imm0* :mode modeval)))))))) |
---|
3194 | |
---|
3195 | |
---|
3196 | (defun x862-macptr-arg-to-reg (seg form address-reg) |
---|
3197 | (x862-one-targeted-reg-form seg |
---|
3198 | form |
---|
3199 | address-reg)) |
---|
3200 | |
---|
3201 | |
---|
3202 | (defun x862-one-lreg-form (seg form lreg) |
---|
3203 | (let ((is-float (= (hard-regspec-class lreg) hard-reg-class-fpr))) |
---|
3204 | (if is-float |
---|
3205 | (x862-form-float seg lreg nil form) |
---|
3206 | (x862-form seg lreg nil form)) |
---|
3207 | lreg)) |
---|
3208 | |
---|
3209 | (defun x862-one-targeted-reg-form (seg form reg) |
---|
3210 | (x862-one-lreg-form seg form reg)) |
---|
3211 | |
---|
3212 | (defun x862-one-untargeted-lreg-form (seg form reg) |
---|
3213 | (x862-one-lreg-form seg form (if (typep reg 'lreg) reg (make-unwired-lreg reg)))) |
---|
3214 | |
---|
3215 | (defun x862-one-untargeted-reg-form (seg form suggested) |
---|
3216 | (with-x86-local-vinsn-macros (seg) |
---|
3217 | (let* ((gpr-p (= (hard-regspec-class suggested) hard-reg-class-gpr)) |
---|
3218 | (node-p (if gpr-p (= (get-regspec-mode suggested) hard-reg-class-gpr-mode-node)))) |
---|
3219 | (if node-p |
---|
3220 | (let* ((ref (x862-lexical-reference-ea form)) |
---|
3221 | (reg (backend-ea-physical-reg ref hard-reg-class-gpr))) |
---|
3222 | (if reg |
---|
3223 | ref |
---|
3224 | (if (nx-null form) |
---|
3225 | (progn |
---|
3226 | (! load-nil suggested) |
---|
3227 | suggested) |
---|
3228 | (if (and (acode-p form) |
---|
3229 | (eq (acode-operator form) (%nx1-operator immediate)) |
---|
3230 | (setq reg (x862-register-constant-p (cadr form)))) |
---|
3231 | reg |
---|
3232 | (x862-one-untargeted-lreg-form seg form suggested))))) |
---|
3233 | (x862-one-untargeted-lreg-form seg form suggested))))) |
---|
3234 | |
---|
3235 | |
---|
3236 | (defun x862-push-register (seg areg) |
---|
3237 | (let* ((a-float (= (hard-regspec-class areg) hard-reg-class-fpr)) |
---|
3238 | (a-single (if a-float (= (get-regspec-mode areg) hard-reg-class-fpr-mode-single))) |
---|
3239 | (a-node (unless a-float (= (get-regspec-mode areg) hard-reg-class-gpr-mode-node))) |
---|
3240 | vinsn) |
---|
3241 | (with-x86-local-vinsn-macros (seg) |
---|
3242 | (if a-node |
---|
3243 | (setq vinsn (x862-vpush-register seg areg :node-temp)) |
---|
3244 | (if a-single |
---|
3245 | (target-arch-case |
---|
3246 | (:x8632 |
---|
3247 | (setq vinsn (! temp-push-single-float areg)) |
---|
3248 | (incf *x862-cstack* *x862-target-dnode-size*)) |
---|
3249 | (:x8664 |
---|
3250 | (setq vinsn (! vpush-single-float areg)) |
---|
3251 | (x862-new-vstack-lcell :single-float *x862-target-lcell-size* 0 nil) |
---|
3252 | (x862-adjust-vstack *x862-target-node-size*))) |
---|
3253 | (target-arch-case |
---|
3254 | (:x8632 |
---|
3255 | (if a-float |
---|
3256 | (progn |
---|
3257 | (setq vinsn (! temp-push-double-float areg)) |
---|
3258 | (incf *x862-cstack* 16)) |
---|
3259 | (progn |
---|
3260 | (setq vinsn (! temp-push-unboxed-word areg)) |
---|
3261 | (incf *x862-cstack* *x862-target-dnode-size*)))) |
---|
3262 | (:x8664 |
---|
3263 | (setq vinsn |
---|
3264 | (if a-float |
---|
3265 | (! temp-push-double-float areg) |
---|
3266 | (! temp-push-unboxed-word areg))) |
---|
3267 | (setq *x862-cstack* (+ *x862-cstack* 16)))))) |
---|
3268 | vinsn))) |
---|
3269 | |
---|
3270 | (defun x862-pop-register (seg areg) |
---|
3271 | (let* ((a-float (= (hard-regspec-class areg) hard-reg-class-fpr)) |
---|
3272 | (a-single (if a-float (= (get-regspec-mode areg) hard-reg-class-fpr-mode-single))) |
---|
3273 | (a-node (unless a-float (= (get-regspec-mode areg) hard-reg-class-gpr-mode-node))) |
---|
3274 | vinsn) |
---|
3275 | (with-x86-local-vinsn-macros (seg) |
---|
3276 | (if a-node |
---|
3277 | (setq vinsn (x862-vpop-register seg areg)) |
---|
3278 | (if a-single |
---|
3279 | (target-arch-case |
---|
3280 | (:x8632 |
---|
3281 | (setq vinsn (! temp-pop-single-float areg)) |
---|
3282 | (decf *x862-cstack* *x862-target-dnode-size*)) |
---|
3283 | (:x8664 |
---|
3284 | (setq vinsn (! vpop-single-float areg)) |
---|
3285 | (setq *x862-top-vstack-lcell* (lcell-parent *x862-top-vstack-lcell*)) |
---|
3286 | (x862-adjust-vstack (- *x862-target-node-size*)))) |
---|
3287 | (target-arch-case |
---|
3288 | (:x8632 |
---|
3289 | (if a-float |
---|
3290 | (progn |
---|
3291 | (setq vinsn (! temp-pop-double-float areg)) |
---|
3292 | (decf *x862-cstack* 16)) |
---|
3293 | (progn |
---|
3294 | (setq vinsn (! temp-pop-unboxed-word areg)) |
---|
3295 | (decf *x862-cstack* *x862-target-dnode-size*)))) |
---|
3296 | (:x8664 |
---|
3297 | (setq vinsn |
---|
3298 | (if a-float |
---|
3299 | (! temp-pop-double-float areg) |
---|
3300 | (! temp-pop-unboxed-word areg))) |
---|
3301 | (setq *x862-cstack* (- *x862-cstack* 16)))))) |
---|
3302 | vinsn))) |
---|
3303 | |
---|
3304 | (defun x862-acc-reg-for (reg) |
---|
3305 | (with-x86-local-vinsn-macros (seg) |
---|
3306 | (let* ((class (hard-regspec-class reg)) |
---|
3307 | (mode (get-regspec-mode reg))) |
---|
3308 | (declare (fixnum class mode)) |
---|
3309 | (cond ((= class hard-reg-class-fpr) |
---|
3310 | (make-wired-lreg *x862-fp1* :class class :mode mode)) |
---|
3311 | ((= class hard-reg-class-gpr) |
---|
3312 | (if (= mode hard-reg-class-gpr-mode-node) |
---|
3313 | ($ *x862-arg-z*) |
---|
3314 | (make-wired-lreg *x862-imm0* :mode mode))) |
---|
3315 | (t (compiler-bug "Unknown register class for reg ~s" reg)))))) |
---|
3316 | |
---|
3317 | ;;; The compiler often generates superfluous pushes & pops. Try to |
---|
3318 | ;;; eliminate them. |
---|
3319 | (defun x862-elide-pushes (seg push-vinsn pop-vinsn) |
---|
3320 | (with-x86-local-vinsn-macros (seg) |
---|
3321 | (let* ((pushed-reg (svref (vinsn-variable-parts push-vinsn) 0)) |
---|
3322 | (popped-reg (svref (vinsn-variable-parts pop-vinsn) 0)) |
---|
3323 | (same-reg (eq (hard-regspec-value pushed-reg) |
---|
3324 | (hard-regspec-value popped-reg))) |
---|
3325 | (csp-p (vinsn-attribute-p push-vinsn :csp))) |
---|
3326 | (when csp-p ; vsp case is harder. |
---|
3327 | (let* ((pushed-reg-is-set (vinsn-sequence-sets-reg-p |
---|
3328 | push-vinsn pop-vinsn pushed-reg)) |
---|
3329 | (popped-reg-is-set (if same-reg |
---|
3330 | pushed-reg-is-set |
---|
3331 | (vinsn-sequence-sets-reg-p |
---|
3332 | push-vinsn pop-vinsn popped-reg)))) |
---|
3333 | (unless (and pushed-reg-is-set popped-reg-is-set) |
---|
3334 | (unless same-reg |
---|
3335 | (let* ((copy (if (eq (hard-regspec-class pushed-reg) |
---|
3336 | hard-reg-class-fpr) |
---|
3337 | (if (= (get-regspec-mode pushed-reg) |
---|
3338 | hard-reg-class-fpr-mode-double) |
---|
3339 | (! copy-double-float popped-reg pushed-reg) |
---|
3340 | (! copy-single-float popped-reg pushed-reg)) |
---|
3341 | (! copy-gpr popped-reg pushed-reg)))) |
---|
3342 | (remove-dll-node copy) |
---|
3343 | (if pushed-reg-is-set |
---|
3344 | (insert-dll-node-after copy push-vinsn) |
---|
3345 | (insert-dll-node-before copy push-vinsn)))) |
---|
3346 | (elide-vinsn push-vinsn) |
---|
3347 | (elide-vinsn pop-vinsn))))))) |
---|
3348 | |
---|
3349 | |
---|
3350 | ;;; we never leave the first form pushed (the 68K compiler had some subprims that |
---|
3351 | ;;; would vpop the first argument out of line.) |
---|
3352 | (defun x862-two-targeted-reg-forms (seg aform areg bform breg) |
---|
3353 | (unless (typep areg 'lreg) |
---|
3354 | (warn "~s is not an lreg (1/2)" areg)) |
---|
3355 | (unless (typep breg 'lreg) |
---|
3356 | (warn "~s is not an lreg (2/2)" breg)) |
---|
3357 | (let* ((avar (x862-lexical-reference-p aform)) |
---|
3358 | (atriv (x862-trivial-p bform)) |
---|
3359 | (aconst (and (not atriv) (or (x86-side-effect-free-form-p aform) |
---|
3360 | (if avar (x862-var-not-set-by-form-p avar bform))))) |
---|
3361 | apushed) |
---|
3362 | (progn |
---|
3363 | (unless aconst |
---|
3364 | (if atriv |
---|
3365 | (x862-one-targeted-reg-form seg aform areg) |
---|
3366 | (setq apushed (x862-push-register seg (x862-one-untargeted-reg-form seg aform (x862-acc-reg-for areg)))))) |
---|
3367 | (x862-one-targeted-reg-form seg bform breg) |
---|
3368 | (if aconst |
---|
3369 | (x862-one-targeted-reg-form seg aform areg) |
---|
3370 | (if apushed |
---|
3371 | (x862-elide-pushes seg apushed (x862-pop-register seg areg))))) |
---|
3372 | (values areg breg))) |
---|
3373 | |
---|
3374 | |
---|
3375 | (defun x862-two-untargeted-reg-forms (seg aform areg bform breg) |
---|
3376 | (with-x86-local-vinsn-macros (seg) |
---|
3377 | (let* ((avar (x862-lexical-reference-p aform)) |
---|
3378 | (adest areg) |
---|
3379 | (bdest breg) |
---|
3380 | (atriv (x862-trivial-p bform)) |
---|
3381 | (aconst (and (not atriv) (or (x86-side-effect-free-form-p aform) |
---|
3382 | (if avar (x862-var-not-set-by-form-p avar bform))))) |
---|
3383 | (apushed (not (or atriv aconst)))) |
---|
3384 | (progn |
---|
3385 | (unless aconst |
---|
3386 | (if atriv |
---|
3387 | (setq adest (x862-one-untargeted-reg-form seg aform areg)) |
---|
3388 | (setq apushed (x862-push-register seg (x862-one-untargeted-reg-form seg aform (x862-acc-reg-for areg)))))) |
---|
3389 | (setq bdest (x862-one-untargeted-reg-form seg bform breg)) |
---|
3390 | (if aconst |
---|
3391 | (setq adest (x862-one-untargeted-reg-form seg aform areg)) |
---|
3392 | (if apushed |
---|
3393 | (x862-elide-pushes seg apushed (x862-pop-register seg areg))))) |
---|
3394 | (values adest bdest)))) |
---|
3395 | |
---|
3396 | |
---|
3397 | (defun x862-three-targeted-reg-forms (seg aform areg bform breg cform creg) |
---|
3398 | (unless (typep areg 'lreg) |
---|
3399 | (warn "~s is not an lreg (1/3)" areg)) |
---|
3400 | (unless (typep breg 'lreg) |
---|
3401 | (warn "~s is not an lreg (2/3)" breg)) |
---|
3402 | (unless (typep creg 'lreg) |
---|
3403 | (warn "~s is not an lreg (3/3)" creg)) |
---|
3404 | (let* ((atriv (or (null aform) |
---|
3405 | (and (x862-trivial-p bform) |
---|
3406 | (x862-trivial-p cform)))) |
---|
3407 | (btriv (or (null bform) |
---|
3408 | (x862-trivial-p cform))) |
---|
3409 | (aconst (and (not atriv) |
---|
3410 | (or (x86-side-effect-free-form-p aform) |
---|
3411 | (let ((avar (x862-lexical-reference-p aform))) |
---|
3412 | (and avar |
---|
3413 | (x862-var-not-set-by-form-p avar bform) |
---|
3414 | (x862-var-not-set-by-form-p avar cform)))))) |
---|
3415 | (bconst (and (not btriv) |
---|
3416 | (or |
---|
3417 | (x86-side-effect-free-form-p bform) |
---|
3418 | (let ((bvar (x862-lexical-reference-p bform))) |
---|
3419 | (and bvar (x862-var-not-set-by-form-p bvar cform)))))) |
---|
3420 | (apushed nil) |
---|
3421 | (bpushed nil)) |
---|
3422 | (if (and aform (not aconst)) |
---|
3423 | (if atriv |
---|
3424 | (x862-one-targeted-reg-form seg aform areg) |
---|
3425 | (setq apushed (x862-push-register seg (x862-one-untargeted-reg-form seg aform (x862-acc-reg-for areg)))))) |
---|
3426 | (if (and bform (not bconst)) |
---|
3427 | (if btriv |
---|
3428 | (x862-one-targeted-reg-form seg bform breg) |
---|
3429 | (setq bpushed (x862-push-register seg (x862-one-untargeted-reg-form seg bform (x862-acc-reg-for breg)))))) |
---|
3430 | (x862-one-targeted-reg-form seg cform creg) |
---|
3431 | (unless btriv |
---|
3432 | (if bconst |
---|
3433 | (x862-one-targeted-reg-form seg bform breg) |
---|
3434 | (x862-elide-pushes seg bpushed (x862-pop-register seg breg)))) |
---|
3435 | (unless atriv |
---|
3436 | (if aconst |
---|
3437 | (x862-one-targeted-reg-form seg aform areg) |
---|
3438 | (x862-elide-pushes seg apushed (x862-pop-register seg areg)))) |
---|
3439 | (values areg breg creg))) |
---|
3440 | |
---|
3441 | (defun x862-four-targeted-reg-forms (seg aform areg bform breg cform creg dform dreg) |
---|
3442 | (unless (typep areg 'lreg) |
---|
3443 | (warn "~s is not an lreg (1/4)" areg)) |
---|
3444 | (unless (typep breg 'lreg) |
---|
3445 | (warn "~s is not an lreg (2/4)" breg)) |
---|
3446 | (unless (typep creg 'lreg) |
---|
3447 | (warn "~s is not an lreg (3/4)" creg)) |
---|
3448 | (unless (typep dreg 'lreg) |
---|
3449 | (warn "~s is not an lreg (4/4)" dreg)) |
---|
3450 | (let* ((atriv (or (null aform) |
---|
3451 | (and (x862-trivial-p bform) |
---|
3452 | (x862-trivial-p cform) |
---|
3453 | (x862-trivial-p dform)))) |
---|
3454 | (btriv (or (null bform) |
---|
3455 | (and (x862-trivial-p cform) |
---|
3456 | (x862-trivial-p dform)))) |
---|
3457 | (ctriv (or (null cform) |
---|
3458 | (x862-trivial-p dform))) |
---|
3459 | (aconst (and (not atriv) |
---|
3460 | (or (x86-side-effect-free-form-p aform) |
---|
3461 | (let ((avar (x862-lexical-reference-p aform))) |
---|
3462 | (and avar |
---|
3463 | (x862-var-not-set-by-form-p avar bform) |
---|
3464 | (x862-var-not-set-by-form-p avar cform) |
---|
3465 | (x862-var-not-set-by-form-p avar dform)))))) |
---|
3466 | (bconst (and (not btriv) |
---|
3467 | (or |
---|
3468 | (x86-side-effect-free-form-p bform) |
---|
3469 | (let ((bvar (x862-lexical-reference-p bform))) |
---|
3470 | (and bvar |
---|
3471 | (x862-var-not-set-by-form-p bvar cform) |
---|
3472 | (x862-var-not-set-by-form-p bvar dform)))))) |
---|
3473 | (cconst (and (not ctriv) |
---|
3474 | (or |
---|
3475 | (x86-side-effect-free-form-p cform) |
---|
3476 | (let ((cvar (x862-lexical-reference-p cform))) |
---|
3477 | (and cvar (x862-var-not-set-by-form-p cvar dform)))))) |
---|
3478 | (apushed nil) |
---|
3479 | (bpushed nil) |
---|
3480 | (cpushed nil)) |
---|
3481 | (if (and aform (not aconst)) |
---|
3482 | (if atriv |
---|
3483 | (x862-one-targeted-reg-form seg aform areg) |
---|
3484 | (setq apushed (x862-push-register seg (x862-one-untargeted-reg-form seg aform (x862-acc-reg-for areg)))))) |
---|
3485 | (if (and bform (not bconst)) |
---|
3486 | (if btriv |
---|
3487 | (x862-one-targeted-reg-form seg bform breg) |
---|
3488 | (setq bpushed (x862-push-register seg (x862-one-untargeted-reg-form seg bform (x862-acc-reg-for breg)))))) |
---|
3489 | (if (and cform (not cconst)) |
---|
3490 | (if ctriv |
---|
3491 | (x862-one-targeted-reg-form seg cform creg) |
---|
3492 | (setq cpushed (x862-push-register seg (x862-one-untargeted-reg-form seg cform (x862-acc-reg-for creg)))))) |
---|
3493 | (x862-one-targeted-reg-form seg dform dreg) |
---|
3494 | (unless ctriv |
---|
3495 | (if cconst |
---|
3496 | (x862-one-targeted-reg-form seg cform creg) |
---|
3497 | (x862-elide-pushes seg cpushed (x862-pop-register seg creg)))) |
---|
3498 | (unless btriv |
---|
3499 | (if bconst |
---|
3500 | (x862-one-targeted-reg-form seg bform breg) |
---|
3501 | (x862-elide-pushes seg bpushed (x862-pop-register seg breg)))) |
---|
3502 | (unless atriv |
---|
3503 | (if aconst |
---|
3504 | (x862-one-targeted-reg-form seg aform areg) |
---|
3505 | (x862-elide-pushes seg apushed (x862-pop-register seg areg)))) |
---|
3506 | (values areg breg creg))) |
---|
3507 | |
---|
3508 | (defun x862-three-untargeted-reg-forms (seg aform areg bform breg cform creg) |
---|
3509 | (with-x86-local-vinsn-macros (seg) |
---|
3510 | (let* ((atriv (or (null aform) |
---|
3511 | (and (x862-trivial-p bform) |
---|
3512 | (x862-trivial-p cform)))) |
---|
3513 | (btriv (or (null bform) |
---|
3514 | (x862-trivial-p cform))) |
---|
3515 | (aconst (and (not atriv) |
---|
3516 | (or (x86-side-effect-free-form-p aform) |
---|
3517 | (let ((avar (x862-lexical-reference-p aform))) |
---|
3518 | (and avar |
---|
3519 | (x862-var-not-set-by-form-p avar bform) |
---|
3520 | (x862-var-not-set-by-form-p avar cform)))))) |
---|
3521 | (bconst (and (not btriv) |
---|
3522 | (or |
---|
3523 | (x86-side-effect-free-form-p bform) |
---|
3524 | (let ((bvar (x862-lexical-reference-p bform))) |
---|
3525 | (and bvar (x862-var-not-set-by-form-p bvar cform)))))) |
---|
3526 | (adest areg) |
---|
3527 | (bdest breg) |
---|
3528 | (cdest creg) |
---|
3529 | (apushed nil) |
---|
3530 | (bpushed nil)) |
---|
3531 | (if (and aform (not aconst)) |
---|
3532 | (if atriv |
---|
3533 | (setq adest (x862-one-untargeted-reg-form seg aform ($ areg))) |
---|
3534 | (setq apushed (x862-push-register seg (x862-one-untargeted-reg-form seg aform (x862-acc-reg-for areg)))))) |
---|
3535 | (if (and bform (not bconst)) |
---|
3536 | (if btriv |
---|
3537 | (setq bdest (x862-one-untargeted-reg-form seg bform ($ breg))) |
---|
3538 | (setq bpushed (x862-push-register seg (x862-one-untargeted-reg-form seg bform (x862-acc-reg-for breg)))))) |
---|
3539 | (setq cdest (x862-one-untargeted-reg-form seg cform creg)) |
---|
3540 | (unless btriv |
---|
3541 | (if bconst |
---|
3542 | (setq bdest (x862-one-untargeted-reg-form seg bform breg)) |
---|
3543 | (x862-elide-pushes seg bpushed (x862-pop-register seg breg)))) |
---|
3544 | (unless atriv |
---|
3545 | (if aconst |
---|
3546 | (setq adest (x862-one-untargeted-reg-form seg aform areg)) |
---|
3547 | (x862-elide-pushes seg apushed (x862-pop-register seg areg)))) |
---|
3548 | (values adest bdest cdest)))) |
---|
3549 | |
---|
3550 | (defun x862-four-untargeted-reg-forms (seg aform areg bform breg cform creg dform dreg) |
---|
3551 | (let* ((atriv (or (null aform) |
---|
3552 | (and (x862-trivial-p bform) |
---|
3553 | (x862-trivial-p cform) |
---|
3554 | (x862-trivial-p dform)))) |
---|
3555 | (btriv (or (null bform) |
---|
3556 | (and (x862-trivial-p cform) |
---|
3557 | (x862-trivial-p dform)))) |
---|
3558 | (ctriv (or (null cform) |
---|
3559 | (x862-trivial-p dform))) |
---|
3560 | (aconst (and (not atriv) |
---|
3561 | (or (x86-side-effect-free-form-p aform) |
---|
3562 | (let ((avar (x862-lexical-reference-p aform))) |
---|
3563 | (and avar |
---|
3564 | (x862-var-not-set-by-form-p avar bform) |
---|
3565 | (x862-var-not-set-by-form-p avar cform) |
---|
3566 | (x862-var-not-set-by-form-p avar dform)))))) |
---|
3567 | (bconst (and (not btriv) |
---|
3568 | (or |
---|
3569 | (x86-side-effect-free-form-p bform) |
---|
3570 | (let ((bvar (x862-lexical-reference-p bform))) |
---|
3571 | (and bvar |
---|
3572 | (x862-var-not-set-by-form-p bvar cform) |
---|
3573 | (x862-var-not-set-by-form-p bvar dform)))))) |
---|
3574 | (cconst (and (not ctriv) |
---|
3575 | (or |
---|
3576 | (x86-side-effect-free-form-p cform) |
---|
3577 | (let ((cvar (x862-lexical-reference-p cform))) |
---|
3578 | (and cvar |
---|
3579 | (x862-var-not-set-by-form-p cvar dform)))))) |
---|
3580 | (adest areg) |
---|
3581 | (bdest breg) |
---|
3582 | (cdest creg) |
---|
3583 | (ddest dreg) |
---|
3584 | (apushed nil) |
---|
3585 | (bpushed nil) |
---|
3586 | (cpushed nil)) |
---|
3587 | (if (and aform (not aconst)) |
---|
3588 | (if atriv |
---|
3589 | (setq adest (x862-one-targeted-reg-form seg aform areg)) |
---|
3590 | (setq apushed (x862-push-register seg (x862-one-untargeted-reg-form seg aform (x862-acc-reg-for areg)))))) |
---|
3591 | (if (and bform (not bconst)) |
---|
3592 | (if btriv |
---|
3593 | (setq bdest (x862-one-untargeted-reg-form seg bform breg)) |
---|
3594 | (setq bpushed (x862-push-register seg (x862-one-untargeted-reg-form seg bform (x862-acc-reg-for breg)))))) |
---|
3595 | (if (and cform (not cconst)) |
---|
3596 | (if ctriv |
---|
3597 | (setq cdest (x862-one-untargeted-reg-form seg cform creg)) |
---|
3598 | (setq cpushed (x862-push-register seg (x862-one-untargeted-reg-form seg cform (x862-acc-reg-for creg)))))) |
---|
3599 | (setq ddest (x862-one-untargeted-reg-form seg dform dreg)) |
---|
3600 | (unless ctriv |
---|
3601 | (if cconst |
---|
3602 | (setq cdest (x862-one-untargeted-reg-form seg cform creg)) |
---|
3603 | (x862-elide-pushes seg cpushed (x862-pop-register seg creg)))) |
---|
3604 | (unless btriv |
---|
3605 | (if bconst |
---|
3606 | (setq bdest (x862-one-untargeted-reg-form seg bform breg)) |
---|
3607 | (x862-elide-pushes seg bpushed (x862-pop-register seg breg)))) |
---|
3608 | (unless atriv |
---|
3609 | (if aconst |
---|
3610 | (setq adest (x862-one-untargeted-reg-form seg aform areg)) |
---|
3611 | (x862-elide-pushes seg apushed (x862-pop-register seg areg)))) |
---|
3612 | (values adest bdest cdest ddest))) |
---|
3613 | |
---|
3614 | (defun x862-lri (seg reg value) |
---|
3615 | (with-x86-local-vinsn-macros (seg) |
---|
3616 | (! lri reg value))) |
---|
3617 | |
---|
3618 | ;;; unsigned variant |
---|
3619 | (defun x862-lriu (seg reg value) |
---|
3620 | (with-x86-local-vinsn-macros (seg) |
---|
3621 | (! lriu reg value))) |
---|
3622 | |
---|
3623 | (defun x862-multiple-value-body (seg form) |
---|
3624 | (let* ((lab (backend-get-next-label)) |
---|
3625 | (*x862-vstack* *x862-vstack*) |
---|
3626 | (*x862-top-vstack-lcell* *x862-top-vstack-lcell*) |
---|
3627 | (old-stack (x862-encode-stack))) |
---|
3628 | (with-x86-local-vinsn-macros (seg) |
---|
3629 | (x862-open-undo $undomvexpect) |
---|
3630 | (x862-undo-body seg nil (logior $backend-mvpass-mask lab) form old-stack) |
---|
3631 | (@ lab)))) |
---|
3632 | |
---|
3633 | (defun x862-afunc-lfun-ref (afunc) |
---|
3634 | (or |
---|
3635 | (afunc-lfun afunc) |
---|
3636 | (progn (pushnew afunc (afunc-fwd-refs *x862-cur-afunc*) :test #'eq) |
---|
3637 | afunc))) |
---|
3638 | |
---|
3639 | (defun x862-augment-arglist (afunc arglist &optional (maxregs *x862-target-num-arg-regs*)) |
---|
3640 | (let ((inherited-args (afunc-inherited-vars afunc))) |
---|
3641 | (when inherited-args |
---|
3642 | (let* ((current-afunc *x862-cur-afunc*) |
---|
3643 | (stkargs (car arglist)) |
---|
3644 | (regargs (cadr arglist)) |
---|
3645 | (inhforms nil) |
---|
3646 | (numregs (length regargs)) |
---|
3647 | (own-inhvars (afunc-inherited-vars current-afunc))) |
---|
3648 | (dolist (var inherited-args) |
---|
3649 | (let* ((root-var (nx-root-var var)) |
---|
3650 | (other-guy |
---|
3651 | (dolist (v own-inhvars #|(error "other guy not found")|# root-var) |
---|
3652 | (when (eq root-var (nx-root-var v)) (return v))))) |
---|
3653 | (push (make-acode (%nx1-operator inherited-arg) other-guy) inhforms))) |
---|
3654 | (dolist (form inhforms) |
---|
3655 | (if (%i< numregs maxregs) |
---|
3656 | (progn |
---|
3657 | (setq regargs (nconc regargs (list form))) |
---|
3658 | (setq numregs (%i+ numregs 1))) |
---|
3659 | (push form stkargs))) |
---|
3660 | (%rplaca (%cdr arglist) regargs) ; might have started out NIL. |
---|
3661 | (%rplaca arglist stkargs)))) |
---|
3662 | arglist) |
---|
3663 | |
---|
3664 | (defun x862-acode-operator-supports-u8 (form) |
---|
3665 | (setq form (acode-unwrapped-form-value form)) |
---|
3666 | (when (acode-p form) |
---|
3667 | (let* ((operator (acode-operator form))) |
---|
3668 | (if (member operator *x862-operator-supports-u8-target*) |
---|
3669 | (values operator (acode-operand 1 form)))))) |
---|
3670 | |
---|
3671 | (defun x862-acode-operator-supports-push (form) |
---|
3672 | (let ((value (acode-unwrapped-form-value form))) |
---|
3673 | (when (acode-p value) |
---|
3674 | (if (or (eq value *nx-t*) |
---|
3675 | (eq value *nx-nil*) |
---|
3676 | (let* ((operator (acode-operator value))) |
---|
3677 | (member operator *x862-operator-supports-push*))) |
---|
3678 | value)))) |
---|
3679 | |
---|
3680 | (defun x862-compare-u8 (seg vreg xfer form u8constant cr-bit true-p u8-operator) |
---|
3681 | (with-x86-local-vinsn-macros (seg vreg xfer) |
---|
3682 | (with-imm-target () (u8 :u8) |
---|
3683 | (if (and (eql u8-operator (%nx1-operator lisptag)) |
---|
3684 | (eql 0 u8constant)) |
---|
3685 | (let* ((formreg (x862-one-untargeted-reg-form seg form *x862-arg-z*))) |
---|
3686 | |
---|
3687 | (! set-flags-from-lisptag formreg)) |
---|
3688 | (progn |
---|
3689 | (x862-use-operator u8-operator seg u8 nil form) |
---|
3690 | (if (zerop u8constant) |
---|
3691 | (! compare-u8-reg-to-zero u8) |
---|
3692 | (! compare-u8-constant u8 u8constant)))) |
---|
3693 | ;; Flags set. Branch or return a boolean value ? |
---|
3694 | (setq cr-bit (x862-cr-bit-for-unsigned-comparison cr-bit)) |
---|
3695 | (regspec-crf-gpr-case |
---|
3696 | (vreg dest) |
---|
3697 | (^ cr-bit true-p) |
---|
3698 | (progn |
---|
3699 | (ensuring-node-target (target dest) |
---|
3700 | (if (not true-p) |
---|
3701 | (setq cr-bit (logxor 1 cr-bit))) |
---|
3702 | (! cr-bit->boolean target cr-bit)) |
---|
3703 | (^)))))) |
---|
3704 | |
---|
3705 | ;;; There are other cases involving constants that are worth exploiting. |
---|
3706 | (defun x862-compare (seg vreg xfer i j cr-bit true-p) |
---|
3707 | (with-x86-local-vinsn-macros (seg vreg xfer) |
---|
3708 | (let* ((iu8 (let* ((i-fixnum (acode-fixnum-form-p i))) |
---|
3709 | (if (typep i-fixnum '(unsigned-byte 8)) |
---|
3710 | i-fixnum))) |
---|
3711 | (ju8 (let* ((j-fixnum (acode-fixnum-form-p j))) |
---|
3712 | (if (typep j-fixnum '(unsigned-byte 8)) |
---|
3713 | j-fixnum))) |
---|
3714 | (u8 (or iu8 ju8)) |
---|
3715 | (other-u8 (if iu8 j (if ju8 i))) |
---|
3716 | (js32 (acode-s32-constant-p j)) |
---|
3717 | (is32 (acode-s32-constant-p i)) |
---|
3718 | (boolean (backend-crf-p vreg))) |
---|
3719 | (multiple-value-bind (u8-operator u8-operand) (if other-u8 (x862-acode-operator-supports-u8 other-u8)) |
---|
3720 | (if u8-operator |
---|
3721 | (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) |
---|
3722 | (if (and boolean (or js32 is32)) |
---|
3723 | (let* ((reg (x862-one-untargeted-reg-form seg (if js32 i j) *x862-arg-z*)) |
---|
3724 | (constant (or js32 is32))) |
---|
3725 | (if (zerop constant) |
---|
3726 | (! compare-reg-to-zero reg) |
---|
3727 | (! compare-s32-constant reg (or js32 is32))) |
---|
3728 | (unless (or js32 (eq cr-bit x86::x86-e-bits)) |
---|
3729 | (setq cr-bit (x862-reverse-cr-bit cr-bit))) |
---|
3730 | (^ cr-bit true-p)) |
---|
3731 | (if (and ;(eq cr-bit x86::x86-e-bits) |
---|
3732 | (or js32 is32)) |
---|
3733 | (progn |
---|
3734 | (unless (or js32 (eq cr-bit x86::x86-e-bits)) |
---|
3735 | (setq cr-bit (x862-reverse-cr-bit cr-bit))) |
---|
3736 | (x862-test-reg-%izerop |
---|
3737 | seg |
---|
3738 | vreg |
---|
3739 | xfer |
---|
3740 | (x862-one-untargeted-reg-form |
---|
3741 | seg |
---|
3742 | (if js32 i j) |
---|
3743 | *x862-arg-z*) |
---|
3744 | cr-bit |
---|
3745 | true-p |
---|
3746 | (or js32 is32))) |
---|
3747 | (multiple-value-bind (ireg jreg) (x862-two-untargeted-reg-forms seg i *x862-arg-y* j *x862-arg-z*) |
---|
3748 | (x862-compare-registers seg vreg xfer ireg jreg cr-bit true-p))))))))) |
---|
3749 | |
---|
3750 | (defun x862-natural-compare (seg vreg xfer i j cr-bit true-p) |
---|
3751 | (with-x86-local-vinsn-macros (seg vreg xfer) |
---|
3752 | (let* ((jconstant (acode-fixnum-form-p j)) |
---|
3753 | (ju31 (typep jconstant '(unsigned-byte 31))) |
---|
3754 | (iconstant (acode-fixnum-form-p i)) |
---|
3755 | (iu31 (typep iconstant '(unsigned-byte 31))) |
---|
3756 | (boolean (backend-crf-p vreg))) |
---|
3757 | (if (and boolean (or ju31 iu31)) |
---|
3758 | (with-imm-target |
---|
3759 | () (reg :natural) |
---|
3760 | (x862-one-targeted-reg-form seg (if ju31 i j) reg) |
---|
3761 | (! compare-u31-constant reg (if ju31 jconstant iconstant)) |
---|
3762 | (unless (or ju31 (eq cr-bit x86::x86-e-bits)) |
---|
3763 | (setq cr-bit (x862-reverse-cr-bit cr-bit))) |
---|
3764 | (^ cr-bit true-p)) |
---|
3765 | (with-imm-target () (ireg :natural) |
---|
3766 | (with-additional-imm-reg () |
---|
3767 | (with-imm-target |
---|
3768 | (ireg) (jreg :natural) |
---|
3769 | (x862-two-targeted-reg-forms seg i ireg j jreg) |
---|
3770 | (x862-compare-natural-registers seg vreg xfer ireg jreg cr-bit true-p)))))))) |
---|
3771 | |
---|
3772 | |
---|
3773 | (defun x862-cr-bit-for-logical-comparison (cr-bit true-p) |
---|
3774 | (declare (fixnum cr-bit)) |
---|
3775 | (let* ((unsigned |
---|
3776 | (case cr-bit |
---|
3777 | (#.x86::x86-l-bits x86::x86-b-bits) |
---|
3778 | (#.x86::x86-le-bits x86::x86-be-bits ) |
---|
3779 | (#.x86::x86-g-bits x86::x86-a-bits) |
---|
3780 | (#.x86::x86-ge-bits x86::x86-ae-bits) |
---|
3781 | (t cr-bit)))) |
---|
3782 | (declare (fixnum unsigned)) |
---|
3783 | (if true-p |
---|
3784 | unsigned |
---|
3785 | (logxor unsigned 1)))) |
---|
3786 | |
---|
3787 | (defun x862-compare-natural-registers (seg vreg xfer ireg jreg cr-bit true-p) |
---|
3788 | (with-x86-local-vinsn-macros (seg vreg xfer) |
---|
3789 | (if vreg |
---|
3790 | (progn |
---|
3791 | (setq cr-bit (x862-cr-bit-for-logical-comparison cr-bit true-p)) |
---|
3792 | (! compare ireg jreg) |
---|
3793 | (regspec-crf-gpr-case |
---|
3794 | (vreg dest) |
---|
3795 | (^ cr-bit true-p) |
---|
3796 | (progn |
---|
3797 | (ensuring-node-target (target dest) |
---|
3798 | (! cr-bit->boolean target cr-bit)) |
---|
3799 | (^)))) |
---|
3800 | (^)))) |
---|
3801 | |
---|
3802 | |
---|
3803 | (defun x862-compare-registers (seg vreg xfer ireg jreg cr-bit true-p) |
---|
3804 | (with-x86-local-vinsn-macros (seg vreg xfer) |
---|
3805 | (if vreg |
---|
3806 | (progn |
---|
3807 | (! compare ireg jreg) |
---|
3808 | (regspec-crf-gpr-case |
---|
3809 | (vreg dest) |
---|
3810 | (^ cr-bit true-p) |
---|
3811 | (progn |
---|
3812 | (ensuring-node-target (target dest) |
---|
3813 | (if (not true-p) |
---|
3814 | (setq cr-bit (logxor 1 cr-bit))) |
---|
3815 | (! cr-bit->boolean target cr-bit)) |
---|
3816 | (^)))) |
---|
3817 | (^)))) |
---|
3818 | |
---|
3819 | (defun x862-compare-register-to-constant (seg vreg xfer ireg cr-bit true-p constant) |
---|
3820 | (cond ((eq constant *nx-nil*) |
---|
3821 | (x862-compare-register-to-nil seg vreg xfer ireg cr-bit true-p)) |
---|
3822 | (t |
---|
3823 | (with-x86-local-vinsn-macros (seg vreg xfer) |
---|
3824 | (when vreg |
---|
3825 | (if (eq constant *nx-t*) |
---|
3826 | (! compare-to-t ireg) |
---|
3827 | (let* ((imm (x862-immediate-operand constant)) |
---|
3828 | (reg (x862-register-constant-p imm))) |
---|
3829 | (if reg |
---|
3830 | (! compare-registers reg ireg) |
---|
3831 | (! compare-constant-to-register (x86-immediate-label imm) ireg)))) |
---|
3832 | (regspec-crf-gpr-case |
---|
3833 | (vreg dest) |
---|
3834 | (^ cr-bit true-p) |
---|
3835 | (progn |
---|
3836 | (ensuring-node-target (target dest) |
---|
3837 | (if (not true-p) |
---|
3838 | (setq cr-bit (logxor 1 cr-bit))) |
---|
3839 | (! cr-bit->boolean target cr-bit)) |
---|
3840 | (^)))))))) |
---|
3841 | |
---|
3842 | (defun x862-compare-register-to-nil (seg vreg xfer ireg cr-bit true-p) |
---|
3843 | (with-x86-local-vinsn-macros (seg vreg xfer) |
---|
3844 | (when vreg |
---|
3845 | (! compare-to-nil ireg) |
---|
3846 | (regspec-crf-gpr-case |
---|
3847 | (vreg dest) |
---|
3848 | (^ cr-bit true-p) |
---|
3849 | (progn |
---|
3850 | (ensuring-node-target (target dest) |
---|
3851 | (if (not true-p) |
---|
3852 | (setq cr-bit (logxor 1 cr-bit))) |
---|
3853 | (! cr-bit->boolean target cr-bit)) |
---|
3854 | (^)))))) |
---|
3855 | |
---|
3856 | (defun x862-compare-ea-to-nil (seg vreg xfer ea cr-bit true-p) |
---|
3857 | (with-x86-local-vinsn-macros (seg vreg xfer) |
---|
3858 | (when vreg |
---|
3859 | (if (addrspec-vcell-p ea) |
---|
3860 | (with-node-target () temp |
---|
3861 | (x862-stack-to-register seg ea temp) |
---|
3862 | (! compare-value-cell-to-nil temp)) |
---|
3863 | (! compare-vframe-offset-to-nil (memspec-frame-address-offset ea) *x862-vstack*)) |
---|
3864 | (regspec-crf-gpr-case |
---|
3865 | (vreg dest) |
---|
3866 | (^ cr-bit true-p) |
---|
3867 | (progn |
---|
3868 | (ensuring-node-target (target dest) |
---|
3869 | (if (not true-p) |
---|
3870 | (setq cr-bit (logxor 1 cr-bit))) |
---|
3871 | (! cr-bit->boolean target cr-bit)) |
---|
3872 | (^)))))) |
---|
3873 | |
---|
3874 | (defun x862-cr-bit-for-unsigned-comparison (cr-bit) |
---|
3875 | (ecase cr-bit |
---|
3876 | (#.x86::x86-e-bits #.x86::x86-e-bits) |
---|
3877 | (#.x86::x86-ne-bits #.x86::x86-ne-bits) |
---|
3878 | (#.x86::x86-l-bits #.x86::x86-b-bits) |
---|
3879 | (#.x86::x86-le-bits #.x86::x86-be-bits) |
---|
3880 | (#.x86::x86-ge-bits #.x86::x86-ae-bits) |
---|
3881 | (#.x86::x86-g-bits #.x86::x86-a-bits))) |
---|
3882 | |
---|
3883 | |
---|
3884 | (defun x862-compare-double-float-registers (seg vreg xfer ireg jreg cr-bit true-p) |
---|
3885 | (with-x86-local-vinsn-macros (seg vreg xfer) |
---|
3886 | (if vreg |
---|
3887 | (progn |
---|
3888 | (setq cr-bit (x862-cr-bit-for-unsigned-comparison cr-bit)) |
---|
3889 | (regspec-crf-gpr-case |
---|
3890 | (vreg dest) |
---|
3891 | (progn |
---|
3892 | (! double-float-compare ireg jreg) |
---|
3893 | (^ cr-bit true-p)) |
---|
3894 | (progn |
---|
3895 | (! double-float-compare ireg jreg) |
---|
3896 | (ensuring-node-target (target dest) |
---|
3897 | (if (not true-p) |
---|
3898 | (setq cr-bit (logxor 1 cr-bit))) |
---|
3899 | (! cr-bit->boolean target cr-bit)) |
---|
3900 | (^)))) |
---|
3901 | (^)))) |
---|
3902 | |
---|
3903 | (defun x862-compare-single-float-registers (seg vreg xfer ireg jreg cr-bit true-p) |
---|
3904 | (with-x86-local-vinsn-macros (seg vreg xfer) |
---|
3905 | (if vreg |
---|
3906 | (progn |
---|
3907 | (setq cr-bit (x862-cr-bit-for-unsigned-comparison cr-bit)) |
---|
3908 | (regspec-crf-gpr-case |
---|
3909 | (vreg dest) |
---|
3910 | (progn |
---|
3911 | (! single-float-compare ireg jreg) |
---|
3912 | (^ cr-bit true-p)) |
---|
3913 | (progn |
---|
3914 | (! single-float-compare ireg jreg) |
---|
3915 | (ensuring-node-target (target dest) |
---|
3916 | (if (not true-p) |
---|
3917 | (setq cr-bit (logxor 1 cr-bit))) |
---|
3918 | (! cr-bit->boolean target cr-bit)) |
---|
3919 | (^)))) |
---|
3920 | (^)))) |
---|
3921 | |
---|
3922 | |
---|
3923 | (defun x862-immediate-form-p (form) |
---|
3924 | (if (and (consp form) |
---|
3925 | (or (eq (%car form) (%nx1-operator immediate)) |
---|
3926 | (eq (%car form) (%nx1-operator simple-function)))) |
---|
3927 | t)) |
---|
3928 | |
---|
3929 | (defun x862-test-%izerop (seg vreg xfer form cr-bit true-p) |
---|
3930 | (x862-test-reg-%izerop seg vreg xfer (x862-one-untargeted-reg-form seg form *x862-arg-z*) cr-bit true-p 0)) |
---|
3931 | |
---|
3932 | (defun x862-test-reg-%izerop (seg vreg xfer reg cr-bit true-p zero) |
---|
3933 | (declare (fixnum zero)) |
---|
3934 | (with-x86-local-vinsn-macros (seg vreg xfer) |
---|
3935 | (if (zerop zero) |
---|
3936 | (! compare-reg-to-zero reg) |
---|
3937 | (! compare-s32-constant reg zero)) |
---|
3938 | (regspec-crf-gpr-case |
---|
3939 | (vreg dest) |
---|
3940 | (^ cr-bit true-p) |
---|
3941 | (progn |
---|
3942 | (ensuring-node-target (target dest) |
---|
3943 | (if (not true-p) |
---|
3944 | (setq cr-bit (logxor 1 cr-bit))) |
---|
3945 | (! cr-bit->boolean target cr-bit)) |
---|
3946 | (^))))) |
---|
3947 | |
---|
3948 | (defun x862-lexical-reference-ea (form &optional (no-closed-p t)) |
---|
3949 | (when (acode-p (setq form (acode-unwrapped-form-value form))) |
---|
3950 | (if (eq (acode-operator form) (%nx1-operator lexical-reference)) |
---|
3951 | (let* ((addr (var-ea (%cadr form)))) |
---|
3952 | (if (typep addr 'lreg) |
---|
3953 | addr |
---|
3954 | (unless (and no-closed-p (addrspec-vcell-p addr )) |
---|
3955 | addr)))))) |
---|
3956 | |
---|
3957 | |
---|
3958 | (defun x862-vpush-register (seg src &optional why info attr) |
---|
3959 | (with-x86-local-vinsn-macros (seg) |
---|
3960 | (prog1 |
---|
3961 | (! vpush-register src) |
---|
3962 | (setq *x862-tos-reg* src) |
---|
3963 | (x862-new-vstack-lcell (or why :node) *x862-target-lcell-size* (or attr 0) info) |
---|
3964 | (x862-adjust-vstack *x862-target-node-size*)))) |
---|
3965 | |
---|
3966 | |
---|
3967 | ;;; Need to track stack usage when pushing label for mv-call. |
---|
3968 | (defun x862-vpush-label (seg label) |
---|
3969 | (with-x86-local-vinsn-macros (seg) |
---|
3970 | (prog1 |
---|
3971 | (! vpush-label label) |
---|
3972 | (x862-new-vstack-lcell :label *x862-target-lcell-size* 0 nil) |
---|
3973 | (x862-adjust-vstack *x862-target-node-size*)))) |
---|
3974 | |
---|
3975 | (defun x862-temp-push-node (seg reg) |
---|
3976 | (with-x86-local-vinsn-macros (seg) |
---|
3977 | (! temp-push-node reg) |
---|
3978 | (x862-open-undo $undostkblk))) |
---|
3979 | |
---|
3980 | (defun x862-temp-pop-node (seg reg) |
---|
3981 | (with-x86-local-vinsn-macros (seg) |
---|
3982 | (! temp-pop-node reg) |
---|
3983 | (x862-close-undo))) |
---|
3984 | |
---|
3985 | (defun x862-vpush-register-arg (seg src) |
---|
3986 | (x862-vpush-register seg src :outgoing-argument)) |
---|
3987 | |
---|
3988 | |
---|
3989 | (defun x862-vpop-register (seg dest) |
---|
3990 | (with-x86-local-vinsn-macros (seg) |
---|
3991 | (prog1 |
---|
3992 | (! vpop-register dest) |
---|
3993 | (setq *x862-top-vstack-lcell* (lcell-parent *x862-top-vstack-lcell*)) |
---|
3994 | (x862-adjust-vstack (- *x862-target-node-size*))))) |
---|
3995 | |
---|
3996 | (defun x862-macptr->heap (seg dest src) |
---|
3997 | (with-x86-local-vinsn-macros (seg) |
---|
3998 | (! setup-macptr-allocation src) |
---|
3999 | (! %allocate-uvector dest) |
---|
4000 | (! %set-new-macptr-value dest))) |
---|
4001 | |
---|
4002 | (defun x862-copy-register (seg dest src) |
---|
4003 | (with-x86-local-vinsn-macros (seg) |
---|
4004 | (when dest |
---|
4005 | (let* ((dest-gpr (backend-ea-physical-reg dest hard-reg-class-gpr)) |
---|
4006 | (src-gpr (if src (backend-ea-physical-reg src hard-reg-class-gpr))) |
---|
4007 | (dest-fpr (backend-ea-physical-reg dest hard-reg-class-fpr)) |
---|
4008 | (src-fpr (if src (backend-ea-physical-reg src hard-reg-class-fpr))) |
---|
4009 | (src-mode (if src (get-regspec-mode src))) |
---|
4010 | (dest-mode (get-regspec-mode dest)) |
---|
4011 | (dest-crf (backend-ea-physical-reg dest hard-reg-class-crf))) |
---|
4012 | (if (null src) |
---|
4013 | (if dest-gpr |
---|
4014 | (! load-nil dest-gpr) |
---|
4015 | (if dest-crf |
---|
4016 | (! set-eq-bit))) |
---|
4017 | (if (and dest-crf src-gpr) |
---|
4018 | ;; "Copying" a GPR to a CR field means comparing it to rnil |
---|
4019 | (! compare-to-nil src) |
---|
4020 | (if (and dest-gpr src-gpr) |
---|
4021 | (if (eq src-mode dest-mode) |
---|
4022 | (unless (eq src-gpr dest-gpr) |
---|
4023 | (! copy-gpr dest src)) |
---|
4024 | ;; This is the "GPR <- GPR" case. There are |
---|
4025 | ;; word-size dependencies, but there's also |
---|
4026 | ;; lots of redundancy here. |
---|
4027 | (target-arch-case |
---|
4028 | (:x8632 |
---|
4029 | (ecase dest-mode |
---|
4030 | (#.hard-reg-class-gpr-mode-node ; boxed result. |
---|
4031 | (case src-mode |
---|
4032 | (#.hard-reg-class-gpr-mode-node |
---|
4033 | (unless (eql dest-gpr src-gpr) |
---|
4034 | (! copy-gpr dest src))) |
---|
4035 | (#.hard-reg-class-gpr-mode-u32 |
---|
4036 | (x862-box-u32 seg dest src)) |
---|
4037 | (#.hard-reg-class-gpr-mode-s32 |
---|
4038 | (x862-box-s32 seg dest src)) |
---|
4039 | (#.hard-reg-class-gpr-mode-u16 |
---|
4040 | (! box-fixnum dest src)) |
---|
4041 | (#.hard-reg-class-gpr-mode-s16 |
---|
4042 | (! box-fixnum dest src)) |
---|
4043 | (#.hard-reg-class-gpr-mode-u8 |
---|
4044 | (! box-fixnum dest src)) |
---|
4045 | (#.hard-reg-class-gpr-mode-s8 |
---|
4046 | (! box-fixnum dest src)) |
---|
4047 | (#.hard-reg-class-gpr-mode-address |
---|
4048 | (x862-macptr->heap seg dest src)))) |
---|
4049 | ((#.hard-reg-class-gpr-mode-u32 |
---|
4050 | #.hard-reg-class-gpr-mode-address) |
---|
4051 | (case src-mode |
---|
4052 | (#.hard-reg-class-gpr-mode-node |
---|
4053 | (let* ((src-type (get-node-regspec-type-modes src))) |
---|
4054 | (declare (fixnum src-type)) |
---|
4055 | (case dest-mode |
---|
4056 | (#.hard-reg-class-gpr-mode-u32 |
---|
4057 | (! unbox-u32 dest src)) |
---|
4058 | (#.hard-reg-class-gpr-mode-address |
---|
4059 | (unless (or (logbitp #.hard-reg-class-gpr-mode-address src-type) |
---|
4060 | *x862-reckless*) |
---|
4061 | (! trap-unless-macptr src)) |
---|
4062 | (! deref-macptr dest src))))) |
---|
4063 | ((#.hard-reg-class-gpr-mode-u32 |
---|
4064 | #.hard-reg-class-gpr-mode-s32 |
---|
4065 | #.hard-reg-class-gpr-mode-address) |
---|
4066 | (unless (eql dest-gpr src-gpr) |
---|
4067 | (! copy-gpr dest src))) |
---|
4068 | (#.hard-reg-class-gpr-mode-u16 |
---|
4069 | (! u16->u32 dest src)) |
---|
4070 | (#.hard-reg-class-gpr-mode-s16 |
---|
4071 | (! s16->s32 dest src)) |
---|
4072 | (#.hard-reg-class-gpr-mode-u8 |
---|
4073 | (! u8->u32 dest src)) |
---|
4074 | (#.hard-reg-class-gpr-mode-s8 |
---|
4075 | (! s8->s32 dest src)))) |
---|
4076 | (#.hard-reg-class-gpr-mode-s32 |
---|
4077 | (case src-mode |
---|
4078 | (#.hard-reg-class-gpr-mode-node |
---|
4079 | (! unbox-s32 dest src)) |
---|
4080 | ((#.hard-reg-class-gpr-mode-u32 |
---|
4081 | #.hard-reg-class-gpr-mode-s32 |
---|
4082 | #.hard-reg-class-gpr-mode-address) |
---|
4083 | (unless (eql dest-gpr src-gpr) |
---|
4084 | (! copy-gpr dest src))) |
---|
4085 | (#.hard-reg-class-gpr-mode-u16 |
---|
4086 | (! u16->u32 dest src)) |
---|
4087 | (#.hard-reg-class-gpr-mode-s16 |
---|
4088 | (! s16->s32 dest src)) |
---|
4089 | (#.hard-reg-class-gpr-mode-u8 |
---|
4090 | (! u8->u32 dest src)) |
---|
4091 | (#.hard-reg-class-gpr-mode-s8 |
---|
4092 | (! s8->s32 dest src)))) |
---|
4093 | (#.hard-reg-class-gpr-mode-u16 |
---|
4094 | (case src-mode |
---|
4095 | (#.hard-reg-class-gpr-mode-node |
---|
4096 | (! unbox-u16 dest src)) |
---|
4097 | ((#.hard-reg-class-gpr-mode-u8 |
---|
4098 | #.hard-reg-class-gpr-mode-s8) |
---|
4099 | (! u8->u32 dest src)) |
---|
4100 | (t |
---|
4101 | (unless (eql dest-gpr src-gpr) |
---|
4102 | (! copy-gpr dest src))))) |
---|
4103 | (#.hard-reg-class-gpr-mode-s16 |
---|
4104 | (case src-mode |
---|
4105 | (#.hard-reg-class-gpr-mode-node |
---|
4106 | (! unbox-s16 dest src)) |
---|
4107 | (#.hard-reg-class-gpr-mode-s8 |
---|
4108 | (! s8->s32 dest src)) |
---|
4109 | (#.hard-reg-class-gpr-mode-u8 |
---|
4110 | (! u8->u32 dest src)) |
---|
4111 | (t |
---|
4112 | (unless (eql dest-gpr src-gpr) |
---|
4113 | (! copy-gpr dest src))))) |
---|
4114 | (#.hard-reg-class-gpr-mode-u8 |
---|
4115 | (case src-mode |
---|
4116 | (#.hard-reg-class-gpr-mode-node |
---|
4117 | (if *x862-reckless* |
---|
4118 | (! %unbox-u8 dest src) |
---|
4119 | (! unbox-u8 dest src))) |
---|
4120 | (t |
---|
4121 | (unless (eql dest-gpr src-gpr) |
---|
4122 | (! copy-gpr dest src))))) |
---|
4123 | (#.hard-reg-class-gpr-mode-s8 |
---|
4124 | (case src-mode |
---|
4125 | (#.hard-reg-class-gpr-mode-node |
---|
4126 | (! unbox-s8 dest src)) |
---|
4127 | (t |
---|
4128 | (unless (eql dest-gpr src-gpr) |
---|
4129 | (! copy-gpr dest src))))))) |
---|
4130 | (:x8664 |
---|
4131 | (ecase dest-mode |
---|
4132 | (#.hard-reg-class-gpr-mode-node ; boxed result. |
---|
4133 | (case src-mode |
---|
4134 | (#.hard-reg-class-gpr-mode-node |
---|
4135 | (unless (eql dest-gpr src-gpr) |
---|
4136 | (! copy-gpr dest src))) |
---|
4137 | (#.hard-reg-class-gpr-mode-u64 |
---|
4138 | (x862-box-u64 seg dest src)) |
---|
4139 | (#.hard-reg-class-gpr-mode-s64 |
---|
4140 | (x862-box-s64 seg dest src)) |
---|
4141 | (#.hard-reg-class-gpr-mode-u32 |
---|
4142 | (x862-box-u32 seg dest src)) |
---|
4143 | (#.hard-reg-class-gpr-mode-s32 |
---|
4144 | (x862-box-s32 seg dest src)) |
---|
4145 | (#.hard-reg-class-gpr-mode-u16 |
---|
4146 | (! box-fixnum dest src)) |
---|
4147 | (#.hard-reg-class-gpr-mode-s16 |
---|
4148 | (! box-fixnum dest src)) |
---|
4149 | (#.hard-reg-class-gpr-mode-u8 |
---|
4150 | (! box-fixnum dest src)) |
---|
4151 | (#.hard-reg-class-gpr-mode-s8 |
---|
4152 | (! box-fixnum dest src)) |
---|
4153 | (#.hard-reg-class-gpr-mode-address |
---|
4154 | (x862-macptr->heap seg dest src)))) |
---|
4155 | ((#.hard-reg-class-gpr-mode-u64 |
---|
4156 | #.hard-reg-class-gpr-mode-address) |
---|
4157 | (case src-mode |
---|
4158 | (#.hard-reg-class-gpr-mode-node |
---|
4159 | (let* ((src-type (get-node-regspec-type-modes src))) |
---|
4160 | (declare (fixnum src-type)) |
---|
4161 | (case dest-mode |
---|
4162 | (#.hard-reg-class-gpr-mode-u64 |
---|
4163 | (! unbox-u64 dest src)) |
---|
4164 | (#.hard-reg-class-gpr-mode-address |
---|
4165 | (unless (or (logbitp #.hard-reg-class-gpr-mode-address src-type) |
---|
4166 | *x862-reckless*) |
---|
4167 | (! trap-unless-macptr src)) |
---|
4168 | (! deref-macptr dest src))))) |
---|
4169 | ((#.hard-reg-class-gpr-mode-u64 |
---|
4170 | #.hard-reg-class-gpr-mode-s64 |
---|
4171 | #.hard-reg-class-gpr-mode-address) |
---|
4172 | (unless (eql dest-gpr src-gpr) |
---|
4173 | (! copy-gpr dest src))) |
---|
4174 | ((#.hard-reg-class-gpr-mode-u16 |
---|
4175 | #.hard-reg-class-gpr-mode-s16) |
---|
4176 | (! u16->u32 dest src)) |
---|
4177 | ((#.hard-reg-class-gpr-mode-u8 |
---|
4178 | #.hard-reg-class-gpr-mode-s8) |
---|
4179 | (! u8->u32 dest src)))) |
---|
4180 | (#.hard-reg-class-gpr-mode-s64 |
---|
4181 | (case src-mode |
---|
4182 | (#.hard-reg-class-gpr-mode-node |
---|
4183 | (! unbox-s64 dest src)) |
---|
4184 | ((#.hard-reg-class-gpr-mode-u64 |
---|
4185 | #.hard-reg-class-gpr-mode-s64 |
---|
4186 | #.hard-reg-class-gpr-mode-address) |
---|
4187 | (unless (eql dest-gpr src-gpr) |
---|
4188 | (! copy-gpr dest src))) |
---|
4189 | ((#.hard-reg-class-gpr-mode-u16 |
---|
4190 | #.hard-reg-class-gpr-mode-s16) |
---|
4191 | (! s16->s32 dest src)) |
---|
4192 | ((#.hard-reg-class-gpr-mode-u8 |
---|
4193 | #.hard-reg-class-gpr-mode-s8) |
---|
4194 | (! s8->s32 dest src)))) |
---|
4195 | (#.hard-reg-class-gpr-mode-s32 |
---|
4196 | (case src-mode |
---|
4197 | (#.hard-reg-class-gpr-mode-node |
---|
4198 | (! unbox-s32 dest src)) |
---|
4199 | ((#.hard-reg-class-gpr-mode-u32 |
---|
4200 | #.hard-reg-class-gpr-mode-s32 |
---|
4201 | #.hard-reg-class-gpr-mode-address) |
---|
4202 | (unless (eql dest-gpr src-gpr) |
---|
4203 | (! copy-gpr dest src))) |
---|
4204 | (#.hard-reg-class-gpr-mode-u16 |
---|
4205 | (! u16->u32 dest src)) |
---|
4206 | (#.hard-reg-class-gpr-mode-s16 |
---|
4207 | (! s16->s32 dest src)) |
---|
4208 | (#.hard-reg-class-gpr-mode-u8 |
---|
4209 | (! u8->u32 dest src)) |
---|
4210 | (#.hard-reg-class-gpr-mode-s8 |
---|
4211 | (! s8->s32 dest src)))) |
---|
4212 | (#.hard-reg-class-gpr-mode-u32 |
---|
4213 | (case src-mode |
---|
4214 | (#.hard-reg-class-gpr-mode-node |
---|
4215 | (if *x862-reckless* |
---|
4216 | (! %unbox-u32 dest src) |
---|
4217 | (! unbox-u32 dest src))) |
---|
4218 | ((#.hard-reg-class-gpr-mode-u32 |
---|
4219 | #.hard-reg-class-gpr-mode-s32) |
---|
4220 | (unless (eql dest-gpr src-gpr) |
---|
4221 | (! copy-gpr |
---|