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