source: branches/1.1/ccl/compiler/PPC/ppc2.lisp

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

In PPC2-ASET2, we need to use 4 targeted regs when need-memoization
is true.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 400.2 KB
Line 
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-node-shift* 0)
32(defparameter *ppc2-target-bits-in-word* 0)
33(defparameter *ppc2-ppc32-half-fixnum-type* '(signed-byte 29))
34(defparameter *ppc2-ppc64-half-fixnum-type* `(signed-byte 60))
35(defparameter *ppc2-target-half-fixnum-type* nil)
36
37
38
39
40(defun ppc2-immediate-operand (x)
41 (if (eq (acode-operator x) (%nx1-operator immediate))
42 (cadr x)
43 (error "~&Bug: not an immediate: ~s" x)))
44
45(defmacro with-ppc-p2-declarations (declsform &body body)
46 `(let* ((*ppc2-tail-allow* *ppc2-tail-allow*)
47 (*ppc2-reckless* *ppc2-reckless*)
48 (*ppc2-open-code-inline* *ppc2-open-code-inline*)
49 (*ppc2-trust-declarations* *ppc2-trust-declarations*))
50 (ppc2-decls ,declsform)
51 ,@body))
52
53
54(defmacro with-ppc-local-vinsn-macros ((segvar &optional vreg-var xfer-var) &body body)
55 (declare (ignorable xfer-var))
56 (let* ((template-name-var (gensym))
57 (template-temp (gensym))
58 (args-var (gensym))
59 (labelnum-var (gensym))
60 (retvreg-var (gensym))
61 (label-var (gensym)))
62 `(macrolet ((! (,template-name-var &rest ,args-var)
63 (let* ((,template-temp (get-vinsn-template-cell ,template-name-var (backend-p2-vinsn-templates *target-backend*))))
64 (unless ,template-temp
65 (warn "VINSN \"~A\" not defined" ,template-name-var))
66 `(%emit-vinsn ,',segvar ',,template-name-var (backend-p2-vinsn-templates *target-backend*) ,@,args-var))))
67 (macrolet ((<- (,retvreg-var)
68 `(ppc2-copy-register ,',segvar ,',vreg-var ,,retvreg-var))
69 (@ (,labelnum-var)
70 `(backend-gen-label ,',segvar ,,labelnum-var))
71 (-> (,label-var)
72 `(! jump (aref *backend-labels* ,,label-var)))
73 (^ (&rest branch-args)
74 `(ppc2-branch ,',segvar ,',xfer-var ,',vreg-var ,@branch-args))
75 (? (&key (class :gpr)
76 (mode :lisp))
77 (let* ((class-val
78 (ecase class
79 (:gpr hard-reg-class-gpr)
80 (:fpr hard-reg-class-fpr)
81 (:crf hard-reg-class-crf)))
82 (mode-val
83 (if (eq class :gpr)
84 (gpr-mode-name-value mode)
85 (if (eq class :fpr)
86 (if (eq mode :single-float)
87 hard-reg-class-fpr-mode-single
88 hard-reg-class-fpr-mode-double)
89 0))))
90 `(make-unwired-lreg nil
91 :class ,class-val
92 :mode ,mode-val)))
93 ($ (reg &key (class :gpr) (mode :lisp))
94 (let* ((class-val
95 (ecase class
96 (:gpr hard-reg-class-gpr)
97 (:fpr hard-reg-class-fpr)
98 (:crf hard-reg-class-crf)))
99 (mode-val
100 (if (eq class :gpr)
101 (gpr-mode-name-value mode)
102 (if (eq class :fpr)
103 (if (eq mode :single-float)
104 hard-reg-class-fpr-mode-single
105 hard-reg-class-fpr-mode-double)
106 0))))
107 `(make-wired-lreg ,reg
108 :class ,class-val
109 :mode ,mode-val))))
110 ,@body))))
111
112
113
114
115
116
117
118
119
120
121
122
123(defvar *ppc-current-context-annotation* nil)
124(defvar *ppc2-woi* nil)
125(defvar *ppc2-open-code-inline* nil)
126(defvar *ppc2-register-restore-count* 0)
127(defvar *ppc2-register-restore-ea* nil)
128(defvar *ppc2-compiler-register-save-label* nil)
129(defvar *ppc2-valid-register-annotations* 0)
130(defvar *ppc2-register-annotation-types* nil)
131(defvar *ppc2-register-ea-annotations* nil)
132
133(defparameter *ppc2-tail-call-aliases*
134 ()
135 #| '((%call-next-method . (%tail-call-next-method . 1))) |#
136
137)
138
139(defvar *ppc2-popreg-labels* nil)
140(defvar *ppc2-popj-labels* nil)
141(defvar *ppc2-valret-labels* nil)
142(defvar *ppc2-nilret-labels* nil)
143
144(defvar *ppc2-icode* nil)
145(defvar *ppc2-undo-stack* nil)
146(defvar *ppc2-undo-because* nil)
147
148
149(defvar *ppc2-cur-afunc* nil)
150(defvar *ppc2-vstack* 0)
151(defvar *ppc2-cstack* 0)
152(defvar *ppc2-undo-count* 0)
153(defvar *ppc2-returning-values* nil)
154(defvar *ppc2-vcells* nil)
155(defvar *ppc2-fcells* nil)
156(defvar *ppc2-entry-vsp-saved-p* nil)
157
158(defvar *ppc2-entry-label* nil)
159(defvar *ppc2-tail-label* nil)
160(defvar *ppc2-tail-vsp* nil)
161(defvar *ppc2-tail-nargs* nil)
162(defvar *ppc2-tail-allow* t)
163(defvar *ppc2-reckless* nil)
164(defvar *ppc2-trust-declarations* nil)
165(defvar *ppc2-entry-vstack* nil)
166(defvar *ppc2-fixed-nargs* nil)
167(defvar *ppc2-need-nargs* t)
168
169(defparameter *ppc2-inhibit-register-allocation* nil)
170(defvar *ppc2-record-symbols* nil)
171(defvar *ppc2-recorded-symbols* nil)
172
173(defvar *ppc2-result-reg* ppc::arg_z)
174
175
176
177
178
179(declaim (fixnum *ppc2-vstack* *ppc2-cstack*))
180
181
182
183
184;;; Before any defppc2's, make the *ppc2-specials* vector.
185
186(defvar *ppc2-all-lcells* ())
187
188
189
190
191
192(defun ppc2-free-lcells ()
193 (without-interrupts
194 (let* ((prev (pool.data *lcell-freelist*)))
195 (dolist (r *ppc2-all-lcells*)
196 (setf (lcell-kind r) prev
197 prev r))
198 (setf (pool.data *lcell-freelist*) prev)
199 (setq *ppc2-all-lcells* nil))))
200
201(defun ppc2-note-lcell (c)
202 (push c *ppc2-all-lcells*)
203 c)
204
205(defvar *ppc2-top-vstack-lcell* ())
206(defvar *ppc2-bottom-vstack-lcell* ())
207
208(defun ppc2-new-lcell (kind parent width attributes info)
209 (ppc2-note-lcell (make-lcell kind parent width attributes info)))
210
211(defun ppc2-new-vstack-lcell (kind width attributes info)
212 (setq *ppc2-top-vstack-lcell* (ppc2-new-lcell kind *ppc2-top-vstack-lcell* width attributes info)))
213
214(defun ppc2-reserve-vstack-lcells (n)
215 (dotimes (i n) (ppc2-new-vstack-lcell :reserved *ppc2-target-lcell-size* 0 nil)))
216
217(defun ppc2-vstack-mark-top ()
218 (ppc2-new-lcell :tos *ppc2-top-vstack-lcell* 0 0 nil))
219
220;;; Alist mapping VARs to lcells/lregs
221(defvar *ppc2-var-cells* ())
222
223(defun ppc2-note-var-cell (var cell)
224 ;(format t "~& ~s -> ~s" (var-name var) cell)
225 (push (cons var cell) *ppc2-var-cells*))
226
227(defun ppc2-note-top-cell (var)
228 (ppc2-note-var-cell var *ppc2-top-vstack-lcell*))
229
230(defun ppc2-lookup-var-cell (var)
231 (or (cdr (assq var *ppc2-var-cells*))
232 (and nil (warn "Cell not found for ~s" (var-name var)))))
233
234(defun ppc2-collect-lcells (kind &optional (bottom *ppc2-bottom-vstack-lcell*) (top *ppc2-top-vstack-lcell*))
235 (do* ((res ())
236 (cell top (lcell-parent cell)))
237 ((eq cell bottom) res)
238 (if (null cell)
239 (error "Horrible compiler bug.")
240 (if (eq (lcell-kind cell) kind)
241 (push cell res)))))
242
243
244
245
246;;; ensure that lcell's offset matches what we expect it to.
247;;; For bootstrapping.
248
249(defun ppc2-ensure-lcell-offset (c expected)
250 (if c (= (calc-lcell-offset c) expected) (zerop expected)))
251
252(defun ppc2-check-lcell-depth (&optional (context "wherever"))
253 (when (logbitp ppc2-debug-verbose-bit *ppc2-debug-mask*)
254 (let* ((depth (calc-lcell-depth *ppc2-top-vstack-lcell*)))
255 (or (= depth *ppc2-vstack*)
256 (warn "~a: lcell depth = ~d, vstack = ~d" context depth *ppc2-vstack*)))))
257
258(defun ppc2-do-lexical-reference (seg vreg ea)
259 (when vreg
260 (with-ppc-local-vinsn-macros (seg vreg)
261 (if (memory-spec-p ea)
262 (ensuring-node-target (target vreg)
263 (progn
264 (ppc2-stack-to-register seg ea target)
265 (if (addrspec-vcell-p ea)
266 (! vcell-ref target target))))
267 (<- ea)))))
268
269(defun ppc2-do-lexical-setq (seg vreg ea valreg)
270 (with-ppc-local-vinsn-macros (seg vreg)
271 (cond ((typep ea 'lreg)
272 (ppc2-copy-register seg ea valreg))
273 ((addrspec-vcell-p ea) ; closed-over vcell
274 (ppc2-copy-register seg ppc::arg_z valreg)
275 (ppc2-stack-to-register seg ea ppc::arg_x)
276 (ppc2-copy-register seg ppc::arg_y ppc::rzero)
277 (! call-subprim-3 ppc::arg_z (subprim-name->offset '.SPgvset) ppc::arg_x ppc::arg_y ppc::arg_z))
278 ((memory-spec-p ea) ; vstack slot
279 (ppc2-register-to-stack seg valreg ea))
280 (t
281 (ppc2-copy-register seg ea valreg)))
282 (when vreg
283 (<- valreg))))
284
285;;; ensure that next-method-var is heap-consed (if it's closed over.)
286;;; it isn't ever setqed, is it ?
287(defun ppc2-heap-cons-next-method-var (seg var)
288 (with-ppc-local-vinsn-macros (seg)
289 (when (eq (ash 1 $vbitclosed)
290 (logand (logior (ash 1 $vbitclosed)
291 (ash 1 $vbitcloseddownward))
292 (the fixnum (nx-var-bits var))))
293 (let* ((ea (var-ea var))
294 (arg ($ ppc::arg_z))
295 (result ($ ppc::arg_z)))
296 (ppc2-do-lexical-reference seg arg ea)
297 (ppc2-set-nargs seg 1)
298 (! ref-constant ($ ppc::fname) (backend-immediate-index (ppc2-symbol-entry-locative '%cons-magic-next-method-arg)))
299 (! call-known-symbol arg)
300 (ppc2-do-lexical-setq seg nil ea result)))))
301
302(defun ppc2-reverse-cc (cc)
303 ; NE NE EQ EQ LE GE LT GT GE LE GT LT MI PL PL MI
304 (%cdr (assq cc '((6 . 6) (7 . 7) (15 . 12) (13 . 14) (12 . 15) (14 . 13) (11 . 10) (10 . 11)))))
305
306 ; NE NE EQ EQ LE GE LT GT GE LE GT LT MI PL PL MI
307(defun ppc2-reverse-condition-keyword (k)
308 (cdr (assq k '((:ne . :ne) (:eq . :eq) (:le . :ge) (:lt . :gt) (:ge . :le) (:gt . :lt)))))
309
310
311
312
313(defun acode-condition-to-ppc-cr-bit (cond)
314 (condition-to-ppc-cr-bit (cadr cond)))
315
316(defun condition-to-ppc-cr-bit (cond)
317 (case cond
318 (:EQ (values ppc::ppc-eq-bit t))
319 (:NE (values ppc::ppc-eq-bit nil))
320 (:GT (values ppc::ppc-gt-bit t))
321 (:LE (values ppc::ppc-gt-bit nil))
322 (:LT (values ppc::ppc-lt-bit t))
323 (:GE (values ppc::ppc-lt-bit nil))))
324
325;;; Generate the start and end bits for a RLWINM instruction that
326;;; would be equivalent to to LOGANDing the constant with some value.
327;;; Return (VALUES NIL NIL) if the constant contains more than one
328;;; sequence of consecutive 1-bits, else bit indices.
329;;; The caller generally wants to treat the constant as an (UNSIGNED-BYTE 32);
330;;; since this uses LOGCOUNT and INTEGER-LENGTH to find the significant
331;;; bits, it ensures that the constant is a (SIGNED-BYTE 32) that has
332;;; the same least-significant 32 bits.
333(defun ppc2-mask-bits (constant)
334 (if (< constant 0) (setq constant (logand #xffffffff constant)))
335 (if (= constant #xffffffff)
336 (values 0 31)
337 (if (zerop constant)
338 (values nil nil)
339 (let* ((signed (if (and (logbitp 31 constant)
340 (> constant 0))
341 (- constant (ash 1 32))
342 constant))
343 (count (logcount signed))
344 (len (integer-length signed))
345 (highbit (logbitp (the fixnum (1- len)) constant)))
346 (declare (fixnum count len))
347 (do* ((i 1 (1+ i))
348 (pos (- len 2) (1- pos)))
349 ((= i count)
350 (let* ((start (- 32 len))
351 (end (+ count start)))
352 (declare (fixnum start end))
353 (if highbit
354 (values start (the fixnum (1- end)))
355 (values (logand 31 end)
356 (the fixnum (1- start))))))
357 (declare (fixnum i pos))
358 (unless (eq (logbitp pos constant) highbit)
359 (return (values nil nil))))))))
360
361
362(defun ppc2-ensure-binding-indices-for-vcells (vcells)
363 (dolist (cell vcells)
364 (ensure-binding-index (car cell)))
365 vcells)
366
367(defun ppc2-compile (afunc &optional lambda-form *ppc2-record-symbols*)
368 (progn
369 (dolist (a (afunc-inner-functions afunc))
370 (unless (afunc-lfun a)
371 (ppc2-compile a
372 (if lambda-form
373 (afunc-lambdaform a))
374 *ppc2-record-symbols*))) ; always compile inner guys
375 (let* ((*ppc2-cur-afunc* afunc)
376 (*ppc2-returning-values* nil)
377 (*ppc-current-context-annotation* nil)
378 (*ppc2-woi* nil)
379 (*next-lcell-id* -1)
380 (*ppc2-open-code-inline* nil)
381 (*ppc2-register-restore-count* nil)
382 (*ppc2-compiler-register-save-label* nil)
383 (*ppc2-valid-register-annotations* 0)
384 (*ppc2-register-ea-annotations* (ppc2-make-stack 16))
385 (*ppc2-register-restore-ea* nil)
386 (*ppc2-vstack* 0)
387 (*ppc2-cstack* 0)
388 (*ppc2-target-lcell-size* (arch::target-lisp-node-size (backend-target-arch *target-backend*)))
389 (*ppc2-target-fixnum-shift* (arch::target-fixnum-shift (backend-target-arch *target-backend*)))
390 (*ppc2-target-node-shift* (arch::target-word-shift (backend-target-arch *target-backend*)))
391 (*ppc2-target-bits-in-word* (arch::target-nbits-in-word (backend-target-arch *target-backend*)))
392 (*ppc2-target-node-size* *ppc2-target-lcell-size*)
393 (*ppc2-target-half-fixnum-type* (target-word-size-case
394 (32 *ppc2-ppc32-half-fixnum-type*)
395 (64 *ppc2-ppc64-half-fixnum-type*)))
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 (*ppc2-popj-labels* nil)
414 (*ppc2-popreg-labels* nil)
415 (*ppc2-valret-labels* nil)
416 (*ppc2-nilret-labels* nil)
417 (*ppc2-undo-count* 0)
418 (*backend-labels* (ppc2-make-stack 64 target::subtag-simple-vector))
419 (*ppc2-undo-stack* (ppc2-make-stack 64 target::subtag-simple-vector))
420 (*ppc2-undo-because* (ppc2-make-stack 64))
421 (*backend-immediates* (ppc2-make-stack 64 target::subtag-simple-vector))
422 (*ppc2-entry-label* nil)
423 (*ppc2-tail-label* nil)
424 (*ppc2-tail-vsp* nil)
425 (*ppc2-tail-nargs* nil)
426 (*ppc2-inhibit-register-allocation* nil)
427 (*ppc2-tail-allow* t)
428 (*ppc2-reckless* nil)
429 (*ppc2-trust-declarations* t)
430 (*ppc2-entry-vstack* nil)
431 (*ppc2-fixed-nargs* nil)
432 (*ppc2-need-nargs* t)
433 (fname (afunc-name afunc))
434 (*ppc2-entry-vsp-saved-p* nil)
435 (*ppc2-vcells* (ppc2-ensure-binding-indices-for-vcells (afunc-vcells afunc)))
436 (*ppc2-fcells* (afunc-fcells afunc))
437 *ppc2-recorded-symbols*)
438 (set-fill-pointer
439 *backend-labels*
440 (set-fill-pointer
441 *ppc2-undo-stack*
442 (set-fill-pointer
443 *ppc2-undo-because*
444 (set-fill-pointer
445 *backend-immediates* 0))))
446 (backend-get-next-label) ; start @ label 1, 0 is confused with NIL in compound cd
447 (with-dll-node-freelist (vinsns *vinsn-freelist*)
448 (unwind-protect
449 (progn
450 (setq bits (ppc2-form vinsns (make-wired-lreg *ppc2-result-reg*) $backend-return (afunc-acode afunc)))
451 (dotimes (i (length *backend-immediates*))
452 (let ((imm (aref *backend-immediates* i)))
453 (when (ppc2-symbol-locative-p imm) (aset *backend-immediates* i (car imm)))))
454 (optimize-vinsns vinsns)
455 (when (logbitp ppc2-debug-vinsns-bit *ppc2-debug-mask*)
456 (format t "~% vinsns for ~s (after generation)" (afunc-name afunc))
457 (do-dll-nodes (v vinsns) (format t "~&~s" v))
458 (format t "~%~%"))
459
460
461 (with-dll-node-freelist (*lap-instructions* *lap-instruction-freelist*)
462 (let* ((*lap-labels* nil))
463 (ppc2-expand-vinsns vinsns)
464 (if (logbitp $fbitnonnullenv (the fixnum (afunc-bits afunc)))
465 (setq bits (+ bits (ash 1 $lfbits-nonnullenv-bit))))
466 (let* ((function-debugging-info (afunc-lfun-info afunc)))
467 (when (or function-debugging-info lambda-form *ppc2-record-symbols*)
468 (if lambda-form (setq function-debugging-info
469 (list* 'function-lambda-expression lambda-form function-debugging-info)))
470 (if *ppc2-record-symbols*
471 (setq function-debugging-info (nconc (list 'function-symbol-map *ppc2-recorded-symbols*)
472 function-debugging-info)))
473 (setq bits (logior (ash 1 $lfbits-symmap-bit) bits))
474 (backend-new-immediate function-debugging-info)))
475 (if (or fname lambda-form *ppc2-recorded-symbols*)
476 (backend-new-immediate fname)
477 (setq bits (logior (ash -1 $lfbits-noname-bit) bits)))
478 (unless (afunc-parent afunc)
479 (ppc2-fixup-fwd-refs afunc))
480 (setf (afunc-all-vars afunc) nil)
481 (setf (afunc-argsword afunc) bits)
482 (let* ((regsave-label (if (typep *ppc2-compiler-register-save-label* 'vinsn-note)
483 (vinsn-label-info (vinsn-note-label *ppc2-compiler-register-save-label*))))
484 (regsave-reg (if regsave-label (- 32 *ppc2-register-restore-count*)))
485 (regsave-addr (if regsave-label (- *ppc2-register-restore-ea*))))
486 (setf (afunc-lfun afunc)
487 (ppc2-xmake-function
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-size (+ traceback-size (ash maxpc -2) prefix-size)))
517 #+ppc32-target
518 (if (>= code-vector-size (ash 1 19)) (compiler-function-overflow))
519 (let* ((code-vector (%alloc-misc code-vector-size
520 (if cross-compiling
521 target::subtag-xcode-vector
522 target::subtag-code-vector)))
523 (i prefix-size))
524 (dotimes (i prefix-size)
525 (setf (uvref code-vector i) (pop prefix)))
526 (ppc-lap-resolve-labels)
527 (do-dll-nodes (insn *lap-instructions*)
528 (ppc-lap-generate-instruction code-vector i insn)
529 (incf i))
530 (unless (eql 0 traceback-size)
531 (add-traceback-table code-vector i traceback-string))
532 (setf (uvref function 0) code-vector)
533 (%make-code-executable code-vector)
534 function))))
535
536
537(defun ppc2-make-stack (size &optional (subtype target::subtag-s16-vector))
538 (make-uarray-1 subtype size t 0 nil nil nil nil t nil))
539
540(defun ppc2-fixup-fwd-refs (afunc)
541 (dolist (f (afunc-inner-functions afunc))
542 (ppc2-fixup-fwd-refs f))
543 (let ((fwd-refs (afunc-fwd-refs afunc)))
544 (when fwd-refs
545 (let* ((v (afunc-lfun afunc))
546 (vlen (uvsize v)))
547 (declare (fixnum vlen))
548 (dolist (ref fwd-refs)
549 (let* ((ref-fun (afunc-lfun ref)))
550 (do* ((i 1 (1+ i)))
551 ((= i vlen))
552 (declare (fixnum i))
553 (if (eq (%svref v i) ref)
554 (setf (%svref v i) ref-fun)))))))))
555
556(defun ppc2-digest-symbols ()
557 (if *ppc2-recorded-symbols*
558 (let* ((symlist *ppc2-recorded-symbols*)
559 (len (length symlist))
560 (syms (make-array len))
561 (ptrs (make-array (%i+ (%i+ len len) len)))
562 (i -1)
563 (j -1))
564 (declare (fixnum i j))
565 (dolist (info symlist (progn (%rplaca symlist syms)
566 (%rplacd symlist ptrs)))
567 (flet ((label-address (note start-p sym)
568 (let* ((label (vinsn-note-label note))
569 (lap-label (if label (vinsn-label-info label))))
570 (if lap-label
571 (lap-label-address lap-label)
572 (error "Missing or bad ~s label: ~s"
573 (if start-p 'start 'end) sym)))))
574 (destructuring-bind (var sym startlab endlab) info
575 (let* ((ea (var-ea var))
576 (ea-val (ldb (byte 16 0) ea)))
577 (setf (aref ptrs (incf i)) (if (memory-spec-p ea)
578 (logior (ash ea-val 6) #o77)
579 ea-val)))
580 (setf (aref syms (incf j)) sym)
581 (setf (aref ptrs (incf i)) (label-address startlab t sym))
582 (setf (aref ptrs (incf i)) (label-address endlab nil sym))))))))
583
584(defun ppc2-decls (decls)
585 (if (fixnump decls)
586 (locally (declare (fixnum decls))
587 (setq *ppc2-tail-allow* (neq 0 (%ilogand2 $decl_tailcalls decls))
588 *ppc2-open-code-inline* (neq 0 (%ilogand2 $decl_opencodeinline decls))
589 *ppc2-reckless* (neq 0 (%ilogand2 $decl_unsafe decls))
590 *ppc2-trust-declarations* (neq 0 (%ilogand2 $decl_trustdecls decls))))))
591
592
593(defun %ppc2-bigger-cdr-than (x y)
594 (declare (cons x y))
595 (> (the fixnum (cdr x)) (the fixnum (cdr y))))
596
597;;; Return an unordered list of "varsets": each var in a varset can be
598;;; assigned a register and all vars in a varset can be assigned the
599;;; same register (e.g., no scope conflicts.)
600
601(defun ppc2-partition-vars (vars)
602 (labels ((var-weight (var)
603 (let* ((bits (nx-var-bits var)))
604 (declare (fixnum bits))
605 (if (eql 0 (logand bits (logior
606 (ash 1 $vbitpuntable)
607 (ash -1 $vbitspecial)
608 (ash 1 $vbitnoreg))))
609 (if (eql (logior (ash 1 $vbitclosed) (ash 1 $vbitsetq))
610 (logand bits (logior (ash 1 $vbitclosed) (ash 1 $vbitsetq))))
611 0
612 (%i+ (%ilogand $vrefmask bits) (%ilsr 8 (%ilogand $vsetqmask bits))))
613 0)))
614 (sum-weights (varlist)
615 (let ((sum 0))
616 (dolist (v varlist sum) (incf sum (var-weight v)))))
617 (vars-disjoint-p (v1 v2)
618 (if (eq v1 v2)
619 nil
620 (if (memq v1 (var-binding-info v2))
621 nil
622 (if (memq v2 (var-binding-info v1))
623 nil
624 t)))))
625 (setq vars (%sort-list-no-key
626 ;(delete-if #'(lambda (v) (eql (var-weight v) 0)) vars)
627 (do* ((handle (cons nil vars))
628 (splice handle))
629 ((null (cdr splice)) (cdr handle))
630 (declare (dynamic-extent handle) (type cons handle splice))
631 (if (eql 0 (var-weight (%car (cdr splice))))
632 (rplacd splice (%cdr (cdr splice)))
633 (setq splice (cdr splice))))
634 #'(lambda (v1 v2) (%i> (var-weight v1) (var-weight v2)))))
635 ; This isn't optimal. It partitions all register-allocatable variables into sets such that
636 ; 1) no variable is a member of more than one set and
637 ; 2) all variables in a given set are disjoint from each other
638 ; A set might have exactly one member.
639 ; If a register is allocated for any member of a set, it's allocated for all members of that
640 ; set.
641 (let* ((varsets nil))
642 (do* ((all vars (cdr all)))
643 ((null all))
644 (let* ((var (car all)))
645 (when (dolist (already varsets t)
646 (when (memq var (car already)) (return)))
647 (let* ((varset (cons var nil)))
648 (dolist (v (cdr all))
649 (when (dolist (already varsets t)
650 (when (memq v (car already)) (return)))
651 (when (dolist (d varset t)
652 (unless (vars-disjoint-p v d) (return)))
653 (push v varset))))
654 (let* ((weight (sum-weights varset)))
655 (declare (fixnum weight))
656 (if (>= weight 3)
657 (push (cons (nreverse varset) weight) varsets)))))))
658 varsets)))
659
660;;; Maybe globally allocate registers to symbols naming functions & variables,
661;;; and to simple lexical variables.
662(defun ppc2-allocate-global-registers (fcells vcells all-vars no-regs)
663 (if no-regs
664 (progn
665 (dolist (c fcells) (%rplacd c nil))
666 (dolist (c vcells) (%rplacd c nil))
667 (values 0 nil))
668 (let* ((maybe (ppc2-partition-vars all-vars)))
669 (dolist (c fcells)
670 (if (>= (the fixnum (cdr c)) 3) (push c maybe)))
671 (dolist (c vcells)
672 (if (>= (the fixnum (cdr c)) 3) (push c maybe)))
673 (do* ((things (%sort-list-no-key maybe #'%ppc2-bigger-cdr-than) (cdr things))
674 (n 0 (1+ n))
675 (regno ppc::save0 (1- regno))
676 (constant-alist ()))
677 ((or (null things) (= n $numppcsaveregs))
678 (dolist (cell fcells) (%rplacd cell nil))
679 (dolist (cell vcells) (%rplacd cell nil))
680 (values n constant-alist))
681 (declare (list things)
682 (fixnum n regno))
683 (let* ((thing (car things)))
684 (if (or (memq thing fcells)
685 (memq thing vcells))
686 (push (cons thing regno) constant-alist)
687 (dolist (var (car thing))
688 (nx-set-var-bits var
689 (%ilogior (%ilogand (%ilognot $vrefmask) (nx-var-bits var))
690 regno
691 (%ilsl $vbitreg 1))))))))))
692
693
694;;; Vpush the last N non-volatile-registers.
695;;; Could use a STM here, especially if N is largish or optimizing for space.
696(defun ppc2-save-nvrs (seg n)
697 (declare (fixnum n))
698 (when (> n 0)
699 (setq *ppc2-compiler-register-save-label* (ppc2-emit-note seg :regsave))
700 (with-ppc-local-vinsn-macros (seg)
701 (if *ppc2-open-code-inline*
702 (! save-nvrs-individually (- 32 n))
703 (! save-nvrs (- 32 n))))
704 (dotimes (i n)
705 (ppc2-new-vstack-lcell :regsave *ppc2-target-lcell-size* 0 (- ppc::save0 i)))
706 (incf *ppc2-vstack* (the fixnum (* n *ppc2-target-node-size*)))
707 (setq *ppc2-register-restore-ea* *ppc2-vstack*
708 *ppc2-register-restore-count* n)))
709
710
711;;; If there are an indefinite number of args/values on the vstack,
712;;; we have to restore from a register that matches the compiler's
713;;; notion of the vstack depth. This can be computed by the caller
714;;; (sum of vsp & nargs, or copy of vsp before indefinite number of
715;;; args pushed, etc.)
716;;; We DON'T try to compute this from the saved context, since the
717;;; saved vsp may belong to a different stack segment. (It's cheaper
718;;; to compute/copy than to load it, anyway.)
719
720(defun ppc2-restore-nvrs (seg ea nregs &optional from-fp)
721 (when (null from-fp)
722 (setq from-fp ppc::vsp))
723 (when (and ea nregs)
724 (with-ppc-local-vinsn-macros (seg)
725 (let* ((first (- 32 nregs)))
726 (declare (fixnum cell first n))
727 (! restore-nvrs first from-fp (- *ppc2-vstack* ea))))))
728
729
730
731(defun ppc2-bind-lambda (seg lcells req opt rest keys auxen optsupvloc passed-in-regs lexpr &optional inherited
732 &aux (vloc 0) (numopt (list-length (%car opt)))
733 (nkeys (list-length (%cadr keys)))
734 reg)
735 (declare (fixnum vloc))
736 (ppc2-check-lcell-depth)
737 (dolist (arg inherited)
738 (if (memq arg passed-in-regs)
739 (ppc2-set-var-ea seg arg (var-ea arg))
740 (let* ((lcell (pop lcells)))
741 (if (setq reg (ppc2-assign-register-var arg))
742 (ppc2-init-regvar seg arg reg (ppc2-vloc-ea vloc))
743 (ppc2-bind-var seg arg vloc lcell))
744 (setq vloc (%i+ vloc *ppc2-target-node-size*)))))
745 (dolist (arg req)
746 (if (memq arg passed-in-regs)
747 (ppc2-set-var-ea seg arg (var-ea arg))
748 (let* ((lcell (pop lcells)))
749 (if (setq reg (ppc2-assign-register-var arg))
750 (ppc2-init-regvar seg arg reg (ppc2-vloc-ea vloc))
751 (ppc2-bind-var seg arg vloc lcell))
752 (setq vloc (%i+ vloc *ppc2-target-node-size*)))))
753 (when opt
754 (if (ppc2-hard-opt-p opt)
755 (setq vloc (apply #'ppc2-initopt seg vloc optsupvloc lcells (nthcdr (- (length lcells) numopt) lcells) opt)
756 lcells (nthcdr numopt lcells))
757
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 rest
767 (if lexpr
768 (progn
769 (if (setq reg (ppc2-assign-register-var rest))
770 (progn
771 (ppc2-load-lexpr-address seg reg)
772 (ppc2-set-var-ea seg rest reg))
773 (with-imm-temps () ((nargs-cell :natural))
774 (ppc2-load-lexpr-address seg nargs-cell)
775 (let* ((loc *ppc2-vstack*))
776 (ppc2-vpush-register seg nargs-cell :reserved)
777 (ppc2-note-top-cell rest)
778 (ppc2-bind-var seg rest loc *ppc2-top-vstack-lcell*)))))
779 (let* ((rvloc (+ vloc (* 2 *ppc2-target-node-size* nkeys))))
780 (if (setq reg (ppc2-assign-register-var rest))
781 (ppc2-init-regvar seg rest reg (ppc2-vloc-ea rvloc))
782 (ppc2-bind-var seg rest rvloc (pop lcells))))))
783 (when keys
784 (apply #'ppc2-init-keys seg vloc lcells keys))
785 (ppc2-seq-bind seg (%car auxen) (%cadr auxen)))
786
787(defun ppc2-initopt (seg vloc spvloc lcells splcells vars inits spvars)
788 (with-ppc-local-vinsn-macros (seg)
789 (dolist (var vars vloc)
790 (let* ((initform (pop inits))
791 (spvar (pop spvars))
792 (lcell (pop lcells))
793 (splcell (pop splcells))
794 (reg (ppc2-assign-register-var var))
795 (sp-reg ($ ppc::arg_z))
796 (regloadedlabel (if reg (backend-get-next-label))))
797 (unless (nx-null initform)
798 (ppc2-stack-to-register seg (ppc2-vloc-ea spvloc) sp-reg)
799 (let ((skipinitlabel (backend-get-next-label)))
800 (with-crf-target () crf
801 (ppc2-compare-register-to-nil seg crf (ppc2-make-compound-cd 0 skipinitlabel) sp-reg ppc::ppc-eq-bit t))
802 (if reg
803 (ppc2-form seg reg regloadedlabel initform)
804 (ppc2-register-to-stack seg (ppc2-one-untargeted-reg-form seg initform ($ ppc::arg_z)) (ppc2-vloc-ea vloc)))
805 (@ skipinitlabel)))
806 (if reg
807 (progn
808 (ppc2-init-regvar seg var reg (ppc2-vloc-ea vloc))
809 (@ regloadedlabel))
810 (ppc2-bind-var seg var vloc lcell))
811 (when spvar
812 (if (setq reg (ppc2-assign-register-var spvar))
813 (ppc2-init-regvar seg spvar reg (ppc2-vloc-ea spvloc))
814 (ppc2-bind-var seg spvar spvloc splcell))))
815 (setq vloc (%i+ vloc *ppc2-target-node-size*))
816 (if spvloc (setq spvloc (%i+ spvloc *ppc2-target-node-size*))))))
817
818(defun ppc2-init-keys (seg vloc lcells allow-others keyvars keysupp keyinits keykeys)
819 (declare (ignore keykeys allow-others))
820 (with-ppc-local-vinsn-macros (seg)
821 (dolist (var keyvars)
822 (let* ((spvar (pop keysupp))
823 (initform (pop keyinits))
824 (reg (ppc2-assign-register-var var))
825 (regloadedlabel (if reg (backend-get-next-label)))
826 (var-lcell (pop lcells))
827 (sp-lcell (pop lcells))
828 (sp-reg ($ ppc::arg_z))
829 (sploc (%i+ vloc *ppc2-target-node-size*)))
830 (unless (nx-null initform)
831 (ppc2-stack-to-register seg (ppc2-vloc-ea sploc) sp-reg)
832 (let ((skipinitlabel (backend-get-next-label)))
833 (with-crf-target () crf
834 (ppc2-compare-register-to-nil seg crf (ppc2-make-compound-cd 0 skipinitlabel) sp-reg ppc::ppc-eq-bit t))
835 (if reg
836 (ppc2-form seg reg regloadedlabel initform)
837 (ppc2-register-to-stack seg (ppc2-one-untargeted-reg-form seg initform ($ ppc::arg_z)) (ppc2-vloc-ea vloc)))
838 (@ skipinitlabel)))
839 (if reg
840 (progn
841 (ppc2-init-regvar seg var reg (ppc2-vloc-ea vloc))
842 (@ regloadedlabel))
843 (ppc2-bind-var seg var vloc var-lcell))
844 (when spvar
845 (if (setq reg (ppc2-assign-register-var spvar))
846 (ppc2-init-regvar seg spvar reg (ppc2-vloc-ea sploc))
847 (ppc2-bind-var seg spvar sploc sp-lcell))))
848 (setq vloc (%i+ vloc (* 2 *ppc2-target-node-size*))))))
849
850;;; Vpush register r, unless var gets a globally-assigned register.
851;;; Return NIL if register was vpushed, else var.
852(defun ppc2-vpush-arg-register (seg reg var)
853 (when var
854 (let* ((bits (nx-var-bits var)))
855 (declare (fixnum bits))
856 (if (logbitp $vbitreg bits)
857 var
858 (progn
859 (ppc2-vpush-register seg reg :reserved)
860 nil)))))
861
862
863;;; nargs has been validated, arguments defaulted and canonicalized.
864;;; Save caller's context, then vpush any argument registers that
865;;; didn't get global registers assigned to their variables.
866;;; Return a list of vars/nils for each argument register
867;;; (nil if vpushed, var if still in arg_reg).
868(defun ppc2-argregs-entry (seg revargs)
869 (with-ppc-local-vinsn-macros (seg)
870 (let* ((nargs (length revargs))
871 (reg-vars ()))
872 (declare (type (unsigned-byte 16) nargs))
873 (! save-lr)
874 (if (<= nargs $numppcargregs) ; caller didn't vpush anything
875 (if *ppc2-open-code-inline*
876 (! save-lisp-context-vsp)
877 (! save-lisp-context-vsp-ool))
878 (let* ((offset (* (the fixnum (- nargs $numppcargregs)) *ppc2-target-node-size*)))
879 (declare (fixnum offset))
880 (if *ppc2-open-code-inline*
881 (! save-lisp-context-offset offset)
882 (! save-lisp-context-offset-ool offset))))
883 (destructuring-bind (&optional zvar yvar xvar &rest stack-args) revargs
884 (let* ((nstackargs (length stack-args)))
885 (ppc2-set-vstack (* nstackargs *ppc2-target-node-size*))
886 (dotimes (i nstackargs)
887 (ppc2-new-vstack-lcell :reserved *ppc2-target-lcell-size* 0 nil))
888 (if (>= nargs 3)
889 (push (ppc2-vpush-arg-register seg ($ ppc::arg_x) xvar) reg-vars))
890 (if (>= nargs 2)
891 (push (ppc2-vpush-arg-register seg ($ ppc::arg_y) yvar) reg-vars))
892 (if (>= nargs 1)
893 (push (ppc2-vpush-arg-register seg ($ ppc::arg_z) zvar) reg-vars))))
894 reg-vars)))
895
896;;; Just required args.
897;;; Since this is just a stupid bootstrapping port, always save
898;;; lisp context.
899(defun ppc2-req-nargs-entry (seg rev-fixed-args)
900 (let* ((nargs (length rev-fixed-args)))
901 (declare (type (unsigned-byte 16) nargs))
902 (with-ppc-local-vinsn-macros (seg)
903 (unless *ppc2-reckless*
904 (! check-exact-nargs nargs))
905 (ppc2-argregs-entry seg rev-fixed-args))))
906
907;;; No more than three &optional args; all default to NIL and none have
908;;; supplied-p vars. No &key/&rest.
909(defun ppc2-simple-opt-entry (seg rev-opt-args rev-req-args)
910 (let* ((min (length rev-req-args))
911 (nopt (length rev-opt-args))
912 (max (+ min nopt)))
913 (declare (type (unsigned-byte 16) min nopt max))
914 (with-ppc-local-vinsn-macros (seg)
915 (unless *ppc2-reckless*
916 (when rev-req-args
917 (! check-min-nargs min))
918 (! check-max-nargs max))
919 (if (= nopt 1)
920 (! default-1-arg min)
921 (if (= nopt 2)
922 (! default-2-args min)
923 (! default-3-args min)))
924 (ppc2-argregs-entry seg (append rev-opt-args rev-req-args)))))
925
926;;; if "num-fixed" is > 0, we've already ensured that at least that many args
927;;; were provided; that may enable us to generate better code for saving the
928;;; argument registers.
929;;; We're responsible for computing the caller's VSP and saving
930;;; caller's state.
931(defun ppc2-lexpr-entry (seg num-fixed)
932 (with-ppc-local-vinsn-macros (seg)
933 (! save-lexpr-argregs num-fixed)
934 (dotimes (i num-fixed)
935 (! copy-lexpr-argument))
936 (! save-lisp-context-lexpr)))
937
938(defun ppc2-load-lexpr-address (seg dest)
939 (with-ppc-local-vinsn-macros (seg)
940 (! load-vframe-address dest *ppc2-vstack*)))
941
942
943(defun ppc2-structured-initopt (seg lcells vloc context vars inits spvars)
944 (with-ppc-local-vinsn-macros (seg)
945 (dolist (var vars vloc)
946 (let* ((initform (pop inits))
947 (spvar (pop spvars))
948 (spvloc (%i+ vloc *ppc2-target-node-size*))
949 (var-lcell (pop lcells))
950 (sp-reg ($ ppc::arg_z))
951 (sp-lcell (pop lcells)))
952 (unless (nx-null initform)
953 (ppc2-stack-to-register seg (ppc2-vloc-ea spvloc) sp-reg)
954 (let ((skipinitlabel (backend-get-next-label)))
955 (with-crf-target () crf
956 (ppc2-compare-register-to-nil seg crf (ppc2-make-compound-cd 0 skipinitlabel) sp-reg ppc::ppc-eq-bit t))
957 (ppc2-register-to-stack seg (ppc2-one-untargeted-reg-form seg initform ($ ppc::arg_z)) (ppc2-vloc-ea vloc))
958 (@ skipinitlabel)))
959 (ppc2-bind-structured-var seg var vloc var-lcell context)
960 (when spvar
961 (ppc2-bind-var seg spvar spvloc sp-lcell)))
962 (setq vloc (%i+ vloc (* 2 *ppc2-target-node-size*))))))
963
964
965
966(defun ppc2-structured-init-keys (seg lcells vloc context allow-others keyvars keysupp keyinits keykeys)
967 (declare (ignore keykeys allow-others))
968 (with-ppc-local-vinsn-macros (seg)
969 (dolist (var keyvars)
970 (let* ((spvar (pop keysupp))
971 (initform (pop keyinits))
972 (sploc (%i+ vloc *ppc2-target-node-size*))
973 (var-lcell (pop lcells))
974 (sp-reg ($ ppc::arg_z))
975 (sp-lcell (pop lcells)))
976 (unless (nx-null initform)
977 (ppc2-stack-to-register seg (ppc2-vloc-ea sploc) sp-reg)
978 (let ((skipinitlabel (backend-get-next-label)))
979 (with-crf-target () crf
980 (ppc2-compare-register-to-nil seg crf (ppc2-make-compound-cd 0 skipinitlabel) sp-reg ppc::ppc-eq-bit t))
981 (ppc2-register-to-stack seg (ppc2-one-untargeted-reg-form seg initform ($ ppc::arg_z)) (ppc2-vloc-ea vloc))
982 (@ skipinitlabel)))
983 (ppc2-bind-structured-var seg var vloc var-lcell context)
984 (when spvar
985 (ppc2-bind-var seg spvar sploc sp-lcell)))
986 (setq vloc (%i+ vloc (* 2 *ppc2-target-node-size*))))))
987
988(defun ppc2-vloc-ea (n &optional vcell-p)
989 (setq n (make-memory-spec (dpb memspec-frame-address memspec-type-byte n)))
990 (if vcell-p
991 (make-vcell-memory-spec n)
992 n))
993
994
995(defun ppc2-form (seg vreg xfer form)
996 (if (nx-null form)
997 (ppc2-nil seg vreg xfer)
998 (if (nx-t form)
999 (ppc2-t seg vreg xfer)
1000 (let* ((op nil)
1001 (fn nil))
1002 (if (and (consp form)
1003 (setq fn (svref *ppc2-specials* (%ilogand #.operator-id-mask (setq op (acode-operator form))))))
1004 (if (and (null vreg)
1005 (%ilogbitp operator-acode-subforms-bit op)
1006 (%ilogbitp operator-assignment-free-bit op))
1007 (dolist (f (%cdr form) (ppc2-branch seg xfer nil))
1008 (ppc2-form seg nil nil f ))
1009 (apply fn seg vreg xfer (%cdr form)))
1010 (error "ppc2-form ? ~s" form))))))
1011
1012;;; dest is a float reg - form is acode
1013(defun ppc2-form-float (seg freg xfer form)
1014 (declare (ignore xfer))
1015 (when (or (nx-null form)(nx-t form))(error "ppc2-form to freg ~s" form))
1016 (when (and (= (get-regspec-mode freg) hard-reg-class-fpr-mode-double)
1017 (ppc2-form-typep form 'double-float))
1018 ; kind of screwy - encoding the source type in the dest register spec
1019 (set-node-regspec-type-modes freg hard-reg-class-fpr-type-double))
1020 (let* ((fn nil))
1021 (if (and (consp form)
1022 (setq fn (svref *ppc2-specials* (%ilogand #.operator-id-mask (acode-operator form)))))
1023 (apply fn seg freg nil (%cdr form))
1024 (error "ppc2-form ? ~s" form))))
1025
1026
1027
1028(defun ppc2-form-typep (form type)
1029 (acode-form-typep form type *ppc2-trust-declarations*)
1030)
1031
1032(defun ppc2-form-type (form)
1033 (acode-form-type form *ppc2-trust-declarations*))
1034
1035(defun ppc2-use-operator (op seg vreg xfer &rest forms)
1036 (declare (dynamic-extent forms))
1037 (apply (svref *ppc2-specials* (%ilogand operator-id-mask op)) seg vreg xfer forms))
1038
1039;;; Returns true iff lexical variable VAR isn't setq'ed in FORM.
1040;;; Punts a lot ...
1041(defun ppc2-var-not-set-by-form-p (var form)
1042 (or (not (%ilogbitp $vbitsetq (nx-var-bits var)))
1043 (ppc2-setqed-var-not-set-by-form-p var form)))
1044
1045(defun ppc2-setqed-var-not-set-by-form-p (var form)
1046 (setq form (acode-unwrapped-form form))
1047 (or (atom form)
1048 (ppc-constant-form-p form)
1049 (ppc2-lexical-reference-p form)
1050 (let ((op (acode-operator form))
1051 (subforms nil))
1052 (if (eq op (%nx1-operator setq-lexical))
1053 (and (neq var (cadr form))
1054 (ppc2-setqed-var-not-set-by-form-p var (caddr form)))
1055 (and (%ilogbitp operator-side-effect-free-bit op)
1056 (flet ((not-set-in-formlist (formlist)
1057 (dolist (subform formlist t)
1058 (unless (ppc2-setqed-var-not-set-by-form-p var subform) (return)))))
1059 (if
1060 (cond ((%ilogbitp operator-acode-subforms-bit op) (setq subforms (%cdr form)))
1061 ((%ilogbitp operator-acode-list-bit op) (setq subforms (cadr form))))
1062 (not-set-in-formlist subforms)
1063 (and (or (eq op (%nx1-operator call))
1064 (eq op (%nx1-operator lexical-function-call)))
1065 (ppc2-setqed-var-not-set-by-form-p var (cadr form))
1066 (setq subforms (caddr form))
1067 (not-set-in-formlist (car subforms))
1068 (not-set-in-formlist (cadr subforms))))))))))
1069
1070(defun ppc2-nil (seg vreg xfer)
1071 (with-ppc-local-vinsn-macros (seg vreg xfer)
1072 (if (ppc2-for-value-p vreg)
1073 (ensuring-node-target (target vreg)
1074 (! load-nil target)))
1075 (ppc2-branch seg (ppc2-cd-false xfer) vreg)))
1076
1077(defun ppc2-t (seg vreg xfer)
1078 (with-ppc-local-vinsn-macros (seg vreg xfer)
1079 (if (ppc2-for-value-p vreg)
1080 (ensuring-node-target (target vreg)
1081 (! load-t target)))
1082 (ppc2-branch seg (ppc2-cd-true xfer) vreg)))
1083
1084(defun ppc2-for-value-p (vreg)
1085 (and vreg (not (backend-crf-p vreg))))
1086
1087(defun ppc2-mvpass (seg form &optional xfer)
1088 (with-ppc-local-vinsn-macros (seg)
1089 (ppc2-form seg ($ ppc::arg_z) (logior (or xfer 0) $backend-mvpass-mask) form)))
1090
1091(defun ppc2-adjust-vstack (delta)
1092 (ppc2-set-vstack (%i+ *ppc2-vstack* delta)))
1093
1094(defun ppc2-set-vstack (new)
1095 (setq *ppc2-vstack* new))
1096
1097
1098;;; Emit a note at the end of the segment.
1099(defun ppc2-emit-note (seg class &rest info)
1100 (declare (dynamic-extent info))
1101 (let* ((note (make-vinsn-note class info)))
1102 (append-dll-node (vinsn-note-label note) seg)
1103 note))
1104
1105;;; Emit a note immediately before the target vinsn.
1106(defun ppc-prepend-note (vinsn class &rest info)
1107 (declare (dynamic-extent info))
1108 (let* ((note (make-vinsn-note class info)))
1109 (insert-dll-node-before (vinsn-note-label note) vinsn)
1110 note))
1111
1112(defun ppc2-close-note (seg note)
1113 (let* ((end (close-vinsn-note note)))
1114 (append-dll-node (vinsn-note-label end) seg)
1115 end))
1116
1117
1118
1119
1120
1121
1122(defun ppc2-stack-to-register (seg memspec reg)
1123 (with-ppc-local-vinsn-macros (seg)
1124 (! vframe-load reg (memspec-frame-address-offset memspec) *ppc2-vstack*)))
1125
1126(defun ppc2-lcell-to-register (seg lcell reg)
1127 (with-ppc-local-vinsn-macros (seg)
1128 (! lcell-load reg lcell (ppc2-vstack-mark-top))))
1129
1130(defun ppc2-register-to-lcell (seg reg lcell)
1131 (with-ppc-local-vinsn-macros (seg)
1132 (! lcell-store reg lcell (ppc2-vstack-mark-top))))
1133
1134(defun ppc2-register-to-stack (seg reg memspec)
1135 (with-ppc-local-vinsn-macros (seg)
1136 (! vframe-store reg (memspec-frame-address-offset memspec) *ppc2-vstack*)))
1137
1138
1139(defun ppc2-ea-open (ea)
1140 (if (and ea (not (typep ea 'lreg)) (addrspec-vcell-p ea))
1141 (make-memory-spec (memspec-frame-address-offset ea))
1142 ea))
1143
1144(defun ppc2-set-NARGS (seg n)
1145 (if (> n call-arguments-limit)
1146 (error "~s exceeded." call-arguments-limit)
1147 (with-ppc-local-vinsn-macros (seg)
1148 (! set-nargs n))))
1149
1150(defun ppc2-assign-register-var (v)
1151 (let ((bits (nx-var-bits v)))
1152 (when (%ilogbitp $vbitreg bits)
1153 (%ilogand bits $vrefmask))))
1154
1155(defun ppc2-single-float-bits (the-sf)
1156 (single-float-bits the-sf))
1157
1158(defun ppc2-double-float-bits (the-df)
1159 (double-float-bits the-df))
1160
1161(defun ppc2-immediate (seg vreg xfer form)
1162 (with-ppc-local-vinsn-macros (seg vreg xfer)
1163 (if vreg
1164 (if (and (= (hard-regspec-class vreg) hard-reg-class-fpr)
1165 (or (and (typep form 'double-float) (= (get-regspec-mode vreg) hard-reg-class-fpr-mode-double))
1166 (and (typep form 'short-float)(= (get-regspec-mode vreg) hard-reg-class-fpr-mode-single))))
1167 (if (zerop form)
1168 (if (eql form 0.0d0)
1169 (! zero-double-float-register vreg)
1170 (! zero-single-float-register vreg))
1171 (if (typep form 'short-float)
1172 (let* ((bits (ppc2-single-float-bits form)))
1173 (with-imm-temps () ((bitsreg :u32))
1174 (! lri bitsreg bits)
1175 (! load-single-float-constant vreg bitsreg)))
1176 (multiple-value-bind (high low) (ppc2-double-float-bits form)
1177 (declare (integer high low))
1178 (with-imm-temps () ((highreg :u32) (lowreg :u32))
1179 (if (zerop high)
1180 (setq highreg ($ ppc::rzero))
1181 (! lri highreg high))
1182 (if (zerop low)
1183 (setq lowreg ($ ppc::rzero))
1184 (! lri lowreg low))
1185 (! load-double-float-constant vreg highreg lowreg)))))
1186 (if (and (typep form '(unsigned-byte 32))
1187 (= (hard-regspec-class vreg) hard-reg-class-gpr)
1188 (= (get-regspec-mode vreg)
1189 hard-reg-class-gpr-mode-u32))
1190 (ppc2-lri seg vreg form)
1191 (ensuring-node-target
1192 (target vreg)
1193 (if (characterp form)
1194 (! load-character-constant target (char-code form))
1195 (ppc2-store-immediate seg form target)))))
1196 (if (and (listp form) *load-time-eval-token* (eq (car form) *load-time-eval-token*))
1197 (ppc2-store-immediate seg form ($ ppc::temp0))))
1198 (^)))
1199
1200(defun ppc2-register-constant-p (form)
1201 (and (consp form)
1202 (or (memq form *ppc2-vcells*)
1203 (memq form *ppc2-fcells*))
1204 (%cdr form)))
1205
1206(defun ppc2-store-immediate (seg imm dest)
1207 (with-ppc-local-vinsn-macros (seg)
1208 (let* ((reg (ppc2-register-constant-p imm)))
1209 (if reg
1210 (ppc2-copy-register seg dest reg)
1211 (let* ((idx (backend-immediate-index imm)))
1212 (target-arch-case
1213 (:ppc32
1214 (if (< idx 8192)
1215 (! ref-constant dest idx)
1216 (with-imm-target () (idxreg :s32)
1217 (ppc2-lri seg idxreg (+ ppc32::misc-data-offset (ash (1+ idx) 2)))
1218 (! ref-indexed-constant dest idxreg))))
1219 (:ppc64
1220 (if (< idx 4096)
1221 (! ref-constant dest idx)
1222 (with-imm-target () (idxreg :s64)
1223 (ppc2-lri seg idxreg (+ ppc64::misc-data-offset (ash (1+ idx) 3)))
1224 (! ref-indexed-constant dest idxreg)))))))
1225 dest)))
1226
1227
1228;;; Returns label iff form is (local-go <tag>) and can go without adjusting stack.
1229(defun ppc2-go-label (form)
1230 (let ((current-stack (ppc2-encode-stack)))
1231 (while (and (acode-p form) (or (eq (acode-operator form) (%nx1-operator progn))
1232 (eq (acode-operator form) (%nx1-operator local-tagbody))))
1233 (setq form (caadr form)))
1234 (when (acode-p form)
1235 (let ((op (acode-operator form)))
1236 (if (and (eq op (%nx1-operator local-go))
1237 (ppc2-equal-encodings-p (%caddr (%cadr form)) current-stack))
1238 (%cadr (%cadr form))
1239 (if (and (eq op (%nx1-operator local-return-from))
1240 (nx-null (caddr form)))
1241 (let ((tagdata (car (cadr form))))
1242 (and (ppc2-equal-encodings-p (cdr tagdata) current-stack)
1243 (null (caar tagdata))
1244 (< 0 (cdar tagdata) $backend-mvpass)
1245 (cdar tagdata)))))))))
1246
1247(defun ppc2-single-valued-form-p (form)
1248 (setq form (acode-unwrapped-form form))
1249 (or (nx-null form)
1250 (nx-t form)
1251 (if (acode-p form)
1252 (let ((op (acode-operator form)))
1253 (or (%ilogbitp operator-single-valued-bit op)
1254 (and (eql op (%nx1-operator values))
1255 (let ((values (cadr form)))
1256 (and values (null (cdr values)))))
1257 nil ; Learn about functions someday
1258 )))))
1259
1260
1261(defun ppc2-box-s32 (seg node-dest s32-src)
1262 (with-ppc-local-vinsn-macros (seg)
1263 (if (target-arch-case
1264 (:ppc32 *ppc2-open-code-inline*)
1265 (:ppc64 t))
1266 (! s32->integer node-dest s32-src)
1267 (let* ((arg_z ($ ppc::arg_z))
1268 (imm0 ($ ppc::imm0 :mode :s32)))
1269 (ppc2-copy-register seg imm0 s32-src)
1270 (! call-subprim (subprim-name->offset '.SPmakes32))
1271 (ppc2-copy-register seg node-dest arg_z)))))
1272
1273(defun ppc2-box-s64 (seg node-dest s64-src)
1274 (with-ppc-local-vinsn-macros (seg)
1275 (if (target-arch-case
1276 (:ppc32 (error "Bug!"))
1277 (:ppc64 *ppc2-open-code-inline*))
1278 (! s64->integer node-dest s64-src)
1279 (let* ((arg_z ($ ppc::arg_z))
1280 (imm0 ($ ppc::imm0 :mode :s64)))
1281 (ppc2-copy-register seg imm0 s64-src)
1282 (! call-subprim (subprim-name->offset '.SPmakes64))
1283 (ppc2-copy-register seg node-dest arg_z)))))
1284
1285(defun ppc2-box-u32 (seg node-dest u32-src)
1286 (with-ppc-local-vinsn-macros (seg)
1287 (if (target-arch-case
1288 (:ppc32 *ppc2-open-code-inline*)
1289 (:ppc64 t))
1290 (! u32->integer node-dest u32-src)
1291 (let* ((arg_z ($ ppc::arg_z))
1292 (imm0 ($ ppc::imm0 :mode :u32)))
1293 (ppc2-copy-register seg imm0 u32-src)
1294 (! call-subprim (subprim-name->offset '.SPmakeu32))
1295 (ppc2-copy-register seg node-dest arg_z)))))
1296
1297(defun ppc2-box-u64 (seg node-dest u64-src)
1298 (with-ppc-local-vinsn-macros (seg)
1299 (if (target-arch-case
1300 (:ppc32 (error "Bug!"))
1301 (:ppc64 *ppc2-open-code-inline*))
1302 (! u64->integer node-dest u64-src)
1303 (let* ((arg_z ($ ppc::arg_z))
1304 (imm0 ($ ppc::imm0 :mode :u64)))
1305 (ppc2-copy-register seg imm0 u64-src)
1306 (! call-subprim (subprim-name->offset '.SPmakeu64))
1307 (ppc2-copy-register seg node-dest arg_z)))))
1308
1309(defun ppc2-vref1 (seg vreg xfer type-keyword src unscaled-idx index-known-fixnum)
1310 (with-ppc-local-vinsn-macros (seg vreg xfer)
1311 (when vreg
1312 (let* ((arch (backend-target-arch *target-backend*))
1313 (is-node (member type-keyword (arch::target-gvector-types arch)))
1314 (is-1-bit (member type-keyword (arch::target-1-bit-ivector-types arch)))
1315
1316 (is-8-bit (member type-keyword (arch::target-8-bit-ivector-types arch)))
1317 (is-16-bit (member type-keyword (arch::target-16-bit-ivector-types arch)))
1318 (is-32-bit (member type-keyword (arch::target-32-bit-ivector-types arch)))
1319 (is-64-bit (member type-keyword (arch::target-64-bit-ivector-types arch)))
1320 (is-signed (member type-keyword '(:signed-8-bit-vector :signed-16-bit-vector :signed-32-bit-vector :signed-64-bit-vector :fixnum-vector)))
1321 (vreg-class (hard-regspec-class vreg))
1322 (vreg-mode
1323 (if (or (eql vreg-class hard-reg-class-gpr)
1324 (eql vreg-class hard-reg-class-fpr))
1325 (get-regspec-mode vreg)
1326 hard-reg-class-gpr-mode-invalid))
1327 (temp-is-vreg nil))
1328 (cond
1329 (is-node
1330 (ensuring-node-target (target vreg)
1331 (if (and index-known-fixnum (<= index-known-fixnum
1332 (target-word-size-case
1333 (32 (arch::target-max-32-bit-constant-index arch))
1334 (64 (arch::target-max-64-bit-constant-index arch)))))
1335 (! misc-ref-c-node target src index-known-fixnum)
1336 (with-imm-target () (idx-reg :u64)
1337 (if index-known-fixnum
1338 (ppc2-absolute-natural seg idx-reg nil (+ (arch::target-misc-data-offset arch) (ash index-known-fixnum *ppc2-target-node-shift*)))
1339 (! scale-node-misc-index idx-reg unscaled-idx))
1340 (! misc-ref-node target src idx-reg)))))
1341 (is-32-bit
1342 (with-imm-target () (temp :u32)
1343 (with-fp-target () (fp-val :single-float)
1344 (if (eql vreg-class hard-reg-class-gpr)
1345 (if
1346 (if is-signed
1347 (or (eql vreg-mode hard-reg-class-gpr-mode-s32)
1348 (eql vreg-mode hard-reg-class-gpr-mode-s64))
1349 (or (eql vreg-mode hard-reg-class-gpr-mode-u32)
1350 (eql vreg-mode hard-reg-class-gpr-mode-u64)))
1351 (setq temp vreg temp-is-vreg t)
1352 (if is-signed
1353 (set-regspec-mode temp hard-reg-class-gpr-mode-s32)))
1354 (if (and (eql vreg-class hard-reg-class-fpr)
1355 (eql vreg-mode hard-reg-class-fpr-mode-single))
1356 (setf fp-val vreg temp-is-vreg t)))
1357 (if (and index-known-fixnum (<= index-known-fixnum (arch::target-max-32-bit-constant-index arch)))
1358 (cond ((eq type-keyword :single-float-vector)
1359 (! misc-ref-c-single-float fp-val src index-known-fixnum))
1360 (t
1361 (if is-signed
1362 (! misc-ref-c-s32 temp src index-known-fixnum)
1363 (! misc-ref-c-u32 temp src index-known-fixnum)))))
1364 (with-imm-target () idx-reg
1365 (if index-known-fixnum
1366 (ppc2-absolute-natural seg idx-reg nil (+ (arch::target-misc-data-offset arch) (ash index-known-fixnum 2)))
1367 (! scale-32bit-misc-index idx-reg unscaled-idx))
1368 (cond ((eq type-keyword :single-float-vector)
1369 (! misc-ref-single-float fp-val src idx-reg))
1370 (t
1371 (if is-signed
1372 (! misc-ref-s32 temp src idx-reg)
1373 (! misc-ref-u32 temp src idx-reg)))))
1374 (case type-keyword
1375 (:single-float-vector
1376 (if (eq vreg-class hard-reg-class-fpr)
1377 (<- fp-val)
1378 (ensuring-node-target (target vreg)
1379 (! single->node target fp-val))))
1380 (:signed-32-bit-vector
1381 (unless temp-is-vreg
1382 (ensuring-node-target (target vreg)
1383 (ppc2-box-s32 seg target temp))))
1384 (:fixnum-vector
1385 (unless temp-is-vreg
1386 (ensuring-node-target (target vreg)
1387 (! box-fixnum target temp))))
1388 (:simple-string
1389 (ensuring-node-target (target vreg)
1390 (! u32->char target temp)))
1391 (t
1392 (unless temp-is-vreg
1393 (ensuring-node-target (target vreg)
1394 (ppc2-box-u32 seg target temp))))))))
1395 (is-8-bit
1396 (with-imm-target () (temp :u8)
1397 (if (and (eql vreg-class hard-reg-class-gpr)
1398 (or
1399 (and is-signed
1400 (or (eql vreg-mode hard-reg-class-gpr-mode-s8)
1401 (eql vreg-mode hard-reg-class-gpr-mode-s16)
1402 (eql vreg-mode hard-reg-class-gpr-mode-s32)
1403 (eql vreg-mode hard-reg-class-gpr-mode-s64)))
1404 (and (not is-signed)
1405 (or (eql vreg-mode hard-reg-class-gpr-mode-u8)
1406 (eql vreg-mode hard-reg-class-gpr-mode-s16)
1407 (eql vreg-mode hard-reg-class-gpr-mode-u16)
1408 (eql vreg-mode hard-reg-class-gpr-mode-s32)
1409 (eql vreg-mode hard-reg-class-gpr-mode-u32)
1410 (eql vreg-mode hard-reg-class-gpr-mode-s64)
1411 (eql vreg-mode hard-reg-class-gpr-mode-u64)))))
1412 (setq temp vreg temp-is-vreg t)
1413 (if is-signed
1414 (set-regspec-mode temp hard-reg-class-gpr-mode-s8)))
1415 (if (and index-known-fixnum (<= index-known-fixnum (arch::target-max-8-bit-constant-index arch)))
1416 (if is-signed
1417 (! misc-ref-c-s8 temp src index-known-fixnum)
1418 (! misc-ref-c-u8 temp src index-known-fixnum))
1419 (with-imm-target () idx-reg
1420 (if index-known-fixnum
1421 (ppc2-absolute-natural seg idx-reg nil (+ (arch::target-misc-data-offset arch) index-known-fixnum))
1422 (! scale-8bit-misc-index idx-reg unscaled-idx))
1423 (if is-signed
1424 (! misc-ref-s8 temp src idx-reg)
1425 (! misc-ref-u8 temp src idx-reg))))
1426 (ecase type-keyword
1427 (:unsigned-8-bit-vector
1428 (unless temp-is-vreg
1429 (ensuring-node-target (target vreg)
1430 (! box-fixnum target temp))))
1431 (:signed-8-bit-vector
1432 (unless temp-is-vreg
1433 (ensuring-node-target (target vreg)
1434 (! box-fixnum target temp))))
1435 (:simple-string
1436 (ensuring-node-target (target vreg)
1437 (! u32->char target temp))))))
1438 (is-16-bit
1439 (ensuring-node-target (target vreg)
1440 (with-imm-target () temp
1441 (if (and index-known-fixnum
1442 (<= index-known-fixnum (arch::target-max-16-bit-constant-index arch)))
1443 (if is-signed
1444 (! misc-ref-c-s16 temp src index-known-fixnum)
1445 (! misc-ref-c-u16 temp src index-known-fixnum))
1446 (with-imm-target () idx-reg
1447 (if index-known-fixnum
1448 (ppc2-absolute-natural seg idx-reg nil (+ (arch::target-misc-data-offset arch) (ash index-known-fixnum 1)))
1449 (! scale-16bit-misc-index idx-reg unscaled-idx))
1450 (if is-signed
1451 (! misc-ref-s16 temp src idx-reg)
1452 (! misc-ref-u16 temp src idx-reg))))
1453 (! box-fixnum target temp))))
1454 (is-64-bit
1455 (with-fp-target () (fp-val :double-float)
1456 (with-imm-target () (temp :u64)
1457 (if (and (eql vreg-class hard-reg-class-fpr)
1458 (eql vreg-mode hard-reg-class-fpr-mode-double))
1459 (setq fp-val vreg)
1460 (if (eql vreg-class hard-reg-class-gpr)
1461 (if (or (and is-signed
1462 (eql vreg-mode hard-reg-class-gpr-mode-s64))
1463 (and (not is-signed)
1464 (eql vreg-mode hard-reg-class-gpr-mode-u64)))
1465 (setf temp vreg temp-is-vreg t)
1466 (if is-signed
1467 (set-regspec-mode temp hard-reg-class-gpr-mode-s64)))))
1468 (case type-keyword
1469 (:double-float-vector
1470 (if (and index-known-fixnum (<= index-known-fixnum (arch::target-max-64-bit-constant-index arch)))
1471 (! misc-ref-c-double-float fp-val src index-known-fixnum)
1472 (with-imm-target () idx-reg
1473 (if index-known-fixnum
1474 (ppc2-absolute-natural seg idx-reg nil (+ (arch::target-misc-data-offset arch) (ash index-known-fixnum 3)))
1475 (! scale-64bit-misc-index idx-reg unscaled-idx))
1476 (! misc-ref-double-float fp-val src idx-reg)))
1477 (if (eq vreg-class hard-reg-class-fpr)
1478 (<- fp-val)
1479 (ensuring-node-target (target vreg)
1480 (! double->heap target fp-val))))
1481 ((:signed-64-bit-vector :fixnum-vector)
1482 (if (and index-known-fixnum (<= index-known-fixnum (arch::target-max-64-bit-constant-index arch)))
1483 (! misc-ref-c-s64 temp src index-known-fixnum)
1484 (with-imm-target () idx-reg
1485 (if index-known-fixnum
1486 (ppc2-absolute-natural seg idx-reg nil (+ (arch::target-misc-data-offset arch) (ash index-known-fixnum 3)))
1487 (! scale-64bit-misc-index idx-reg unscaled-idx))
1488 (! misc-ref-s64 temp src idx-reg)))
1489 (if (eq type-keyword :fixnum-vector)
1490 (ensuring-node-target (target vreg)
1491 (! box-fixnum target temp))
1492 (unless temp-is-vreg
1493 (ensuring-node-target (target vreg)
1494 (! s64->integer target temp)))))
1495 (t
1496 (if (and index-known-fixnum (<= index-known-fixnum (arch::target-max-64-bit-constant-index arch)))
1497 (! misc-ref-c-u64 temp src index-known-fixnum)
1498 (with-imm-target () idx-reg
1499 (if index-known-fixnum
1500 (ppc2-absolute-natural seg idx-reg nil (+ (arch::target-misc-data-offset arch) (ash index-known-fixnum 3)))
1501 (! scale-64bit-misc-index idx-reg unscaled-idx))
1502 (! misc-ref-u64 temp src idx-reg)))
1503 (unless temp-is-vreg
1504 (ensuring-node-target (target vreg)
1505 (! u64->integer target temp))))))))
1506 (t
1507 (unless is-1-bit
1508 (nx-error "~& unsupported vector type: ~s"
1509 type-keyword))
1510 (ensuring-node-target (target vreg)
1511 (if (and index-known-fixnum (<= index-known-fixnum (arch::target-max-1-bit-constant-index arch)))
1512 (! misc-ref-c-bit-fixnum target src index-known-fixnum)
1513 (with-imm-temps
1514 () (word-index bitnum dest)
1515 (if index-known-fixnum
1516 (progn
1517 (ppc2-lri seg word-index (+ (arch::target-misc-data-offset arch) (ash index-known-fixnum -5)))
1518 (ppc2-lri seg bitnum (logand index-known-fixnum #x1f)))
1519 (! scale-1bit-misc-index word-index bitnum unscaled-idx))
1520 (! misc-ref-u32 dest src word-index)
1521 (! extract-variable-bit-fixnum target dest bitnum))))))))
1522 (^)))
1523
1524
1525
1526;;; safe = T means assume "vector" is miscobj, do bounds check.
1527;;; safe = fixnum means check that subtag of vector = "safe" and do
1528;;; bounds check.
1529;;; safe = nil means crash&burn.
1530;;; This mostly knows how to reference the elements of an immediate miscobj.
1531(defun ppc2-vref (seg vreg xfer type-keyword vector index safe)
1532 (with-ppc-local-vinsn-macros (seg vreg xfer)
1533 (let* ((index-known-fixnum (acode-fixnum-form-p index))
1534 (unscaled-idx nil)
1535 (src nil))
1536 (if (or safe (not index-known-fixnum))
1537 (multiple-value-setq (src unscaled-idx)
1538 (ppc2-two-untargeted-reg-forms seg vector ppc::arg_y index ppc::arg_z))
1539 (setq src (ppc2-one-untargeted-reg-form seg vector ppc::arg_z)))
1540 (when safe
1541 (if (typep safe 'fixnum)
1542 (! trap-unless-typecode= src safe))
1543 (unless index-known-fixnum
1544 (! trap-unless-fixnum unscaled-idx))
1545 (! check-misc-bound unscaled-idx src))
1546 (ppc2-vref1 seg vreg xfer type-keyword src unscaled-idx index-known-fixnum))))
1547
1548
1549
1550(defun ppc2-aset2 (seg vreg xfer array i j new safe type-keyword dim0 dim1)
1551 (with-ppc-local-vinsn-macros (seg vreg xfer)
1552 (let* ((i-known-fixnum (acode-fixnum-form-p i))
1553 (j-known-fixnum (acode-fixnum-form-p j))
1554 (arch (backend-target-arch *target-backend*))
1555 (is-node (member type-keyword (arch::target-gvector-types arch)))
1556 (constval (ppc2-constant-value-ok-for-type-keyword type-keyword new))
1557 (needs-memoization (and is-node (ppc2-acode-needs-memoization new)))
1558 (src)
1559 (unscaled-i)
1560 (unscaled-j)
1561 (val-reg (ppc2-target-reg-for-aset vreg type-keyword))
1562 (constidx
1563 (and dim0 dim1 i-known-fixnum j-known-fixnum
1564 (>= i-known-fixnum 0)
1565 (>= j-known-fixnum 0)
1566 (< i-known-fixnum dim0)
1567 (< j-known-fixnum dim1)
1568 (+ (* i-known-fixnum dim1) j-known-fixnum))))
1569 (progn
1570 (if constidx
1571 (multiple-value-setq (src val-reg)
1572 (ppc2-two-targeted-reg-forms seg array ($ ppc::temp0) new val-reg))
1573 (multiple-value-setq (src unscaled-i unscaled-j val-reg)
1574 (if needs-memoization
1575 (progn
1576 (ppc2-four-targeted-reg-forms seg
1577 array ($ ppc::temp0)
1578 i ($ ppc::arg_x)
1579 j ($ ppc::arg_y)
1580 new val-reg)
1581 (values ($ ppc::temp0) ($ ppc::arg_x) ($ ppc::arg_y) ($ ppc::arg_z)))
1582 (ppc2-four-untargeted-reg-forms seg
1583 array ($ ppc::temp0)
1584 i ($ ppc::arg_x)
1585 j ($ ppc::arg_y)
1586 new val-reg))))
1587 (let* ((*available-backend-imm-temps* *available-backend-imm-temps*))
1588 (when (and (= (hard-regspec-class val-reg) hard-reg-class-gpr)
1589 (logbitp (hard-regspec-value val-reg)
1590 *backend-imm-temps*))
1591 (use-imm-temp (hard-regspec-value val-reg)))
1592 (when safe
1593 (when (typep safe 'fixnum)
1594 (! trap-unless-simple-array-2
1595 src
1596 (dpb safe target::arrayH.flags-cell-subtag-byte
1597 (ash 1 $arh_simple_bit))
1598 (nx-error-for-simple-2d-array-type type-keyword)))
1599 (unless i-known-fixnum
1600 (! trap-unless-fixnum unscaled-i))
1601 (unless j-known-fixnum
1602 (! trap-unless-fixnum unscaled-j)))
1603 (with-imm-target () dim1
1604 (let* ((idx-reg ($ ppc::arg_y)))
1605 (unless constidx
1606 (if safe
1607 (! check-2d-bound dim1 unscaled-i unscaled-j src)
1608 (! 2d-dim1 dim1 src))
1609 (! 2d-unscaled-index idx-reg dim1 unscaled-i unscaled-j))
1610 (let* ((v ($ ppc::arg_x)))
1611 (! array-data-vector-ref v src)
1612 (ppc2-vset1 seg vreg xfer type-keyword v idx-reg constidx val-reg (ppc2-unboxed-reg-for-aset seg type-keyword val-reg safe constval) constval needs-memoization)))))))))
1613
1614
1615(defun ppc2-aset3 (seg vreg xfer array i j k new safe type-keyword dim0 dim1 dim2)
1616 (with-ppc-local-vinsn-macros (seg target)
1617 (let* ((i-known-fixnum (acode-fixnum-form-p i))
1618 (j-known-fixnum (acode-fixnum-form-p j))
1619 (k-known-fixnum (acode-fixnum-form-p k))
1620 (arch (backend-target-arch *target-backend*))
1621 (is-node (member type-keyword (arch::target-gvector-types arch)))
1622 (constval (ppc2-constant-value-ok-for-type-keyword type-keyword new))
1623 (needs-memoization (and is-node (ppc2-acode-needs-memoization new)))
1624 (src)
1625 (unscaled-i)
1626 (unscaled-j)
1627 (unscaled-k)
1628 (val-reg (ppc2-target-reg-for-aset vreg type-keyword))
1629 (constidx
1630 (and dim0 dim1 dim2 i-known-fixnum j-known-fixnum k-known-fixnum
1631 (>= i-known-fixnum 0)
1632 (>= j-known-fixnum 0)
1633 (>= k-known-fixnum 0)
1634 (< i-known-fixnum dim0)
1635 (< j-known-fixnum dim1)
1636 (< k-known-fixnum dim2)
1637 (+ (* i-known-fixnum dim1 dim2)
1638 (* j-known-fixnum dim2)
1639 k-known-fixnum))))
1640 (progn
1641 (if constidx
1642 (multiple-value-setq (src val-reg)
1643 (ppc2-two-targeted-reg-forms seg array ($ ppc::temp0) new val-reg))
1644 (progn
1645 (setq src ($ ppc::temp1)
1646 unscaled-i ($ ppc::temp0)
1647 unscaled-j ($ ppc::arg_x)
1648 unscaled-k ($ ppc::arg_y))
1649 (ppc2-push-register
1650 seg
1651 (ppc2-one-untargeted-reg-form seg array ($ ppc::arg_z)))
1652 (ppc2-four-targeted-reg-forms seg
1653 i ($ ppc::temp0)
1654 j ($ ppc::arg_x)
1655 k ($ ppc::arg_y)
1656 new val-reg)
1657 (ppc2-pop-register seg src)))
1658 (let* ((*available-backend-imm-temps* *available-backend-imm-temps*))
1659 (when (and (= (hard-regspec-class val-reg) hard-reg-class-gpr)
1660 (logbitp (hard-regspec-value val-reg)
1661 *backend-imm-temps*))
1662 (use-imm-temp (hard-regspec-value val-reg)))
1663
1664 (when safe
1665 (when (typep safe 'fixnum)
1666 (! trap-unless-simple-array-3
1667 src
1668 (dpb safe target::arrayH.flags-cell-subtag-byte
1669 (ash 1 $arh_simple_bit))
1670 (nx-error-for-simple-3d-array-type type-keyword)))
1671 (unless i-known-fixnum
1672 (! trap-unless-fixnum unscaled-i))
1673 (unless j-known-fixnum
1674 (! trap-unless-fixnum unscaled-j))
1675 (unless k-known-fixnum
1676 (! trap-unless-fixnum unscaled-k)))
1677 (with-imm-target () dim1
1678 (with-imm-target (dim1) dim2
1679 (let* ((idx-reg ($ ppc::arg_y)))
1680 (unless constidx
1681 (if safe
1682 (! check-3d-bound dim1 dim2 unscaled-i unscaled-j unscaled-k src)
1683 (! 3d-dims dim1 dim2 src))
1684 (! 3d-unscaled-index idx-reg dim1 dim2 unscaled-i unscaled-j unscaled-k))
1685 (let* ((v ($ ppc::arg_x)))
1686 (! array-data-vector-ref v src)
1687 (ppc2-vset1 seg vreg xfer type-keyword v idx-reg constidx val-reg (ppc2-unboxed-reg-for-aset seg type-keyword val-reg safe constval) constval needs-memoization))))))))))
1688
1689(defun ppc2-aref2 (seg vreg xfer array i j safe typekeyword &optional dim0 dim1)
1690 (with-ppc-local-vinsn-macros (seg vreg xfer)
1691 (let* ((i-known-fixnum (acode-fixnum-form-p i))
1692 (j-known-fixnum (acode-fixnum-form-p j))
1693 (src)
1694 (unscaled-i)
1695 (unscaled-j)
1696 (constidx
1697 (and dim0 dim1 i-known-fixnum j-known-fixnum
1698 (>= i-known-fixnum 0)
1699 (>= j-known-fixnum 0)
1700 (< i-known-fixnum dim0)
1701 (< j-known-fixnum dim1)
1702 (+ (* i-known-fixnum dim1) j-known-fixnum))))
1703 (if constidx
1704 (setq src (ppc2-one-targeted-reg-form seg array ($ ppc::arg_z)))
1705 (multiple-value-setq (src unscaled-i unscaled-j)
1706 (ppc2-three-untargeted-reg-forms seg
1707 array ppc::arg_x
1708 i ppc::arg_y
1709 j ppc::arg_z)))
1710 (when safe
1711 (when (typep safe 'fixnum)
1712 (! trap-unless-simple-array-2
1713 src
1714 (dpb safe target::arrayH.flags-cell-subtag-byte
1715 (ash 1 $arh_simple_bit))
1716 (nx-error-for-simple-2d-array-type typekeyword)))
1717 (unless i-known-fixnum
1718 (! trap-unless-fixnum unscaled-i))
1719 (unless j-known-fixnum
1720 (! trap-unless-fixnum unscaled-j)))
1721 (with-node-target (src) idx-reg
1722 (with-imm-target () dim1
1723 (unless constidx
1724 (if safe
1725 (! check-2d-bound dim1 unscaled-i unscaled-j src)
1726 (! 2d-dim1 dim1 src))
1727 (! 2d-unscaled-index idx-reg dim1 unscaled-i unscaled-j))
1728 (with-node-target (idx-reg) v
1729 (! array-data-vector-ref v src)
1730 (ppc2-vref1 seg vreg xfer typekeyword v idx-reg constidx)))))))
1731
1732
1733
1734(defun ppc2-aref3 (seg vreg xfer array i j k safe typekeyword &optional dim0 dim1 dim2)
1735 (with-ppc-local-vinsn-macros (seg vreg xfer)
1736 (let* ((i-known-fixnum (acode-fixnum-form-p i))
1737 (j-known-fixnum (acode-fixnum-form-p j))
1738 (k-known-fixnum (acode-fixnum-form-p k))
1739 (src)
1740 (unscaled-i)
1741 (unscaled-j)
1742 (unscaled-k)
1743 (constidx
1744 (and dim0 dim1 i-known-fixnum j-known-fixnum k-known-fixnum
1745 (>= i-known-fixnum 0)
1746 (>= j-known-fixnum 0)
1747 (>= k-known-fixnum 0)
1748 (< i-known-fixnum dim0)
1749 (< j-known-fixnum dim1)
1750 (< k-known-fixnum dim2)
1751 (+ (* i-known-fixnum dim1 dim2)
1752 (* j-known-fixnum dim2)
1753 k-known-fixnum))))
1754 (if constidx
1755 (setq src (ppc2-one-targeted-reg-form seg array ($ ppc::arg_z)))
1756 (multiple-value-setq (src unscaled-i unscaled-j unscaled-k)
1757 (ppc2-four-untargeted-reg-forms seg
1758 array ppc::temp0
1759 i ppc::arg_x
1760 j ppc::arg_y
1761 k ppc::arg_z)))
1762 (when safe
1763 (when (typep safe 'fixnum)
1764 (! trap-unless-simple-array-3
1765 src
1766 (dpb safe target::arrayH.flags-cell-subtag-byte
1767 (ash 1 $arh_simple_bit))
1768 (nx-error-for-simple-3d-array-type typekeyword)))
1769 (unless i-known-fixnum
1770 (! trap-unless-fixnum unscaled-i))
1771 (unless j-known-fixnum
1772 (! trap-unless-fixnum unscaled-j))
1773 (unless k-known-fixnum
1774 (! trap-unless-fixnum unscaled-k)))
1775 (with-node-target (src) idx-reg
1776 (with-imm-target () dim1
1777 (with-imm-target (dim1) dim2
1778 (unless constidx
1779 (if safe
1780 (! check-3d-bound dim1 dim2 unscaled-i unscaled-j unscaled-k src)
1781 (! 3d-dims dim1 dim2 src))
1782 (! 3d-unscaled-index idx-reg dim1 dim2 unscaled-i unscaled-j unscaled-k))))
1783 (with-node-target (idx-reg) v
1784 (! array-data-vector-ref v src)
1785 (ppc2-vref1 seg vreg xfer typekeyword v idx-reg constidx))))))
1786
1787
1788(defun ppc2-constant-value-ok-for-type-keyword (type-keyword form)
1789 (if (and (acode-p form)
1790 (or (eq (acode-operator form) (%nx1-operator immediate))
1791 (eq (acode-operator form) (%nx1-operator fixnum))))
1792 (let* ((val (%cadr form))
1793 (typep (cond ((eq type-keyword :signed-32-bit-vector)
1794 (typep val '(signed-byte 32)))
1795 ((eq type-keyword :single-float-vector)
1796 (typep val 'short-float))
1797 ((eq type-keyword :double-float-vector)
1798 (typep val 'double-float))
1799 ((eq type-keyword :simple-string)
1800 (typep val 'base-char))
1801 ((eq type-keyword :signed-8-bit-vector)
1802 (typep val '(signed-byte 8)))
1803 ((eq type-keyword :unsigned-8-bit-vector)
1804 (typep val '(unsigned-byte 8)))
1805 ((eq type-keyword :signed-16-bit-vector)
1806 (typep val '(signed-byte 16)))
1807 ((eq type-keyword :unsigned-16-bit-vector)
1808 (typep val '(unsigned-byte 16)))
1809 ((eq type-keyword :bit-vector)
1810 (typep val 'bit)))))
1811 (if typep val))))
1812
1813(defun ppc2-target-reg-for-aset (vreg type-keyword)
1814 (let* ((arch (backend-target-arch *target-backend*))
1815 (is-node (member type-keyword (arch::target-gvector-types arch)))
1816 (is-1-bit (member type-keyword (arch::target-1-bit-ivector-types arch)))
1817 (is-8-bit (member type-keyword (arch::target-8-bit-ivector-types arch)))
1818 (is-16-bit (member type-keyword (arch::target-16-bit-ivector-types arch)))
1819 (is-32-bit (member type-keyword (arch::target-32-bit-ivector-types arch)))
1820 (is-64-bit (member type-keyword (arch::target-64-bit-ivector-types arch)))
1821 (is-signed (member type-keyword '(:signed-8-bit-vector :signed-16-bit-vector :signed-32-bit-vector :signed-64-bit-vector :fixnum-vector)))
1822 (vreg-class (if vreg (hard-regspec-class vreg)))
1823 (vreg-mode (if (or (eql vreg-class hard-reg-class-gpr)
1824 (eql vreg-class hard-reg-class-fpr))
1825 (get-regspec-mode vreg)))
1826 (next-imm-target (available-imm-temp *available-backend-imm-temps*))
1827 (next-fp-target (available-fp-temp *available-backend-fp-temps*))
1828 (acc (make-wired-lreg ppc::arg_z)))
1829 (cond ((or is-node
1830 is-1-bit
1831 (eq type-keyword :simple-string)
1832 (eq type-keyword :fixnum-vector)
1833 (and (eql vreg-class hard-reg-class-gpr)
1834 (eql vreg-mode hard-reg-class-gpr-mode-node)))
1835 acc)
1836 ;; If there's no vreg - if we're setting for effect only, and
1837 ;; not for value - we can target an unboxed register directly.
1838 ;; Usually.
1839 ((null vreg)
1840 (cond (is-64-bit
1841 (if (eq type-keyword :double-float-vector)
1842 (make-unwired-lreg next-fp-target :mode hard-reg-class-fpr-mode-double)
1843 (make-unwired-lreg next-imm-target :mode (if is-signed hard-reg-class-gpr-mode-s64 hard-reg-class-gpr-mode-u64))))
1844 (is-32-bit
1845 (if (eq type-keyword :single-float-vector)
1846 (make-unwired-lreg next-fp-target :mode hard-reg-class-fpr-mode-single)
1847 (make-unwired-lreg next-imm-target :mode (if is-signed hard-reg-class-gpr-mode-s32 hard-reg-class-gpr-mode-u32))))
1848 (is-16-bit
1849 (make-unwired-lreg next-imm-target :mode (if is-signed hard-reg-class-gpr-mode-s16 hard-reg-class-gpr-mode-u16)))
1850 (is-8-bit
1851 (make-unwired-lreg next-imm-target :mode (if is-signed hard-reg-class-gpr-mode-s8 hard-reg-class-gpr-mode-u8)))
1852 (t "Bug: can't determine operand size for ~s" type-keyword)))
1853 ;; Vreg is non-null. We might be able to use it directly.
1854 (t
1855 (let* ((lreg (if vreg-mode
1856 (make-unwired-lreg (lreg-value vreg)))))
1857 (if
1858 (cond
1859 (is-64-bit
1860 (if (eq type-keyword :double-float-vector)
1861 (and (eql vreg-class hard-reg-class-fpr)
1862 (eql vreg-mode hard-reg-class-fpr-mode-double))
1863 (if is-signed
1864 (and (eql vreg-class hard-reg-class-gpr)
1865 (eql vreg-mode hard-reg-class-gpr-mode-s64))
1866 (and (eql vreg-class hard-reg-class-gpr)
1867 (eql vreg-mode hard-reg-class-gpr-mode-u64)))))
1868 (is-32-bit
1869 (if (eq type-keyword :single-float-vector)
1870 (and (eql vreg-class hard-reg-class-fpr)
1871 (eql vreg-mode hard-reg-class-fpr-mode-single))
1872 (if is-signed
1873 (and (eql vreg-class hard-reg-class-gpr)
1874 (or (eql vreg-mode hard-reg-class-gpr-mode-s32)
1875 (eql vreg-mode hard-reg-class-gpr-mode-s64)))
1876 (and (eql vreg-class hard-reg-class-gpr)
1877 (or (eql vreg-mode hard-reg-class-gpr-mode-u32)
1878 (eql vreg-mode hard-reg-class-gpr-mode-u64)
1879 (eql vreg-mode hard-reg-class-gpr-mode-s64))))))
1880 (is-16-bit
1881 (if is-signed
1882 (and (eql vreg-class hard-reg-class-gpr)
1883 (or (eql vreg-mode hard-reg-class-gpr-mode-s16)
1884 (eql vreg-mode hard-reg-class-gpr-mode-s32)
1885 (eql vreg-mode hard-reg-class-gpr-mode-s64)))
1886 (and (eql vreg-class hard-reg-class-gpr)
1887 (or (eql vreg-mode hard-reg-class-gpr-mode-u16)
1888 (eql vreg-mode hard-reg-class-gpr-mode-u32)
1889 (eql vreg-mode hard-reg-class-gpr-mode-u64)
1890 (eql vreg-mode hard-reg-class-gpr-mode-s32)
1891 (eql vreg-mode hard-reg-class-gpr-mode-s64)))))
1892 (t
1893 (if is-signed
1894 (and (eql vreg-class hard-reg-class-gpr)
1895 (or (eql vreg-mode hard-reg-class-gpr-mode-s8)
1896 (eql vreg-mode hard-reg-class-gpr-mode-s16)
1897 (eql vreg-mode hard-reg-class-gpr-mode-s32)
1898 (eql vreg-mode hard-reg-class-gpr-mode-s64)))
1899 (and (eql vreg-class hard-reg-class-gpr)
1900 (or (eql vreg-mode hard-reg-class-gpr-mode-u8)
1901 (eql vreg-mode hard-reg-class-gpr-mode-u16)
1902 (eql vreg-mode hard-reg-class-gpr-mode-u32)
1903 (eql vreg-mode hard-reg-class-gpr-mode-u64)
1904 (eql vreg-mode hard-reg-class-gpr-mode-s16)
1905 (eql vreg-mode hard-reg-class-gpr-mode-s32)
1906 (eql vreg-mode hard-reg-class-gpr-mode-s64))))))
1907 lreg
1908 acc))))))
1909
1910(defun ppc2-unboxed-reg-for-aset (seg type-keyword result-reg safe constval)
1911 (with-ppc-local-vinsn-macros (seg)
1912 (let* ((arch (backend-target-arch *target-backend*))
1913 (is-node (member type-keyword (arch::target-gvector-types arch)))
1914 (is-8-bit (member type-keyword (arch::target-8-bit-ivector-types arch)))
1915 (is-16-bit (member type-keyword (arch::target-16-bit-ivector-types arch)))
1916 (is-32-bit (member type-keyword (arch::target-32-bit-ivector-types arch)))
1917 (is-64-bit (member type-keyword (arch::target-64-bit-ivector-types arch)))
1918 (is-signed (member type-keyword '(:signed-8-bit-vector :signed-16-bit-vector :signed-32-bit-vector :signed-64-bit-vector :fixnum-vector)))
1919 (result-is-node-gpr (and (eql (hard-regspec-class result-reg)
1920 hard-reg-class-gpr)
1921 (eql (get-regspec-mode result-reg)
1922 hard-reg-class-gpr-mode-node)))
1923 (next-imm-target (available-imm-temp *available-backend-imm-temps*))
1924 (next-fp-target (available-fp-temp *available-backend-fp-temps*)))
1925 (if (or is-node (not result-is-node-gpr))
1926 result-reg
1927 (cond (is-64-bit
1928 (if (eq type-keyword :double-float-vector)
1929 (let* ((reg (make-unwired-lreg next-fp-target :mode hard-reg-class-fpr-mode-double)))
1930 (if safe
1931 (! get-double? reg result-reg)
1932 (! get-double reg result-reg))
1933 reg)
1934 (if is-signed
1935 (let* ((reg (make-unwired-lreg next-imm-target :mode hard-reg-class-gpr-mode-s64)))
1936 (if (eq type-keyword :fixnum-vector)
1937 (progn
1938 (when safe
1939 (! trap-unless-fixnum result-reg))
1940 (! fixnum->signed-natural reg result-reg))
1941 (! unbox-s64 reg result-reg))
1942 reg)
1943 (let* ((reg (make-unwired-lreg next-imm-target :mode hard-reg-class-gpr-mode-u64)))
1944 (! unbox-u64 reg result-reg)
1945 reg))))
1946 (is-32-bit
1947 ;; Generally better to use a GPR for the :SINGLE-FLOAT-VECTOR
1948 ;; case here.
1949 (if is-signed
1950 (let* ((reg (make-unwired-lreg next-imm-target :mode hard-reg-class-gpr-mode-s32)))
1951 (if (eq type-keyword :fixnum-vector)
1952 (progn
1953 (when safe
1954 (! trap-unless-fixnum result-reg))
1955 (! fixnum->signed-natural reg result-reg))
1956 (! unbox-s32 reg result-reg))
1957 reg)
1958 (let* ((reg (make-unwired-lreg next-imm-target :mode hard-reg-class-gpr-mode-u32)))
1959 (cond ((eq type-keyword :simple-string)
1960 (if (characterp constval)
1961 (ppc2-lri seg reg (char-code constval))
1962 (! unbox-base-char reg result-reg)))
1963 ((eq type-keyword :single-float-vector)
1964 (if (typep constval 'single-float)
1965 (ppc2-lri seg reg (single-float-bits constval))
1966 (progn
1967 (when safe
1968 (! trap-unless-single-float result-reg))
1969 (! single-float-bits reg result-reg))))
1970 (t
1971 (if (typep constval '(unsigned-byte 32))
1972 (ppc2-lri seg reg constval)
1973 (! unbox-u32 reg result-reg))))
1974 reg)))
1975 (is-16-bit
1976 (if is-signed
1977 (let* ((reg (make-unwired-lreg next-imm-target :mode hard-reg-class-gpr-mode-s16)))
1978 (if (typep constval '(signed-byte 16))
1979 (ppc2-lri seg reg constval)
1980 (! unbox-s16 reg result-reg))
1981 reg)
1982 (let* ((reg (make-unwired-lreg next-imm-target :mode hard-reg-class-gpr-mode-u16)))
1983 (if (typep constval '(unsigned-byte 16))
1984 (ppc2-lri seg reg constval)
1985 (! unbox-u16 reg result-reg))
1986 reg)))
1987 (is-8-bit
1988 (if is-signed
1989 (let* ((reg (make-unwired-lreg next-imm-target :mode hard-reg-class-gpr-mode-s8)))
1990 (if (typep constval '(signed-byte 8))
1991 (ppc2-lri seg reg constval)
1992 (! unbox-s8 reg result-reg))
1993 reg)
1994 (let* ((reg (make-unwired-lreg next-imm-target :mode hard-reg-class-gpr-mode-u8)))
1995 (if (typep constval '(unsigned-byte 8))
1996 (ppc2-lri seg reg constval)
1997 (! unbox-u8 reg result-reg))
1998 reg)))
1999 (t
2000 (let* ((reg (make-unwired-lreg next-imm-target :mode hard-reg-class-gpr-mode-u8)))
2001 (unless (typep constval 'bit)
2002 (! unbox-bit-bit0 reg result-reg))
2003 reg)))))))
2004
2005
2006;;; "val-reg" might be boxed, if the vreg requires it to be.
2007(defun ppc2-vset1 (seg vreg xfer type-keyword src unscaled-idx index-known-fixnum val-reg unboxed-val-reg constval &optional (node-value-needs-memoization t))
2008 (with-ppc-local-vinsn-macros (seg vreg xfer)
2009 (let* ((arch (backend-target-arch *target-backend*))
2010 (is-node (member type-keyword (arch::target-gvector-types arch)))
2011 (is-1-bit (member type-keyword (arch::target-1-bit-ivector-types arch)))
2012 (is-8-bit (member type-keyword (arch::target-8-bit-ivector-types arch)))
2013 (is-16-bit (member type-keyword (arch::target-16-bit-ivector-types arch)))
2014 (is-32-bit (member type-keyword (arch::target-32-bit-ivector-types arch)))
2015 (is-64-bit (member type-keyword (arch::target-64-bit-ivector-types arch)))
2016 (is-signed (member type-keyword '(:signed-8-bit-vector :signed-16-bit-vector :signed-32-bit-vector :signed-64-bit-vector :fixnum-vector))))
2017 (cond ((and is-node node-value-needs-memoization)
2018 (unless (and (eql (hard-regspec-value src) ppc::arg_x)
2019 (eql (hard-regspec-value unscaled-idx) ppc::arg_y)
2020 (eql (hard-regspec-value val-reg) ppc::arg_z))
2021 (nx-error "Bug: invalid register targeting for gvset: ~s" (list src unscaled-idx val-reg)))
2022 (! call-subprim-3 val-reg (subprim-name->offset '.SPgvset) src unscaled-idx val-reg))
2023 (is-node
2024 (if (and index-known-fixnum (<= index-known-fixnum
2025 (target-word-size-case
2026 (32 (arch::target-max-32-bit-constant-index arch))
2027 (64 (arch::target-max-64-bit-constant-index arch)))))
2028 (! misc-set-c-node val-reg src index-known-fixnum)
2029 (with-imm-target () scaled-idx
2030
2031 (if index-known-fixnum
2032 (ppc2-absolute-natural seg scaled-idx nil (+ (arch::target-misc-data-offset arch) (ash index-known-fixnum *ppc2-target-node-shift*)))
2033 (! scale-node-misc-index scaled-idx unscaled-idx))
2034 (! misc-set-node val-reg src scaled-idx))))
2035 (t
2036 (with-imm-target (unboxed-val-reg) scaled-idx
2037 (cond
2038 (is-64-bit
2039 (if (and index-known-fixnum
2040 (<= index-known-fixnum
2041 (arch::target-max-64-bit-constant-index arch)))
2042 (if (eq type-keyword :double-float-vector)
2043 (! misc-set-c-double-float unboxed-val-reg src index-known-fixnum)
2044 (if is-signed
2045 (! misc-set-c-s64 unboxed-val-reg src index-known-fixnum)
2046 (! misc-set-c-u64 unboxed-val-reg src index-known-fixnum)))
2047 (progn
2048 (if index-known-fixnum
2049 (ppc2-absolute-natural seg scaled-idx nil (+ (arch::target-misc-dfloat-offset arch) (ash index-known-fixnum 3)))
2050 (! scale-64bit-misc-index scaled-idx unscaled-idx))
2051 (if (eq type-keyword :double-float-vector)
2052 (! misc-set-double-float unboxed-val-reg src scaled-idx)
2053 (if is-signed
2054 (! misc-set-s64 unboxed-val-reg src scaled-idx)
2055 (! misc-set-u64 unboxed-val-reg src scaled-idx))))))
2056 (is-32-bit
2057 (if (and index-known-fixnum
2058 (<= index-known-fixnum
2059 (arch::target-max-32-bit-constant-index arch)))
2060 (if (eq type-keyword :single-float-vector)
2061 (if (eq (hard-regspec-class unboxed-val-reg)
2062 hard-reg-class-fpr)
2063 (! misc-set-c-single-float unboxed-val-reg src index-known-fixnum)
2064 (! misc-set-c-u32 unboxed-val-reg src index-known-fixnum))
2065 (if is-signed
2066 (! misc-set-c-s32 unboxed-val-reg src index-known-fixnum)
2067 (! misc-set-c-u32 unboxed-val-reg src index-known-fixnum)))
2068 (progn
2069 (if index-known-fixnum
2070 (ppc2-absolute-natural seg scaled-idx nil (+ (arch::target-misc-data-offset arch) (ash index-known-fixnum 2)))
2071 (! scale-32bit-misc-index scaled-idx unscaled-idx))
2072 (if (and (eq type-keyword :single-float-vector)
2073 (eql (hard-regspec-class unboxed-val-reg)
2074 hard-reg-class-fpr))
2075 (! misc-set-single-float unboxed-val-reg src scaled-idx)
2076 (if is-signed
2077 (! misc-set-s32 unboxed-val-reg src scaled-idx)
2078 (! misc-set-u32 unboxed-val-reg src scaled-idx))))))
2079 (is-16-bit
2080 (if (and index-known-fixnum
2081 (<= index-known-fixnum
2082 (arch::target-max-16-bit-constant-index arch)))
2083 (if is-signed
2084 (! misc-set-c-s16 unboxed-val-reg src index-known-fixnum)
2085 (! misc-set-c-u16 unboxed-val-reg src index-known-fixnum))
2086 (progn
2087 (if index-known-fixnum
2088 (ppc2-absolute-natural seg scaled-idx nil (+ (arch::target-misc-data-offset arch) (ash index-known-fixnum 1)))
2089 (! scale-16bit-misc-index scaled-idx unscaled-idx))
2090 (if is-signed
2091 (! misc-set-s16 unboxed-val-reg src scaled-idx)
2092 (! misc-set-u16 unboxed-val-reg src scaled-idx)))))
2093 (is-8-bit
2094 (if (and index-known-fixnum
2095 (<= index-known-fixnum
2096 (arch::target-max-8-bit-constant-index arch)))
2097 (if is-signed
2098 (! misc-set-c-s8 unboxed-val-reg src index-known-fixnum)
2099 (! misc-set-c-u8 unboxed-val-reg src index-known-fixnum))
2100 (progn
2101 (if index-known-fixnum
2102 (ppc2-absolute-natural seg scaled-idx nil (+ (arch::target-misc-data-offset arch) index-known-fixnum))
2103 (! scale-8bit-misc-index scaled-idx unscaled-idx))
2104 (if is-signed
2105 (! misc-set-s8 unboxed-val-reg src scaled-idx)
2106 (! misc-set-u8 unboxed-val-reg src scaled-idx)))))
2107 (t
2108 (unless is-1-bit
2109 (nx-error "~& unsupported vector type: ~s"
2110 type-keyword))
2111 (if (and index-known-fixnum (<= index-known-fixnum (arch::target-max-1-bit-constant-index arch)))
2112 (with-imm-target (unboxed-val-reg) word
2113 (let* ((word-index (ash index-known-fixnum -5))
2114 (bit-number (logand index-known-fixnum #x1f)))
2115 (! misc-ref-c-u32 word src word-index)
2116 (if constval
2117 (if (zerop constval)
2118 (! set-constant-ppc-bit-to-0 word word bit-number)
2119 (! set-constant-ppc-bit-to-1 word word bit-number))
2120 (! set-constant-ppc-bit-to-variable-value word word unboxed-val-reg bit-number))
2121 (! misc-set-c-u32 word src word-index)))
2122 (with-imm-temps (unboxed-val-reg) (word-index bit-number temp)
2123 (! scale-1bit-misc-index word-index bit-number unscaled-idx)
2124 (if constval
2125 (progn
2126 (! lri temp #x80000000)
2127 (! shift-right-variable-word bit-number temp bit-number)
2128 (! misc-ref-u32 temp src word-index)
2129 (if (zerop constval)
2130 (! u32logandc2 temp temp bit-number)
2131 (! u32logior temp temp bit-number)))
2132 (with-imm-temps () (bitval)
2133 (! shift-right-variable-word bitval unboxed-val-reg bit-number)
2134 (! lri temp #x80000000)
2135 (! shift-right-variable-word bit-number temp bit-number)
2136 (! misc-ref-u32 temp src word-index)
2137 (! u32logandc2 temp temp bit-number)
2138 (! u32logior temp temp bitval)))
2139 (! misc-set-u32 temp src word-index))))))))
2140 (when (and vreg val-reg) (<- val-reg))
2141 (^))))
2142
2143
2144(defun ppc2-vset (seg vreg xfer type-keyword vector index value safe)
2145 (with-ppc-local-vinsn-macros (seg)
2146 (let* ((arch (backend-target-arch *target-backend*))
2147 (is-node (member type-keyword (arch::target-gvector-types arch)))
2148 (constval (ppc2-constant-value-ok-for-type-keyword type-keyword value))
2149 (needs-memoization (and is-node (ppc2-acode-needs-memoization value)))
2150 (index-known-fixnum (acode-fixnum-form-p index)))
2151 (let* ((src ($ ppc::arg_x))
2152 (unscaled-idx ($ ppc::arg_y))
2153 (result-reg ($ ppc::arg_z)))
2154 (cond (needs-memoization
2155 (ppc2-three-targeted-reg-forms seg
2156 vector src
2157 index unscaled-idx
2158 value result-reg))
2159 (t
2160 (setq result-reg (ppc2-target-reg-for-aset vreg type-keyword))
2161 (ppc2-three-targeted-reg-forms seg
2162 vector src
2163 index unscaled-idx
2164 value result-reg)))
2165 (when safe
2166 (let* ((*available-backend-imm-temps* *available-backend-imm-temps*)
2167 (value (if (eql (hard-regspec-class result-reg)
2168 hard-reg-class-gpr)
2169 (hard-regspec-value result-reg))))
2170 (when (and value (logbitp value *available-backend-imm-temps*))
2171 (setq *available-backend-imm-temps* (bitclr value *available-backend-imm-temps*)))
2172 (if (typep safe 'fixnum)
2173 (! trap-unless-typecode= src safe))
2174 (unless index-known-fixnum
2175 (! trap-unless-fixnum unscaled-idx))
2176 (! check-misc-bound unscaled-idx src)))
2177 (ppc2-vset1 seg vreg xfer type-keyword src unscaled-idx index-known-fixnum result-reg (ppc2-unboxed-reg-for-aset seg type-keyword result-reg safe constval) constval needs-memoization)))))
2178
2179
2180(defun ppc2-tail-call-alias (immref sym &optional arglist)
2181 (let ((alias (cdr (assq sym *ppc2-tail-call-aliases*))))
2182 (if (and alias (or (null arglist) (eq (+ (length (car arglist)) (length (cadr arglist))) (cdr alias))))
2183 (make-acode (%nx1-operator immediate) (car alias))
2184 immref)))
2185
2186;;; If BODY is essentially an APPLY involving an &rest arg, try to avoid
2187;;; consing it.
2188(defun ppc2-eliminate-&rest (body rest key-p auxen rest-values)
2189 (when (and rest (not key-p) (not (cadr auxen)) rest-values)
2190 (when (eq (logand (the fixnum (nx-var-bits rest))
2191 (logior $vsetqmask (ash -1 $vbitspecial)
2192 (ash 1 $vbitclosed) (ash 1 $vbitsetq) (ash 1 $vbitcloseddownward)))
2193 0) ; Nothing but simple references
2194 (do* ()
2195 ((not (acode-p body)))
2196 (let* ((op (acode-operator body)))
2197 (if (or (eq op (%nx1-operator lexical-function-call))
2198 (eq op (%nx1-operator call)))
2199 (destructuring-bind (fn-form (stack-args reg-args) &optional spread-p) (%cdr body)
2200 (unless (and (eq spread-p t)
2201 (eq (ppc2-lexical-reference-p (%car reg-args)) rest))
2202 (return nil))
2203 (flet ((independent-of-all-values (form)
2204 (setq form (acode-unwrapped-form form))
2205 (or (ppc-constant-form-p form)
2206 (let* ((lexref (ppc2-lexical-reference-p form)))
2207 (and lexref
2208 (neq lexref rest)
2209 (dolist (val rest-values t)
2210 (unless (ppc2-var-not-set-by-form-p lexref val)
2211 (return))))))))
2212 (unless (or (eq op (%nx1-operator lexical-function-call))
2213 (independent-of-all-values fn-form))
2214 (return nil))
2215 (if (dolist (s stack-args t)
2216 (unless (independent-of-all-values s)
2217 (return nil)))
2218 (let* ((arglist (append stack-args rest-values)))
2219 (return
2220 (make-acode op
2221 fn-form
2222 (if (<= (length arglist) $numppcargregs)
2223 (list nil (reverse arglist))
2224 (list (butlast arglist $numppcargregs)
2225 (reverse (last arglist $numppcargregs))))
2226 nil)))
2227 (return nil))))
2228 (if (eq op (%nx1-operator local-block))
2229 (setq body (%cadr body))
2230 (if (and (eq op (%nx1-operator if))
2231 (eq (ppc2-lexical-reference-p (%cadr body)) rest))
2232 (setq body (%caddr body))
2233 (return nil)))))))))
2234
2235(defun ppc2-call-fn (seg vreg xfer fn arglist spread-p)
2236 (with-ppc-local-vinsn-macros (seg vreg xfer)
2237 (when spread-p
2238 (destructuring-bind (stack-args reg-args) arglist
2239 (when (and (null (cdr reg-args))
2240 (nx-null (acode-unwrapped-form (car reg-args))))
2241 (setq spread-p nil)
2242 (let* ((nargs (length stack-args)))
2243 (declare (fixnum nargs))
2244 (if (<= nargs $numppcargregs)
2245 (setq arglist (list nil (reverse stack-args)))
2246 (setq arglist (list (butlast stack-args $numppcargregs) (reverse (last stack-args $numppcargregs)))))))))
2247 (let* ((lexref (ppc2-lexical-reference-p fn))
2248 (simple-case (or (fixnump fn)
2249 (typep fn 'lreg)
2250 (ppc2-immediate-function-p fn)
2251 (and
2252 lexref
2253 (not spread-p)
2254 (flet ((all-simple (args)
2255 (dolist (arg args t)
2256 (when (and arg (not (ppc2-var-not-set-by-form-p lexref arg)))
2257 (return)))))
2258 (and (all-simple (car arglist))
2259 (all-simple (cadr arglist))
2260 (setq fn (var-ea lexref)))))))
2261 (cstack *ppc2-cstack*)
2262 (top *ppc2-top-vstack-lcell*)
2263 (vstack *ppc2-vstack*))
2264 (setq xfer (or xfer 0))
2265 (when (and (eq xfer $backend-return)
2266 (eq 0 *ppc2-undo-count*)
2267 (acode-p fn)
2268 (eq (acode-operator fn) (%nx1-operator immediate))
2269 (symbolp (cadr fn)))
2270 (setq fn (ppc2-tail-call-alias fn (%cadr fn) arglist)))
2271
2272 (if (and (eq xfer $backend-return) (not (ppc2-tailcallok xfer)))
2273 (progn
2274 (ppc2-call-fn seg vreg $backend-mvpass fn arglist spread-p)
2275 (ppc2-set-vstack (%i+ (if simple-case 0 *ppc2-target-node-size*) vstack))
2276 (setq *ppc2-cstack* cstack)
2277 (let ((*ppc2-returning-values* t)) (ppc2-do-return seg)))
2278 (let* ((mv-p (ppc2-mv-p xfer)))
2279 (unless simple-case
2280 (ppc2-vpush-register seg (ppc2-one-untargeted-reg-form seg fn ppc::arg_z))
2281 (setq fn (ppc2-vloc-ea vstack)))
2282 (ppc2-invoke-fn seg fn (ppc2-arglist seg arglist) spread-p xfer)
2283 (if (and (logbitp $backend-mvpass-bit xfer)
2284 (not simple-case))
2285 (progn
2286 (! save-values)
2287 (! vstack-discard 1)
2288 (ppc2-set-nargs seg 0)
2289 (! recover-values))
2290 (unless (or mv-p simple-case)
2291 (! vstack-discard 1)))
2292 (ppc2-set-vstack vstack)
2293 (setq *ppc2-top-vstack-lcell* top)
2294 (setq *ppc2-cstack* cstack)
2295 (when (or (logbitp $backend-mvpass-bit xfer) (not mv-p))
2296 (<- ppc::arg_z)
2297 (ppc2-branch seg (logand (lognot $backend-mvpass-mask) xfer) vreg))))
2298 nil)))
2299
2300(defun ppc2-restore-full-lisp-context (seg)
2301 (with-ppc-local-vinsn-macros (seg)
2302 (if *ppc2-open-code-inline*
2303 (! restore-full-lisp-context)
2304 (! restore-full-lisp-context-ool))))
2305
2306(defun ppc2-call-symbol (seg jump-p)
2307 ; fname contains a symbol; we can either call it via
2308 ; a call to .SPjmpsym or expand the instructions inline.
2309 ; Since the branches are unconditional, the call doesn't
2310 ; cost much, but doing the instructions inline would give
2311 ; an instruction scheduler some opportunities to improve
2312 ; performance, so this isn't a strict time/speed tradeoff.
2313 ; This should probably dispatch on something other than
2314 ; *ppc2-open-code-inline*, since that does imply a time/speed
2315 ; tradeoff.
2316 (with-ppc-local-vinsn-macros (seg)
2317 (if *ppc2-open-code-inline*
2318 (if jump-p
2319 (! jump-known-symbol)
2320 (! call-known-symbol ppc::arg_z))
2321 (if jump-p
2322 (! jump-known-symbol-ool)
2323 (! call-known-symbol-ool)))))
2324
2325;;; Nargs = nil -> multiple-value case.
2326(defun ppc2-invoke-fn (seg fn nargs spread-p xfer)
2327 (with-ppc-local-vinsn-macros (seg)
2328 (let* ((f-op (acode-unwrapped-form fn))
2329 (immp (and (consp f-op)
2330 (eq (%car f-op) (%nx1-operator immediate))))
2331 (symp (and immp (symbolp (%cadr f-op))))
2332 (label-p (and (fixnump fn)
2333 (locally (declare (fixnum fn))
2334 (and (= fn -1) (- fn)))))
2335 (tail-p (eq xfer $backend-return))
2336 (func (if (consp f-op) (%cadr f-op)))
2337 (a-reg nil)
2338 (lfunp (and (acode-p f-op)
2339 (eq (acode-operator f-op) (%nx1-operator simple-function))))
2340 (expression-p (or (typep fn 'lreg) (and (fixnump fn) (not label-p))))
2341 (callable (or symp lfunp label-p))
2342 (destreg (if symp ($ ppc::fname) (if lfunp ($ ppc::nfn) (unless label-p ($ ppc::temp0)))))
2343 (alternate-tail-call
2344 (and tail-p label-p *ppc2-tail-label* (eql nargs *ppc2-tail-nargs*) (not spread-p)))
2345 )
2346 (when expression-p
2347 ;Have to do this before spread args, since might be vsp-relative.
2348 (if nargs
2349 (ppc2-do-lexical-reference seg destreg fn)
2350 (ppc2-copy-register seg destreg fn)))
2351 (if (or symp lfunp)
2352 (setq func (if symp (ppc2-symbol-entry-locative func)
2353 (ppc2-afunc-lfun-ref func))
2354 a-reg (ppc2-register-constant-p func)))
2355 (when tail-p
2356 #-no-compiler-bugs
2357 (unless (or immp symp lfunp (typep fn 'lreg) (fixnump fn)) (error "Well, well, well. How could this have happened ?"))
2358 (when a-reg
2359 (ppc2-copy-register seg destreg a-reg))
2360 (unless spread-p
2361 (unless alternate-tail-call
2362 (if nargs
2363 (ppc2-restore-nvrs seg *ppc2-register-restore-ea* *ppc2-register-restore-count*)
2364 (when *ppc2-register-restore-count*
2365 (with-imm-temps () (vsp0)
2366 (! fixnum-add vsp0 ppc::vsp ppc::nargs)
2367 (ppc2-restore-nvrs seg *ppc2-register-restore-ea* *ppc2-register-restore-count* vsp0)))))))
2368 (if spread-p
2369 (progn
2370 (ppc2-set-nargs seg (%i- nargs 1))
2371 (when (and tail-p *ppc2-register-restore-count*)
2372 (! copy-gpr ppc::temp1 ppc::vsp)) ; .SPspread-lexpr-z & .SPspreadargz preserve temp1
2373 (if (eq spread-p 0)
2374 (! spread-lexpr)
2375 (! spread-list))
2376 (when (and tail-p *ppc2-register-restore-count*)
2377 (ppc2-restore-nvrs seg *ppc2-register-restore-ea* *ppc2-register-restore-count* ppc::temp1)))
2378 (if nargs
2379 (unless alternate-tail-call (ppc2-set-nargs seg nargs))
2380 (! pop-argument-registers)))
2381 (if callable
2382 (if (not tail-p)
2383 (if (ppc2-mvpass-p xfer)
2384 (let* ((call-reg (if symp ($ ppc::fname) ($ ppc::temp0))))
2385 (if label-p
2386 (ppc2-copy-register seg call-reg ($ ppc::fn))
2387 (if a-reg
2388 (ppc2-copy-register seg call-reg a-reg)
2389 (ppc2-store-immediate seg func call-reg)))
2390 (if symp
2391 (! pass-multiple-values-symbol)
2392 (! pass-multiple-values)))
2393 (progn
2394 (if label-p
2395 (progn
2396 (ppc2-copy-register seg ($ ppc::nfn) ($ ppc::fn))
2397 (! call-label (aref *backend-labels* 1)))
2398 (progn
2399 (if a-reg
2400 (ppc2-copy-register seg destreg a-reg)
2401 (ppc2-store-immediate seg func destreg))
2402 (if symp
2403 (ppc2-call-symbol seg nil)
2404 (! call-known-function))))))
2405 (if alternate-tail-call
2406 (progn
2407 (ppc2-unwind-stack seg xfer 0 0 *ppc2-tail-vsp*)
2408 (! jump (aref *backend-labels* *ppc2-tail-label*)))
2409 (progn
2410 (ppc2-unwind-stack seg xfer 0 0 #x7fffff)
2411 (if (and (not spread-p) nargs (%i<= nargs $numppcargregs))
2412 (progn
2413 (if label-p
2414 (ppc2-copy-register seg ppc::nfn ppc::fn))
2415 (unless (or label-p a-reg) (ppc2-store-immediate seg func destreg))
2416 (ppc2-restore-full-lisp-context seg)
2417 (if label-p
2418 (! jump (aref *backend-labels* 1))
2419 (progn
2420 (if symp
2421 (ppc2-call-symbol seg t)
2422 (! jump-known-function)))))
2423 (progn
2424 (if label-p
2425 (ppc2-copy-register seg ppc::nfn ppc::fn)
2426 (unless a-reg (ppc2-store-immediate seg func destreg)))
2427 (cond ((or spread-p (null nargs))
2428 (if symp
2429 (! tail-call-sym-gen)
2430 (! tail-call-fn-gen)))
2431 ((%i> nargs $numppcargregs)
2432 (if symp
2433 (! tail-call-sym-slide)
2434 (! tail-call-fn-slide)))
2435 (t
2436 (if symp
2437 (! tail-call-sym-vsp)
2438 (! tail-call-fn-vsp)))))))))
2439 ;; The general (funcall) case: we don't know (at compile-time)
2440 ;; for sure whether we've got a symbol or a (local, constant)
2441 ;; function.
2442 (progn
2443 (unless (or (fixnump fn) (typep fn 'lreg))
2444 (ppc2-one-targeted-reg-form seg fn destreg))
2445 (if (not tail-p)
2446 (if (ppc2-mvpass-p xfer)
2447 (! pass-multiple-values)
2448 (! funcall))
2449 (cond ((or (null nargs) spread-p)
2450 (! tail-funcall-gen))
2451 ((%i> nargs $numppcargregs)
2452 (! tail-funcall-slide))
2453 (t
2454 (! tail-funcall-vsp)))))))
2455 nil))
2456
2457(defun ppc2-seq-fbind (seg vreg xfer vars afuncs body p2decls)
2458 (let* ((old-stack (ppc2-encode-stack))
2459 (copy afuncs)
2460 (func nil))
2461 (with-ppc-p2-declarations p2decls
2462 (dolist (var vars)
2463 (when (neq 0 (afunc-fn-refcount (setq func (pop afuncs))))
2464 (ppc2-seq-bind-var seg var (nx1-afunc-ref func))))
2465 (ppc2-undo-body seg vreg xfer body old-stack)
2466 (dolist (var vars)
2467 (when (neq 0 (afunc-fn-refcount (setq func (pop copy))))
2468 (ppc2-close-var seg var))))))
2469
2470(defun ppc2-make-closure (seg afunc downward-p)
2471 (with-ppc-local-vinsn-macros (seg)
2472 (flet ((var-to-reg (var target)
2473 (let* ((ea (var-ea (var-bits var))))
2474 (if ea
2475 (ppc2-addrspec-to-reg seg (ppc2-ea-open ea) target)
2476 (! load-nil target))
2477 target))
2478 (set-some-cells (dest cellno c0 c1 c2 c3)
2479 (declare (fixnum cellno))
2480 (! misc-set-c-node c0 dest cellno)
2481 (incf cellno)
2482 (when c1
2483 (! misc-set-c-node c1 dest cellno)
2484 (incf cellno)
2485 (when c2
2486 (! misc-set-c-node c2 dest cellno)
2487 (incf cellno)
2488 (when c3
2489 (! misc-set-c-node c3 dest cellno)
2490 (incf cellno))))
2491 cellno))
2492 (let* ((inherited-vars (afunc-inherited-vars afunc))
2493 (arch (backend-target-arch *target-backend*))
2494 (dest ($ ppc::arg_z))
2495 (vsize (+ (length inherited-vars)
2496 2 ; %closure-code%, afunc
2497 2))) ; name, lfun-bits
2498 (declare (list inherited-vars))
2499 (if downward-p
2500 (progn
2501 (let* ((*ppc2-vstack* *ppc2-vstack*)
2502 (*ppc2-top-vstack-lcell* *ppc2-top-vstack-lcell*))
2503 (ppc2-lri seg ppc::arg_x (ash (nx-lookup-target-uvector-subtag :function) *ppc2-target-fixnum-shift*))
2504 (! %closure-code% ppc::arg_y)
2505 (ppc2-store-immediate seg (ppc2-afunc-lfun-ref afunc) ppc::arg_z)
2506 (ppc2-vpush-register-arg seg ppc::arg_x)
2507 (ppc2-vpush-register-arg seg ppc::arg_y)
2508 (ppc2-vpush-register-arg seg ppc::arg_z)
2509 ; Could be smarter about memory traffic here.
2510 (dolist (v inherited-vars)
2511 (ppc2-vpush-register-arg seg (var-to-reg v ppc::arg_z)))
2512 (! load-nil ppc::arg_z)
2513 (ppc2-vpush-register-arg seg ppc::arg_z)
2514 (ppc2-lri seg ppc::arg_z (ash (ash 1 $lfbits-trampoline-bit) *ppc2-target-fixnum-shift*))
2515 (ppc2-vpush-register-arg seg ppc::arg_z)
2516 (ppc2-set-nargs seg (1+ vsize)) ; account for subtag
2517 (! make-stack-gvector))
2518 (ppc2-open-undo $undostkblk))
2519 (let* ((cell 0))
2520 (declare (fixnum cell))
2521 (progn
2522 (ppc2-lri seg
2523 ppc::imm0
2524 (arch::make-vheader vsize (nx-lookup-target-uvector-subtag :function)))
2525 (! %alloc-misc-fixed dest ppc::imm0 (ash vsize (arch::target-word-shift arch)))
2526 )
2527 (! %closure-code% ppc::arg_x)
2528 (ppc2-store-immediate seg (ppc2-afunc-lfun-ref afunc) ppc::arg_y)
2529 (with-node-temps (ppc::arg_z) (t0 t1 t2 t3)
2530 (do* ((ccode ppc::arg_x nil)
2531 (func ppc::arg_y nil))
2532 ((null inherited-vars))
2533 (let* ((t0r (or ccode (if inherited-vars (var-to-reg (pop inherited-vars) t0))))
2534 (t1r (or func (if inherited-vars (var-to-reg (pop inherited-vars) t1))))
2535 (t2r (if inherited-vars (var-to-reg (pop inherited-vars) t2)))
2536 (t3r (if inherited-vars (var-to-reg (pop inherited-vars) t3))))
2537 (setq cell (set-some-cells dest cell t0r t1r t2r t3r)))))
2538 (ppc2-lri seg ppc::arg_y (ash (ash 1 $lfbits-trampoline-bit) *ppc2-target-fixnum-shift*))
2539 (! load-nil ppc::arg_x)
2540 (! misc-set-c-node ppc::arg_x dest cell)
2541 (! misc-set-c-node ppc::arg_y dest (1+ cell))))
2542 dest))))
2543
2544(defun ppc2-symbol-entry-locative (sym)
2545 (setq sym (require-type sym 'symbol))
2546 (when (eq sym '%call-next-method-with-args)
2547 (setf (afunc-bits *ppc2-cur-afunc*)
2548 (%ilogior (%ilsl $fbitnextmethargsp 1) (afunc-bits *ppc2-cur-afunc*))))
2549 (or (assq sym *ppc2-fcells*)
2550 (let ((new (list sym)))
2551 (push new *ppc2-fcells*)
2552 new)))
2553
2554(defun ppc2-symbol-value-cell (sym)
2555 (setq sym (require-type sym 'symbol))
2556 (or (assq sym *ppc2-vcells*)
2557 (let ((new (list sym)))
2558 (push new *ppc2-vcells*)
2559 (ensure-binding-index sym)
2560 new)))
2561
2562
2563(defun ppc2-symbol-locative-p (imm)
2564 (and (consp imm)
2565 (or (memq imm *ppc2-vcells*)
2566 (memq imm *ppc2-fcells*))))
2567
2568
2569
2570
2571(defun ppc2-immediate-function-p (f)
2572 (setq f (acode-unwrapped-form f))
2573 (and (acode-p f)
2574 (or (eq (%car f) (%nx1-operator immediate))
2575 (eq (%car f) (%nx1-operator simple-function)))))
2576
2577(defun ppc-constant-form-p (form)
2578 (setq form (nx-untyped-form form))
2579 (if form
2580 (or (nx-null form)
2581 (nx-t form)
2582 (and (consp form)
2583 (or (eq (acode-operator form) (%nx1-operator immediate))
2584 (eq (acode-operator form) (%nx1-operator fixnum))
2585 (eq (acode-operator form) (%nx1-operator simple-function)))))))
2586
2587
2588
2589(defun ppc2-long-constant-p (form)
2590 (setq form (acode-unwrapped-form form))
2591 (or (acode-fixnum-form-p form)
2592 (and (acode-p form)
2593 (eq (acode-operator form) (%nx1-operator immediate))
2594 (setq form (%cadr form))
2595 (if (integerp form)
2596 form))))
2597
2598
2599(defun ppc-side-effect-free-form-p (form)
2600 (when (consp (setq form (acode-unwrapped-form form)))
2601 (or (ppc-constant-form-p form)
2602 ;(eq (acode-operator form) (%nx1-operator bound-special-ref))
2603 (if (eq (acode-operator form) (%nx1-operator lexical-reference))
2604 (not (%ilogbitp $vbitsetq (nx-var-bits (%cadr form))))))))
2605
2606(defun ppc2-formlist (seg stkargs &optional revregargs)
2607 (with-ppc-local-vinsn-macros (seg)
2608 (let* ((nregs (length revregargs))
2609 (n nregs))
2610 (declare (fixnum n))
2611 (dolist (arg stkargs)
2612 (let* ((reg (ppc2-one-untargeted-reg-form seg arg ppc::arg_z)))
2613 (ppc2-vpush-register-arg seg reg)
2614 (incf n)))
2615 (when revregargs
2616 (let* ((zform (%car revregargs))
2617 (yform (%cadr revregargs))
2618 (xform (%caddr revregargs)))
2619 (if (eq 3 nregs)
2620 (ppc2-three-targeted-reg-forms seg xform ($ ppc::arg_x) yform ($ ppc::arg_y) zform ($ ppc::arg_z))
2621 (if (eq 2 nregs)
2622 (ppc2-two-targeted-reg-forms seg yform ($ ppc::arg_y) zform ($ ppc::arg_z))
2623 (ppc2-one-targeted-reg-form seg zform ($ ppc::arg_z))))))
2624 n)))
2625
2626(defun ppc2-arglist (seg args)
2627 (ppc2-formlist seg (car args) (cadr args)))
2628
2629
2630
2631
2632;;; treat form as a 32-bit immediate value and load it into immreg.
2633;;; This is the "lenient" version of 32-bit-ness; OSTYPEs and chars
2634;;; count, and we don't care about the integer's sign.
2635
2636(defun ppc2-unboxed-integer-arg-to-reg (seg form immreg &optional ffi-arg-type)
2637 (let* ((mode (case ffi-arg-type
2638 ((nil) :natural)
2639 (:signed-byte :s8)
2640 (:unsigned-byte :u8)
2641 (:signed-halfword :s16)
2642 (:unsigned-halfword :u16)
2643 (:signed-fullword :s32)
2644 (:unsigned-fullword :u32)))
2645 (modeval (gpr-mode-name-value mode)))
2646 (with-ppc-local-vinsn-macros (seg)
2647 (let* ((value (ppc2-long-constant-p form)))
2648 (if value
2649 (if (eql value 0)
2650 (make-wired-lreg ppc::rzero :mode modeval)
2651 (progn
2652 (unless (typep immreg 'lreg)
2653 (setq immreg (make-unwired-lreg immreg :mode modeval)))
2654 (ppc2-lri seg immreg value)
2655 immreg))
2656 (progn
2657 (ppc2-one-targeted-reg-form seg form (make-wired-lreg ppc::imm0 :mode modeval))))))))
2658
2659
2660(defun ppc2-macptr-arg-to-reg (seg form address-reg)
2661 (ppc2-one-targeted-reg-form seg
2662 form
2663 address-reg))
2664
2665
2666(defun ppc2-one-lreg-form (seg form lreg)
2667 (let ((is-float (= (hard-regspec-class lreg) hard-reg-class-fpr)))
2668 (if is-float
2669 (ppc2-form-float seg lreg nil form)
2670 (ppc2-form seg lreg nil form))
2671 lreg))
2672
2673(defun ppc2-one-targeted-reg-form (seg form reg)
2674 (ppc2-one-lreg-form seg form reg))
2675
2676(defun ppc2-one-untargeted-lreg-form (seg form reg)
2677 (ppc2-one-lreg-form seg form (if (typep reg 'lreg) reg (make-unwired-lreg reg))))
2678
2679(defun ppc2-one-untargeted-reg-form (seg form suggested)
2680 (with-ppc-local-vinsn-macros (seg)
2681 (let* ((gpr-p (= (hard-regspec-class suggested) hard-reg-class-gpr))
2682 (node-p (if gpr-p (= (get-regspec-mode suggested) hard-reg-class-gpr-mode-node))))
2683 (if node-p
2684 (let* ((ref (ppc2-lexical-reference-ea form))
2685 (reg (backend-ea-physical-reg ref hard-reg-class-gpr)))
2686 (if reg
2687 ref
2688 (if (nx-null form)
2689 (progn
2690 (! load-nil suggested)
2691 suggested)
2692 (if (eql 0 (acode-fixnum-form-p form))
2693 ($ ppc::rzero)
2694 (if (and (acode-p form)
2695 (eq (acode-operator form) (%nx1-operator immediate))
2696 (setq reg (ppc2-register-constant-p (cadr form))))
2697 reg
2698 (if (and (acode-p form)
2699 (eq (acode-operator form) (%nx1-operator %current-tcr)))
2700 (target-arch-case
2701 (:ppc32 ($ ppc32::rcontext))
2702 (:ppc64 ($ ppc64::rcontext)))
2703 (ppc2-one-untargeted-lreg-form seg form suggested)))))))
2704 (ppc2-one-untargeted-lreg-form seg form suggested)))))
2705
2706
2707(defun ppc2-push-register (seg areg)
2708 (let* ((a-float (= (hard-regspec-class areg) hard-reg-class-fpr))
2709 (a-double (if a-float (= (get-regspec-mode areg) hard-reg-class-fpr-mode-double)))
2710 (a-node (unless a-float (= (get-regspec-mode areg) hard-reg-class-gpr-mode-node)))
2711 vinsn)
2712 (with-ppc-local-vinsn-macros (seg)
2713 (if a-node
2714 (setq vinsn (ppc2-vpush-register seg areg :node-temp))
2715 (progn
2716 (setq vinsn
2717 (if a-float
2718 (if a-double
2719 (! temp-push-double-float areg)
2720 (! temp-push-single-float areg))
2721 (! temp-push-unboxed-word areg)))
2722 (ppc2-open-undo $undostkblk)))
2723 vinsn)))
2724
2725(defun ppc2-pop-register (seg areg)
2726 (let* ((a-float (= (hard-regspec-class areg) hard-reg-class-fpr))
2727 (a-double (if a-float (= (get-regspec-mode areg) hard-reg-class-fpr-mode-double)))
2728 (a-node (unless a-float (= (get-regspec-mode areg) hard-reg-class-gpr-mode-node)))
2729 vinsn)
2730 (with-ppc-local-vinsn-macros (seg)
2731 (if a-node
2732 (setq vinsn (ppc2-vpop-register seg areg))
2733 (progn
2734 (setq vinsn
2735 (if a-float
2736 (if a-double
2737 (! temp-pop-double-float areg)
2738 (! temp-pop-single-float areg))
2739 (! temp-pop-unboxed-word areg)))
2740 (ppc2-close-undo)))
2741 vinsn)))
2742
2743(defun ppc2-acc-reg-for (reg)
2744 (with-ppc-local-vinsn-macros (seg)
2745 (let* ((class (hard-regspec-class reg))
2746 (mode (get-regspec-mode reg)))
2747 (declare (fixnum class mode))
2748 (cond ((= class hard-reg-class-fpr)
2749 (make-wired-lreg ppc::fp1 :class class :mode mode))
2750 ((= class hard-reg-class-gpr)
2751 (if (= mode hard-reg-class-gpr-mode-node)
2752 ($ ppc::arg_z)
2753 (make-wired-lreg ppc::imm0 :mode mode)))
2754 (t (error "Unknown register class for reg ~s" reg))))))
2755
2756;;; The compiler often generates superfluous pushes & pops. Try to
2757;;; eliminate them.
2758;;; It's easier to elide pushes and pops to the TSP.
2759(defun ppc2-elide-pushes (seg push-vinsn pop-vinsn)
2760 (with-ppc-local-vinsn-macros (seg)
2761 (let* ((pushed-reg (svref (vinsn-variable-parts push-vinsn) 0))
2762 (popped-reg (svref (vinsn-variable-parts pop-vinsn) 0))
2763 (same-reg (eq (hard-regspec-value pushed-reg)
2764 (hard-regspec-value popped-reg)))
2765 (tsp-p (vinsn-attribute-p push-vinsn :tsp)))
2766 (when (and tsp-p t) ; vsp case is harder.
2767 (let* ((pushed-reg-is-set (vinsn-sequence-sets-reg-p
2768 push-vinsn pop-vinsn pushed-reg))
2769 (popped-reg-is-set (if same-reg
2770 pushed-reg-is-set
2771 (vinsn-sequence-sets-reg-p
2772 push-vinsn pop-vinsn popped-reg))))
2773 (unless (and pushed-reg-is-set popped-reg-is-set)
2774 (unless same-reg
2775 (let* ((copy (if (eq (hard-regspec-class pushed-reg)
2776 hard-reg-class-fpr)
2777 (! copy-fpr popped-reg pushed-reg)
2778 (! copy-gpr popped-reg pushed-reg))))
2779 (remove-dll-node copy)
2780 (if pushed-reg-is-set
2781 (insert-dll-node-after copy push-vinsn)
2782 (insert-dll-node-before copy push-vinsn))))
2783 (elide-vinsn push-vinsn)
2784 (elide-vinsn pop-vinsn)))))))
2785
2786
2787;;; we never leave the first form pushed (the 68K compiler had some subprims that
2788;;; would vpop the first argument out of line.)
2789(defun ppc2-two-targeted-reg-forms (seg aform areg bform breg)
2790 (unless (typep areg 'lreg)
2791 (warn "~s is not an lreg (1/2)" areg))
2792 (unless (typep breg 'lreg)
2793 (warn "~s is not an lreg (2/2)" breg))
2794 (let* ((avar (ppc2-lexical-reference-p aform))
2795 (atriv (ppc2-trivial-p bform))
2796 (aconst (and (not atriv) (or (ppc-side-effect-free-form-p aform)
2797 (if avar (ppc2-var-not-set-by-form-p avar bform)))))
2798 (apushed (not (or atriv aconst))))
2799 (progn
2800 (unless aconst
2801 (if atriv
2802 (ppc2-one-targeted-reg-form seg aform areg)
2803 (setq apushed (ppc2-push-register seg (ppc2-one-untargeted-reg-form seg aform (ppc2-acc-reg-for areg))))))
2804 (ppc2-one-targeted-reg-form seg bform breg)
2805 (if aconst
2806 (ppc2-one-targeted-reg-form seg aform areg)
2807 (if apushed
2808 (ppc2-elide-pushes seg apushed (ppc2-pop-register seg areg)))))
2809 (values areg breg)))
2810
2811
2812(defun ppc2-two-untargeted-reg-forms (seg aform areg bform breg)
2813 (with-ppc-local-vinsn-macros (seg)
2814 (let* ((avar (ppc2-lexical-reference-p aform))
2815 (adest areg)
2816 (bdest breg)
2817 (atriv (ppc2-trivial-p bform))
2818 (aconst (and (not atriv) (or (ppc-side-effect-free-form-p aform)
2819 (if avar (ppc2-var-not-set-by-form-p avar bform)))))
2820 (apushed (not (or atriv aconst))))
2821 (progn
2822 (unless aconst
2823 (if atriv
2824 (setq adest (ppc2-one-untargeted-reg-form seg aform areg))
2825 (setq apushed (ppc2-push-register seg (ppc2-one-untargeted-reg-form seg aform (ppc2-acc-reg-for areg))))))
2826 (setq bdest (ppc2-one-untargeted-reg-form seg bform breg))
2827 (if aconst
2828 (setq adest (ppc2-one-untargeted-reg-form seg aform areg))
2829 (if apushed
2830 (ppc2-elide-pushes seg apushed (ppc2-pop-register seg areg)))))
2831 (values adest bdest))))
2832
2833
2834(defun ppc2-four-targeted-reg-forms (seg aform areg bform breg cform creg dform dreg)
2835 (unless (typep areg 'lreg)
2836 (warn "~s is not an lreg (1/4)" areg))
2837 (unless (typep breg 'lreg)
2838 (warn "~s is not an lreg (2/4)" breg))
2839 (unless (typep creg 'lreg)
2840 (warn "~s is not an lreg (3/4)" creg))
2841 (unless (typep dreg 'lreg)
2842 (warn "~s is not an lreg (4/4)" dreg))
2843 (let* ((atriv (or (null aform)
2844 (and (ppc2-trivial-p bform)
2845 (ppc2-trivial-p cform)
2846 (ppc2-trivial-p dform))))
2847 (btriv (or (null bform)
2848 (and (ppc2-trivial-p cform)
2849 (ppc2-trivial-p dform))))
2850 (ctriv (or (null cform)
2851 (ppc2-trivial-p dform)))
2852
2853 (aconst (and (not atriv)
2854 (or (ppc-side-effect-free-form-p aform)
2855 (let ((avar (ppc2-lexical-reference-p aform)))
2856 (and avar
2857 (ppc2-var-not-set-by-form-p avar bform)
2858 (ppc2-var-not-set-by-form-p avar cform)
2859 (ppc2-var-not-set-by-form-p avar dform))))))
2860 (bconst (and (not btriv)
2861 (or (ppc-side-effect-free-form-p bform)
2862 (let ((bvar (ppc2-lexical-reference-p bform)))
2863 (and bvar
2864 (ppc2-var-not-set-by-form-p bvar cform)
2865 (ppc2-var-not-set-by-form-p bvar dform))))))
2866 (cconst (and (not ctriv)
2867 (or (ppc-side-effect-free-form-p cform)
2868 (let ((cvar (ppc2-lexical-reference-p cform)))
2869 (and cvar
2870 (ppc2-var-not-set-by-form-p cvar dform))))))
2871 (apushed nil)
2872 (bpushed nil)
2873 (cpushed nil))
2874 (if (and aform (not aconst))
2875 (if atriv
2876 (ppc2-one-targeted-reg-form seg aform areg)
2877 (setq apushed (ppc2-push-register seg (ppc2-one-untargeted-reg-form seg aform (ppc2-acc-reg-for areg))))))
2878 (if (and bform (not bconst))
2879 (if btriv
2880 (ppc2-one-targeted-reg-form seg bform breg)
2881 (setq bpushed (ppc2-push-register seg (ppc2-one-untargeted-reg-form seg bform (ppc2-acc-reg-for breg))))))
2882 (if (and cform (not cconst))
2883 (if ctriv
2884 (ppc2-one-targeted-reg-form seg cform creg)
2885 (setq cpushed (ppc2-push-register seg (ppc2-one-untargeted-reg-form seg cform (ppc2-acc-reg-for creg))))))
2886 (ppc2-one-targeted-reg-form seg dform dreg)
2887 (unless ctriv
2888 (if cconst
2889 (ppc2-one-targeted-reg-form seg cform creg)
2890 (ppc2-elide-pushes seg cpushed (ppc2-pop-register seg creg))))
2891 (unless btriv
2892 (if bconst
2893 (ppc2-one-targeted-reg-form seg bform breg)
2894 (ppc2-elide-pushes seg bpushed (ppc2-pop-register seg breg))))
2895 (unless atriv
2896 (if aconst
2897 (ppc2-one-targeted-reg-form seg aform areg)
2898 (ppc2-elide-pushes seg apushed (ppc2-pop-register seg areg))))
2899 (values areg breg creg dreg)))
2900
2901(defun ppc2-three-targeted-reg-forms (seg aform areg bform breg cform creg)
2902 (unless (typep areg 'lreg)
2903 (warn "~s is not an lreg (1/3)" areg))
2904 (unless (typep breg 'lreg)
2905 (warn "~s is not an lreg (2/3)" breg))
2906 (unless (typep creg 'lreg)
2907 (warn "~s is not an lreg (3/3)" creg))
2908 (let* ((atriv (or (null aform)
2909 (and (ppc2-trivial-p bform)
2910 (ppc2-trivial-p cform))))
2911 (btriv (or (null bform)
2912 (ppc2-trivial-p cform)))
2913 (aconst (and (not atriv)
2914 (or (ppc-side-effect-free-form-p aform)
2915 (let ((avar (ppc2-lexical-reference-p aform)))
2916 (and avar
2917 (ppc2-var-not-set-by-form-p avar bform)
2918 (ppc2-var-not-set-by-form-p avar cform))))))
2919 (bconst (and (not btriv)
2920 (or
2921 (ppc-side-effect-free-form-p bform)
2922 (let ((bvar (ppc2-lexical-reference-p bform)))
2923 (and bvar (ppc2-var-not-set-by-form-p bvar cform))))))
2924 (apushed nil)
2925 (bpushed nil))
2926 (if (and aform (not aconst))
2927 (if atriv
2928 (ppc2-one-targeted-reg-form seg aform areg)
2929 (setq apushed (ppc2-push-register seg (ppc2-one-untargeted-reg-form seg aform (ppc2-acc-reg-for areg))))))
2930 (if (and bform (not bconst))
2931 (if btriv
2932 (ppc2-one-targeted-reg-form seg bform breg)
2933 (setq bpushed (ppc2-push-register seg (ppc2-one-untargeted-reg-form seg bform (ppc2-acc-reg-for breg))))))
2934 (ppc2-one-targeted-reg-form seg cform creg)
2935 (unless btriv
2936 (if bconst
2937 (ppc2-one-targeted-reg-form seg bform breg)
2938 (ppc2-elide-pushes seg bpushed (ppc2-pop-register seg breg))))
2939 (unless atriv
2940 (if aconst
2941 (ppc2-one-targeted-reg-form seg aform areg)
2942 (ppc2-elide-pushes seg apushed (ppc2-pop-register seg areg))))
2943 (values areg breg creg)))
2944
2945(defun ppc2-three-untargeted-reg-forms (seg aform areg bform breg cform creg)
2946 (with-ppc-local-vinsn-macros (seg)
2947 (let* ((atriv (or (null aform)
2948 (and (ppc2-trivial-p bform)
2949 (ppc2-trivial-p cform))))
2950 (btriv (or (null bform)
2951 (ppc2-trivial-p cform)))
2952 (aconst (and (not atriv)
2953 (or (ppc-side-effect-free-form-p aform)
2954 (let ((avar (ppc2-lexical-reference-p aform)))
2955 (and avar
2956 (ppc2-var-not-set-by-form-p avar bform)
2957 (ppc2-var-not-set-by-form-p avar cform))))))
2958 (bconst (and (not btriv)
2959 (or
2960 (ppc-side-effect-free-form-p bform)
2961 (let ((bvar (ppc2-lexical-reference-p bform)))
2962 (and bvar (ppc2-var-not-set-by-form-p bvar cform))))))
2963 (adest areg)
2964 (bdest breg)
2965 (cdest creg)
2966 (apushed nil)
2967 (bpushed nil))
2968 (if (and aform (not aconst))
2969 (if atriv
2970 (setq adest (ppc2-one-untargeted-reg-form seg aform ($ areg)))
2971 (setq apushed (ppc2-push-register seg (ppc2-one-untargeted-reg-form seg aform (ppc2-acc-reg-for areg))))))
2972 (if (and bform (not bconst))
2973 (if btriv
2974 (setq bdest (ppc2-one-untargeted-reg-form seg bform ($ breg)))
2975 (setq bpushed (ppc2-push-register seg (ppc2-one-untargeted-reg-form seg bform (ppc2-acc-reg-for breg))))))
2976 (setq cdest (ppc2-one-untargeted-reg-form seg cform creg))
2977 (unless btriv
2978 (if bconst
2979 (setq bdest (ppc2-one-untargeted-reg-form seg bform breg))
2980 (ppc2-elide-pushes seg bpushed (ppc2-pop-register seg breg))))
2981 (unless atriv
2982 (if aconst
2983 (setq adest (ppc2-one-untargeted-reg-form seg aform areg))
2984 (ppc2-elide-pushes seg apushed (ppc2-pop-register seg areg))))
2985 (values adest bdest cdest))))
2986
2987(defun ppc2-four-untargeted-reg-forms (seg aform areg bform breg cform creg dform dreg)
2988 (let* ((atriv (or (null aform)
2989 (and (ppc2-trivial-p bform)
2990 (ppc2-trivial-p cform)
2991 (ppc2-trivial-p dform))))
2992 (btriv (or (null bform)
2993 (and (ppc2-trivial-p cform)
2994 (ppc2-trivial-p dform))))
2995 (ctriv (or (null cform)
2996 (ppc2-trivial-p dform)))
2997 (aconst (and (not atriv)
2998 (or (ppc-side-effect-free-form-p aform)
2999 (let ((avar (ppc2-lexical-reference-p aform)))
3000 (and avar
3001 (ppc2-var-not-set-by-form-p avar bform)
3002 (ppc2-var-not-set-by-form-p avar cform)
3003 (ppc2-var-not-set-by-form-p avar dform))))))
3004 (bconst (and (not btriv)
3005 (or
3006 (ppc-side-effect-free-form-p bform)
3007 (let ((bvar (ppc2-lexical-reference-p bform)))
3008 (and bvar
3009 (ppc2-var-not-set-by-form-p bvar cform)
3010 (ppc2-var-not-set-by-form-p bvar dform))))))
3011 (cconst (and (not ctriv)
3012 (or
3013 (ppc-side-effect-free-form-p cform)
3014 (let ((cvar (ppc2-lexical-reference-p cform)))
3015 (and cvar
3016 (ppc2-var-not-set-by-form-p cvar dform))))))
3017 (adest areg)
3018 (bdest breg)
3019 (cdest creg)
3020 (ddest dreg)
3021 (apushed nil)
3022 (bpushed nil)
3023 (cpushed nil))
3024 (if (and aform (not aconst))
3025 (if atriv
3026 (setq adest (ppc2-one-targeted-reg-form seg aform areg))
3027 (setq apushed (ppc2-push-register seg (ppc2-one-untargeted-reg-form seg aform (ppc2-acc-reg-for areg))))))
3028 (if (and bform (not bconst))
3029 (if btriv
3030 (setq bdest (ppc2-one-untargeted-reg-form seg bform breg))
3031 (setq bpushed (ppc2-push-register seg (ppc2-one-untargeted-reg-form seg bform (ppc2-acc-reg-for breg))))))
3032 (if (and cform (not cconst))
3033 (if ctriv
3034 (setq cdest (ppc2-one-untargeted-reg-form seg cform creg))
3035 (setq cpushed (ppc2-push-register seg (ppc2-one-untargeted-reg-form seg cform (ppc2-acc-reg-for creg))))))
3036 (setq ddest (ppc2-one-untargeted-reg-form seg dform dreg))
3037 (unless ctriv
3038 (if cconst
3039 (setq cdest (ppc2-one-untargeted-reg-form seg cform creg))
3040 (ppc2-elide-pushes seg cpushed (ppc2-pop-register seg creg))))
3041 (unless btriv
3042 (if bconst
3043 (setq bdest (ppc2-one-untargeted-reg-form seg bform breg))
3044 (ppc2-elide-pushes seg bpushed (ppc2-pop-register seg breg))))
3045 (unless atriv
3046 (if aconst
3047 (setq adest (ppc2-one-untargeted-reg-form seg aform areg))
3048 (ppc2-elide-pushes seg apushed (ppc2-pop-register seg areg))))
3049 (values adest bdest cdest ddest)))
3050
3051(defun ppc2-lri (seg reg value)
3052 (with-ppc-local-vinsn-macros (seg)
3053 (if (>= value 0)
3054 (! lri reg value)
3055 (target-arch-case
3056 (:ppc32 (! lri reg (logand value #xffffffff)))
3057 (:ppc64 (! lri reg (logand value #xffffffffffffffff)))))))
3058
3059
3060(defun ppc2-multiple-value-body (seg form)
3061 (let* ((lab (backend-get-next-label))
3062 (*ppc2-vstack* *ppc2-vstack*)
3063 (*ppc2-top-vstack-lcell* *ppc2-top-vstack-lcell*)
3064 (old-stack (ppc2-encode-stack)))
3065 (with-ppc-local-vinsn-macros (seg)
3066 (ppc2-open-undo $undomvexpect)
3067 (ppc2-undo-body seg nil (logior $backend-mvpass-mask lab) form old-stack)
3068 (@ lab))))
3069
3070(defun ppc2-afunc-lfun-ref (afunc)
3071 (or
3072 (afunc-lfun afunc)
3073 (progn (pushnew afunc (afunc-fwd-refs *ppc2-cur-afunc*) :test #'eq)
3074 afunc)))
3075
3076(defun ppc2-augment-arglist (afunc arglist &optional (maxregs $numppcargregs))
3077 (let ((inherited-args (afunc-inherited-vars afunc)))
3078 (when inherited-args
3079 (let* ((current-afunc *ppc2-cur-afunc*)
3080 (stkargs (car arglist))
3081 (regargs (cadr arglist))
3082 (inhforms nil)
3083 (numregs (length regargs))
3084 (own-inhvars (afunc-inherited-vars current-afunc)))
3085 (dolist (var inherited-args)
3086 (let* ((root-var (nx-root-var var))
3087 (other-guy
3088 (dolist (v own-inhvars #|(error "other guy not found")|# root-var)
3089 (when (eq root-var (nx-root-var v)) (return v)))))
3090 (push (make-acode (%nx1-operator inherited-arg) other-guy) inhforms)))
3091 (dolist (form inhforms)
3092 (if (%i< numregs maxregs)
3093 (progn
3094 (setq regargs (nconc regargs (list form)))
3095 (setq numregs (%i+ numregs 1)))
3096 (push form stkargs)))
3097 (%rplaca (%cdr arglist) regargs) ; might have started out NIL.
3098 (%rplaca arglist stkargs))))
3099 arglist)
3100
3101
3102
3103;;; There are other cases involving constants that are worth exploiting.
3104(defun ppc2-compare (seg vreg xfer i j cr-bit true-p)
3105 (with-ppc-local-vinsn-macros (seg vreg xfer)
3106 (let* ((js16 (acode-s16-constant-p j))
3107 (is16 (acode-s16-constant-p i))
3108 (boolean (backend-crf-p vreg)))
3109 (if (and boolean (or js16 is16))
3110 (let* ((reg (ppc2-one-untargeted-reg-form seg (if js16 i j) ppc::arg_z)))
3111 (! compare-signed-s16const vreg reg (or js16 is16))
3112 (unless (or js16 (eq cr-bit ppc::ppc-eq-bit))
3113 (setq cr-bit (- 1 cr-bit)))
3114 (^ cr-bit true-p))
3115 (if (and (eq cr-bit ppc::ppc-eq-bit)
3116 (or js16 is16))
3117 (ppc2-test-reg-%izerop
3118 seg
3119 vreg
3120 xfer
3121 (ppc2-one-untargeted-reg-form
3122 seg
3123 (if js16 i j)
3124 ppc::arg_z)
3125 cr-bit
3126 true-p
3127 (or js16 is16))
3128 (multiple-value-bind (ireg jreg) (ppc2-two-untargeted-reg-forms seg i ppc::arg_y j ppc::arg_z)
3129 (ppc2-compare-registers seg vreg xfer ireg jreg cr-bit true-p)))))))
3130
3131(defun ppc2-natural-compare (seg vreg xfer i j cr-bit true-p)
3132 (with-ppc-local-vinsn-macros (seg vreg xfer)
3133 (let* ((jconstant (acode-fixnum-form-p j))
3134 (ju16 (typep jconstant '(unsigned-byte 16)))
3135 (iconstant (acode-fixnum-form-p i))
3136 (iu16 (typep iconstant '(unsigned-byte 16)))
3137 (boolean (backend-crf-p vreg)))
3138 (if (and boolean (or ju16 iu16))
3139 (with-imm-target
3140 () (reg :natural)
3141 (ppc2-one-targeted-reg-form seg (if ju16 i j) reg)
3142 (! compare-unsigned-u16const vreg reg (if ju16 jconstant iconstant))
3143 (unless (or ju16 (eq cr-bit ppc::ppc-eq-bit))
3144 (setq cr-bit (- 1 cr-bit)))
3145 (^ cr-bit true-p))
3146 (with-imm-target ()
3147 (ireg :natural)
3148 (with-imm-target
3149 (ireg) (jreg :natural)
3150 (ppc2-two-targeted-reg-forms seg i ireg j jreg)
3151 (ppc2-compare-natural-registers seg vreg xfer ireg jreg cr-bit true-p)))))))
3152
3153(defun ppc2-compare-natural-registers (seg vreg xfer ireg jreg cr-bit true-p)
3154 (with-ppc-local-vinsn-macros (seg vreg xfer)
3155 (if vreg
3156 (regspec-crf-gpr-case
3157 (vreg dest)
3158 (progn
3159 (! compare-logical dest ireg jreg)
3160 (^ cr-bit true-p))
3161 (with-imm-temps () ((b31-reg :natural))
3162 (ecase cr-bit
3163 (#. ppc::ppc-eq-bit
3164 (if true-p
3165 (! eq->bit31 b31-reg ireg jreg)
3166 (! ne->bit31 b31-reg ireg jreg)))
3167 (#. ppc::ppc-lt-bit
3168 (if true-p
3169 (! ltu->bit31 b31-reg ireg jreg)
3170 (! geu->bit31 b31-reg ireg jreg)))
3171 (#. ppc::ppc-gt-bit
3172 (if true-p
3173 (! gtu->bit31 b31-reg ireg jreg)
3174 (! leu->bit31 b31-reg ireg jreg))))
3175 (ensuring-node-target (target dest)
3176 (! lowbit->truth target b31-reg))
3177 (^)))
3178 (^))))
3179
3180(defun ppc2-compare-registers (seg vreg xfer ireg jreg cr-bit true-p)
3181 (with-ppc-local-vinsn-macros (seg vreg xfer)
3182 (if vreg
3183 (regspec-crf-gpr-case
3184 (vreg dest)
3185 (progn
3186 (! compare dest ireg jreg)
3187 (^ cr-bit true-p))
3188 (with-imm-temps () ((b31-reg :natural))
3189 (ecase cr-bit
3190 (#. ppc::ppc-eq-bit
3191 (if true-p
3192 (! eq->bit31 b31-reg ireg jreg)
3193 (! ne->bit31 b31-reg ireg jreg)))
3194 (#. ppc::ppc-lt-bit
3195 (if true-p
3196 (! lt->bit31 b31-reg ireg jreg)
3197 (! ge->bit31 b31-reg ireg jreg)))
3198 (#. ppc::ppc-gt-bit
3199 (if true-p
3200 (! gt->bit31 b31-reg ireg jreg)
3201 (! le->bit31 b31-reg ireg jreg))))
3202 (ensuring-node-target (target dest)
3203 (! lowbit->truth target b31-reg))
3204 (^)))
3205 (^))))
3206
3207(defun ppc2-compare-register-to-nil (seg vreg xfer ireg cr-bit true-p)
3208 (with-ppc-local-vinsn-macros (seg vreg xfer)
3209 (if vreg
3210 (regspec-crf-gpr-case
3211 (vreg dest)
3212 (progn
3213 (! compare-to-nil dest ireg)
3214 (^ cr-bit true-p))
3215 (with-imm-temps () ((b31-reg :natural))
3216 (ecase cr-bit
3217 (#. ppc::ppc-eq-bit
3218 (if true-p
3219 (! eqnil->bit31 b31-reg ireg)
3220 (! nenil->bit31 b31-reg ireg))))
3221 (ensuring-node-target (target dest)
3222 (! lowbit->truth target b31-reg))
3223 (^)))
3224 (^))))
3225
3226;;; Have to extract a bit out of the CR when a boolean result needed.
3227(defun ppc2-compare-double-float-registers (seg vreg xfer ireg jreg cr-bit true-p)
3228 (with-ppc-local-vinsn-macros (seg vreg xfer)
3229 (if vreg
3230 (regspec-crf-gpr-case
3231 (vreg dest)
3232 (progn
3233 (! double-float-compare dest ireg jreg)
3234 (^ cr-bit true-p))
3235 (with-imm-temps () ((lowbit-reg :natural))
3236 (with-crf-target () flags
3237 (! double-float-compare flags ireg jreg)
3238 (! crbit->bit31 lowbit-reg flags cr-bit))
3239 (unless true-p
3240 (! invert-lowbit lowbit-reg))
3241 (ensuring-node-target (target dest)
3242 (! lowbit->truth target lowbit-reg))
3243 (^)))
3244 (^))))
3245
3246
3247(defun ppc2-immediate-form-p (form)
3248 (if (and (consp form)
3249 (or (eq (%car form) (%nx1-operator immediate))
3250 (eq (%car form) (%nx1-operator simple-function))))
3251 t))
3252
3253(defun ppc2-test-%izerop (seg vreg xfer form cr-bit true-p)
3254 (ppc2-test-reg-%izerop seg vreg xfer (ppc2-one-untargeted-reg-form seg form ppc::arg_z) cr-bit true-p 0))
3255
3256(defun ppc2-test-reg-%izerop (seg vreg xfer reg cr-bit true-p zero)
3257 (declare (fixnum reg zero))
3258 (with-ppc-local-vinsn-macros (seg vreg xfer)
3259 (regspec-crf-gpr-case
3260 (vreg dest)
3261 (progn
3262 (! compare-signed-s16const dest reg zero)
3263 (^ cr-bit true-p))
3264 (with-imm-temps (reg) (b31-reg scaled)
3265 (if (zerop zero)
3266 (setq scaled reg)
3267 (! subtract-constant scaled reg zero))
3268 (ecase cr-bit
3269 (#. ppc::ppc-eq-bit
3270 (if true-p
3271 (! eq0->bit31 b31-reg scaled)
3272 (! ne0->bit31 b31-reg scaled)))
3273 (#. ppc::ppc-lt-bit
3274 (if true-p
3275 (! lt0->bit31 b31-reg scaled)
3276 (! ge0->bit31 b31-reg scaled)))
3277 (#. ppc::ppc-gt-bit
3278 (if true-p
3279 (! gt0->bit31 b31-reg scaled)
3280 (! le0->bit31 b31-reg scaled))))
3281 (ensuring-node-target (target dest)
3282 (! lowbit->truth target b31-reg))
3283 (^)))))
3284
3285(defun ppc2-lexical-reference-ea (form &optional (no-closed-p t))
3286 (when (acode-p (setq form (acode-unwrapped-form form)))
3287 (if (eq (acode-operator form) (%nx1-operator lexical-reference))
3288 (let* ((addr (var-ea (%cadr form))))
3289 (if (typep addr 'lreg)
3290 addr
3291 (unless (and no-closed-p (addrspec-vcell-p addr ))
3292 addr))))))
3293
3294
3295(defun ppc2-vpush-register (seg src &optional why info attr)
3296 (with-ppc-local-vinsn-macros (seg)
3297 (prog1
3298 (! vpush-register src)
3299 (ppc2-new-vstack-lcell (or why :node) *ppc2-target-lcell-size* (or attr 0) info)
3300 (ppc2-adjust-vstack *ppc2-target-node-size*))))
3301
3302(defun ppc2-vpush-register-arg (seg src)
3303 (ppc2-vpush-register seg src :outgoing-argument))
3304
3305
3306(defun ppc2-vpop-register (seg dest)
3307 (with-ppc-local-vinsn-macros (seg)
3308 (prog1
3309 (! vpop-register dest)
3310 (setq *ppc2-top-vstack-lcell* (lcell-parent *ppc2-top-vstack-lcell*))
3311 (ppc2-adjust-vstack (- *ppc2-target-node-size*)))))
3312
3313(defun ppc2-copy-register (seg dest src)
3314 (with-ppc-local-vinsn-macros (seg)
3315 (when dest
3316 (let* ((dest-gpr (backend-ea-physical-reg dest hard-reg-class-gpr))
3317 (src-gpr (if src (backend-ea-physical-reg src hard-reg-class-gpr)))
3318 (dest-fpr (backend-ea-physical-reg dest hard-reg-class-fpr))
3319 (src-fpr (if src (backend-ea-physical-reg src hard-reg-class-fpr)))
3320 (src-mode (if src (get-regspec-mode src)))
3321 (dest-mode (get-regspec-mode dest))
3322 (dest-crf (backend-ea-physical-reg dest hard-reg-class-crf)))
3323 (if (and dest-gpr (eql dest-gpr ppc::rzero))
3324 (break "Bad destination register: ~s" dest-gpr))
3325 (if (null src)
3326 (if dest-gpr
3327 (! load-nil dest-gpr)
3328 (if dest-crf
3329 (! set-eq-bit dest-crf)))
3330 (if (and dest-crf src-gpr)
3331 ;; "Copying" a GPR to a CR field means comparing it to rnil
3332 (! compare-to-nil dest src)
3333 (if (and dest-gpr src-gpr)
3334 (if (eql src-gpr ppc::rzero)
3335 ;; Rzero always contains 0, so we can
3336 ;; save ourselves some trouble.
3337 ;; This assumes that (LI dest-gpr 0) is easier
3338 ;; on the register-renaming pipeline nonsense than
3339 ;; (MR dest-gpr rzero) would be.
3340 (! lri dest-gpr 0)
3341 ;; This is the "GPR <- GPR" case. There are
3342 ;; word-size dependencies, but there's also
3343 ;; lots of redundancy here.
3344 (target-word-size-case
3345 (32
3346 (case dest-mode
3347 (#.hard-reg-class-gpr-mode-node ; boxed result.
3348 (case src-mode
3349 (#.hard-reg-class-gpr-mode-node
3350 (unless (eql dest-gpr src-gpr)
3351 (! copy-gpr dest src)))
3352 (#.hard-reg-class-gpr-mode-u32
3353 (ppc2-box-u32 seg dest src))
3354 (#.hard-reg-class-gpr-mode-s32
3355 (ppc2-box-s32 seg dest src))
3356 (#.hard-reg-class-gpr-mode-u16
3357 (! u16->fixnum dest src))
3358 (#.hard-reg-class-gpr-mode-s16
3359 (! s16->fixnum dest src))
3360 (#.hard-reg-class-gpr-mode-u8
3361 (! u8->fixnum dest src))
3362 (#.hard-reg-class-gpr-mode-s8
3363 (! s8->fixnum dest src))
3364 (#.hard-reg-class-gpr-mode-address
3365 (! macptr->heap dest src))))
3366 ((#.hard-reg-class-gpr-mode-u32
3367 #.hard-reg-class-gpr-mode-address)
3368 (case src-mode
3369 (#.hard-reg-class-gpr-mode-node
3370 (let* ((src-type (get-node-regspec-type-modes src)))
3371 (declare (fixnum src-type))
3372 (case dest-mode
3373 (#.hard-reg-class-gpr-mode-u32
3374 (! unbox-u32 dest src))
3375 (#.hard-reg-class-gpr-mode-address
3376 (unless (or (logbitp #.hard-reg-class-gpr-mode-address src-type)
3377 *ppc2-reckless*)
3378 (! trap-unless-macptr src))
3379 (! deref-macptr dest src)))))
3380 ((#.hard-reg-class-gpr-mode-u32
3381 #.hard-reg-class-gpr-mode-s32
3382 #.hard-reg-class-gpr-mode-address)
3383 (unless (eql dest-gpr src-gpr)
3384 (! copy-gpr dest src)))
3385 ((#.hard-reg-class-gpr-mode-u16
3386 #.hard-reg-class-gpr-mode-s16)
3387 (! u16->u32 dest src))
3388 ((#.hard-reg-class-gpr-mode-u8
3389 #.hard-reg-class-gpr-mode-s8)
3390 (! u8->u32 dest src))))
3391 (#.hard-reg-class-gpr-mode-s32
3392 (case src-mode
3393 (#.hard-reg-class-gpr-mode-node
3394 (! unbox-s32 dest src))
3395 ((#.hard-reg-class-gpr-mode-u32
3396 #.hard-reg-class-gpr-mode-s32
3397 #.hard-reg-class-gpr-mode-address)
3398 (unless (eql dest-gpr src-gpr)
3399 (! copy-gpr dest src)))
3400 (#.hard-reg-class-gpr-mode-u16
3401 (! u16->u32 dest src))
3402 (#.hard-reg-class-gpr-mode-s16
3403 (! s16->s32 dest src))
3404 (#.hard-reg-class-gpr-mode-u8
3405 (! u8->u32 dest src))
3406 (#.hard-reg-class-gpr-mode-s8
3407 (! s8->s32 dest src))))
3408 (#.hard-reg-class-gpr-mode-u16
3409 (case src-mode
3410 (#.hard-reg-class-gpr-mode-node
3411 (! unbox-u16 dest src))
3412 ((#.hard-reg-class-gpr-mode-u8
3413 #.hard-reg-class-gpr-mode-s8)
3414 (! u8->u32 dest src))
3415 (t
3416 (unless (eql dest-gpr src-gpr)
3417 (! copy-gpr dest src)))))
3418 (#.hard-reg-class-gpr-mode-s16
3419 (case src-mode
3420 (#.hard-reg-class-gpr-mode-node
3421 (! unbox-s16 dest src))
3422 (#.hard-reg-class-gpr-mode-s8
3423 (! s8->s32 dest src))
3424 (#.hard-reg-class-gpr-mode-u8
3425 (! u8->u32 dest src))
3426 (t
3427 (unless (eql dest-gpr src-gpr)
3428 (! copy-gpr dest src)))))
3429 (#.hard-reg-class-gpr-mode-u8
3430 (case src-mode
3431 (#.hard-reg-class-gpr-mode-node
3432 (if *ppc2-reckless*
3433 (! %unbox-u8 dest src)
3434 (! unbox-u8 dest src)))
3435 (t
3436 (unless (eql dest-gpr src-gpr)
3437 (! copy-gpr dest src)))))
3438 (#.hard-reg-class-gpr-mode-s8
3439 (case src-mode
3440 (#.hard-reg-class-gpr-mode-node
3441 (! unbox-s8 dest src))
3442 (t
3443 (unless (eql dest-gpr src-gpr)
3444 (! copy-gpr dest src)))))))
3445 (64
3446 (case dest-mode
3447 (#.hard-reg-class-gpr-mode-node ; boxed result.
3448 (case src-mode
3449 (#.hard-reg-class-gpr-mode-node
3450 (unless (eql dest-gpr src-gpr)
3451 (! copy-gpr dest src)))
3452 (#.hard-reg-class-gpr-mode-u64
3453 (ppc2-box-u64 seg dest src))
3454 (#.hard-reg-class-gpr-mode-s64
3455 (ppc2-box-s64 seg dest src))
3456 (#.hard-reg-class-gpr-mode-u32
3457 (ppc2-box-u32 seg dest src))
3458 (#.hard-reg-class-gpr-mode-s32
3459 (ppc2-box-s32 seg dest src))
3460 (#.hard-reg-class-gpr-mode-u16
3461 (! u16->fixnum dest src))
3462 (#.hard-reg-class-gpr-mode-s16
3463 (! s16->fixnum dest src))
3464 (#.hard-reg-class-gpr-mode-u8
3465 (! u8->fixnum dest src))
3466 (#.hard-reg-class-gpr-mode-s8
3467 (! s8->fixnum dest src))
3468 (#.hard-reg-class-gpr-mode-address
3469 (! macptr->heap dest src))))
3470 ((#.hard-reg-class-gpr-mode-u64
3471 #.hard-reg-class-gpr-mode-address)
3472 (case src-mode
3473 (#.hard-reg-class-gpr-mode-node
3474 (let* ((src-type (get-node-regspec-type-modes src)))
3475 (declare (fixnum src-type))
3476 (case dest-mode
3477 (#.hard-reg-class-gpr-mode-u64
3478 (! unbox-u64 dest src))
3479 (#.hard-reg-class-gpr-mode-address
3480 (unless (or (logbitp #.hard-reg-class-gpr-mode-address src-type)
3481 *ppc2-reckless*)
3482 (! trap-unless-macptr src))
3483 (! deref-macptr dest src)))))
3484 ((#.hard-reg-class-gpr-mode-u64
3485 #.hard-reg-class-gpr-mode-s64
3486 #.hard-reg-class-gpr-mode-address)
3487 (unless (eql dest-gpr src-gpr)
3488 (! copy-gpr dest src)))
3489 ((#.hard-reg-class-gpr-mode-u16
3490 #.hard-reg-class-gpr-mode-s16)
3491 (! u16->u32 dest src))
3492 ((#.hard-reg-class-gpr-mode-u8
3493 #.hard-reg-class-gpr-mode-s8)
3494 (! u8->u32 dest src))))
3495 (#.hard-reg-class-gpr-mode-s32
3496 (case src-mode
3497 (#.hard-reg-class-gpr-mode-node
3498 (! unbox-s32 dest src))
3499 ((#.hard-reg-class-gpr-mode-u32
3500 #.hard-reg-class-gpr-mode-s32
3501 #.hard-reg-class-gpr-mode-address)
3502 (unless (eql dest-gpr src-gpr)
3503 (! copy-gpr dest src)))
3504 (#.hard-reg-class-gpr-mode-u16
3505 (! u16->u32 dest src))
3506 (#.hard-reg-class-gpr-mode-s16
3507 (! s16->s32 dest src))
3508 (#.hard-reg-class-gpr-mode-u8
3509 (! u8->u32 dest src))
3510 (#.hard-reg-class-gpr-mode-s8
3511 (! s8->s32 dest src))))
3512 (#.hard-reg-class-gpr-mode-u32
3513 (case src-mode
3514 (#.hard-reg-class-gpr-mode-node
3515 (! unbox-u32 dest src))
3516 ((#.hard-reg-class-gpr-mode-u32
3517 #.hard-reg-class-gpr-mode-s32)
3518 (unless (eql dest-gpr src-gpr)
3519 (! copy-gpr dest src)))
3520 (#.hard-reg-class-gpr-mode-u16
3521 (! u16->u32 dest src))
3522 (#.hard-reg-class-gpr-mode-s16
3523 (! s16->s32 dest src))
3524 (#.hard-reg-class-gpr-mode-u8
3525 (! u8->u32 dest src))
3526 (#.hard-reg-class-gpr-mode-s8
3527 (! s8->s32 dest src))))
3528 (#.hard-reg-class-gpr-mode-u16
3529 (case src-mode
3530 (#.hard-reg-class-gpr-mode-node
3531 (! unbox-u16 dest src))
3532 ((#.hard-reg-class-gpr-mode-u8
3533 #.hard-reg-class-gpr-mode-s8)
3534 (! u8->u32 dest src))
3535 (t
3536 (unless (eql dest-gpr src-gpr)
3537 (! copy-gpr dest src)))))
3538 (#.hard-reg-class-gpr-mode-s16
3539 (case src-mode
3540 (#.hard-reg-class-gpr-mode-node
3541 (! unbox-s16 dest src))
3542 (#.hard-reg-class-gpr-mode-s8
3543 (! s8->s32 dest src))
3544 (#.hard-reg-class-gpr-mode-u8
3545 (! u8->u32 dest src))
3546 (t
3547 (unless (eql dest-gpr src-gpr)
3548 (! copy-gpr dest src)))))
3549 (#.hard-reg-class-gpr-mode-u8
3550 (case src-mode
3551 (#.hard-reg-class-gpr-mode-node
3552 (if *ppc2-reckless*
3553 (! %unbox-u8 dest src)
3554 (! unbox-u8 dest src)))
3555 (t
3556 (unless (eql dest-gpr src-gpr)
3557 (! copy-gpr dest src)))))
3558 (#.hard-reg-class-gpr-mode-s8
3559 (case src-mode
3560 (#.hard-reg-class-gpr-mode-node
3561 (! unbox-s8 dest src))
3562 (t
3563 (unless (eql dest-gpr src-gpr)
3564 (! copy-gpr dest src)))))))))
3565 (if src-gpr
3566 (if dest-fpr
3567 (progn
3568 (case src-mode
3569 (#.hard-reg-class-gpr-mode-node
3570 (case dest-mode
3571 (#.hard-reg-class-fpr-mode-double
3572 (unless (or (logbitp hard-reg-class-fpr-type-double
3573 (get-node-regspec-type-modes src))
3574 *ppc2-reckless*)
3575 (! trap-unless-double-float src))
3576 (! get-double dest src))
3577 (#.hard-reg-class-fpr-mode-single
3578 (unless *ppc2-reckless*
3579 (! trap-unless-single-float src))
3580 (! get-single dest src)))))))
3581 (if dest-gpr
3582 (case dest-mode
3583 (#.hard-reg-class-gpr-mode-node
3584 (case src-mode
3585 (#.hard-reg-class-fpr-mode-double
3586 (! double->heap dest src))
3587 (#.hard-reg-class-fpr-mode-single
3588 (! single->node dest src)))))
3589 (if (and src-fpr dest-fpr)
3590 (unless (eql dest-fpr src-fpr)
3591 (! copy-fpr dest src))))))))))))
3592
3593(defun ppc2-unreachable-store (&optional vreg)
3594 ;; I don't think that anything needs to be done here,
3595 ;; but leave this guy around until we're sure.
3596 ;; (PPC2-VPUSH-REGISTER will always vpush something, even
3597 ;; if code to -load- that "something" never gets generated.
3598 ;; If I'm right about this, that means that the compile-time
3599 ;; stack-discipline problem that this is supposed to deal
3600 ;; with can't happen.)
3601 (declare (ignore vreg))
3602 nil)
3603
3604;;; bind vars to initforms, as per let*, &aux.
3605(defun ppc2-seq-bind (seg vars initforms)
3606 (dolist (var vars)
3607 (ppc2-seq-bind-var seg var (pop initforms))))
3608
3609(defun ppc2-dynamic-extent-form (seg curstack val)
3610 (when (acode-p val)
3611 (with-ppc-local-vinsn-macros (seg)
3612 (let* ((op (acode-operator val)))
3613 (cond ((eq op (%nx1-operator list))
3614 (let* ((*ppc2-vstack* *ppc2-vstack*)
3615 (*ppc2-top-vstack-lcell* *ppc2-top-vstack-lcell*))
3616 (ppc2-set-nargs seg (ppc2-formlist seg (%cadr val) nil))
3617 (ppc2-open-undo $undostkblk curstack)
3618 (! stack-cons-list))
3619 (setq val ppc::arg_z))
3620 ((eq op (%nx1-operator list*))
3621 (let* ((arglist (%cadr val)))
3622 (let* ((*ppc2-vstack* *ppc2-vstack*)
3623 (*ppc2-top-vstack-lcell* *ppc2-top-vstack-lcell*))
3624 (ppc2-arglist seg arglist))
3625 (when (car arglist)
3626 (ppc2-set-nargs seg (length (%car arglist)))
3627 (! stack-cons-list*)
3628 (ppc2-open-undo $undostkblk curstack))
3629 (setq val ppc::arg_z)))
3630 ((eq op (%nx1-operator multiple-value-list))
3631 (ppc2-multiple-value-body seg (%cadr val))
3632 (ppc2-open-undo $undostkblk curstack)
3633 (! stack-cons-list)
3634 (setq val ppc::arg_z))
3635 ((eq op (%nx1-operator cons))
3636 (let* ((y ($ ppc::arg_y))
3637 (z ($ ppc::arg_z))
3638 (result ($ ppc::arg_z)))
3639 (ppc2-two-targeted-reg-forms seg (%cadr val) y (%caddr val) z)
3640 (ppc2-open-undo $undostkblk )
3641 (! make-tsp-cons result y z)
3642 (setq val result)))
3643 ((eq op (%nx1-operator %consmacptr%))
3644 (with-imm-target () (address :address)
3645 (ppc2-one-targeted-reg-form seg val address)
3646 (with-node-temps () (node)
3647 (! macptr->stack node address)
3648 (ppc2-open-undo $undostkblk)
3649 (setq val node))))
3650 ((eq op (%nx1-operator %new-ptr))
3651 (let ((clear-form (caddr val)))
3652 (if (nx-constant-form-p clear-form)
3653 (progn
3654 (ppc2-one-targeted-reg-form seg (%cadr val) ($ ppc::arg_z))
3655 (if (nx-null clear-form)
3656 (! make-stack-block)
3657 (! make-stack-block0)))
3658 (with-crf-target () crf
3659 (let ((stack-block-0-label (backend-get-next-label))
3660 (done-label (backend-get-next-label))
3661 (rval ($ ppc::arg_z))
3662 (rclear ($ ppc::arg_y)))
3663 (ppc2-two-targeted-reg-forms seg (%cadr val) rval clear-form rclear)
3664 (! compare-to-nil crf rclear)
3665 (! cbranch-false (aref *backend-labels* stack-block-0-label) crf ppc::ppc-eq-bit)
3666 (! make-stack-block)
3667 (-> done-label)
3668 (@ stack-block-0-label)
3669 (! make-stack-block0)
3670 (@ done-label)))))
3671 (ppc2-open-undo $undostkblk)
3672 (setq val ($ ppc::arg_z)))
3673 ((eq op (%nx1-operator make-list))
3674 (ppc2-two-targeted-reg-forms seg (%cadr val) ($ ppc::arg_y) (%caddr val) ($ ppc::arg_z))
3675 (ppc2-open-undo $undostkblk curstack)
3676 (! make-stack-list)
3677 (setq val ppc::arg_z))
3678 ((eq (%car val) (%nx1-operator vector))
3679 (let* ((*ppc2-vstack* *ppc2-vstack*)
3680 (*ppc2-top-vstack-lcell* *ppc2-top-vstack-lcell*))
3681 (ppc2-set-nargs seg (ppc2-formlist seg (%cadr val) nil))
3682 (! make-stack-vector))
3683 (ppc2-open-undo $undostkblk)
3684 (setq val ppc::arg_z))
3685 ((eq op (%nx1-operator %gvector))
3686 (let* ((*ppc2-vstack* *ppc2-vstack*)
3687 (*ppc2-top-vstack-lcell* *ppc2-top-vstack-lcell*)
3688 (arglist (%cadr val)))
3689 (ppc2-set-nargs seg (ppc2-formlist seg (append (car arglist) (reverse (cadr arglist))) nil))
3690 (! make-stack-gvector))
3691 (ppc2-open-undo $undostkblk)
3692 (setq val ppc::arg_z))
3693 ((eq op (%nx1-operator closed-function))
3694 (setq val (ppc2-make-closure seg (cadr val) t))) ; can't error
3695 ((eq op (%nx1-operator %make-uvector))
3696 (destructuring-bind (element-count subtag &optional (init 0 init-p)) (%cdr val)
3697 (if init-p
3698 (progn
3699 (ppc2-three-targeted-reg-forms seg element-count ($ ppc::arg_x) subtag ($ ppc::arg_y) init ($ ppc::arg_z))
3700 (! stack-misc-alloc-init))
3701 (progn
3702 (ppc2-two-targeted-reg-forms seg element-count ($ ppc::arg_y) subtag ($ ppc::arg_z))
3703 (! stack-misc-alloc)))
3704 (ppc2-open-undo $undostkblk)
3705 (setq val ($ ppc::arg_z))))))))
3706 val)
3707
3708(defun ppc2-addrspec-to-reg (seg addrspec reg)
3709 (if (memory-spec-p addrspec)
3710 (ppc2-stack-to-register seg addrspec reg)
3711 (ppc2-copy-register seg reg addrspec)))
3712
3713(defun ppc2-seq-bind-var (seg var val)
3714 (with-ppc-local-vinsn-macros (seg)
3715 (let* ((sym (var-name var))
3716 (bits (nx-var-bits var))
3717 (closed-p (and (%ilogbitp $vbitclosed bits)
3718 (%ilogbitp $vbitsetq bits)))
3719 (curstack (ppc2-encode-stack))
3720 (make-vcell (and closed-p (eq bits (var-bits var))))
3721 (closed-downward (and closed-p (%ilogbitp $vbitcloseddownward bits))))
3722 (unless (fixnump val)
3723 (setq val (nx-untyped-form val))
3724 (when (and (%ilogbitp $vbitdynamicextent bits) (acode-p val))
3725 (setq val (ppc2-dynamic-extent-form seg curstack val))))
3726 (if (%ilogbitp $vbitspecial bits)
3727 (progn
3728 (ppc2-dbind seg val sym)
3729 (ppc2-set-var-ea seg var (ppc2-vloc-ea (- *ppc2-vstack* *ppc2-target-node-size*))))
3730 (let ((puntval nil))
3731 (flet ((ppc2-puntable-binding-p (var initform)
3732 ; The value returned is acode.
3733 (let* ((bits (nx-var-bits var)))
3734 (if (%ilogbitp $vbitpuntable bits)
3735 (nx-untyped-form initform)))))
3736 (declare (inline ppc2-puntable-binding-p))
3737 (if (and (not (ppc2-load-ea-p val))
3738 (setq puntval (ppc2-puntable-binding-p var val)))
3739 (progn
3740 (nx-set-var-bits var (%ilogior (%ilsl $vbitpunted 1) bits))
3741 (ppc2-set-var-ea seg var puntval))
3742 (progn
3743 (let* ((vloc *ppc2-vstack*)
3744 (reg (let* ((r (ppc2-assign-register-var var)))
3745 (if r ($ r)))))
3746 (if (ppc2-load-ea-p val)
3747 (if reg
3748 (ppc2-addrspec-to-reg seg val reg)
3749 (if (memory-spec-p val)
3750 (with-node-temps () (temp)
3751 (ppc2-addrspec-to-reg seg val temp)
3752 (ppc2-vpush-register seg temp :node var bits))
3753 (ppc2-vpush-register seg val :node var bits)))
3754 (if reg
3755 (ppc2-one-targeted-reg-form seg val reg)
3756 (ppc2-vpush-register seg (ppc2-one-untargeted-reg-form seg val ppc::arg_z) :node var bits)))
3757 (ppc2-set-var-ea seg var (or reg (ppc2-vloc-ea vloc closed-p)))
3758 (if reg
3759 (ppc2-note-var-cell var reg)
3760 (ppc2-note-top-cell var))
3761 (when make-vcell
3762 (with-node-temps () (vcell closed)
3763 (ppc2-stack-to-register seg vloc closed)
3764 (if closed-downward
3765 (progn
3766 (! make-tsp-vcell vcell closed)
3767 (ppc2-open-undo $undostkblk))
3768 (! make-vcell vcell closed))
3769 (ppc2-register-to-stack seg vcell vloc))))))))))))
3770
3771
3772
3773;;; Never make a vcell if this is an inherited var.
3774;;; If the var's inherited, its bits won't be a fixnum (and will
3775;;; therefore be different from what NX-VAR-BITS returns.)
3776(defun ppc2-bind-var (seg var vloc &optional lcell &aux
3777 (bits (nx-var-bits var))
3778 (closed-p (and (%ilogbitp $vbitclosed bits) (%ilogbitp $vbitsetq bits)))
3779 (closed-downward (if closed-p (%ilogbitp $vbitcloseddownward bits)))
3780 (make-vcell (and closed-p (eq bits (var-bits var))))
3781 (addr (ppc2-vloc-ea vloc)))
3782 (with-ppc-local-vinsn-macros (seg)
3783 (if (%ilogbitp $vbitspecial bits)
3784 (progn
3785 (ppc2-dbind seg addr (var-name var))
3786 (ppc2-set-var-ea seg var (ppc2-vloc-ea (- *ppc2-vstack* *ppc2-target-node-size*)))
3787 t)
3788 (progn
3789 (when (%ilogbitp $vbitpunted bits)
3790 (error "bind-var: var ~s was punted" var))
3791 (when make-vcell
3792 (with-node-temps () (vcell closed)
3793 (ppc2-stack-to-register seg vloc closed)
3794 (if closed-downward
3795 (progn
3796 (! make-tsp-vcell vcell closed)
3797 (ppc2-open-undo $undostkblk))
3798 (! make-vcell vcell closed))
3799 (ppc2-register-to-stack seg vcell vloc)))
3800 (when lcell
3801 (setf (lcell-kind lcell) :node
3802 (lcell-attributes lcell) bits
3803 (lcell-info lcell) var)
3804 (ppc2-note-var-cell var lcell))
3805 (ppc2-set-var-ea seg var (ppc2-vloc-ea vloc closed-p))
3806 closed-downward))))
3807
3808(defun ppc2-set-var-ea (seg var ea)
3809 (setf (var-ea var) ea)
3810 (when (and *ppc2-record-symbols* (or (typep ea 'lreg) (typep ea 'fixnum)))
3811 (let* ((start (ppc2-emit-note seg :begin-variable-scope)))
3812 (push (list var (var-name var) start (close-vinsn-note start))
3813 *ppc2-recorded-symbols*)))
3814 ea)
3815
3816(defun ppc2-close-var (seg var)
3817 (let ((bits (nx-var-bits var)))
3818 (when (and *ppc2-record-symbols*
3819 (or (logbitp $vbitspecial bits)
3820 (not (logbitp $vbitpunted bits))))
3821 (let ((endnote (%car (%cdddr (assq var *ppc2-recorded-symbols*)))))
3822 (unless endnote (error "ppc2-close-var for ~s ?" (var-name var)))
3823 (setf (vinsn-note-class endnote) :end-variable-scope)
3824 (append-dll-node (vinsn-note-label endnote) seg)))))
3825
3826(defun ppc2-load-ea-p (ea)
3827 (or (typep ea 'fixnum)
3828 (typep ea 'lreg)
3829 (typep ea 'lcell)))
3830
3831(defun ppc2-dbind (seg value sym)
3832 (with-ppc-local-vinsn-macros (seg)
3833 (let* ((ea-p (ppc2-load-ea-p value))
3834 (nil-p (unless ea-p (eq (setq value (nx-untyped-form value)) *nx-nil*)))
3835 (self-p (unless ea-p (and (or
3836 (eq (acode-operator value) (%nx1-operator bound-special-ref))
3837 (eq (acode-operator value) (%nx1-operator special-ref)))
3838 (eq (cadr value) sym)))))
3839 (cond ((eq sym '*interrupt-level*)
3840 (let* ((fixval (acode-fixnum-form-p value)))
3841 (cond ((eql fixval 0) (if *ppc2-open-code-inline*
3842 (! bind-interrupt-level-0-inline)
3843 (! bind-interrupt-level-0)))
3844 ((eql fixval -1) (if *ppc2-open-code-inline*
3845 (! bind-interrupt-level-m1-inline)
3846 (! bind-interrupt-level-m1)))
3847 (t
3848 (if ea-p
3849 (ppc2-store-ea seg value ppc::arg_z)
3850 (ppc2-one-targeted-reg-form seg value ($ ppc::arg_z)))
3851 (! bind-interrupt-level))))
3852 (ppc2-open-undo $undointerruptlevel))
3853 (t
3854 (if (or nil-p self-p)
3855 (progn
3856 (ppc2-store-immediate seg (ppc2-symbol-value-cell sym) ppc::arg_z)
3857 (if nil-p
3858 (! bind-nil)
3859 (if (or *ppc2-reckless* (eq (acode-operator value) (%nx1-operator special-ref)))
3860 (! bind-self)
3861 (! bind-self-boundp-check))))
3862 (progn
3863 (if ea-p
3864 (ppc2-store-ea seg value ppc::arg_z)
3865 (ppc2-one-targeted-reg-form seg value ($ ppc::arg_z)))
3866 (ppc2-store-immediate seg (ppc2-symbol-value-cell sym) ($ ppc::arg_y))
3867 (! bind)))
3868 (ppc2-open-undo $undospecial)))
3869 (ppc2-new-vstack-lcell :special-value *ppc2-target-lcell-size* 0 sym)
3870 (ppc2-new-vstack-lcell :special *ppc2-target-lcell-size* (ash 1 $vbitspecial) sym)
3871 (ppc2-new-vstack-lcell :special-link *ppc2-target-lcell-size* 0 sym)
3872 (ppc2-adjust-vstack (* 3 *ppc2-target-node-size*)))))
3873
3874;;; Store the contents of EA - which denotes either a vframe location
3875;;; or a hard register - in reg.
3876
3877(defun ppc2-store-ea (seg ea reg)
3878 (if (typep ea 'fixnum)
3879 (if (memory-spec-p ea)
3880 (ppc2-stack-to-register seg ea reg)
3881 (ppc2-copy-register seg reg ea))
3882 (if (typep ea 'lreg)
3883 (ppc2-copy-register seg reg ea)
3884 (if (typep ea 'lcell)
3885 (ppc2-lcell-to-register seg ea reg)))))
3886
3887
3888
3889
3890;;; Callers should really be sure that this is what they want to use.
3891(defun ppc2-absolute-natural (seg vreg xfer value)
3892 (with-ppc-local-vinsn-macros (seg vreg xfer)
3893 (when vreg
3894 (ppc2-lri seg vreg value))
3895 (^)))
3896
3897
3898
3899(defun ppc2-store-macptr (seg vreg address-reg)
3900 (with-ppc-local-vinsn-macros (seg vreg)
3901 (when (ppc2-for-value-p vreg)
3902 (if (logbitp vreg ppc-imm-regs)
3903 (<- address-reg)
3904 (! macptr->heap vreg address-reg)))))
3905
3906(defun ppc2-store-signed-longword (seg vreg imm-reg)
3907 (with-ppc-local-vinsn-macros (seg vreg)
3908 (when (ppc2-for-value-p vreg)
3909 (if (logbitp vreg ppc-imm-regs)
3910 (<- imm-reg)
3911 (ppc2-box-s32 seg vreg imm-reg)))))
3912
3913(defun ppc2-store-signed-halfword (seg vreg imm-reg)
3914 (with-ppc-local-vinsn-macros (seg vreg)
3915 (when (ppc2-for-value-p vreg)
3916 (if (logbitp vreg ppc-imm-regs)
3917 (<- imm-reg)
3918 (! s16->fixnum vreg imm-reg)))))
3919
3920
3921(defun ppc2-store-unsigned-halfword (seg vreg imm-reg)
3922 (with-ppc-local-vinsn-macros (seg vreg)
3923 (when (ppc2-for-value-p vreg)
3924 (if (logbitp vreg ppc-imm-regs)
3925 (<- imm-reg)
3926 (! u16->fixnum vreg imm-reg)))))
3927
3928
3929
3930;;; If "value-first-p" is true and both "offset" and "val" need to be
3931;;; evaluated, evaluate "val" before evaluating "offset".
3932(defun ppc2-%immediate-set-ptr (seg vreg xfer ptr offset val)
3933 (with-ppc-local-vinsn-macros (seg vreg xfer)
3934 (let* ((intval (acode-absolute-ptr-p val))
3935 (offval (acode-fixnum-form-p offset))
3936 (absptr (and offval (acode-absolute-ptr-p ptr)))
3937 (for-value (ppc2-for-value-p vreg)))
3938 (flet ((address-and-node-regs ()
3939 (if for-value
3940 (progn
3941 (ppc2-one-targeted-reg-form seg val ($ ppc::arg_z))
3942 (if (eq intval 0)
3943 (values ppc::rzero ppc::arg_z)
3944 (progn
3945 (if intval
3946 (ppc2-lri seg ppc::imm0 intval)
3947 (! deref-macptr ppc::imm0 ppc::arg_z))
3948 (values ppc::imm0 ppc::arg_z))))
3949 (if (eq intval 0)
3950 (values ppc::rzero nil)
3951 (values (ppc2-macptr-arg-to-reg seg val ($ ppc::imm0 :mode :address)) nil)))))
3952 (if (and absptr offval)
3953 (setq absptr (+ absptr offval) offval 0)
3954 (setq absptr nil))
3955 (and offval (%i> (integer-length offval) 15) (setq offval nil))
3956 (and absptr (%i> (integer-length absptr) 15) (setq absptr nil))
3957 (target-arch-case
3958 (:ppc32 (progn))
3959 (:ppc64 (progn
3960 (and offval (logtest 3 offval) (setq offval nil))
3961 (and absptr (logtest 3 absptr) (setq absptr nil)))))
3962 (if absptr
3963 (multiple-value-bind (address node) (address-and-node-regs)
3964 (! mem-set-c-address address ppc::rzero absptr)
3965 (if for-value
3966 (<- node)))
3967 ; No absolute ptr (which is presumably a rare case anyway.)
3968 (if offval
3969 ; Easier: need one less register than in the general case.
3970 (with-imm-target () (ptr-reg :address)
3971 (ppc2-one-targeted-reg-form seg ptr ptr-reg)
3972 (if intval
3973 (with-imm-target (ptr-reg) (val-target :address)
3974 (if (eql intval 0)
3975 (setq val-target ppc::rzero)
3976 (ppc2-lri seg val-target intval))
3977 (! mem-set-c-address val-target ptr-reg offval)
3978 (if for-value
3979 (<- (set-regspec-mode val-target (gpr-mode-name-value :address)))))
3980 (progn
3981 (! temp-push-unboxed-word ptr-reg)
3982 (ppc2-open-undo $undostkblk)
3983 (multiple-value-bind (address node) (address-and-node-regs)
3984 (with-imm-target (address) (ptr-reg :address)
3985 (! temp-pop-unboxed-word ptr-reg)
3986 (ppc2-close-undo)
3987 (! mem-set-c-address address ptr-reg offval)
3988 (if for-value
3989 (<- node)))))))
3990 ;; No (16-bit) constant offset. Might still have a 32-bit
3991 ;; constant offset; might have a constant value. Might
3992 ;; not. Might not. Easiest to special-case the
3993 ;; constant-value case first ...
3994 (let* ((xptr-reg nil)
3995 (xoff-reg nil)
3996 (xval-reg nil)
3997 (node-arg_z nil)
3998 (constant-offset (acode-fixnum-form-p offset)))
3999 (if intval
4000 (if constant-offset
4001 (with-imm-target () (ptr-reg :address)
4002 (ppc2-one-targeted-reg-form seg ptr ptr-reg)
4003 (with-imm-target (ptr-reg) (off-reg :signed-natural)
4004 (ppc2-lri seg off-reg constant-offset)
4005 (with-imm-target (ptr-reg off-reg) (val-reg :address)
4006 (if (eql intval 0)
4007 (setq val-reg ppc::rzero)
4008 (ppc2-lri seg val-reg intval))
4009 (setq xptr-reg ptr-reg
4010 xoff-reg off-reg
4011 xval-reg val-reg))))
4012 ; Offset's non-constant. Temp-push the pointer, evaluate
4013 ; and unbox the offset, load the value, pop the pointer.
4014 (progn
4015 (with-imm-target () (ptr-reg :address)
4016 (ppc2-one-targeted-reg-form seg ptr ptr-reg)
4017 (! temp-push-unboxed-word ptr-reg)
4018 (ppc2-open-undo $undostkblk))
4019 (with-imm-target () (off-reg :signed-natural)
4020 (! fixnum->signed-natural off-reg (ppc2-one-targeted-reg-form seg offset ($ ppc::arg_z)))
4021 (with-imm-target (off-reg) (val-reg :signed-natural)
4022 (if (eql intval 0)
4023 (setq val-reg ppc::rzero)
4024 (ppc2-lri seg val-reg intval))
4025 (with-imm-target (off-reg val-reg) (ptr-reg :address)
4026 (! temp-pop-unboxed-word ptr-reg)
4027 (ppc2-close-undo)
4028 (setq xptr-reg ptr-reg
4029 xoff-reg off-reg
4030 xval-reg val-reg))))))
4031 ;; No intval; maybe constant-offset.
4032 (with-imm-target () (ptr-reg :address)
4033 (ppc2-one-targeted-reg-form seg ptr ptr-reg)
4034 (! temp-push-unboxed-word ptr-reg)
4035 (ppc2-open-undo $undostkblk)
4036 (progn
4037 (if (not constant-offset)
4038 (ppc2-vpush-register seg (ppc2-one-untargeted-reg-form seg offset ppc::arg_z)))
4039 (multiple-value-bind (address node) (address-and-node-regs)
4040 (with-imm-target (address) (off-reg :s32)
4041 (if constant-offset
4042 (ppc2-lri seg off-reg constant-offset)
4043 (with-node-temps (ppc::arg_z) (temp)
4044 (ppc2-vpop-register seg temp)
4045 (! fixnum->signed-natural off-reg temp)))
4046 (with-imm-target (ppc::imm0 off-reg) (ptr-reg :address)
4047 (! temp-pop-unboxed-word ptr-reg)
4048 (ppc2-close-undo)
4049 (setq xptr-reg ptr-reg
4050 xoff-reg off-reg
4051 xval-reg address
4052 node-arg_z node)))))))
4053 (! mem-set-address xval-reg xptr-reg xoff-reg)
4054 (when for-value
4055 (if node-arg_z
4056 (<- node-arg_z)
4057 (<- (set-regspec-mode
4058 xval-reg
4059 (gpr-mode-name-value :address))))))))
4060 (^)))))
4061
4062(defun ppc2-memory-store-displaced (seg valreg basereg displacement size)
4063 (with-ppc-local-vinsn-macros (seg)
4064 (case size
4065 (8 (! mem-set-c-doubleword valreg basereg displacement))
4066 (4 (! mem-set-c-fullword valreg basereg displacement))
4067 (2 (! mem-set-c-halfword valreg basereg displacement))
4068 (1 (! mem-set-c-byte valreg basereg displacement)))))
4069
4070(defun ppc2-memory-store-indexed (seg valreg basereg idxreg size)
4071 (with-ppc-local-vinsn-macros (seg)
4072 (case size
4073 (8 (! mem-set-doubleword valreg basereg idxreg))
4074 (4 (! mem-set-fullword valreg basereg idxreg))
4075 (2 (! mem-set-halfword valreg basereg idxreg))
4076 (1 (! mem-set-byte valreg basereg idxreg)))))
4077
4078(defun ppc2-%immediate-store (seg vreg xfer bits ptr offset val)
4079 (with-ppc-local-vinsn-macros (seg vreg xfer)
4080 (if (eql 0 (%ilogand #xf bits))
4081 (ppc2-%immediate-set-ptr seg vreg xfer ptr offset val)
4082 (let* ((size (logand #xf bits))
4083 (long-p (eq size 4))
4084 (signed (not (logbitp 5 bits)))
4085 (intval (if long-p (ppc2-long-constant-p val) (acode-fixnum-form-p val)))
4086 (offval (acode-fixnum-form-p offset))
4087 (absptr (and offval (acode-absolute-ptr-p ptr)))
4088 (for-value (ppc2-for-value-p vreg)))
4089 (declare (fixnum size))
4090 (flet ((val-to-argz-and-imm0 ()
4091 (ppc2-one-targeted-reg-form seg val ($ ppc::arg_z))
4092 (if (eq size 8)
4093 (if signed
4094 (! gets64)
4095 (! getu64))
4096 (if (and (eq size 4)
4097 (target-arch-case
4098 (:ppc32 t)
4099 (:ppc64 nil)))
4100 (if signed
4101 (! gets32)
4102 (! getu32))
4103 (! fixnum->signed-natural ppc::imm0 ppc::arg_z)))))
4104 (if (and absptr offval)
4105 (setq absptr (+ absptr offval) offval 0)
4106 (setq absptr nil))
4107 (and offval (%i> (integer-length offval) 15) (setq offval nil))
4108 (and absptr (%i> (integer-length absptr) 15) (setq absptr nil))
4109 (target-arch-case
4110 (:ppc32 (progn))
4111 (:ppc64 (when (eql size 8)
4112 (and offval (logtest 3 offval) (setq offval nil))
4113 (and absptr (logtest 3 absptr) (setq absptr nil)))))
4114 (if absptr
4115 (if intval
4116 (with-imm-target () (val-target :s32)
4117 (if (eql intval 0)
4118 (setq val-target ppc::rzero)
4119 (ppc2-lri seg val-target intval))
4120 (ppc2-memory-store-displaced seg val-target ppc::rzero absptr size)
4121 (if for-value
4122 (<- (set-regspec-mode
4123 val-target
4124 (gpr-mode-name-value
4125 (case size
4126 (8 (if signed :s64 :u64))
4127 (4 (if signed :s32 :u32))
4128 (2 (if signed :s16 :u16))
4129 (1 (if signed :s8 :u8))))))))
4130 (progn
4131 (val-to-argz-and-imm0)
4132 (ppc2-memory-store-displaced seg ppc::imm0 ppc::rzero absptr size)
4133 (<- ppc::arg_z)))
4134 ; No absolute ptr (which is presumably a rare case anyway.)
4135 (if offval
4136 ; Easier: need one less register than in the general case.
4137 (with-imm-target () (ptr-reg :address)
4138 (ppc2-one-targeted-reg-form seg ptr ptr-reg)
4139 (if intval
4140 (with-imm-target (ptr-reg) (val-target :s32)
4141 (if (eql intval 0)
4142 (setq val-target ppc::rzero)
4143 (ppc2-lri seg val-target intval))
4144 (ppc2-memory-store-displaced seg val-target ptr-reg offval size)
4145 (if for-value
4146 (<- (set-regspec-mode
4147 val-target
4148 (gpr-mode-name-value
4149 (case size
4150 (8 (if signed :s64 :u64))
4151 (4 (if signed :s32 :u32))
4152 (2 (if signed :s16 :u16))
4153 (1 (if signed :s8 :u8))))))))
4154 (progn
4155 (! temp-push-unboxed-word ptr-reg)
4156 (ppc2-open-undo $undostkblk)
4157 (val-to-argz-and-imm0)
4158 (with-imm-target (ppc::imm0) (ptr-reg :address)
4159 (! temp-pop-unboxed-word ptr-reg)
4160 (ppc2-close-undo)
4161 (ppc2-memory-store-displaced seg ppc::imm0 ptr-reg offval size)
4162 (if for-value
4163 (<- ppc::arg_z))))))
4164 ;; No (16-bit) constant offset. Might still have a 32-bit constant offset;
4165 ;; might have a constant value. Might not. Might not.
4166 ;; Easiest to special-case the constant-value case first ...
4167 (let* ((xptr-reg nil)
4168 (xoff-reg nil)
4169 (xval-reg nil)
4170 (node-arg_z nil)
4171 (constant-offset (acode-fixnum-form-p offset)))
4172 (if intval
4173 (if constant-offset
4174 (with-imm-target () (ptr-reg :address)
4175 (ppc2-one-targeted-reg-form seg ptr ptr-reg)
4176 (with-imm-target (ptr-reg) (off-reg :s32)
4177 (ppc2-lri seg off-reg constant-offset)
4178 (with-imm-target (ptr-reg off-reg) (val-reg :s32)
4179 (if (eql intval 0)
4180 (setq val-reg ppc::rzero)
4181 (ppc2-lri seg val-reg intval))
4182 (setq xptr-reg ptr-reg
4183 xoff-reg off-reg
4184 xval-reg val-reg))))
4185 ; Offset's non-constant. Temp-push the pointer, evaluate
4186 ; and unbox the offset, load the value, pop the pointer.
4187 (progn
4188 (with-imm-target () (ptr-reg :address)
4189 (ppc2-one-targeted-reg-form seg ptr ptr-reg)
4190 (! temp-push-unboxed-word ptr-reg)
4191 (ppc2-open-undo $undostkblk))
4192 (with-imm-target () (off-reg :s32)
4193 (! fixnum->signed-natural off-reg (ppc2-one-targeted-reg-form seg offset ($ ppc::arg_z)))
4194 (with-imm-target (off-reg) (val-reg :s32)
4195 (if (eql intval 0)
4196 (setq val-reg ppc::rzero)
4197 (ppc2-lri seg val-reg intval))
4198 (with-imm-target (off-reg val-reg) (ptr-reg :address)
4199 (! temp-pop-unboxed-word ptr-reg)
4200 (ppc2-close-undo)
4201 (setq xptr-reg ptr-reg
4202 xoff-reg off-reg
4203 xval-reg val-reg))))))
4204 ;; No intval; maybe constant-offset.
4205 (with-imm-target () (ptr-reg :address)
4206 (ppc2-one-targeted-reg-form seg ptr ptr-reg)
4207 (! temp-push-unboxed-word ptr-reg)
4208 (ppc2-open-undo $undostkblk)
4209 (progn
4210 (if (not constant-offset)
4211 (ppc2-vpush-register seg (ppc2-one-untargeted-reg-form seg offset ppc::arg_z)))
4212 (val-to-argz-and-imm0)
4213 (with-imm-target (ppc::imm0) (off-reg :signed-natural)
4214 (if constant-offset
4215 (ppc2-lri seg off-reg constant-offset)
4216 (with-node-temps (ppc::arg_z) (temp)
4217 (ppc2-vpop-register seg temp)
4218 (! fixnum->signed-natural off-reg temp)))
4219 (with-imm-target (ppc::imm0 off-reg) (ptr-reg :address)
4220 (! temp-pop-unboxed-word ptr-reg)
4221 (ppc2-close-undo)
4222 (setq xptr-reg ptr-reg
4223 xoff-reg off-reg
4224 xval-reg ppc::imm0
4225 node-arg_z t))))))
4226 (ppc2-memory-store-indexed seg xval-reg xptr-reg xoff-reg size)
4227 (when for-value
4228 (if node-arg_z
4229 (<- ppc::arg_z)
4230 (<- (set-regspec-mode
4231 xval-reg
4232 (gpr-mode-name-value
4233 (case size
4234 (8 (if signed :s64 :u64))
4235 (4 (if signed :s32 :u32))
4236 (2 (if signed :s16 :u16))
4237 (1 (if signed :s8 :u8)))))))))))
4238 (^))))))
4239
4240
4241
4242
4243
4244(defun ppc2-encoding-undo-count (encoding)
4245 (svref encoding 0))
4246
4247(defun ppc2-encoding-cstack-depth (encoding) ; hardly ever interesting
4248 (svref encoding 1))
4249
4250(defun ppc2-encoding-vstack-depth (encoding)
4251 (svref encoding 2))
4252
4253(defun ppc2-encoding-vstack-top (encoding)
4254 (svref encoding 3))
4255
4256(defun ppc2-encode-stack ()
4257 (vector *ppc2-undo-count* *ppc2-cstack* *ppc2-vstack* *ppc2-top-vstack-lcell*))
4258
4259(defun ppc2-decode-stack (encoding)
4260 (values (ppc2-encoding-undo-count encoding)
4261 (ppc2-encoding-cstack-depth encoding)
4262 (ppc2-encoding-vstack-depth encoding)
4263 (ppc2-encoding-vstack-top encoding)))
4264
4265(defun ppc2-equal-encodings-p (a b)
4266 (dotimes (i 3 t)
4267 (unless (eq (svref a i) (svref b i)) (return))))
4268
4269(defun ppc2-open-undo (&optional (reason $undocatch) (curstack (ppc2-encode-stack)))
4270 (set-fill-pointer
4271 *ppc2-undo-stack*
4272 (set-fill-pointer *ppc2-undo-because* *ppc2-undo-count*))
4273 (vector-push-extend curstack *ppc2-undo-stack*)
4274 (vector-push-extend reason *ppc2-undo-because*)
4275 (setq *ppc2-undo-count* (%i+ *ppc2-undo-count* 1)))
4276
4277(defun ppc2-close-undo (&aux
4278 (new-count (%i- *ppc2-undo-count* 1))
4279 (i (aref *ppc2-undo-stack* new-count)))
4280 (multiple-value-setq (*ppc2-undo-count* *ppc2-cstack* *ppc2-vstack* *ppc2-top-vstack-lcell*)
4281 (ppc2-decode-stack i))
4282 (set-fill-pointer
4283 *ppc2-undo-stack*
4284 (set-fill-pointer *ppc2-undo-because* new-count)))
4285
4286
4287
4288
4289
4290;;; "Trivial" means can be evaluated without allocating or modifying registers.
4291;;; Interim definition, which will probably stay here forever.
4292(defun ppc2-trivial-p (form &aux op bits)
4293 (setq form (nx-untyped-form form))
4294 (and
4295 (consp form)
4296 (not (eq (setq op (%car form)) (%nx1-operator call)))
4297 (or
4298 (nx-null form)
4299 (nx-t form)
4300 (eq op (%nx1-operator simple-function))
4301 (eq op (%nx1-operator fixnum))
4302 (eq op (%nx1-operator immediate))
4303 #+nil
4304 (eq op (%nx1-operator bound-special-ref))
4305 (and (or (eq op (%nx1-operator inherited-arg))
4306 (eq op (%nx1-operator lexical-reference)))
4307 (or (%ilogbitp $vbitpunted (setq bits (nx-var-bits (cadr form))))
4308 (neq (%ilogior (%ilsl $vbitclosed 1) (%ilsl $vbitsetq 1))
4309 (%ilogand (%ilogior (%ilsl $vbitclosed 1) (%ilsl $vbitsetq 1)) bits)))))))
4310
4311(defun ppc2-lexical-reference-p (form)
4312 (when (acode-p form)
4313 (let ((op (acode-operator (setq form (acode-unwrapped-form form)))))
4314 (when (or (eq op (%nx1-operator lexical-reference))
4315 (eq op (%nx1-operator inherited-arg)))
4316 (%cadr form)))))
4317
4318
4319
4320(defun ppc2-ref-symbol-value (seg vreg xfer sym check-boundp)
4321 (with-ppc-local-vinsn-macros (seg vreg xfer)
4322 (when vreg
4323 (if (eq sym '*interrupt-level*)
4324 (ensuring-node-target (target vreg)
4325 (! ref-interrupt-level target))
4326 (if *ppc2-open-code-inline*
4327 (ensuring-node-target (target vreg)
4328 (with-node-target (target) src
4329 (let* ((vcell (ppc2-symbol-value-cell sym))
4330 (reg (ppc2-register-constant-p vcell)))
4331 (if reg
4332 (setq src reg)
4333 (ppc2-store-immediate seg vcell src)))
4334 (if check-boundp
4335 (! ref-symbol-value-inline target src)
4336 (! %ref-symbol-value-inline target src))))
4337 (let* ((src ($ ppc::arg_z))
4338 (dest ($ ppc::arg_z)))
4339 (ppc2-store-immediate seg (ppc2-symbol-value-cell sym) src)
4340 (if check-boundp
4341 (! ref-symbol-value dest src)
4342 (! %ref-symbol-value dest src))
4343 (<- dest)))))
4344 (^)))
4345
4346#|
4347(defun ppc2-ref-symbol-value (seg vreg xfer sym check-boundp)
4348 (with-ppc-local-vinsn-macros (seg vreg xfer)
4349 (when vreg
4350 (if (eq sym '*interrupt-level*)
4351 (ensuring-node-target (target vreg)
4352 (! ref-interrupt-level target))
4353 (let* ((src ($ ppc::arg_z))
4354 (dest ($ ppc::arg_z)))
4355 (ppc2-store-immediate seg (ppc2-symbol-value-cell sym) src)
4356 (if check-boundp
4357 (! ref-symbol-value dest src)
4358 (! %ref-symbol-value dest src))
4359 (<- dest))))
4360 (^)))
4361||#
4362
4363;;; Should be less eager to box result
4364(defun ppc2-extract-charcode (seg vreg xfer char safe)
4365 (with-ppc-local-vinsn-macros (seg vreg xfer)
4366 (let* ((src (ppc2-one-untargeted-reg-form seg char ppc::arg_z)))
4367 (when safe
4368 (! trap-unless-character src))
4369 (if vreg
4370 (ensuring-node-target (target vreg)
4371 (! character->fixnum target src)))
4372 (^))))
4373
4374
4375(defun ppc2-reference-list (seg vreg xfer listform safe refcdr)
4376 (if (ppc2-form-typep listform 'list)
4377 (setq safe nil)) ; May also have been passed as NIL.
4378 (with-ppc-local-vinsn-macros (seg vreg xfer)
4379 (let* ((src (ppc2-one-untargeted-reg-form seg listform ppc::arg_z)))
4380 (when safe
4381 (! trap-unless-list src))
4382 (if vreg
4383 (ensuring-node-target (target vreg)
4384 (if refcdr
4385 (! %cdr target src)
4386 (! %car target src))))
4387 (^))))
4388
4389
4390
4391
4392
4393
4394
4395(defun ppc2-misc-byte-count (subtag element-count)
4396 (funcall (arch::target-array-data-size-function
4397 (backend-target-arch *target-backend*))
4398 subtag element-count))
4399
4400
4401;;; The naive approach is to vpush all of the initforms, allocate the
4402;;; miscobj, then sit in a loop vpopping the values into the vector.
4403;;; That's "naive" when most of the initforms in question are
4404;;; "side-effect-free" (constant references or references to un-SETQed
4405;;; lexicals), in which case it makes more sense to just store the
4406;;; things into the vector cells, vpushing/ vpopping only those things
4407;;; that aren't side-effect-free. (It's necessary to evaluate any
4408;;; non-trivial forms before allocating the miscobj, since that
4409;;; ensures that the initforms are older (in the EGC sense) than it
4410;;; is.) The break-even point space-wise is when there are around 3
4411;;; non-trivial initforms to worry about.
4412
4413
4414(defun ppc2-allocate-initialized-gvector (seg vreg xfer subtag initforms)
4415 (with-ppc-local-vinsn-macros (seg vreg xfer)
4416 (if (null vreg)
4417 (dolist (f initforms) (ppc2-form seg nil nil f))
4418 (let* ((*ppc2-vstack* *ppc2-vstack*)
4419 (*ppc2-top-vstack-lcell* *ppc2-top-vstack-lcell*)
4420 (arch (backend-target-arch *target-backend*))
4421 (n (length initforms))
4422 (nntriv (let* ((count 0))
4423 (declare (fixnum count))
4424 (dolist (f initforms count)
4425 (unless (ppc-side-effect-free-form-p f)
4426 (incf count)))))
4427 (header (arch::make-vheader n subtag)))
4428 (declare (fixnum n nntriv))
4429 (cond ( (or *ppc2-open-code-inline* (> nntriv 3))
4430 (ppc2-formlist seg initforms nil)
4431 (ppc2-lri seg ppc::imm0 header)
4432 (! %ppc-gvector vreg ppc::imm0 (ash n (arch::target-word-shift arch))))
4433 (t
4434 (let* ((pending ())
4435 (vstack *ppc2-vstack*))
4436 (declare (fixnum vstack))
4437 (dolist (form initforms)
4438 (if (ppc-side-effect-free-form-p form)
4439 (push form pending)
4440 (progn
4441 (push nil pending)
4442 (ppc2-vpush-register seg (ppc2-one-untargeted-reg-form seg form ppc::arg_z)))))
4443 (ppc2-lri seg ppc::imm0 header)
4444 (ensuring-node-target (target vreg)
4445 (! %alloc-misc-fixed target ppc::imm0 (ash n (arch::target-word-shift arch)))
4446 (with-node-temps (target) (nodetemp)
4447 (do* ((forms pending (cdr forms))
4448 (index (1- n) (1- index))
4449 (pushed-cell (+ vstack (the fixnum (ash nntriv (arch::target-word-shift arch))))))
4450 ((null forms))
4451 (declare (list forms) (fixnum pushed-cell))
4452 (let* ((form (car forms))
4453 (reg nodetemp))
4454 (if form
4455 (setq reg (ppc2-one-untargeted-reg-form seg form nodetemp))
4456 (progn
4457 (decf pushed-cell *ppc2-target-node-size*)
4458 (ppc2-stack-to-register seg (ppc2-vloc-ea pushed-cell) nodetemp)))
4459 (! misc-set-c-node reg target index)))))
4460 (! vstack-discard nntriv))
4461 ))))
4462 (^)))
4463
4464;;; Heap-allocated constants -might- need memoization: they might be newly-created,
4465;;; as in the case of synthesized toplevel functions in .pfsl files.
4466(defun ppc2-acode-needs-memoization (valform)
4467 (if (ppc2-form-typep valform 'fixnum)
4468 nil
4469 (let* ((val (acode-unwrapped-form valform)))
4470 (if (or (eq val *nx-t*)
4471 (eq val *nx-nil*)
4472 (and (acode-p val)
4473 (let* ((op (acode-operator val)))
4474 (or (eq op (%nx1-operator fixnum)) #|(eq op (%nx1-operator immediate))|#))))
4475 nil
4476 t))))
4477
4478(defun ppc2-modify-cons (seg vreg xfer ptrform valform safe setcdr returnptr)
4479 (if (ppc2-form-typep ptrform 'cons)
4480 (setq safe nil)) ; May also have been passed as NIL.
4481 (with-ppc-local-vinsn-macros (seg vreg xfer)
4482 (multiple-value-bind (ptr-vreg val-vreg) (ppc2-two-targeted-reg-forms seg ptrform ($ ppc::arg_y) valform ($ ppc::arg_z))
4483 (when safe
4484 (! trap-unless-cons ptr-vreg))
4485 (if setcdr
4486 (! call-subprim-2 ($ ppc::arg_z) (subprim-name->offset '.SPrplacd) ptr-vreg val-vreg)
4487 (! call-subprim-2 ($ ppc::arg_z) (subprim-name->offset '.SPrplaca) ptr-vreg val-vreg))
4488 (if returnptr
4489 (<- ptr-vreg)
4490 (<- val-vreg))
4491 (^))))
4492
4493
4494
4495(defun ppc2-find-nilret-label ()
4496 (dolist (l *ppc2-nilret-labels*)
4497 (destructuring-bind (label vsp csp register-restore-count register-restore-ea &rest agenda) l
4498 (and (or (and (eql 0 register-restore-count)
4499 (or (not (eql 0 vsp))
4500 (eq vsp *ppc2-vstack*)))
4501 (and
4502 (eq register-restore-count *ppc2-register-restore-count*)
4503 (eq vsp *ppc2-vstack*)))
4504 (or agenda (eq csp *ppc2-cstack*))
4505 (eq register-restore-ea *ppc2-register-restore-ea*)
4506 (eq (%ilsr 1 (length agenda)) *ppc2-undo-count*)
4507 (dotimes (i (the fixnum *ppc2-undo-count*) t)
4508 (unless (and (eq (pop agenda) (aref *ppc2-undo-because* i))
4509 (eq (pop agenda) (aref *ppc2-undo-stack* i)))
4510 (return)))
4511 (return label)))))
4512
4513(defun ppc2-record-nilret-label ()
4514 (let* ((lab (backend-get-next-label))
4515 (info nil))
4516 (dotimes (i (the fixnum *ppc2-undo-count*))
4517 (push (aref *ppc2-undo-because* i) info)
4518 (push (aref *ppc2-undo-stack* i) info))
4519 (push (cons
4520 lab
4521 (cons
4522 *ppc2-vstack*
4523 (cons
4524 *ppc2-cstack*
4525 (cons
4526 *ppc2-register-restore-count*
4527 (cons
4528 *ppc2-register-restore-ea*
4529 (nreverse info))))))
4530 *ppc2-nilret-labels*)
4531 lab))
4532
4533;;; If we know that the form is something that sets a CR bit,
4534;;; allocate a CR field and evaluate the form in such a way
4535;;; as to set that bit.
4536;;; If it's a compile-time constant, branch accordingly and
4537;;; let the dead code die.
4538;;; Otherwise, evaluate it to some handy register and compare
4539;;; that register to RNIL.
4540;;; "XFER" is a compound destination.
4541(defun ppc2-conditional-form (seg xfer form)
4542 (let* ((uwf (acode-unwrapped-form form)))
4543 (if (nx-null uwf)
4544 (ppc2-branch seg (ppc2-cd-false xfer) nil)
4545 (if (ppc-constant-form-p uwf)
4546 (ppc2-branch seg (ppc2-cd-true xfer) nil)
4547 (with-crf-target () crf
4548 (ppc2-form seg crf xfer form))))))
4549
4550
4551(defun ppc2-branch (seg xfer crf &optional cr-bit true-p)
4552 (let* ((*ppc2-vstack* *ppc2-vstack*)
4553 (*ppc2-top-vstack-lcell* *ppc2-top-vstack-lcell*))
4554 (with-ppc-local-vinsn-macros (seg)
4555 (setq xfer (or xfer 0))
4556 (when (logbitp $backend-mvpass-bit xfer) ;(ppc2-mvpass-p cd)
4557 (setq xfer (logand (lognot $backend-mvpass-mask) xfer))
4558 (unless *ppc2-returning-values*
4559 (ppc2-vpush-register seg ppc::arg_z)
4560 (ppc2-set-nargs seg 1)))
4561 (if (neq 0 xfer)
4562 (if (eq xfer $backend-return) ;; xfer : RETURN ==> popj
4563 (ppc2-do-return seg)
4564 (if (not (ppc2-cd-compound-p xfer))
4565 (-> xfer) ;; xfer : label# ==> BRA label#
4566 ;; cd is compound : (<true> / <false>)
4567 (let* ((truebranch (ppc2-cd-true xfer))
4568 (falsebranch (ppc2-cd-false xfer))
4569 (tbranch (if true-p truebranch falsebranch))
4570 (nbranch (if true-p falsebranch truebranch))
4571 (tn0 (neq 0 tbranch))
4572 (tnret (neq $backend-return tbranch))
4573 (nn0 (neq 0 nbranch))
4574 (nnret (neq $backend-return nbranch))
4575 (tlabel (if (and tnret tn0) (aref *backend-labels* tbranch)))
4576 (nlabel (if (and nnret nn0) (aref *backend-labels* nbranch))))
4577 (unless cr-bit (setq cr-bit ppc::ppc-eq-bit))
4578 (if (and tn0 tnret nn0 nnret)
4579 (progn
4580 (! cbranch-true tlabel crf cr-bit ) ;; (label# / label#)
4581 (-> nbranch)))
4582 (if (and nnret tnret)
4583 (if nn0
4584 (! cbranch-false nlabel crf cr-bit)
4585 (! cbranch-true tlabel crf cr-bit))
4586 (let* ((aux-label (backend-get-next-label))
4587 (auxl (aref *backend-labels* aux-label)))
4588 (if tn0
4589 (! cbranch-true auxl crf cr-bit)
4590 (! cbranch-false auxl crf cr-bit))
4591 (ppc2-do-return seg)
4592 (@ aux-label))))))))))
4593
4594(defun ppc2-cd-merge (cd label)
4595 (setq cd (or cd 0))
4596 (let ((mvpass (logbitp $backend-mvpass-bit cd)))
4597 (if (neq 0 (logand (lognot $backend-mvpass-mask) cd))
4598 (if (ppc2-cd-compound-p cd)
4599 (ppc2-make-compound-cd
4600 (ppc2-cd-merge (ppc2-cd-true cd) label)
4601 (ppc2-cd-merge (ppc2-cd-false cd) label)
4602 mvpass)
4603 cd)
4604 (if mvpass
4605 (logior $backend-mvpass-mask label)
4606 label))))
4607
4608(defun ppc2-mvpass-p (xfer)
4609 (if xfer (or (logbitp $backend-mvpass-bit xfer) (eq xfer $backend-mvpass))))
4610
4611(defun ppc2-cd-compound-p (xfer)
4612 (if xfer (logbitp $backend-compound-branch-target-bit xfer)))
4613
4614(defun ppc2-cd-true (xfer)
4615 (if (ppc2-cd-compound-p xfer)
4616 (ldb $backend-compound-branch-true-byte xfer)
4617 xfer))
4618
4619(defun ppc2-cd-false (xfer)
4620 (if (ppc2-cd-compound-p xfer)
4621 (ldb $backend-compound-branch-false-byte xfer)
4622 xfer))
4623
4624(defun ppc2-make-compound-cd (tpart npart &optional mvpass-p)
4625 (dpb (or npart 0) $backend-compound-branch-false-byte
4626 (dpb (or tpart 0) $backend-compound-branch-true-byte
4627 (logior (if mvpass-p $backend-mvpass-mask 0) $backend-compound-branch-target-mask))))
4628
4629(defun ppc2-invert-cd (cd)
4630 (if (ppc2-cd-compound-p cd)
4631 (ppc2-make-compound-cd (ppc2-cd-false cd) (ppc2-cd-true cd) (logbitp $backend-mvpass-bit cd))
4632 cd))
4633
4634(defun ppc2-long-constant-p (form)
4635 (setq form (acode-unwrapped-form form))
4636 (or (acode-fixnum-form-p form)
4637 (and (acode-p form)
4638 (eq (acode-operator form) (%nx1-operator immediate))
4639 (setq form (%cadr form))
4640 (if (integerp form)
4641 form
4642 (progn
4643 (if (symbolp form) (setq form (symbol-name form)))
4644 (if (and (stringp form) (eql (length form) 4))
4645 (logior (ash (%char-code (char form 0)) 24)
4646 (ash (%char-code (char form 1)) 16)
4647 (ash (%char-code (char form 2)) 8)
4648 (%char-code (char form 3)))
4649 (if (characterp form) (%char-code form))))))))
4650
4651;;; execute body, cleanup afterwards (if need to)
4652(defun ppc2-undo-body (seg vreg xfer body old-stack)
4653 (let* ((current-stack (ppc2-encode-stack))
4654 (numundo (%i- *ppc2-undo-count* (ppc2-encoding-undo-count old-stack))))
4655 (declare (fixnum numundo))
4656 (with-ppc-local-vinsn-macros (seg vreg xfer)
4657 (if (eq current-stack old-stack)
4658 (ppc2-form seg vreg xfer body)
4659 (if (eq xfer $backend-return)
4660 (progn
4661 (ppc2-form seg vreg xfer body)
4662 (dotimes (i numundo) (ppc2-close-undo)))
4663 (if (ppc2-mvpass-p xfer)
4664 (progn
4665 (ppc2-mvpass seg body) ; presumed to be ok
4666 (let* ((*ppc2-returning-values* :pass))
4667 (ppc2-nlexit seg xfer numundo)
4668 (^))
4669 (dotimes (i numundo) (ppc2-close-undo)))
4670 (progn
4671 ;; There are some cases where storing thru ppc::arg_z
4672 ;; can be avoided (stores to vlocs, specials, etc.) and
4673 ;; some other case where it can't ($test, $vpush.) The
4674 ;; case of a null vd can certainly avoid it; the check
4675 ;; of numundo is to keep $acc boxed in case of nthrow.
4676 (ppc2-form seg (if (or vreg (not (%izerop numundo))) ppc::arg_z) nil body)
4677 (ppc2-unwind-set seg xfer old-stack)
4678 (when vreg (<- ppc::arg_z))
4679 (^))))))))
4680
4681
4682(defun ppc2-unwind-set (seg xfer encoding)
4683 (multiple-value-bind (target-catch target-cstack target-vstack target-vstack-lcell)
4684 (ppc2-decode-stack encoding)
4685 (ppc2-unwind-stack seg xfer target-catch target-cstack target-vstack)
4686 (setq *ppc2-undo-count* target-catch
4687 *ppc2-cstack* target-cstack
4688 *ppc2-vstack* target-vstack
4689 *ppc2-top-vstack-lcell* target-vstack-lcell)))
4690
4691(defun ppc2-unwind-stack (seg xfer target-catch target-cstack target-vstack)
4692 (let* ((current-catch *ppc2-undo-count*)
4693 (current-cstack *ppc2-cstack*)
4694 (current-vstack *ppc2-vstack*)
4695 (diff (%i- current-catch target-catch))
4696 target
4697 (exit-vstack current-vstack))
4698 (declare (ignore-if-unused target))
4699 (when (neq 0 diff)
4700 (setq exit-vstack (ppc2-nlexit seg xfer diff))
4701 (multiple-value-setq (target current-cstack current-vstack)
4702 (ppc2-decode-stack (aref *ppc2-undo-stack* target-catch))))
4703 (if (%i< 0 (setq diff (%i- current-cstack target-cstack)))
4704 (with-ppc-local-vinsn-macros (seg)
4705 (! adjust-sp diff)))
4706 (if (%i< 0 (setq diff (%i- current-vstack target-vstack)))
4707 (with-ppc-local-vinsn-macros (seg)
4708 (! vstack-discard (ash diff (- *ppc2-target-fixnum-shift*)))))
4709 exit-vstack))
4710
4711;;; We can sometimes combine unwinding the catch stack with returning from the function
4712;;; by jumping to a subprim that knows how to do this. If catch frames were distinguished
4713;;; from unwind-protect frames, we might be able to do this even when saved registers
4714;;; are involved (but the subprims restore them from the last catch frame.)
4715;;; *** there are currently only subprims to handle the "1 frame" case; add more ***
4716(defun ppc2-do-return (seg)
4717 (let* ((*ppc2-vstack* *ppc2-vstack*)
4718 (*ppc2-top-vstack-lcell* *ppc2-top-vstack-lcell*)
4719 (mask *ppc2-register-restore-count*)
4720 (ea *ppc2-register-restore-ea*)
4721 (label nil)
4722 (vstack nil)
4723 (foldp (not *ppc2-open-code-inline*)))
4724 (if (%izerop mask) (setq mask nil))
4725 (with-ppc-local-vinsn-macros (seg)
4726 (progn
4727 (setq vstack (ppc2-set-vstack (ppc2-unwind-stack seg $backend-return 0 0 #x7fffff)))
4728 (if *ppc2-returning-values*
4729 (cond ((and mask foldp (setq label (%cdr (assq vstack *ppc2-valret-labels*))))
4730 (-> label))
4731 (t
4732 (@ (setq label (backend-get-next-label)))
4733 (push (cons vstack label) *ppc2-valret-labels*)
4734 (when mask
4735 (with-imm-temps () (vsp0)
4736 (! fixnum-add vsp0 ppc::vsp ppc::nargs)
4737 (ppc2-restore-nvrs seg ea mask vsp0)))
4738 (! nvalret)))
4739 (if (null mask)
4740 (if *ppc2-open-code-inline*
4741 (progn
4742 (! restore-full-lisp-context)
4743 (! jump-return-pc))
4744 (! popj))
4745 (if (and foldp (setq label (assq *ppc2-vstack* *ppc2-popreg-labels*)))
4746 (-> (cdr label))
4747 (let* ((new-label (backend-get-next-label)))
4748 (@ new-label)
4749 (push (cons *ppc2-vstack* new-label) *ppc2-popreg-labels*)
4750 (ppc2-set-vstack (ppc2-restore-nvrs seg ea mask))
4751 (if *ppc2-open-code-inline*
4752 (progn
4753 (! restore-full-lisp-context)
4754 (! jump-return-pc))
4755 (! popj))))))))
4756 nil))
4757
4758
4759
4760(defun ppc2-mvcall (seg vreg xfer fn arglist &optional recursive-p)
4761 (let* ((cstack *ppc2-cstack*)
4762 (vstack *ppc2-vstack*))
4763 (with-ppc-local-vinsn-macros (seg vreg xfer)
4764 (if (and (eq xfer $backend-return) (not (ppc2-tailcallok xfer)))
4765 (progn
4766 (ppc2-mvcall seg vreg $backend-mvpass fn arglist t)
4767 (ppc2-set-vstack (%i+ (if arglist *ppc2-target-node-size* 0) vstack))
4768 (setq *ppc2-cstack* cstack)
4769 (let* ((*ppc2-returning-values* t)) (^)))
4770 (let* ((mv-p (ppc2-mv-p xfer)))
4771 (if (null arglist)
4772 (ppc2-call-fn seg vreg xfer fn arglist nil)
4773 (progn
4774 (ppc2-vpush-register seg (ppc2-one-untargeted-reg-form seg fn ppc::arg_z))
4775 (ppc2-multiple-value-body seg (pop arglist))
4776 (when arglist
4777 (ppc2-open-undo $undostkblk)
4778 (! save-values)
4779 (dolist (form arglist)
4780 (ppc2-multiple-value-body seg form)
4781 (! add-values))
4782 (ppc2-set-nargs seg 0)
4783 (! recover-values)
4784 (ppc2-close-undo))
4785 (! lisp-word-ref ppc::temp0 ppc::vsp ppc::nargs)
4786 (ppc2-invoke-fn seg ppc::temp0 nil nil xfer)))
4787 (unless recursive-p
4788 (if mv-p
4789 (unless (eq xfer $backend-return)
4790 (let* ((*ppc2-returning-values* t))
4791 (^)))
4792 (progn
4793 (ppc2-adjust-vstack (- *ppc2-target-node-size*)) ; discard function
4794 (! vstack-discard 1)
4795 (<- ppc::arg_z)
4796 (^)))))))))
4797
4798
4799(defun ppc2-hard-opt-p (opts)
4800 (or
4801 (dolist (x (%cadr opts))
4802 (unless (nx-null x) (return t)))
4803 (dolist (x (%caddr opts))
4804 (when x (return t)))))
4805
4806(defun ppc2-close-lambda (seg req opt rest keys auxen)
4807 (dolist (var req)
4808 (ppc2-close-var seg var))
4809 (dolist (var (%car opt))
4810 (ppc2-close-var seg var))
4811 (dolist (var (%caddr opt))
4812 (when var
4813 (ppc2-close-var seg var)))
4814 (if rest
4815 (ppc2-close-var seg rest))
4816 (dolist (var (%cadr keys))
4817 (ppc2-close-var seg var))
4818 (dolist (var (%caddr keys))
4819 (if var (ppc2-close-var seg var)))
4820 (dolist (var (%car auxen))
4821 (ppc2-close-var seg var)))
4822
4823(defun ppc2-close-structured-var (seg var)
4824 (if (ppc2-structured-var-p var)
4825 (apply #'ppc2-close-structured-lambda seg (cdr var))
4826 (ppc2-close-var seg var)))
4827
4828(defun ppc2-close-structured-lambda (seg whole req opt rest keys auxen)
4829 (if whole
4830 (ppc2-close-var seg whole))
4831 (dolist (var req)
4832 (ppc2-close-structured-var seg var))
4833 (dolist (var (%car opt))
4834 (ppc2-close-structured-var seg var))
4835 (dolist (var (%caddr opt))
4836 (when var
4837 (ppc2-close-var seg var)))
4838 (if rest
4839 (ppc2-close-structured-var seg rest))
4840 (dolist (var (%cadr keys))
4841 (ppc2-close-structured-var seg var))
4842 (dolist (var (%caddr keys))
4843 (if var (ppc2-close-var seg var)))
4844 (dolist (var (%car auxen))
4845 (ppc2-close-var seg var)))
4846
4847
4848(defun ppc2-init-regvar (seg var reg addr)
4849 (with-ppc-local-vinsn-macros (seg)
4850 (ppc2-stack-to-register seg addr reg)
4851 (ppc2-set-var-ea seg var ($ reg))))
4852
4853(defun ppc2-bind-structured-var (seg var vloc lcell &optional context)
4854 (if (not (ppc2-structured-var-p var))
4855 (let* ((reg (ppc2-assign-register-var var)))
4856 (if reg
4857 (ppc2-init-regvar seg var reg (ppc2-vloc-ea vloc))
4858 (ppc2-bind-var seg var vloc lcell)))
4859 (let* ((v2 (%cdr var))
4860 (v v2)
4861 (vstack *ppc2-vstack*)
4862 (whole (pop v))
4863 (req (pop v))
4864 (opt (pop v))
4865 (rest (pop v))
4866 (keys (pop v)))
4867
4868 (apply #'ppc2-bind-structured-lambda seg
4869 (ppc2-spread-lambda-list seg (ppc2-vloc-ea vloc) whole req opt rest keys context)
4870 vstack context v2))))
4871
4872(defun ppc2-bind-structured-lambda (seg lcells vloc context whole req opt rest keys auxen
4873 &aux (nkeys (list-length (%cadr keys))))
4874 (declare (fixnum vloc))
4875 (when whole
4876 (ppc2-bind-structured-var seg whole vloc (pop lcells))
4877 (incf vloc *ppc2-target-node-size*))
4878 (dolist (arg req)
4879 (ppc2-bind-structured-var seg arg vloc (pop lcells) context)
4880 (incf vloc *ppc2-target-node-size*))
4881 (when opt
4882 (if (ppc2-hard-opt-p opt)
4883 (setq vloc (apply #'ppc2-structured-initopt seg lcells vloc context opt)
4884 lcells (nthcdr (ash (length (car opt)) 1) lcells))
4885 (dolist (var (%car opt))
4886 (ppc2-bind-structured-var seg var vloc (pop lcells) context)
4887 (incf vloc *ppc2-target-node-size*))))
4888 (when rest
4889 (ppc2-bind-structured-var seg rest vloc (pop lcells) context)
4890 (incf vloc *ppc2-target-node-size*))
4891 (when keys
4892 (apply #'ppc2-structured-init-keys seg lcells vloc context keys)
4893 (setq vloc (%i+ vloc (* *ppc2-target-node-size* (+ nkeys nkeys)))))
4894 (ppc2-seq-bind seg (%car auxen) (%cadr auxen)))
4895
4896(defun ppc2-structured-var-p (var)
4897 (and (consp var) (or (eq (%car var) *nx-lambdalist*)
4898 (eq (%car var) (%nx1-operator lambda-list)))))
4899
4900(defun ppc2-simple-var (var &aux (bits (cadr var)))
4901 (if (or (%ilogbitp $vbitclosed bits)
4902 (%ilogbitp $vbitspecial bits))
4903 (nx-error "Non-simple-variable ~S" (%car var))
4904 var))
4905
4906(defun ppc2-nlexit (seg xfer &optional (nlevels 0))
4907 (let* ((numnthrow 0)
4908 (n *ppc2-undo-count*)
4909 (cstack *ppc2-cstack*)
4910 (vstack *ppc2-vstack*)
4911 (target-cstack)
4912 (target-vstack)
4913 (lastcatch n)
4914 (i nil)
4915 (returning (eq xfer $backend-return))
4916 (junk1 nil)
4917 (unbind ())
4918 (dest (%i- n nlevels))
4919 (retval *ppc2-returning-values*)
4920 reason)
4921 (declare (ignorable junk1))
4922 (with-ppc-local-vinsn-macros (seg)
4923 (when (neq 0 nlevels)
4924 (let* ((numnlispareas 0))
4925 (declare (fixnum numnlispareas))
4926 (flet ((popnlispareas ()
4927 (dotimes (i numnlispareas)
4928 (! discard-temp-frame)))
4929 (throw-through-numnthrow-catch-frames ()
4930 (when (neq 0 numnthrow)
4931 (ppc2-lri seg ppc::imm0 (ash numnthrow *ppc2-target-fixnum-shift*))
4932 (if retval
4933 (! nthrowvalues)
4934 (! nthrow1value))
4935 (setq numnthrow 0)
4936 (multiple-value-setq (junk1 cstack vstack)
4937 (ppc2-decode-stack (aref *ppc2-undo-stack* lastcatch))))))
4938 (while (%i> n dest)
4939 (cond ((eql $undocatch (setq reason (aref *ppc2-undo-because* (setq n (%i- n 1)))))
4940 (popnlispareas)
4941 (setq numnthrow (%i+ numnthrow 1) lastcatch n))
4942 ((eql $undostkblk reason)
4943 (throw-through-numnthrow-catch-frames)
4944 (incf numnlispareas))
4945 ((eql $undo-ppc-c-frame reason)
4946 (! discard-c-frame))))
4947 (throw-through-numnthrow-catch-frames)
4948 (setq i lastcatch)
4949 (while (%i> i dest)
4950 (let ((reason (aref *ppc2-undo-because* (setq i (%i- i 1)))))
4951 (if (or (eql reason $undospecial)
4952 (eql reason $undointerruptlevel))
4953 (push reason unbind))))
4954 (if unbind
4955 (ppc2-dpayback-list seg (nreverse unbind)))
4956 (when (and (neq lastcatch dest)
4957 (%i>
4958 vstack
4959 (setq target-vstack
4960 (nth-value 2 (ppc2-decode-stack (aref *ppc2-undo-stack* dest)))))
4961 (neq retval t))
4962 (unless returning
4963 (let ((vdiff (%i- vstack target-vstack)))
4964 (if retval
4965 (progn
4966 (ppc2-lri seg ppc::imm0 vdiff)
4967 (! slide-values))
4968 (! adjust-vsp vdiff)))))
4969 (setq numnlispareas 0)
4970 (while (%i> lastcatch dest)
4971 (let ((reason (aref *ppc2-undo-because* (setq lastcatch (%i- lastcatch 1)))))
4972 (setq target-cstack (nth-value 1
4973 (ppc2-decode-stack (aref *ppc2-undo-stack* lastcatch))))
4974 (if (eq reason $undostkblk)
4975 (incf numnlispareas))
4976 (if (%i> cstack target-cstack)
4977 (with-ppc-local-vinsn-macros (seg)
4978 (! adjust-sp (%i- cstack target-cstack))))
4979 ; else what's going on? $sp-stkcons, for one thing
4980 (setq cstack target-cstack)))
4981 (popnlispareas)))
4982 vstack))))
4983
4984
4985;;; Restore the most recent dynamic bindings. Bindings
4986;;; of *INTERRUPT-LEVEL* get special treatment.
4987(defun ppc2-dpayback-list (seg reasons)
4988 (with-ppc-local-vinsn-macros (seg)
4989 (let* ((n 0))
4990 (declare (fixnum n))
4991 (dolist (r reasons (if (> n 0) (! dpayback n)))
4992 (if (eql r $undospecial)
4993 (incf n)
4994 (if (eql r $undointerruptlevel)
4995 (progn
4996 (when (> n 0)
4997 (! dpayback n)
4998 (setq n 0))
4999 (if *ppc2-open-code-inline*
5000 (! unbind-interrupt-level-inline)
5001 (! unbind-interrupt-level)))
5002 (nx-error "unknown payback token ~s" r)))))))
5003
5004(defun ppc2-spread-lambda-list (seg listform whole req opt rest keys
5005 &optional enclosing-ea cdr-p)
5006 (with-ppc-local-vinsn-macros (seg)
5007 (let* ((numopt (length (%car opt)))
5008 (nkeys (length (%cadr keys)))
5009 (numreq (length req))
5010 (vtotal numreq)
5011 (old-top *ppc2-top-vstack-lcell*)
5012 (listreg ($ ppc::temp3))
5013 (doadlword (dpb nkeys (byte 8 16) (dpb numopt (byte 8 8) (dpb numreq (byte 8 0) 0 )))))
5014 (declare (fixnum numopt nkeys numreq vtotal doadlword))
5015 (when (or (> numreq 255) (> numopt 255) (> nkeys 255))
5016 (error "A lambda list can contain a maximum of 255 required, 255 optional, and 255 keywords args"))
5017 (if (fixnump listform)
5018 (ppc2-store-ea seg listform listreg)
5019 (ppc2-one-targeted-reg-form seg listform listreg))
5020 (when whole
5021 (ppc2-vpush-register seg listreg :reserved))
5022 (when keys
5023 (setq doadlword (%ilogior2 (ash #x80000000 -6) doadlword))
5024 (incf vtotal (%ilsl 1 nkeys))
5025 (if (%car keys) ; &allow-other-keys
5026 (setq doadlword (%ilogior doadlword (ash #x80000000 -5))))
5027 (ppc2-store-immediate seg (%car (%cdr (%cdr (%cdr (%cdr keys))))) ppc::temp2))
5028 (when opt
5029 (setq vtotal (%i+ vtotal numopt))
5030 (when (ppc2-hard-opt-p opt)
5031 (setq doadlword (%ilogior2 doadlword (ash #x80000000 -7)))
5032 (setq vtotal (%i+ vtotal numopt))))
5033 (when rest
5034 (setq doadlword (%ilogior2 (ash #x80000000 -4) doadlword) vtotal (%i+ vtotal 1)))
5035 (ppc2-reserve-vstack-lcells vtotal)
5036 (! load-adl doadlword)
5037 (if cdr-p
5038 (! macro-bind)
5039 (if enclosing-ea
5040 (progn
5041 (ppc2-store-ea seg enclosing-ea ppc::arg_z)
5042 (! destructuring-bind-inner))
5043 (! destructuring-bind)))
5044 (ppc2-set-vstack (%i+ *ppc2-vstack* (* *ppc2-target-node-size* vtotal)))
5045 (ppc2-collect-lcells :reserved old-top))))
5046
5047
5048(defun ppc2-tailcallok (xfer)
5049 (and (eq xfer $backend-return)
5050 *ppc2-tail-allow*
5051 (eq 0 *ppc2-undo-count*)))
5052
5053(defun ppc2-mv-p (cd)
5054 (or (eq cd $backend-return) (ppc2-mvpass-p cd)))
5055
5056(defun ppc2-expand-note (note)
5057 (let* ((lab (vinsn-note-label note)))
5058 (case (vinsn-note-class note)
5059 ((:regsave :begin-variable-scope :end-variable-scope)
5060 (setf (vinsn-label-info lab) (emit-lap-label lab))))))
5061
5062(defun ppc2-expand-vinsns (header)
5063 (do-dll-nodes (v header)
5064 (if (%vinsn-label-p v)
5065 (let* ((id (vinsn-label-id v)))
5066 (if (typep id 'fixnum)
5067 (when (or t (vinsn-label-refs v))
5068 (setf (vinsn-label-info v) (emit-lap-label v)))
5069 (ppc2-expand-note id)))
5070 (ppc2-expand-vinsn v)))
5071 ;;; This doesn't have too much to do with anything else that's
5072 ;;; going on here, but it needs to happen before the lregs
5073 ;;; are freed. There really shouldn't be such a thing as a
5074 ;;; var-ea, of course ...
5075 (dolist (s *ppc2-recorded-symbols*)
5076 (let* ((var (car s))
5077 (ea (var-ea var)))
5078 (when (typep ea 'lreg)
5079 (setf (var-ea var) (lreg-value ea)))))
5080 (free-logical-registers)
5081 (ppc2-free-lcells))
5082
5083;;; It's not clear whether or not predicates, etc. want to look
5084;;; at an lreg or just at its value slot.
5085;;; It's clear that the assembler just wants the value, and that
5086;;; the value had better be assigned by the time we start generating
5087;;; machine code.
5088;;; For now, we replace lregs in the operand vector with their values
5089;;; on entry, but it might be reasonable to make PARSE-OPERAND-FORM
5090;;; deal with lregs ...
5091(defun ppc2-expand-vinsn (vinsn)
5092 (let* ((template (vinsn-template vinsn))
5093 (vp (vinsn-variable-parts vinsn))
5094 (nvp (vinsn-template-nvp template))
5095 (unique-labels ()))
5096 (declare (fixnum nvp))
5097 (dotimes (i nvp)
5098 (let* ((val (svref vp i)))
5099 (when (typep val 'lreg)
5100 (setf (svref vp i) (lreg-value val)))))
5101 (dolist (name (vinsn-template-local-labels template))
5102 (let* ((unique (cons name nil)))
5103 (push unique unique-labels)
5104 (make-lap-label unique)))
5105 (labels ((parse-operand-form (valform)
5106 (cond ((typep valform 'keyword)
5107 (or (assq valform unique-labels)
5108 (error "unknown vinsn label ~s" valform)))
5109 ((atom valform) valform)
5110 ((atom (cdr valform)) (svref vp (car valform)))
5111 (t (let* ((op-vals (cdr valform))
5112 (parsed-ops (make-list (length op-vals)))
5113 (tail parsed-ops))
5114 (declare (dynamic-extent parsed-ops)
5115 (cons parsed-ops tail))
5116 (dolist (op op-vals (apply (car valform) parsed-ops))
5117 (setq tail (cdr (rplaca tail (parse-operand-form op)))))))))
5118 (expand-insn-form (f)
5119 (let* ((operands (cdr f))
5120 (head (make-list (length operands)))
5121 (tail head))
5122 (declare (dynamic-extent head)
5123 (cons (head tail)))
5124 (dolist (op operands)
5125 (rplaca tail (parse-operand-form op))
5126 (setq tail (cdr tail)))
5127 (ppc-emit-lap-instruction (svref ppc::*ppc-opcodes* (car f))
5128 head)))
5129 (eval-predicate (f)
5130 (case (car f)
5131 (:pred (let* ((op-vals (cddr f))
5132 (parsed-ops (make-list (length op-vals)))
5133 (tail parsed-ops))
5134 (declare (dynamic-extent parsed-ops)
5135 (cons parsed-ops tail))
5136 (dolist (op op-vals (apply (cadr f) parsed-ops))
5137 (setq tail (cdr (rplaca tail (parse-operand-form op)))))))
5138 (:not (not (eval-predicate (cadr f))))
5139 (:or (dolist (pred (cadr f))
5140 (when (eval-predicate pred)
5141 (return t))))
5142 (:and (dolist (pred (cadr f) t)
5143 (unless (eval-predicate pred)
5144 (return nil))))
5145 (t (error "Unknown predicate: ~s" f))))
5146 (expand-form (f)
5147 (if (keywordp f)
5148 (emit-lap-label (assq f unique-labels))
5149 (if (atom f)
5150 (error "Invalid form in vinsn body: ~s" f)
5151 (if (atom (car f))
5152 (expand-insn-form f)
5153 (if (eval-predicate (car f))
5154 (dolist (subform (cdr f))
5155 (expand-form subform))))))))
5156 (declare (dynamic-extent #'expand-form #'parse-operand-form #'expand-insn-form #'eval-predicate))
5157 ;(format t "~& vinsn = ~s" vinsn)
5158 (dolist (form (vinsn-template-body template))
5159 (expand-form form ))
5160 (setf (vinsn-variable-parts vinsn) nil)
5161 (when vp
5162 (free-varparts-vector vp)))))
5163
5164
5165
5166
5167
5168(defun ppc2-builtin-index-subprim (idx)
5169 (let* ((arch (backend-target-arch *target-backend*))
5170 (table (arch::target-primitive->subprims arch))
5171 (shift (arch::target-subprims-shift arch)))
5172 (dolist (cell table)
5173 (destructuring-bind ((low . high) . base) cell
5174 (if (and (>= idx low)
5175 (< idx high))
5176 (return (+ base (ash (- idx low) shift))))))))
5177
5178(defun ppc2-fixed-call-builtin (seg vreg xfer name subprim)
5179 (with-ppc-local-vinsn-macros (seg vreg xfer)
5180 (let* ((index (arch::builtin-function-name-offset name))
5181 (idx-subprim (if index (ppc2-builtin-index-subprim index)))
5182 (tail-p (ppc2-tailcallok xfer)))
5183 (when tail-p
5184 (ppc2-restore-nvrs seg *ppc2-register-restore-ea* *ppc2-register-restore-count*)
5185 (ppc2-restore-full-lisp-context seg))
5186 (if idx-subprim
5187 (setq subprim idx-subprim)
5188 (if index (! lri ($ ppc::imm0) (ash index *ppc2-target-fixnum-shift*))))
5189 (if tail-p
5190 (! jump-subprim subprim)
5191 (progn
5192 (! call-subprim subprim)
5193 (<- ($ ppc::arg_z))
5194 (^))))))
5195
5196(defun ppc2-unary-builtin (seg vreg xfer name form)
5197 (with-ppc-local-vinsn-macros (seg)
5198 (ppc2-one-targeted-reg-form seg form ($ ppc::arg_z))
5199 (ppc2-fixed-call-builtin seg vreg xfer name (subprim-name->offset '.SPcallbuiltin1))))
5200
5201(defun ppc2-binary-builtin (seg vreg xfer name form1 form2)
5202 (with-ppc-local-vinsn-macros (seg)
5203 (ppc2-two-targeted-reg-forms seg form1 ($ ppc::arg_y) form2 ($ ppc::arg_z))
5204 (ppc2-fixed-call-builtin seg vreg xfer name (subprim-name->offset '.SPcallbuiltin2))))
5205
5206(defun ppc2-ternary-builtin (seg vreg xfer name form1 form2 form3)
5207 (with-ppc-local-vinsn-macros (seg)
5208 (ppc2-three-targeted-reg-forms seg form1 ($ ppc::arg_x) form2 ($ ppc::arg_y) form3 ($ ppc::arg_z))
5209 (ppc2-fixed-call-builtin seg vreg xfer name (subprim-name->offset '.SPcallbuiltin3))))
5210
5211
5212(eval-when (:compile-toplevel :execute :load-toplevel)
5213
5214
5215(defmacro defppc2 (name locative arglist &body forms)
5216 (multiple-value-bind (body decls)
5217 (parse-body forms nil t)
5218 (destructuring-bind (vcode-block dest control &rest other-args) arglist
5219 (let* ((fun `(nfunction ,name
5220 (lambda (,vcode-block ,dest ,control ,@other-args) ,@decls
5221 (block ,name (with-ppc-local-vinsn-macros (,vcode-block ,dest ,control) ,@body))))))
5222 `(progn
5223 (record-source-file ',name 'function)
5224 (svset *ppc2-specials* (%ilogand #.operator-id-mask (%nx1-operator ,locative)) ,fun))))))
5225)
5226
5227(defppc2 ppc2-lambda lambda-list (seg vreg xfer req opt rest keys auxen body p2decls)
5228 (with-ppc-local-vinsn-macros (seg vreg xfer)
5229 (let* ((stack-consed-rest nil)
5230 (lexprp (if (consp rest) (progn (setq rest (car rest)) t)))
5231 (rest-var-bits (and rest (nx-var-bits rest)))
5232 (rest-ignored-p (and rest (not lexprp) (%ilogbitp $vbitignore rest-var-bits)))
5233 (want-stack-consed-rest (or rest-ignored-p
5234 (and rest (not lexprp) (%ilogbitp $vbitdynamicextent rest-var-bits))))
5235 (afunc *ppc2-cur-afunc*)
5236 (inherited-vars (afunc-inherited-vars afunc))
5237 (fbits (afunc-bits afunc))
5238 (methodp (%ilogbitp $fbitmethodp fbits))
5239 (method-var (if methodp (pop req)))
5240 (next-method-p (%ilogbitp $fbitnextmethp fbits))
5241 (allow-other-keys-p (%car keys))
5242 (hardopt (ppc2-hard-opt-p opt))
5243 (lap-p (when (and (consp (%car req)) (eq (%caar req) '&lap))
5244 (prog1 (%cdar req) (setq req nil))))
5245 (num-inh (length inherited-vars))
5246 (num-req (length req))
5247 (num-opt (length (%car opt)))
5248 (no-regs nil)
5249 (arg-regs nil)
5250 optsupvloc
5251 reglocatives
5252 pregs
5253 (reserved-lcells nil)
5254 (*ppc2-vstack* 0))
5255 (declare (type (unsigned-byte 16) num-req num-opt num-inh reqvloc))
5256 (with-ppc-p2-declarations p2decls
5257 (setq *ppc2-inhibit-register-allocation*
5258 (setq no-regs (%ilogbitp $fbitnoregs fbits)))
5259 (multiple-value-setq (pregs reglocatives)
5260 (ppc2-allocate-global-registers *ppc2-fcells* *ppc2-vcells* (afunc-all-vars afunc) no-regs))
5261 (@ (backend-get-next-label)) ; generic self-reference label, should be label #1
5262 (unless next-method-p
5263 (setq method-var nil))
5264
5265 (let* ((rev-req (reverse req))
5266 (rev-fixed (if inherited-vars (reverse (append inherited-vars req)) rev-req))
5267 (num-fixed (length rev-fixed))
5268 (rev-opt (reverse (car opt))))
5269 (if (not (or opt rest keys))
5270 (setq arg-regs (ppc2-req-nargs-entry seg rev-fixed))
5271 (if (and (not (or hardopt rest keys))
5272 (<= num-opt $numppcargregs))
5273 (setq arg-regs (ppc2-simple-opt-entry seg rev-opt rev-fixed))
5274 (progn
5275 ; If the minumum acceptable number of args is non-zero, ensure
5276 ; that at least that many were received. If there's an upper bound,
5277 ; enforce it.
5278
5279 (when rev-fixed
5280 (ppc2-reserve-vstack-lcells num-fixed)
5281 (! check-min-nargs num-fixed))
5282 (unless (or rest keys)
5283 (! check-max-nargs (+ num-fixed num-opt)))
5284 ;; Going to have to call one or more subprims. First save
5285 ;; the LR in LOC-PC.
5286 (! save-lr)
5287 ;; If there were &optional args, initialize their values
5288 ;; to NIL. All of the argregs get vpushed as a result of this.
5289 (when opt
5290 (ppc2-reserve-vstack-lcells num-opt)
5291 (! default-optionals (+ num-fixed num-opt)))
5292 (when keys
5293 (let* ((keyvect (%car (%cdr (%cdr (%cdr (%cdr keys))))))
5294 (flags (the fixnum (logior (the fixnum (if rest 4 0))
5295 (the fixnum (if (or methodp allow-other-keys-p) 1 0)))))
5296 (nkeys (length keyvect))
5297 (nprev (+ num-fixed num-opt)))
5298 (declare (fixnum flags nkeys nprev))
5299 (dotimes (i (the fixnum (+ nkeys nkeys)))
5300 (ppc2-new-vstack-lcell :reserved *ppc2-target-lcell-size* 0 nil))
5301 (! misc-ref-c-node ppc::temp3 ppc::nfn (1+ (backend-immediate-index keyvect)))
5302 (ppc2-lri seg ppc::imm2 (ash flags *ppc2-target-fixnum-shift*))
5303 (ppc2-lri seg ppc::imm3 (ash nkeys *ppc2-target-fixnum-shift*))
5304 (unless (= nprev 0)
5305 (ppc2-lri seg ppc::imm0 (ash nprev *ppc2-target-fixnum-shift*)))
5306 (if (= 0 nprev)
5307 (! simple-keywords)
5308 (if (= 0 num-opt)
5309 (! keyword-args)
5310 (! keyword-bind)))))
5311 (when rest
5312 ;; If any keyword-binding's happened, the key/value
5313 ;; pairs have been slid to the top-of-stack for us.
5314 ;; There'll be an even number of them (nargs - the
5315 ;; "previous" (required/&optional) count.)
5316 (if lexprp
5317 (ppc2-lexpr-entry seg num-fixed)
5318 (progn
5319 (if want-stack-consed-rest
5320 (setq stack-consed-rest t))
5321 (let* ((nprev (+ num-fixed num-opt))
5322 (simple (and (not keys) (= 0 nprev))))
5323 (declare (fixnum nprev))
5324 (unless simple
5325 (ppc2-lri seg ppc::imm0 (ash nprev *ppc2-target-fixnum-shift*)))
5326 (if stack-consed-rest
5327 (if simple
5328 (! stack-rest-arg)
5329 (if (and (not keys) (= 0 num-opt))
5330 (! req-stack-rest-arg)
5331 (! stack-cons-rest-arg)))
5332 (if simple
5333 (! heap-rest-arg)
5334 (if (and (not keys) (= 0 num-opt))
5335 (! req-heap-rest-arg)
5336 (! heap-cons-rest-arg)))))
5337 ; Make an lcell for the &rest arg
5338 (ppc2-reserve-vstack-lcells 1))))
5339 (when hardopt
5340 (ppc2-reserve-vstack-lcells num-opt)
5341 (ppc2-lri seg ppc::imm0 (ash num-opt *ppc2-target-fixnum-shift*))
5342
5343 ;; .SPopt-supplied-p wants nargs to contain the
5344 ;; actual arg-count minus the number of "fixed"
5345 ;; (required, inherited) args.
5346
5347 (unless (= 0 num-fixed)
5348 (! scale-nargs num-fixed))
5349 (! opt-supplied-p))
5350 (let* ((nwords-vpushed (+ num-fixed
5351 num-opt
5352 (if hardopt num-opt 0)
5353 (if lexprp 0 (if rest 1 0))
5354 (ash (length (%cadr keys)) 1)))
5355 (nbytes-vpushed (* nwords-vpushed *ppc2-target-node-size*)))
5356 (declare (fixnum nwords-vpushed nbytes-vpushed))
5357 (unless (or lexprp keys)
5358 (if *ppc2-open-code-inline*
5359 (! save-lisp-context-offset nbytes-vpushed)
5360 (! save-lisp-context-offset-ool nbytes-vpushed)))
5361 (ppc2-set-vstack nbytes-vpushed)
5362 (setq optsupvloc (- *ppc2-vstack* (* num-opt *ppc2-target-node-size*)))))))
5363 ;; Caller's context is saved; *ppc2-vstack* is valid. Might still have method-var
5364 ;; to worry about.
5365 (unless (= 0 pregs)
5366 ;; Save NVRs; load constants into any that get constants.
5367 (ppc2-save-nvrs seg pregs)
5368
5369 (dolist (pair reglocatives)
5370 (declare (cons pair))
5371 (let* ((constant (car pair))
5372 (reg (cdr pair)))
5373 (declare (cons constant))
5374 (rplacd constant reg)
5375 (! ref-constant reg (backend-immediate-index (car constant))))))
5376 (when (and (not (or opt rest keys))
5377 (<= num-fixed $numppcargregs)
5378 (not (some #'null arg-regs)))
5379 (setq *ppc2-tail-vsp* *ppc2-vstack*
5380 *ppc2-tail-nargs* num-fixed)
5381 (@ (setq *ppc2-tail-label* (backend-get-next-label))))
5382 (when method-var
5383 (ppc2-seq-bind-var seg method-var ppc::next-method-context))
5384 ;; If any arguments are still in arg_x, arg_y, arg_z, that's
5385 ;; because they weren't vpushed in a "simple" entry case and
5386 ;; belong in some NVR. Put them in their NVRs, so that we
5387 ;; can handle arbitrary expression evaluation (special
5388 ;; binding, value-cell consing, etc.) without clobbering the
5389 ;; argument registers.
5390 (when arg-regs
5391 (do* ((vars arg-regs (cdr vars))
5392 (arg-reg-num ppc::arg_z (1- arg-reg-num)))
5393 ((null vars))
5394 (declare (list vars) (fixnum arg-reg-num))
5395 (let* ((var (car vars)))
5396 (when var
5397 (let* ((reg (ppc2-assign-register-var var)))
5398 (ppc2-copy-register seg reg arg-reg-num)
5399 (setf (var-ea var) reg))))))
5400 (setq *ppc2-entry-vsp-saved-p* t)
5401#|
5402 (when stack-consed-rest
5403 (if rest-ignored-p
5404 (if nil (ppc2-jsrA5 $sp-popnlisparea))
5405 (progn
5406 (ppc2-open-undo $undostkblk))))
5407|#
5408 (when stack-consed-rest
5409 (ppc2-open-undo $undostkblk))
5410 (setq *ppc2-entry-vstack* *ppc2-vstack*)
5411 (setq reserved-lcells (ppc2-collect-lcells :reserved))
5412 (ppc2-bind-lambda seg reserved-lcells req opt rest keys auxen optsupvloc arg-regs lexprp inherited-vars))
5413 (when method-var (ppc2-heap-cons-next-method-var seg method-var))
5414 (ppc2-form seg vreg xfer body)
5415 (ppc2-close-lambda seg req opt rest keys auxen)
5416 (dolist (v inherited-vars)
5417 (ppc2-close-var seg v))
5418 (when method-var
5419 (ppc2-close-var seg method-var))
5420 (let* ((bits 0))
5421 (when (%i> num-inh (ldb $lfbits-numinh -1))
5422 (setq num-inh (ldb $lfbits-numinh -1)))
5423 (setq bits (dpb num-inh $lfbits-numinh bits))
5424 (unless lap-p
5425 (when (%i> num-req (ldb $lfbits-numreq -1))
5426 (setq num-req (ldb $lfbits-numreq -1)))
5427 (setq bits (dpb num-req $lfbits-numreq bits))
5428 (when (%i> num-opt (ldb $lfbits-numopt -1))
5429 (setq num-opt (ldb $lfbits-numopt -1)))
5430 (setq bits (dpb num-opt $lfbits-numopt bits))
5431 (when hardopt (setq bits (%ilogior (%ilsl $lfbits-optinit-bit 1) bits)))
5432 (when rest (setq bits (%ilogior (if lexprp (%ilsl $lfbits-restv-bit 1) (%ilsl $lfbits-rest-bit 1)) bits)))
5433 (when keys (setq bits (%ilogior (%ilsl $lfbits-keys-bit 1) bits)))
5434 (when allow-other-keys-p (setq bits (%ilogior (%ilsl $lfbits-aok-bit 1) bits)))
5435 (when (%ilogbitp $fbitnextmethargsp (afunc-bits afunc))
5436 (if methodp
5437 (setq bits (%ilogior (%ilsl $lfbits-nextmeth-with-args-bit 1) bits))
5438 (let ((parent (afunc-parent afunc)))
5439 (when parent
5440 (setf (afunc-bits parent) (bitset $fbitnextmethargsp (afunc-bits parent)))))))
5441 (when methodp
5442 (setq bits (logior (ash 1 $lfbits-method-bit) bits))
5443 (when next-method-p
5444 (setq bits (logior (%ilsl $lfbits-nextmeth-bit 1) bits)))))
5445 bits)))))
5446
5447
5448(defppc2 ppc2-progn progn (seg vreg xfer forms)
5449 (declare (list forms))
5450 (if (null forms)
5451 (ppc2-nil seg vreg xfer)
5452 (loop
5453 (let* ((form (pop forms)))
5454 (if forms
5455 (ppc2-form seg nil nil form)
5456 (return (ppc2-form seg vreg xfer form)))))))
5457
5458
5459
5460(defppc2 ppc2-prog1 prog1 (seg vreg xfer forms)
5461 (if (eq (list-length forms) 1)
5462 (ppc2-use-operator (%nx1-operator values) seg vreg xfer forms)
5463 (if (null vreg)
5464 (ppc2-use-operator (%nx1-operator progn) seg vreg xfer forms)
5465 (let* ((float-p (= (hard-regspec-class vreg) hard-reg-class-fpr))
5466 (crf-p (= (hard-regspec-class vreg) hard-reg-class-crf))
5467 (node-p (unless (or float-p crf-p)
5468 (= (get-regspec-mode vreg) hard-reg-class-gpr-mode-node)))
5469 (first (pop forms)))
5470 (ppc2-push-register seg
5471 (if (or node-p crf-p)
5472 (ppc2-one-untargeted-reg-form seg first ppc::arg_z)
5473 (ppc2-one-targeted-reg-form seg first vreg)))
5474 (dolist (form forms)
5475 (ppc2-form seg nil nil form))
5476 (if crf-p
5477 (progn
5478 (ppc2-vpop-register seg ppc::arg_z)
5479 (<- ppc::arg_z))
5480 (ppc2-pop-register seg vreg))
5481 (^)))))
5482
5483(defppc2 ppc2-free-reference free-reference (seg vreg xfer sym)
5484 (ppc2-ref-symbol-value seg vreg xfer sym t))
5485
5486(defppc2 ppc2-special-ref special-ref (seg vreg xfer sym)
5487 (ppc2-ref-symbol-value seg vreg xfer sym t))
5488
5489(defppc2 ppc2-bound-special-ref bound-special-ref (seg vreg xfer sym)
5490 (ppc2-ref-symbol-value seg vreg xfer sym nil))
5491
5492(defppc2 ppc2-%slot-ref %slot-ref (seg vreg xfer instance idx)
5493 (ensuring-node-target (target (or vreg ($ ppc::arg_z)))
5494 (multiple-value-bind (v i)
5495 (ppc2-two-untargeted-reg-forms seg instance ppc::arg_y idx ppc::arg_z)
5496 (unless *ppc2-reckless*
5497 (! check-misc-bound i v))
5498 (with-node-temps (v) (temp)
5499 (! %slot-ref temp v i)
5500 (ppc2-copy-register seg target temp))))
5501 (^))
5502
5503(defppc2 ppc2-%svref %svref (seg vreg xfer vector index)
5504 (ppc2-vref seg vreg xfer :simple-vector vector index nil))
5505
5506(defppc2 ppc2-svref svref (seg vreg xfer vector index)
5507 (ppc2-vref seg vreg xfer :simple-vector vector index (unless *ppc2-reckless* (nx-lookup-target-uvector-subtag :simple-vector))))
5508
5509;;; It'd be nice if this didn't box the result. Worse things happen ...
5510;;; Once there's a robust mechanism, adding a CHARCODE storage class shouldn't be hard.
5511(defppc2 ppc2-%sbchar %sbchar (seg vreg xfer string index)
5512 (ppc2-vref seg vreg xfer :simple-string string index (unless *ppc2-reckless* (nx-lookup-target-uvector-subtag :simple-string))))
5513
5514
5515(defppc2 ppc2-%svset %svset (seg vreg xfer vector index value)
5516 (ppc2-vset seg vreg xfer :simple-vector vector index value nil))
5517
5518(defppc2 ppc2-svset svset (seg vreg xfer vector index value)
5519 (ppc2-vset seg vreg xfer :simple-vector vector index value (nx-lookup-target-uvector-subtag :simple-vector)))
5520
5521(defppc2 ppc2-typed-form typed-form (seg vreg xfer typespec form)
5522 (declare (ignore typespec)) ; Boy, do we ever !
5523 (ppc2-form seg vreg xfer form))
5524
5525(defppc2 ppc2-%primitive %primitive (seg vreg xfer &rest ignore)
5526 (declare (ignore seg vreg xfer ignore))
5527 (error "You're probably losing big: using %primitive ..."))
5528
5529(defppc2 ppc2-consp consp (seg vreg xfer cc form)
5530 (if (null vreg)
5531 (ppc2-form seg vreg xfer form)
5532 (let* ((tagreg ppc::imm0))
5533 (multiple-value-bind (cr-bit true-p) (acode-condition-to-ppc-cr-bit cc)
5534 (! extract-fulltag tagreg (ppc2-one-untargeted-reg-form seg form ppc::arg_z))
5535 (ppc2-test-reg-%izerop seg vreg xfer tagreg cr-bit true-p
5536 (target-arch-case
5537 (:ppc32 ppc32::fulltag-cons)
5538 (:ppc64 ppc64::fulltag-cons)))))))
5539
5540(defppc2 ppc2-cons cons (seg vreg xfer y z)
5541 (if (null vreg)
5542 (progn
5543 (ppc2-form seg nil nil y)
5544 (ppc2-form seg nil xfer z))
5545 (multiple-value-bind (yreg zreg) (ppc2-two-untargeted-reg-forms seg y ppc::arg_y z ppc::arg_z)
5546 (ensuring-node-target (target vreg)
5547 (! cons target yreg zreg))
5548 (^))))
5549
5550
5551
5552(defppc2 ppc2-%rplaca %rplaca (seg vreg xfer ptr val)
5553 (ppc2-modify-cons seg vreg xfer ptr val nil nil t))
5554
5555(defppc2 ppc2-%rplacd %rplacd (seg vreg xfer ptr val)
5556 (ppc2-modify-cons seg vreg xfer ptr val nil t t))
5557
5558(defppc2 ppc2-rplaca rplaca (seg vreg xfer ptr val)
5559 (ppc2-modify-cons seg vreg xfer ptr val t nil t))
5560
5561(defppc2 ppc2-set-car set-car (seg vreg xfer ptr val)
5562 (ppc2-modify-cons seg vreg xfer ptr val t nil nil))
5563
5564(defppc2 ppc2-rplacd rplacd (seg vreg xfer ptr val)
5565 (ppc2-modify-cons seg vreg xfer ptr val t t t))
5566
5567(defppc2 ppc2-set-cdr set-cdr (seg vreg xfer ptr val)
5568 (ppc2-modify-cons seg vreg xfer ptr val t t nil))
5569
5570(defppc2 ppc2-%car %car (seg vreg xfer form)
5571 (ppc2-reference-list seg vreg xfer form nil nil))
5572
5573(defppc2 ppc2-%cdr %cdr (seg vreg xfer form)
5574 (ppc2-reference-list seg vreg xfer form nil t))
5575
5576(defppc2 ppc2-car car (seg vreg xfer form)
5577 (ppc2-reference-list seg vreg xfer form t nil))
5578
5579(defppc2 ppc2-cdr cdr (seg vreg xfer form)
5580 (ppc2-reference-list seg vreg xfer form t t))
5581
5582
5583(defppc2 ppc2-vector vector (seg vreg xfer arglist)
5584 (ppc2-allocate-initialized-gvector seg vreg xfer
5585 (nx-lookup-target-uvector-subtag
5586 :simple-vector) arglist))
5587
5588(defppc2 ppc2-%gvector %gvector (seg vreg xfer arglist)
5589 (let* ((all-on-stack (append (car arglist) (reverse (cadr arglist))))
5590 (subtag-form (car all-on-stack))
5591 (subtag (acode-fixnum-form-p subtag-form)))
5592 (if (null vreg)
5593 (dolist (form all-on-stack (^)) (ppc2-form seg nil nil form))
5594 (if (null subtag)
5595 (progn ; Vpush everything and call subprim
5596 (let* ((*ppc2-vstack* *ppc2-vstack*)
5597 (*ppc2-top-vstack-lcell* *ppc2-top-vstack-lcell*))
5598 (ppc2-set-nargs seg (ppc2-formlist seg all-on-stack nil))
5599 (! gvector))
5600 (<- ppc::arg_z)
5601 (^))
5602 (ppc2-allocate-initialized-gvector seg vreg xfer subtag (cdr all-on-stack))))))
5603
5604;;; Should be less eager to box result
5605(defppc2 ppc2-%char-code %char-code (seg vreg xfer c)
5606 (ppc2-extract-charcode seg vreg xfer c nil))
5607
5608(defppc2 ppc2-char-code char-code (seg vreg xfer c)
5609 (ppc2-extract-charcode seg vreg xfer c (not (ppc2-form-typep c 'character))))
5610
5611(defppc2 ppc2-%ilogior2 %ilogior2 (seg vreg xfer form1 form2)
5612 (let* ((fix1 (acode-fixnum-form-p form1))
5613 (fix2 (acode-fixnum-form-p form2)))
5614 (if (and fix1 fix2)
5615 (ppc2-use-operator (%nx1-operator fixnum) seg vreg xfer (logior fix1 fix2)))
5616 (let* ((fixval (or fix1 fix2))
5617 (unboxed-fixval (if fixval (ash fixval *ppc2-target-fixnum-shift*)))
5618 (high (if fixval (if (= unboxed-fixval (logand #xffff0000 unboxed-fixval)) (ash unboxed-fixval -16))))
5619 (low (if fixval (unless high (if (= unboxed-fixval (logand #x0000ffff unboxed-fixval)) unboxed-fixval))))
5620 (otherform (if (or high low) (if fix1 form2 form1))))
5621 (if otherform
5622 (let* ((other-reg (ppc2-one-untargeted-reg-form seg otherform ppc::arg_z)))
5623 (when vreg
5624 (ensuring-node-target (target vreg)
5625 (if high
5626 (! logior-high target other-reg high)
5627 (! logior-low target other-reg low)))))
5628 (multiple-value-bind (r1 r2) (ppc2-two-untargeted-reg-forms seg form1 ppc::arg_y form2 ppc::arg_z)
5629 (if vreg (ensuring-node-target (target vreg) (! %logior2 target r1 r2)))))
5630 (^))))
5631
5632;;; in a lot of (typical ?) cases, it might be possible to use a
5633;;; rotate-and-mask instead of andi./andis.
5634
5635(defppc2 ppc2-%ilogand2 %ilogand2 (seg vreg xfer form1 form2)
5636 (let* ((fix1 (acode-fixnum-form-p form1))
5637 (fix2 (acode-fixnum-form-p form2)))
5638 (if (and fix1 fix2)
5639 (ppc2-use-operator (%nx1-operator fixnum) seg vreg xfer (logand fix1 fix2))
5640 (let* ((fixval (or fix1 fix2))
5641 (fixlen (if fixval (integer-length fixval)))
5642 (unboxed-fixval (if fixval (ash fixval *ppc2-target-fixnum-shift*)))
5643 (high (if fixval (if (= unboxed-fixval (logand #xffff0000 unboxed-fixval)) (ash unboxed-fixval -16))))
5644 (low (if fixval (unless high (if (= unboxed-fixval (logand #x0000ffff unboxed-fixval)) unboxed-fixval))))
5645 (otherform (if (or high low) (if fix1 form2 form1))))
5646 (if otherform
5647 (let* ((other-reg (ppc2-one-untargeted-reg-form seg otherform ppc::arg_z)))
5648 (when vreg
5649 (ensuring-node-target (target vreg)
5650 (if high
5651 (! logand-high target other-reg high)
5652 (! logand-low target other-reg low)))))
5653 (if (and fixval (= fixlen (logcount fixval)))
5654 (let* ((nbits (- *ppc2-target-bits-in-word*
5655 (1+ (+ *ppc2-target-fixnum-shift* fixlen))))
5656 (otherreg (ppc2-one-untargeted-reg-form seg (if fix1 form2 form1) ppc::arg_z)))
5657
5658 (if vreg (ensuring-node-target (target vreg)
5659 (if (> fixval 0)
5660 (! clear-left target otherreg nbits)
5661 (! clear-right target otherreg (+ fixlen
5662 *ppc2-target-fixnum-shift*))))))
5663
5664 (multiple-value-bind (r1 r2) (ppc2-two-untargeted-reg-forms seg form1 ppc::arg_y form2 ppc::arg_z)
5665 (if vreg (ensuring-node-target (target vreg) (! %logand2 target r1 r2))))))
5666 (^)))))
5667
5668(defppc2 ppc2-%ilogxor2 %ilogxor2 (seg vreg xfer form1 form2)
5669 (let* ((fix1 (acode-fixnum-form-p form1))
5670 (fix2 (acode-fixnum-form-p form2)))
5671 (if (and fix1 fix2)
5672 (ppc2-use-operator (%nx1-operator fixnum) seg vreg xfer (logxor fix1 fix2)))
5673 (let* ((fixval (or fix1 fix2))
5674 (unboxed-fixval (if fixval (ash fixval *ppc2-target-fixnum-shift*)))
5675 (high (if fixval (if (= unboxed-fixval (logand #xffff0000 unboxed-fixval)) (ash unboxed-fixval -16))))
5676 (low (if fixval (unless high (if (= unboxed-fixval (logand #x0000ffff unboxed-fixval)) unboxed-fixval))))
5677 (otherform (if (or high low) (if fix1 form2 form1))))
5678 (if otherform
5679 (let* ((other-reg (ppc2-one-untargeted-reg-form seg otherform ppc::arg_z)))
5680 (when vreg
5681 (ensuring-node-target (target vreg)
5682 (if high
5683 (! logxor-high target other-reg high)
5684 (! logxor-low target other-reg low)))))
5685 (multiple-value-bind (r1 r2) (ppc2-two-untargeted-reg-forms seg form1 ppc::arg_y form2 ppc::arg_z)
5686 (if vreg (ensuring-node-target (target vreg) (! %logxor2 vreg r1 r2)))))
5687 (^))))
5688
5689(defppc2 ppc2-%ineg %ineg (seg vreg xfer n)
5690 (let* ((src (ppc2-one-untargeted-reg-form seg n ppc::arg_z)))
5691 (when vreg
5692 (ensuring-node-target (target vreg)
5693 (if *ppc2-open-code-inline*
5694 (! negate-fixnum-overflow-inline target src)
5695 (progn
5696 (! negate-fixnum-overflow-ool src)
5697 (ppc2-copy-register seg target ($ ppc::arg_z))))))
5698 (^)))
5699
5700(defppc2 ppc2-%%ineg %%ineg (seg vreg xfer n)
5701 (let* ((src (ppc2-one-untargeted-reg-form seg n ppc::arg_z)))
5702 (when vreg
5703 (ensuring-node-target (target vreg)
5704 (! negate-fixnum-no-ovf target src)))
5705 (^)))
5706
5707(defppc2 ppc2-characterp characterp (seg vreg xfer cc form)
5708 (ppc2-char-p seg vreg xfer cc form))
5709
5710(defppc2 ppc2-struct-ref struct-ref (seg vreg xfer struct offset)
5711 (ppc2-vref seg vreg xfer :struct struct offset (unless *ppc2-reckless* (nx-lookup-target-uvector-subtag :struct))))
5712
5713(defppc2 ppc2-struct-set struct-set (seg vreg xfer struct offset value)
5714 (ppc2-vset seg vreg xfer :struct struct offset value (unless *ppc2-reckless* (nx-lookup-target-uvector-subtag :struct))))
5715
5716(defppc2 ppc2-istruct-typep istruct-typep (seg vreg xfer cc form type)
5717 (multiple-value-bind (cr-bit true-p) (acode-condition-to-ppc-cr-bit cc)
5718 (multiple-value-bind (r1 r2) (ppc2-two-untargeted-reg-forms seg form ppc::arg_y type ppc::arg_z)
5719 (with-imm-target () (target :signed-natural)
5720 (! istruct-typep target r1 r2)
5721 (ppc2-test-reg-%izerop seg vreg xfer target cr-bit true-p 0)))))
5722
5723
5724(defppc2 ppc2-lisptag lisptag (seg vreg xfer node)
5725 (if (null vreg)
5726 (ppc2-form seg vreg xfer node)
5727 (progn
5728 (ensuring-node-target (target vreg)
5729 (! extract-tag-fixnum target (ppc2-one-untargeted-reg-form seg node ppc::arg_z)))
5730 (^))))
5731
5732(defppc2 ppc2-fulltag fulltag (seg vreg xfer node)
5733 (if (null vreg)
5734 (ppc2-form seg vreg xfer node)
5735 (progn
5736 (ensuring-node-target (target vreg)
5737 (! extract-fulltag-fixnum target (ppc2-one-untargeted-reg-form seg node ppc::arg_z)))
5738 (^))))
5739
5740(defppc2 ppc2-typecode typecode (seg vreg xfer node)
5741 (if (null vreg)
5742 (ppc2-form seg vreg xfer node)
5743 (let* ((reg (ppc2-one-untargeted-reg-form seg node (if (eq (hard-regspec-value vreg) ppc::arg_z)
5744 ppc::arg_y ppc::arg_z))))
5745 (ensuring-node-target (target vreg)
5746 (! extract-typecode-fixnum target reg ))
5747 (^))))
5748
5749(defppc2 ppc2-setq-special setq-special (seg vreg xfer sym val)
5750 (let* ((symreg ($ ppc::arg_y))
5751 (valreg ($ ppc::arg_z)))
5752 (ppc2-one-targeted-reg-form seg val valreg)
5753 (ppc2-store-immediate seg (ppc2-symbol-value-cell sym) symreg)
5754 (! setq-special symreg valreg)
5755 (<- valreg))
5756 (^))
5757
5758
5759(defppc2 ppc2-local-go local-go (seg vreg xfer tag)
5760 (declare (ignorable xfer))
5761 (let* ((curstack (ppc2-encode-stack))
5762 (label (cadr tag))
5763 (deststack (caddr tag)))
5764 (if (not (ppc2-equal-encodings-p curstack deststack))
5765 (multiple-value-bind (catch cstack vstack)
5766 (ppc2-decode-stack deststack)
5767 (ppc2-unwind-stack seg nil catch cstack vstack)))
5768 (-> label)
5769 (ppc2-unreachable-store vreg)))
5770
5771(defppc2 ppc2-local-block local-block (seg vreg xfer blocktag body)
5772 (let* ((curstack (ppc2-encode-stack))
5773 (compound (ppc2-cd-compound-p xfer))
5774 (mvpass-p (ppc2-mvpass-p xfer))
5775 (need-label (if xfer (or compound mvpass-p) t))
5776 end-of-block
5777 last-cd
5778 (dest (if (backend-crf-p vreg) ppc::arg_z vreg)))
5779 (if need-label
5780 (setq end-of-block (backend-get-next-label)))
5781 (setq last-cd (if need-label (%ilogior2 (if mvpass-p $backend-mvpass-mask 0) end-of-block) xfer))
5782 (%rplaca blocktag (cons (cons dest last-cd) curstack))
5783 (if mvpass-p
5784 (ppc2-multiple-value-body seg body)
5785 (ppc2-form seg dest (if xfer last-cd) body))
5786 (when need-label
5787 (@ end-of-block)
5788 (if compound
5789 (<- dest))
5790 (ppc2-branch seg (logand (lognot $backend-mvpass-mask) (or xfer 0)) vreg))))
5791
5792(defppc2 ppc2-%izerop %izerop (seg vreg xfer cc form)
5793 (multiple-value-bind (cr-bit true-p) (acode-condition-to-ppc-cr-bit cc)
5794 (ppc2-test-%izerop seg vreg xfer form cr-bit true-p)))
5795
5796
5797(defppc2 ppc2-uvsize uvsize (seg vreg xfer v)
5798 (let* ((misc-reg (ppc2-one-untargeted-reg-form seg v ppc::arg_z)))
5799 (unless *ppc2-reckless* (! trap-unless-uvector misc-reg))
5800 (if vreg
5801 (ensuring-node-target (target vreg)
5802 (! misc-element-count-fixnum target misc-reg)))
5803 (^)))
5804
5805(defppc2 ppc2-%ilsl %ilsl (seg vreg xfer form1 form2)
5806 (if (null vreg)
5807 (progn
5808 (ppc2-form seg nil nil form1)
5809 (ppc2-form seg nil xfer form2))
5810 (let* ((const (acode-fixnum-form-p form1))
5811 (max (target-arch-case (:ppc32 31) (:ppc64 63))))
5812 (ensuring-node-target (target vreg)
5813 (if const
5814 (let* ((src (ppc2-one-untargeted-reg-form seg form2 ppc::arg_z)))
5815 (if (<= const max)
5816 (! %ilsl-c target const src)
5817 (! lri target 0)))
5818 (multiple-value-bind (count src) (ppc2-two-untargeted-reg-forms seg form1 ppc::arg_y form2 ppc::arg_z)
5819 (! %ilsl target count src))))
5820 (^))))
5821
5822(defppc2 ppc2-endp endp (seg vreg xfer cc form)
5823 (let* ((formreg (ppc2-one-untargeted-reg-form seg form ppc::arg_z)))
5824 (! trap-unless-list formreg)
5825 (multiple-value-bind (cr-bit true-p) (acode-condition-to-ppc-cr-bit cc)
5826 (ppc2-compare-register-to-nil seg vreg xfer formreg cr-bit true-p))))
5827
5828
5829
5830(defppc2 ppc2-%code-char %code-char (seg vreg xfer c)
5831 (if (null vreg)
5832 (ppc2-form seg nil xfer c)
5833 (progn
5834 (ensuring-node-target (target vreg)
5835 (with-imm-target () (dest :u8)
5836 (! u32->char target (ppc2-one-untargeted-reg-form seg c dest))))
5837 (^))))
5838
5839(defppc2 ppc2-%schar %schar (seg vreg xfer str idx)
5840 (multiple-value-bind (src unscaled-idx)
5841 (ppc2-two-untargeted-reg-forms seg str ppc::arg_y idx ppc::arg_z)
5842 (if vreg
5843 (ensuring-node-target (target vreg)
5844 (case (arch::target-char-code-limit (backend-target-arch *target-backend*))
5845 (256 (! %schar8 target src unscaled-idx))
5846 (t (! %schar32 target src unscaled-idx)))))
5847 (^)))
5848
5849(defppc2 ppc2-%set-schar %set-schar (seg vreg xfer str idx char)
5850 (multiple-value-bind (src unscaled-idx char)
5851 (ppc2-three-untargeted-reg-forms seg
5852 str ppc::arg_x
5853 idx ppc::arg_y
5854 char ppc::arg_z)
5855 (case (arch::target-char-code-limit (backend-target-arch *target-backend*))
5856 (256 (! %set-schar8 src unscaled-idx char))
5857 (t (! %set-schar32 src unscaled-idx char)))
5858 (when vreg (<- char))
5859 (^)))
5860
5861(defppc2 ppc2-%set-scharcode %set-scharcode (seg vreg xfer str idx char)
5862 (multiple-value-bind (src unscaled-idx char)
5863 (ppc2-three-untargeted-reg-forms seg str ppc::arg_x idx ppc::arg_y
5864 char ppc::arg_z)
5865 (case (arch::target-char-code-limit (backend-target-arch *target-backend*))
5866 (256 (! %set-scharcode8 src unscaled-idx char))
5867 (t (! %set-scharcode32 src unscaled-idx char)))
5868 (when vreg (<- char))
5869 (^)))
5870
5871(defppc2 ppc2-%scharcode %scharcode (seg vreg xfer str idx)
5872 (multiple-value-bind (src unscaled-idx)
5873 (ppc2-two-untargeted-reg-forms seg str ppc::arg_y idx ppc::arg_z)
5874 (if vreg
5875 (ensuring-node-target (target vreg)
5876 (case (arch::target-char-code-limit (backend-target-arch *target-backend*))
5877 (256 (! %scharcode8 target src unscaled-idx))
5878 (t (! %scharcode32 target src unscaled-idx)))))
5879 (^)))
5880
5881
5882
5883(defppc2 ppc2-code-char code-char (seg vreg xfer c)
5884 (let* ((reg (ppc2-one-untargeted-reg-form seg c ppc::arg_z)))
5885 ;; Typecheck even if result unused.
5886 (case (arch::target-char-code-limit (backend-target-arch *target-backend*))
5887 (256 (! require-u8 reg))
5888 (t (! require-char-code reg)))
5889 (if vreg
5890 (ensuring-node-target (target vreg)
5891 (! fixnum->char target reg)))
5892 (^)))
5893
5894(defppc2 ppc2-eq eq (seg vreg xfer cc form1 form2)
5895 (multiple-value-bind (cr-bit true-p) (acode-condition-to-ppc-cr-bit cc)
5896 (ppc2-compare seg vreg xfer form1 form2 cr-bit true-p)))
5897
5898(defppc2 ppc2-neq neq (seg vreg xfer cc form1 form2)
5899 (multiple-value-bind (cr-bit true-p) (acode-condition-to-ppc-cr-bit cc)
5900 (ppc2-compare seg vreg xfer form1 form2 cr-bit true-p)))
5901
5902(defppc2 ppc2-numcmp numcmp (seg vreg xfer cc form1 form2)
5903 (let* ((name (ecase (cadr cc)
5904 (:eq '=-2)
5905 (:ne '/=-2)
5906 (:lt '<-2)
5907 (:le '<=-2)
5908 (:gt '>-2)
5909 (:ge '>=-2))))
5910 (if (or (ppc2-explicit-non-fixnum-type-p form1)
5911 (ppc2-explicit-non-fixnum-type-p form2))
5912 (ppc2-binary-builtin seg vreg xfer name form1 form2)
5913 (ppc2-inline-numcmp seg vreg xfer cc name form1 form2))))
5914
5915(defun ppc2-inline-numcmp (seg vreg xfer cc name form1 form2)
5916 (with-ppc-local-vinsn-macros (seg vreg xfer)
5917 (multiple-value-bind (cr-bit true-p) (acode-condition-to-ppc-cr-bit cc)
5918 (let* ((otherform (and (eql cr-bit ppc::ppc-eq-bit)
5919 (if (eql (acode-fixnum-form-p form2) 0)
5920 form1
5921 (if (eql (acode-fixnum-form-p form1) 0)
5922 form2)))))
5923 (if otherform
5924 (ppc2-one-targeted-reg-form seg otherform ($ ppc::arg_z))
5925 (ppc2-two-targeted-reg-forms seg form1 ($ ppc::arg_y) form2 ($ ppc::arg_z)))
5926 (let* ((out-of-line (backend-get-next-label))
5927 (done (backend-get-next-label)))
5928 (if otherform
5929 (unless (acode-fixnum-form-p otherform)
5930 (! branch-unless-arg-fixnum ($ ppc::arg_z) (aref *backend-labels* out-of-line)))
5931 (if (acode-fixnum-form-p form1)
5932 (! branch-unless-arg-fixnum ($ ppc::arg_z) (aref *backend-labels* out-of-line))
5933 (if (acode-fixnum-form-p form2)
5934 (! branch-unless-arg-fixnum ($ ppc::arg_y) (aref *backend-labels* out-of-line))
5935 (! branch-unless-both-args-fixnums ($ ppc::arg_y) ($ ppc::arg_z) (aref *backend-labels* out-of-line)))))
5936 (with-imm-target () (b31-reg :natural)
5937 (if otherform
5938 (if true-p
5939 (! eq0->bit31 b31-reg ($ ppc::arg_z))
5940 (! ne0->bit31 b31-reg ($ ppc::arg_z)))
5941 (ecase cr-bit
5942 (#. ppc::ppc-eq-bit
5943 (if true-p
5944 (! eq->bit31 b31-reg ($ ppc::arg_y) ($ ppc::arg_z))
5945 (! ne->bit31 b31-reg ($ ppc::arg_y) ($ ppc::arg_z))))
5946 (#. ppc::ppc-lt-bit
5947 (if true-p
5948 (! lt->bit31 b31-reg ($ ppc::arg_y) ($ ppc::arg_z))
5949 (! ge->bit31 b31-reg ($ ppc::arg_y) ($ ppc::arg_z))))
5950 (#. ppc::ppc-gt-bit
5951 (if true-p
5952 (! gt->bit31 b31-reg ($ ppc::arg_y) ($ ppc::arg_z))
5953 (! le->bit31 b31-reg ($ ppc::arg_y) ($ ppc::arg_z))))))
5954 (! lowbit->truth ($ ppc::arg_z) b31-reg)
5955 (-> done)
5956 (@ out-of-line)
5957 (if otherform
5958 (ppc2-lri seg ($ ppc::arg_y) 0))
5959 (let* ((index (arch::builtin-function-name-offset name))
5960 (idx-subprim (ppc2-builtin-index-subprim index)))
5961 (! call-subprim-2 ($ ppc::arg_z) idx-subprim ($ ppc::arg_y) ($ ppc::arg_z)))
5962 (@ done)
5963 (<- ($ ppc::arg_z))
5964 (^)))))))
5965
5966(defppc2 ppc2-%word-to-int %word-to-int (seg vreg xfer form)
5967 (if (null vreg)
5968 (ppc2-form seg nil xfer form)
5969 (progn
5970 (ensuring-node-target (target vreg)
5971 (! sign-extend-halfword target (ppc2-one-untargeted-reg-form seg form ppc::arg_z)))
5972 (^))))
5973
5974(defppc2 ppc2-multiple-value-list multiple-value-list (seg vreg xfer form)
5975 (ppc2-multiple-value-body seg form)
5976 (! list)
5977 (when vreg
5978 (<- ppc::arg_z))
5979 (^))
5980
5981(defppc2 ppc2-immform immediate (seg vreg xfer form)
5982 (ppc2-immediate seg vreg xfer form))
5983
5984(defppc2 ppc2-lexical-reference lexical-reference (seg vreg xfer varnode)
5985 (let* ((ea-or-form (var-ea varnode)))
5986 (if (and (acode-punted-var-p varnode) (not (fixnump ea-or-form)))
5987 (ppc2-form seg vreg xfer ea-or-form)
5988 (let* ((cell (ppc2-lookup-var-cell varnode)))
5989 (if (and cell (typep cell 'lcell))
5990 (if (ppc2-ensure-lcell-offset cell (logand ea-or-form #xffff))
5991 (and nil (format t "~& could use cell ~s for var ~s" cell (var-name varnode)))
5992 (if (logbitp ppc2-debug-verbose-bit *ppc2-debug-mask*)
5993 (break "wrong ea for lcell for var ~s: got ~d, expected ~d"
5994 (var-name varnode) (calc-lcell-offset cell) (logand ea-or-form #xffff))))
5995 (if (not cell)
5996 (when (memory-spec-p ea-or-form)
5997 (if (logbitp ppc2-debug-verbose-bit *ppc2-debug-mask*)
5998 (format t "~& no lcell for ~s." (var-name varnode))))))
5999
6000 (unless (or (typep ea-or-form 'lreg) (fixnump ea-or-form))
6001 (break "bogus ref to var ~s (~s) : ~s " varnode (var-name varnode) ea-or-form))
6002 (ppc2-do-lexical-reference seg vreg ea-or-form)
6003 (^)))))
6004
6005(defppc2 ppc2-setq-lexical setq-lexical (seg vreg xfer varspec form)
6006 (let* ((ea (var-ea varspec)))
6007 ;(unless (fixnump ea) (break "setq lexical is losing BIG"))
6008 (let* ((valreg (ppc2-one-untargeted-reg-form seg form (if (and (register-spec-p ea)
6009 (or (null vreg) (eq ea vreg)))
6010 ea
6011 ppc::arg_z))))
6012 (ppc2-do-lexical-setq seg vreg ea valreg))
6013 (^)))
6014
6015(defppc2 ppc2-fixnum fixnum (seg vreg xfer value)
6016 (if (null vreg)
6017 (^)
6018 (let* ((class (hard-regspec-class vreg))
6019 (mode (get-regspec-mode vreg))
6020 (unboxed (if (= class hard-reg-class-gpr)
6021 (not (or (= hard-reg-class-gpr-mode-node mode)
6022 (= hard-reg-class-gpr-mode-address mode))))))
6023 (if unboxed
6024 (ppc2-absolute-natural seg vreg xfer value)
6025 (if (= class hard-reg-class-crf)
6026 (progn
6027 ;(break "Would have clobbered a GPR!")
6028 (ppc2-branch seg (ppc2-cd-true xfer) nil))
6029 (progn
6030 (ensuring-node-target (target vreg)
6031 (ppc2-absolute-natural seg target nil (ash value *ppc2-target-fixnum-shift*)))
6032 (^)))))))
6033
6034(defppc2 ppc2-%ilogbitp %ilogbitp (seg vreg xfer cc bitnum form)
6035 (if (null vreg)
6036 (progn
6037 (ppc2-form seg nil nil bitnum)
6038 (ppc2-form seg vreg xfer form))
6039 (multiple-value-bind (cr-bit true-p) (acode-condition-to-ppc-cr-bit cc)
6040 (let* ((fixbit (acode-fixnum-form-p bitnum)))
6041 (if fixbit
6042 (let* ((reg (ppc2-one-untargeted-reg-form seg form ppc::arg_z))
6043 (ppc-bit (- (1- *ppc2-target-bits-in-word*) (max (min (+ fixbit *ppc2-target-fixnum-shift*) (1- *ppc2-target-bits-in-word*)) *ppc2-target-fixnum-shift*))))
6044 (with-imm-temps () (bitreg)
6045 (! extract-constant-ppc-bit bitreg reg ppc-bit)
6046 (regspec-crf-gpr-case
6047 (vreg dest)
6048 (progn
6049 (! compare-signed-s16const dest bitreg 0)
6050 (^ cr-bit true-p))
6051 (progn
6052 (if true-p
6053 (! invert-lowbit bitreg))
6054 (ensuring-node-target (target dest)
6055 (! lowbit->truth target bitreg))
6056 (^)))))
6057 (multiple-value-bind (rbit rform) (ppc2-two-untargeted-reg-forms seg bitnum ppc::arg_y form ppc::arg_z)
6058 (with-imm-temps () (bitreg)
6059 (! extract-variable-non-insane-bit bitreg rform rbit)
6060 (regspec-crf-gpr-case
6061 (vreg dest)
6062 (progn
6063 (! compare-signed-s16const dest bitreg 0)
6064 (^ cr-bit true-p))
6065 (progn
6066 (if true-p
6067 (! invert-lowbit bitreg))
6068 (ensuring-node-target (target dest)
6069 (! lowbit->truth target bitreg))
6070 (^))))))))))
6071
6072(defppc2 ppc2-uvref uvref (seg vreg xfer vector index)
6073 (ppc2-two-targeted-reg-forms seg vector ($ ppc::arg_y) index ($ ppc::arg_z))
6074 (! misc-ref)
6075 (<- ($ ppc::arg_z))
6076 (^))
6077
6078(defppc2 ppc2-uvset uvset (seg vreg xfer vector index value)
6079 (ppc2-three-targeted-reg-forms seg vector ($ ppc::arg_x) index ($ ppc::arg_y) value ($ ppc::arg_z))
6080 (! misc-set)
6081 (<- ($ ppc::arg_z))
6082 (^))
6083
6084(defppc2 ppc2-%decls-body %decls-body (seg vreg xfer form p2decls)
6085 (with-ppc-p2-declarations p2decls
6086 (ppc2-form seg vreg xfer form)))
6087
6088
6089
6090(defppc2 ppc2-%err-disp %err-disp (seg vreg xfer arglist)
6091 (ppc2-set-nargs seg (ppc2-arglist seg arglist))
6092 (! ksignalerr)
6093 (ppc2-nil seg vreg xfer))
6094
6095
6096(defppc2 ppc2-local-tagbody local-tagbody (seg vreg xfer taglist body)
6097 (let* ((encstack (ppc2-encode-stack))
6098 (tagop (%nx1-operator tag-label)))
6099 (dolist (tag taglist)
6100 (rplacd tag (cons (backend-get-next-label) (cons encstack (cadr (cddr (cddr tag)))))))
6101 (dolist (form body)
6102 (if (eq (acode-operator form) tagop)
6103 (let ((tag (cddr form)))
6104 (@ (car tag)))
6105 (ppc2-form seg nil nil form)))
6106 (ppc2-nil seg vreg xfer)))
6107
6108(defppc2 ppc2-call call (seg vreg xfer fn arglist &optional spread-p)
6109 (ppc2-call-fn seg vreg xfer fn arglist spread-p))
6110
6111(defppc2 ppc2-self-call self-call (seg vreg xfer arglist &optional spread-p)
6112 (setq arglist (ppc2-augment-arglist *ppc2-cur-afunc* arglist (if spread-p 1 $numppcargregs)))
6113 (ppc2-call-fn seg vreg xfer -1 arglist spread-p))
6114
6115
6116(defppc2 ppc2-lexical-function-call lexical-function-call (seg vreg xfer afunc arglist &optional spread-p)
6117 (ppc2-call-fn seg vreg xfer (list (%nx1-operator simple-function) afunc)
6118 (ppc2-augment-arglist afunc arglist (if spread-p 1 $numppcargregs))
6119 spread-p))
6120
6121(defppc2 ppc2-builtin-call builtin-call (seg vreg xfer index arglist)
6122 (let* ((nargs (ppc2-arglist seg arglist))
6123 (tail-p (and (ppc2-tailcallok xfer) (<= nargs $numppcargregs)))
6124 (idx (acode-fixnum-form-p index))
6125 (idx-subprim (ppc2-builtin-index-subprim idx))
6126 (subprim
6127 (or idx-subprim
6128 (case nargs
6129 (0 (subprim-name->offset '.SPcallbuiltin0))
6130 (1 (subprim-name->offset '.SPcallbuiltin1))
6131 (2 (subprim-name->offset '.SPcallbuiltin2))
6132 (3 (subprim-name->offset '.SPcallbuiltin3))
6133 (t (subprim-name->offset '.SPcallbuiltin))))))
6134 (when tail-p
6135 (ppc2-restore-nvrs seg *ppc2-register-restore-ea* *ppc2-register-restore-count*)
6136 (ppc2-restore-full-lisp-context seg))
6137 (unless idx-subprim
6138 (! lri ppc::imm0 (ash idx *ppc2-target-fixnum-shift*))
6139 (when (eql subprim (subprim-name->offset '.SPcallbuiltin))
6140 (ppc2-set-nargs seg nargs)))
6141 (if tail-p
6142 (! jump-subprim subprim)
6143 (progn
6144 (! call-subprim subprim)
6145 (<- ppc::arg_z)
6146 (^)))))
6147
6148
6149(defppc2 ppc2-if if (seg vreg xfer testform true false)
6150 (if (nx-constant-form-p (acode-unwrapped-form testform))
6151 (ppc2-form seg vreg xfer (if (nx-null (acode-unwrapped-form testform)) false true))
6152 (let* ((cstack *ppc2-cstack*)
6153 (vstack *ppc2-vstack*)
6154 (top-lcell *ppc2-top-vstack-lcell*)
6155 (entry-stack (ppc2-encode-stack))
6156 (true-stack nil)
6157 (false-stack nil)
6158 (true-cleanup-label nil)
6159 (same-stack-effects nil)
6160 (true-is-goto (ppc2-go-label true))
6161 (false-is-goto (and (not true-is-goto) (ppc2-go-label false)))
6162 (endlabel (backend-get-next-label))
6163 (falselabel (backend-get-next-label))
6164 (need-else (unless false-is-goto (or (not (nx-null false)) (ppc2-for-value-p vreg))))
6165 (both-single-valued (and (not *ppc2-open-code-inline*)
6166 (eq xfer $backend-return)
6167 (ppc2-for-value-p vreg)
6168 need-else
6169 (ppc2-single-valued-form-p true)
6170 (ppc2-single-valued-form-p false))))
6171 (if (eq 0 xfer)
6172 (setq xfer nil))
6173 (if both-single-valued ; it's implied that we're returning
6174 (let* ((result ppc::arg_z))
6175 (let ((merge-else-branch-label (if (nx-null false) (ppc2-find-nilret-label))))
6176 (ppc2-conditional-form seg (ppc2-make-compound-cd 0 falselabel) testform)
6177 (ppc2-form seg result endlabel true)
6178 (if (and merge-else-branch-label (neq -1 (aref *backend-labels* merge-else-branch-label)))
6179 (backend-copy-label merge-else-branch-label falselabel)
6180 (progn
6181 (@ falselabel)
6182 (if (nx-null false) (@ (ppc2-record-nilret-label)))
6183 (ppc2-form seg result nil false)))
6184 (@ endlabel)
6185 (<- result)
6186 (^)))
6187 (progn
6188 (if (and need-else (ppc2-mvpass-p xfer))
6189 (setq true-cleanup-label (backend-get-next-label)))
6190 (ppc2-conditional-form
6191 seg
6192 (ppc2-make-compound-cd
6193 (or true-is-goto 0)
6194 (or false-is-goto
6195 (if need-else
6196 (if true-is-goto 0 falselabel)
6197 (if true-is-goto xfer (ppc2-cd-merge xfer falselabel)))))
6198 testform)
6199 (if true-is-goto
6200 (ppc2-unreachable-store)
6201 (if true-cleanup-label
6202 (progn
6203 (ppc2-open-undo $undomvexpect)
6204 (ppc2-form seg vreg (logior $backend-mvpass-mask true-cleanup-label) true))
6205 (ppc2-form seg vreg (if need-else (ppc2-cd-merge xfer endlabel) xfer) true)))
6206 (setq true-stack (ppc2-encode-stack))
6207 (setq *ppc2-cstack* cstack)
6208 (ppc2-set-vstack vstack)
6209 (setq *ppc2-top-vstack-lcell* top-lcell)
6210 (if false-is-goto (ppc2-unreachable-store))
6211 (let ((merge-else-branch-label (if (and (nx-null false) (eq xfer $backend-return)) (ppc2-find-nilret-label))))
6212 (if (and merge-else-branch-label (neq -1 (aref *backend-labels* merge-else-branch-label)))
6213 (backend-copy-label merge-else-branch-label falselabel)
6214 (progn
6215 (@ falselabel)
6216 (when need-else
6217 (if true-cleanup-label
6218 (ppc2-mvpass seg false)
6219 (ppc2-form seg vreg xfer false))
6220 (setq false-stack (ppc2-encode-stack))))))
6221 (when true-cleanup-label
6222 (if (setq same-stack-effects (ppc2-equal-encodings-p true-stack false-stack)) ; can share cleanup code
6223 (@ true-cleanup-label))
6224 (let* ((*ppc2-returning-values* :pass))
6225 (ppc2-nlexit seg xfer 1)
6226 (ppc2-branch seg (if (and xfer (neq xfer $backend-mvpass-mask)) xfer (if (not same-stack-effects) endlabel)) vreg))
6227 (unless same-stack-effects
6228 (@ true-cleanup-label)
6229 (multiple-value-setq (true *ppc2-cstack* *ppc2-vstack* *ppc2-top-vstack-lcell*)
6230 (ppc2-decode-stack true-stack))
6231 (let* ((*ppc2-returning-values* :pass))
6232 (ppc2-nlexit seg xfer 1)
6233 (^)))
6234 (ppc2-close-undo)
6235 (multiple-value-setq (*ppc2-undo-count* *ppc2-cstack* *ppc2-vstack* *ppc2-top-vstack-lcell*)
6236 (ppc2-decode-stack entry-stack)))
6237 (@ endlabel))))))
6238
6239(defppc2 ppc2-or or (seg vreg xfer forms)
6240 (let* ((mvpass (ppc2-mvpass-p xfer))
6241 (tag1 (backend-get-next-label))
6242 (tag2 (backend-get-next-label))
6243 (vstack *ppc2-vstack*)
6244 (cstack *ppc2-cstack*)
6245 (dest (if (backend-crf-p vreg) vreg (if vreg ppc::arg_z (available-crf-temp *available-backend-crf-temps*))))
6246 (cd1 (ppc2-make-compound-cd
6247 (if (eq dest ppc::arg_z) tag1 (ppc2-cd-merge (ppc2-cd-true xfer) tag1)) 0)))
6248 (while (cdr forms)
6249 (ppc2-form seg dest (if (eq dest ppc::arg_z) nil cd1) (car forms))
6250 (when (eq dest ppc::arg_z)
6251 (with-crf-target () val-crf
6252 (ppc2-copy-register seg val-crf dest)
6253 (ppc2-branch seg cd1 val-crf)))
6254 (setq forms (%cdr forms)))
6255 (if mvpass
6256 (progn (ppc2-multiple-value-body seg (car forms))
6257 (let* ((*ppc2-returning-values* t)) (ppc2-branch seg (ppc2-cd-merge xfer tag2) vreg)))
6258 (ppc2-form seg vreg (if (eq dest ppc::arg_z) (ppc2-cd-merge xfer tag2) xfer) (car forms)))
6259 (setq *ppc2-vstack* vstack *ppc2-cstack* cstack)
6260 (@ tag1)
6261 (when (eq dest ppc::arg_z)
6262 (<- ppc::arg_z)
6263 (^))
6264 (@ tag2)))
6265
6266(defppc2 ppc2-simple-function simple-function (seg vreg xfer afunc)
6267 (ppc2-immediate seg vreg xfer (ppc2-afunc-lfun-ref afunc)))
6268
6269(defppc2 ppc2-list list (seg vreg xfer arglist)
6270 (if (null vreg)
6271 (dolist (form arglist)
6272 (ppc2-form seg vreg nil form))
6273 (let* ((*ppc2-vstack* *ppc2-vstack*)
6274 (*ppc2-top-vstack-lcell* *ppc2-top-vstack-lcell*)
6275 (nargs (ppc2-formlist seg arglist nil)))
6276 (ppc2-set-nargs seg nargs)
6277 (! list)
6278 (<- ppc::arg_z)))
6279 (^))
6280
6281(defppc2 ppc2-list* list* (seg vreg xfer arglist)
6282 (if (null vreg)
6283 (dolist (arg (apply #'append arglist))
6284 (ppc2-form seg nil nil arg))
6285 (let* ((*ppc2-vstack* *ppc2-vstack*)
6286 (*ppc2-top-vstack-lcell* *ppc2-top-vstack-lcell*)
6287 (nargs (ppc2-arglist seg arglist)))
6288 (declare (fixnum args))
6289 (when (> nargs 1)
6290 (ppc2-set-nargs seg (1- nargs))
6291 (! list*))
6292 (<- ppc::arg_z)))
6293 (^))
6294
6295(defppc2 ppc2-minus1 minus1 (seg vreg xfer form)
6296 (ppc2-unary-builtin seg vreg xfer '%negate form))
6297
6298(defun ppc2-inline-add2 (seg vreg xfer form1 form2)
6299 (with-ppc-local-vinsn-macros (seg vreg xfer)
6300 (ppc2-two-targeted-reg-forms seg form1 ($ ppc::arg_y) form2 ($ ppc::arg_z))
6301 (let* ((out-of-line (backend-get-next-label))
6302 (done (backend-get-next-label)))
6303 (ensuring-node-target (target vreg)
6304 (if (acode-fixnum-form-p form1)
6305 (! branch-unless-arg-fixnum ($ ppc::arg_z) (aref *backend-labels* out-of-line))
6306 (if (acode-fixnum-form-p form2)
6307 (! branch-unless-arg-fixnum ($ ppc::arg_y) (aref *backend-labels* out-of-line))
6308 (! branch-unless-both-args-fixnums ($ ppc::arg_y) ($ ppc::arg_z) (aref *backend-labels* out-of-line))))
6309 (if *ppc2-open-code-inline*
6310 (! fixnum-add-overflow-inline-skip ($ ppc::arg_z) ($ ppc::arg_y) ($ ppc::arg_z) (aref *backend-labels* done))
6311 (progn
6312 (! fixnum-add-overflow-ool ($ ppc::arg_y) ($ ppc::arg_z))
6313 (-> done)))
6314 (@ out-of-line)
6315 (! call-subprim-2 ($ ppc::arg_z) (subprim-name->offset '.SPbuiltin-plus) ($ ppc::arg_y) ($ ppc::arg_z))
6316 (@ done)
6317 (ppc2-copy-register seg target ($ ppc::arg_z)))
6318 (^))))
6319
6320(defun ppc2-inline-sub2 (seg vreg xfer form1 form2)
6321 (with-ppc-local-vinsn-macros (seg vreg xfer)
6322 (ppc2-two-targeted-reg-forms seg form1 ($ ppc::arg_y) form2 ($ ppc::arg_z))
6323 (let* ((out-of-line (backend-get-next-label))
6324 (done (backend-get-next-label)))
6325 (ensuring-node-target (target vreg)
6326 (if (acode-fixnum-form-p form1)
6327 (! branch-unless-arg-fixnum ($ ppc::arg_z) (aref *backend-labels* out-of-line))
6328 (if (acode-fixnum-form-p form2)
6329 (! branch-unless-arg-fixnum ($ ppc::arg_y) (aref *backend-labels* out-of-line))
6330 (! branch-unless-both-args-fixnums ($ ppc::arg_y) ($ ppc::arg_z) (aref *backend-labels* out-of-line))))
6331 (if *ppc2-open-code-inline*
6332 (! fixnum-sub-overflow-inline-skip ($ ppc::arg_z) ($ ppc::arg_y) ($ ppc::arg_z) (aref *backend-labels* done))
6333 (progn
6334 (! fixnum-sub-overflow-ool ($ ppc::arg_y) ($ ppc::arg_z))
6335 (-> done)))
6336 (@ out-of-line)
6337 (! call-subprim-2 ($ ppc::arg_z) (subprim-name->offset '.SPbuiltin-minus) ($ ppc::arg_y) ($ ppc::arg_z))
6338 (@ done)
6339 (ppc2-copy-register seg target ($ ppc::arg_z)))
6340 (^))))
6341
6342;;; Return T if form is declared to be something that couldn't be a fixnum.
6343(defun ppc2-explicit-non-fixnum-type-p (form)
6344 (let* ((type (ppc2-form-type form))
6345 (target-fixnum-type (nx-target-type 'fixnum)))
6346 (and (not (subtypep type target-fixnum-type))
6347 (not (subtypep target-fixnum-type type)))))
6348
6349
6350
6351
6352(defppc2 ppc2-add2 add2 (seg vreg xfer form1 form2)
6353 (multiple-value-bind (form1 form2)
6354 (nx-binop-numeric-contagion form1 form2 *ppc2-trust-declarations*)
6355 (if (and (ppc2-form-typep form1 'double-float)
6356 (ppc2-form-typep form2 'double-float))
6357 (ppc2-use-operator (%nx1-operator %double-float+-2)
6358 seg
6359 vreg
6360 xfer
6361 form1
6362 form2)
6363 (if (and (ppc2-form-typep form1 'single-float)
6364 (ppc2-form-typep form2 'single-float))
6365 (ppc2-use-operator (%nx1-operator %short-float+-2)
6366 seg
6367 vreg
6368 xfer
6369 form1
6370 form2)
6371 (if (and (ppc2-form-typep form1 'fixnum)
6372 (ppc2-form-typep form2 'fixnum))
6373 (ppc2-use-operator (%nx1-operator %i+)
6374 seg
6375 vreg
6376 xfer
6377 form1
6378 form2
6379 t)
6380 (if (or (ppc2-explicit-non-fixnum-type-p form1)
6381 (ppc2-explicit-non-fixnum-type-p form2))
6382 (ppc2-binary-builtin seg vreg xfer '+-2 form1 form2)
6383 (ppc2-inline-add2 seg vreg xfer form1 form2)))))))
6384
6385(defppc2 ppc2-sub2 sub2 (seg vreg xfer form1 form2)
6386 (multiple-value-bind (form1 form2)
6387 (nx-binop-numeric-contagion form1 form2 *ppc2-trust-declarations*)
6388 (if (and (ppc2-form-typep form1 'double-float)
6389 (ppc2-form-typep form2 'double-float))
6390 (ppc2-use-operator (%nx1-operator %double-float--2)
6391 seg
6392 vreg
6393 xfer
6394 form1
6395 form2)
6396 (if (and (ppc2-form-typep form1 'single-float)
6397 (ppc2-form-typep form2 'single-float))
6398 (ppc2-use-operator (%nx1-operator %short-float--2)
6399 seg
6400 vreg
6401 xfer
6402 form1
6403 form2)
6404 (if (and (ppc2-form-typep form1 'fixnum)
6405 (ppc2-form-typep form2 'fixnum))
6406 (ppc2-use-operator (%nx1-operator %i-)
6407 seg
6408 vreg
6409 xfer
6410 form1
6411 form2
6412 t)
6413 (if (or (ppc2-explicit-non-fixnum-type-p form1)
6414 (ppc2-explicit-non-fixnum-type-p form2))
6415 (ppc2-binary-builtin seg vreg xfer '--2 form1 form2)
6416 (ppc2-inline-sub2 seg vreg xfer form1 form2)))))))
6417
6418(defppc2 ppc2-mul2 mul2 (seg vreg xfer form1 form2)
6419 (multiple-value-bind (form1 form2)
6420 (nx-binop-numeric-contagion form1 form2 *ppc2-trust-declarations*)
6421 (if (and (ppc2-form-typep form1 'double-float)
6422 (ppc2-form-typep form2 'double-float))
6423 (ppc2-use-operator (%nx1-operator %double-float*-2)
6424 seg
6425 vreg
6426 xfer
6427 form1
6428 form2)
6429 (if (and (ppc2-form-typep form1 'single-float)
6430 (ppc2-form-typep form2 'single-float))
6431 (ppc2-use-operator (%nx1-operator %short-float*-2)
6432 seg
6433 vreg
6434 xfer
6435 form1
6436 form2)
6437 (ppc2-binary-builtin seg vreg xfer '*-2 form1 form2)))))
6438
6439
6440(defppc2 ppc2-div2 div2 (seg vreg xfer form1 form2)
6441 (multiple-value-bind (form1 form2)
6442 (nx-binop-numeric-contagion form1 form2 *ppc2-trust-declarations*)
6443 (if (and (ppc2-form-typep form1 'double-float)
6444 (ppc2-form-typep form2 'double-float))
6445 (ppc2-use-operator (%nx1-operator %double-float/-2)
6446 seg
6447 vreg
6448 xfer
6449 form1
6450 form2)
6451 (if (and (ppc2-form-typep form1 'single-float)
6452 (ppc2-form-typep form2 'single-float))
6453 (ppc2-use-operator (%nx1-operator %short-float/-2)
6454 seg
6455 vreg
6456 xfer
6457 form1
6458 form2)
6459 (let* ((f2 (acode-fixnum-form-p form2))
6460 (unwrapped (acode-unwrapped-form form1))
6461 (f1 nil)
6462 (f1/f2 nil))
6463 (if (and f2
6464 (not (zerop f2))
6465 (acode-p unwrapped)
6466 (or (eq (acode-operator unwrapped) (%nx1-operator mul2))
6467 (eq (acode-operator unwrapped) (%nx1-operator %i*)))
6468 (setq f1 (acode-fixnum-form-p (cadr unwrapped)))
6469 (typep (setq f1/f2 (/ f1 f2)) 'fixnum))
6470 (ppc2-use-operator (%nx1-operator mul2)
6471 seg
6472 vreg
6473 xfer
6474 (make-acode (%nx1-operator fixnum) f1/f2)
6475 (caddr unwrapped))
6476 (ppc2-binary-builtin seg vreg xfer '/-2 form1 form2)))))))
6477
6478(defppc2 ppc2-logbitp logbitp (seg vreg xfer bitnum int)
6479 (ppc2-binary-builtin seg vreg xfer 'logbitp bitnum int))
6480
6481
6482(defun ppc2-inline-logior2 (seg vreg xfer form1 form2)
6483 (with-ppc-local-vinsn-macros (seg vreg xfer)
6484 (let* ((fix1 (acode-fixnum-form-p form1))
6485 (fix2 (acode-fixnum-form-p form2)))
6486 (if (and fix1 fix2)
6487 (ppc2-use-operator (%nx1-operator fixnum) seg vreg xfer (logior fix1 fix2))
6488 (let* ((fixval (or fix1 fix2))
6489 (unboxed-fixval (if fixval (ash fixval *ppc2-target-fixnum-shift*)))
6490 (high (if fixval (if (= unboxed-fixval (logand #xffff0000 unboxed-fixval)) (ash unboxed-fixval -16))))
6491 (low (if fixval (unless high (if (= unboxed-fixval (logand #x0000ffff unboxed-fixval)) unboxed-fixval))))
6492 (otherform (if (or high low) (if fix1 form2 form1)))
6493 (out-of-line (backend-get-next-label))
6494 (done (backend-get-next-label)))
6495
6496 (if otherform
6497 (ppc2-one-targeted-reg-form seg otherform ($ ppc::arg_z))
6498 (ppc2-two-targeted-reg-forms seg form1 ($ ppc::arg_y) form2 ($ ppc::arg_z)))
6499 (ensuring-node-target (target vreg)
6500 (if otherform
6501 (unless (acode-fixnum-form-p otherform)
6502 (! branch-unless-arg-fixnum ($ ppc::arg_z) (aref *backend-labels* out-of-line)))
6503 (if (acode-fixnum-form-p form1)
6504 (! branch-unless-arg-fixnum ($ ppc::arg_z) (aref *backend-labels* out-of-line))
6505 (if (acode-fixnum-form-p form2)
6506 (! branch-unless-arg-fixnum ($ ppc::arg_y) (aref *backend-labels* out-of-line))
6507 (! branch-unless-both-args-fixnums ($ ppc::arg_y) ($ ppc::arg_z) (aref *backend-labels* out-of-line)))))
6508 (if otherform
6509 (if high
6510 (! logior-high ($ ppc::arg_z) ($ ppc::arg_z) high)
6511 (! logior-low ($ ppc::arg_z) ($ ppc::arg_z) low))
6512 (! %logior2 ($ ppc::arg_z) ($ ppc::arg_z) ($ ppc::arg_y)))
6513 (-> done)
6514 (@ out-of-line)
6515 (if otherform
6516 (ppc2-lri seg ($ ppc::arg_y) (ash fixval *ppc2-target-fixnum-shift*)))
6517 (! call-subprim-2 ($ ppc::arg_z) (subprim-name->offset '.SPbuiltin-logior) ($ ppc::arg_y) ($ ppc::arg_z))
6518 (@ done)
6519 (ppc2-copy-register seg target ($ ppc::arg_z)))
6520 (^))))))
6521
6522(defppc2 ppc2-logior2 logior2 (seg vreg xfer form1 form2)
6523 (if (or (ppc2-explicit-non-fixnum-type-p form1)
6524 (ppc2-explicit-non-fixnum-type-p form2))
6525 (ppc2-binary-builtin seg vreg xfer 'logior-2 form1 form2)
6526 (ppc2-inline-logior2 seg vreg xfer form1 form2)))
6527
6528(defppc2 ppc2-logxor2 logxor2 (seg vreg xfer form1 form2)
6529 (ppc2-binary-builtin seg vreg xfer 'logxor-2 form1 form2))
6530
6531(defun ppc2-inline-logand2 (seg vreg xfer form1 form2)
6532 (with-ppc-local-vinsn-macros (seg vreg xfer)
6533 (let* ((fix1 (acode-fixnum-form-p form1))
6534 (fix2 (acode-fixnum-form-p form2)))
6535 (if (and fix1 fix2)
6536 (ppc2-use-operator (%nx1-operator fixnum) seg vreg xfer (logand fix1 fix2))
6537 (let* ((fixval (or fix1 fix2))
6538 (fixlen (if fixval (integer-length fixval)))
6539 (unboxed-fixval (if fixval (ash fixval *ppc2-target-fixnum-shift*)))
6540 (high (if fixval (if (= unboxed-fixval (logand #xffff0000 unboxed-fixval)) (ash unboxed-fixval -16))))
6541 (low (if fixval (unless high (if (= unboxed-fixval (logand #x0000ffff unboxed-fixval)) unboxed-fixval))))
6542 (maskable (and fixval (= fixlen (logcount fixval))))
6543 (otherform (if (or high low maskable) (if fix1 form2 form1)))
6544 (out-of-line (backend-get-next-label))
6545 (done (backend-get-next-label)))
6546 (if otherform
6547 (ppc2-one-targeted-reg-form seg otherform ($ ppc::arg_z))
6548 (ppc2-two-targeted-reg-forms seg form1 ($ ppc::arg_y) form2 ($ ppc::arg_z)))
6549 (ensuring-node-target (target vreg)
6550 (if otherform
6551 (unless (acode-fixnum-form-p otherform)
6552 (! branch-unless-arg-fixnum ($ ppc::arg_z) (aref *backend-labels* out-of-line)))
6553 (if (acode-fixnum-form-p form1)
6554 (! branch-unless-arg-fixnum ($ ppc::arg_z) (aref *backend-labels* out-of-line))
6555 (if (acode-fixnum-form-p form2)
6556 (! branch-unless-arg-fixnum ($ ppc::arg_y) (aref *backend-labels* out-of-line))
6557 (! branch-unless-both-args-fixnums ($ ppc::arg_y) ($ ppc::arg_z) (aref *backend-labels* out-of-line)))))
6558 (if otherform
6559 (if (or high low)
6560 (if high
6561 (! logand-high ($ ppc::arg_z) ($ ppc::arg_z) high)
6562 (! logand-low ($ ppc::arg_z) ($ ppc::arg_z) low))
6563 (let* ((nbits (- *ppc2-target-bits-in-word*
6564 (1+ (+ *ppc2-target-fixnum-shift* fixlen)))))
6565 (if (> fixval 0)
6566 (! clear-left ($ ppc::arg_z) ($ ppc::arg_z) nbits)
6567 (! clear-right ($ ppc::arg_z) ($ ppc::arg_z) (+ fixlen
6568 *ppc2-target-fixnum-shift*)))))
6569 (! %logand2 ($ ppc::arg_z) ($ ppc::arg_z) ($ ppc::arg_y)))
6570 (-> done)
6571 (@ out-of-line)
6572 (if otherform
6573 (ppc2-lri seg ($ ppc::arg_y) (ash fixval *ppc2-target-fixnum-shift*)))
6574 (! call-subprim-2 ($ ppc::arg_z) (subprim-name->offset '.SPbuiltin-logand) ($ ppc::arg_y) ($ ppc::arg_z))
6575 (@ done)
6576 (ppc2-copy-register seg target ($ ppc::arg_z)))
6577 (^))))))
6578
6579(defppc2 ppc2-logand2 logand2 (seg vreg xfer form1 form2)
6580 (if (or (ppc2-explicit-non-fixnum-type-p form1)
6581 (ppc2-explicit-non-fixnum-type-p form2))
6582 (ppc2-binary-builtin seg vreg xfer 'logand-2 form1 form2)
6583 (ppc2-inline-logand2 seg vreg xfer form1 form2)))
6584
6585
6586
6587(defppc2 ppc2-%aref1 %aref1 (seg vreg xfer v i)
6588 (let* ((vtype (acode-form-type v t))
6589 (atype (if vtype (specifier-type vtype)))
6590 (keyword (if (and atype
6591 (not (array-ctype-complexp atype)))
6592 (funcall
6593 (arch::target-array-type-name-from-ctype-function
6594 (backend-target-arch *target-backend*))
6595 atype))))
6596 (if keyword
6597 (ppc2-vref seg vreg xfer keyword v i (not *ppc2-reckless*))
6598 (ppc2-binary-builtin seg vreg xfer '%aref1 v i))))
6599
6600(defppc2 ppc2-%aset1 aset1 (seg vreg xfer v i n)
6601 (let* ((vtype (acode-form-type v t))
6602 (atype (if vtype (specifier-type vtype)))
6603 (keyword (if (and atype
6604 (not (array-ctype-complexp atype)))
6605 (funcall
6606 (arch::target-array-type-name-from-ctype-function
6607 (backend-target-arch *target-backend*))
6608 atype))))
6609 (if keyword
6610 (ppc2-vset seg vreg xfer keyword v i n (not *ppc2-reckless*))
6611 (ppc2-ternary-builtin seg vreg xfer '%aset1 v i n))))
6612
6613(defppc2 ppc2-%i+ %i+ (seg vreg xfer form1 form2 &optional overflow)
6614 (when overflow
6615 (let* ((type *ppc2-target-half-fixnum-type*))
6616 (when (and (ppc2-form-typep form1 type)
6617 (ppc2-form-typep form2 type))
6618 (setq overflow nil))))
6619 (cond ((null vreg)
6620 (ppc2-form seg nil nil form1)
6621 (ppc2-form seg nil xfer form2))
6622 (overflow
6623 (multiple-value-bind (r1 r2) (ppc2-two-untargeted-reg-forms seg form1 ppc::arg_y form2 ppc::arg_z)
6624 (ensuring-node-target (target vreg)
6625 (if *ppc2-open-code-inline*
6626 (! fixnum-add-overflow-inline target r1 r2)
6627 (progn
6628 (! fixnum-add-overflow-ool r1 r2)
6629 (ppc2-copy-register seg target ($ ppc::arg_z)))))
6630 (^)))
6631 (t
6632 ;; There isn't any "addi" that checks for overflow, which is
6633 ;; why we didn't bother.
6634 (let* ((fix1 (acode-fixnum-form-p form1))
6635 (fix2 (acode-fixnum-form-p form2))
6636 (other (if (and fix1
6637 (typep (ash fix1 *ppc2-target-fixnum-shift*)
6638 '(signed-byte 32)))
6639 form2
6640 (if (and fix2
6641 (typep (ash fix2 *ppc2-target-fixnum-shift*)
6642 '(signed-byte 32)))
6643 form1))))
6644 (if (and fix1 fix2)
6645 (ppc2-lri seg vreg (ash (+ fix1 fix2) *ppc2-target-fixnum-shift*))
6646 (if other
6647 (let* ((constant (ash (or fix1 fix2) *ppc2-target-fixnum-shift*))
6648 (reg (ppc2-one-untargeted-reg-form seg other ppc::arg_z))
6649 (high (ldb (byte 16 16) constant))
6650 (low (ldb (byte 16 0) constant)))
6651 (declare (fixnum high low))
6652 (if (zerop constant)
6653 (<- reg)
6654 (progn
6655 (if (logbitp 15 low) (setq high (ldb (byte 16 0) (1+ high))))
6656 (if (and (eq vreg reg) (not (zerop high)))
6657 (with-node-temps (vreg) (temp)
6658 (! add-immediate temp reg high low)
6659 (<- temp))
6660 (ensuring-node-target (target vreg)
6661 (! add-immediate target reg high low))))))
6662 (multiple-value-bind (r1 r2) (ppc2-two-untargeted-reg-forms seg form1 ppc::arg_y form2 ppc::arg_z)
6663 (ensuring-node-target (target vreg)
6664 (! fixnum-add target r1 r2)))))
6665 (^)))))
6666
6667(defppc2 ppc2-%i- %i- (seg vreg xfer num1 num2 &optional overflow)
6668 (when overflow
6669 (let* ((type *ppc2-target-half-fixnum-type*))
6670 (when (and (ppc2-form-typep num1 type)
6671 (ppc2-form-typep num2 type))
6672 (setq overflow nil))))
6673 (let* ((v1 (acode-fixnum-form-p num1))
6674 (v2 (acode-fixnum-form-p num2)))
6675 (if (and v1 v2)
6676 (ppc2-use-operator (%nx1-operator fixnum) seg vreg xfer (%i- v1 v2))
6677 (if (and v2 (neq v2 most-negative-fixnum))
6678 (ppc2-use-operator (%nx1-operator %i+) seg vreg xfer num1 (make-acode (%nx1-operator fixnum) (- v2)) overflow)
6679 (if (eq v2 0)
6680 (ppc2-form seg vreg xfer num1)
6681 (cond
6682 ((null vreg)
6683 (ppc2-form seg nil nil num1)
6684 (ppc2-form seg nil xfer num2))
6685 (overflow
6686 (multiple-value-bind (r1 r2) (ppc2-two-untargeted-reg-forms seg num1 ppc::arg_y num2 ppc::arg_z)
6687 (ensuring-node-target (target vreg)
6688 (if *ppc2-open-code-inline*
6689 (! fixnum-sub-overflow-inline target r1 r2)
6690 (progn
6691 (! fixnum-sub-overflow-ool r1 r2)
6692 (ppc2-copy-register seg target ($ ppc::arg_z)))))
6693 (^)))
6694 ((and v1 (<= (integer-length v1) (- 15 *ppc2-target-fixnum-shift*)))
6695 (ensuring-node-target (target vreg)
6696 (! fixnum-sub-from-constant target v1 (ppc2-one-untargeted-reg-form seg num2 ppc::arg_z)))
6697 (^))
6698 (t
6699 (multiple-value-bind (r1 r2) (ppc2-two-untargeted-reg-forms seg num1 ppc::arg_y num2 ppc::arg_z)
6700 (ensuring-node-target (target vreg)
6701 (! fixnum-sub target r1 r2))
6702 (^)))))))))
6703
6704(defppc2 ppc2-%i* %i* (seg vreg xfer num1 num2)
6705 (if (null vreg)
6706 (progn
6707 (ppc2-form seg nil nil num1)
6708 (ppc2-form seg nil xfer num2))
6709 (let* ((fix1 (acode-fixnum-form-p num1))
6710 (fix2 (acode-fixnum-form-p num2))
6711 (other (if (typep fix1 '(signed-byte 16)) num2 (if (typep fix2 '(signed-byte 16)) num1))))
6712 (if (and fix1 fix2)
6713 (ppc2-lri seg vreg (ash (* fix1 fix2) *ppc2-target-fixnum-shift*))
6714 (if other
6715 (! multiply-immediate vreg (ppc2-one-untargeted-reg-form seg other ppc::arg_z) (or fix1 fix2))
6716 (multiple-value-bind (rx ry) (ppc2-two-untargeted-reg-forms seg num1 ppc::arg_y num2 ppc::arg_z)
6717 (ensuring-node-target (target vreg)
6718 (! multiply-fixnums target rx ry)))))
6719 (^))))
6720
6721(defppc2 ppc2-nth-value nth-value (seg vreg xfer n form)
6722 (let* ((*ppc2-vstack* *ppc2-vstack*)
6723 (*ppc2-top-vstack-lcell* *ppc2-top-vstack-lcell*))
6724 (let* ((nreg (ppc2-one-untargeted-reg-form seg n ppc::arg_z)))
6725 (unless (acode-fixnum-form-p n)
6726 (! trap-unless-fixnum nreg))
6727 (ppc2-vpush-register seg nreg))
6728 (ppc2-multiple-value-body seg form) ; sets nargs
6729 (! nth-value ppc::arg_z))
6730 (<- ppc::arg_z)
6731 (^))
6732
6733(defppc2 ppc2-values values (seg vreg xfer forms)
6734 (if (eq (list-length forms) 1)
6735 (if (ppc2-cd-compound-p xfer)
6736 (ppc2-form seg vreg xfer (%car forms))
6737 (progn
6738 (ppc2-form seg vreg nil (%car forms))
6739 (^)))
6740 (if (not (ppc2-mv-p xfer))
6741 (if forms
6742 (ppc2-use-operator (%nx1-operator prog1) seg vreg xfer forms)
6743 (ppc2-nil seg vreg xfer))
6744 (progn
6745 (let* ((*ppc2-vstack* *ppc2-vstack*)
6746 (*ppc2-top-vstack-lcell* *ppc2-top-vstack-lcell*))
6747 (ppc2-set-nargs seg (ppc2-formlist seg forms nil)))
6748 (let* ((*ppc2-returning-values* t))
6749 (^))))))
6750
6751(defppc2 ppc2-base-char-p base-char-p (seg vreg xfer cc form)
6752 (ppc2-char-p seg vreg xfer cc form))
6753
6754(defun ppc2-char-p (seg vreg xfer cc form)
6755 (with-ppc-local-vinsn-macros (seg vreg xfer)
6756 (multiple-value-bind (cr-bit true-p) (acode-condition-to-ppc-cr-bit cc)
6757 (! mask-base-char ppc::imm0 (ppc2-one-untargeted-reg-form seg form ppc::arg_z))
6758 (ppc2-test-reg-%izerop seg vreg xfer ppc::imm0 cr-bit true-p
6759 (target-arch-case
6760 (:ppc32 ppc32::subtag-character)
6761 (:ppc64 ppc64::subtag-character))))))
6762
6763
6764(defppc2 ppc2-let* let* (seg vreg xfer vars vals body p2decls &aux
6765 (old-stack (ppc2-encode-stack)))
6766 (ppc2-check-lcell-depth)
6767 (with-ppc-p2-declarations p2decls
6768 (ppc2-seq-bind seg vars vals)
6769 (ppc2-undo-body seg vreg xfer body old-stack))
6770 (dolist (v vars) (ppc2-close-var seg v)))
6771
6772(defppc2 ppc2-multiple-value-bind multiple-value-bind (seg vreg xfer vars valform body p2decls)
6773 (let* ((n (list-length vars))
6774 (vloc *ppc2-vstack*)
6775 (nbytes (* n *ppc2-target-node-size*))
6776 (old-stack (ppc2-encode-stack)))
6777 (with-ppc-p2-declarations p2decls
6778 (ppc2-multiple-value-body seg valform)
6779 (ppc2-lri seg ppc::imm0 nbytes)
6780 (! fitvals)
6781 (ppc2-set-vstack (%i+ vloc nbytes))
6782 (let* ((old-top *ppc2-top-vstack-lcell*)
6783 (lcells (progn (ppc2-reserve-vstack-lcells n) (ppc2-collect-lcells :reserved old-top))))
6784 (dolist (var vars)
6785 (let* ((lcell (pop lcells))
6786 (reg (ppc2-assign-register-var var)))
6787 (if reg
6788 (ppc2-init-regvar seg var reg (ppc2-vloc-ea vloc))
6789 (ppc2-bind-var seg var vloc lcell))
6790 (setq vloc (%i+ vloc *ppc2-target-node-size*)))))
6791 (ppc2-undo-body seg vreg xfer body old-stack)
6792 (dolist (var vars)
6793 (ppc2-close-var seg var)))))
6794
6795(defppc2 ppc2-debind debind (seg vreg xfer lambda-list bindform req opt rest keys auxen whole body p2decls cdr-p)
6796 (declare (ignore lambda-list))
6797 (let* ((old-stack (ppc2-encode-stack))
6798 (*ppc2-top-vstack-lcell* *ppc2-top-vstack-lcell*)
6799 (vloc *ppc2-vstack*))
6800 (with-ppc-p2-declarations p2decls
6801 (ppc2-bind-structured-lambda
6802 seg
6803 (ppc2-spread-lambda-list seg bindform whole req opt rest keys nil cdr-p)
6804 vloc (ppc2-vloc-ea vloc) whole req opt rest keys auxen)
6805 (ppc2-undo-body seg vreg xfer body old-stack)
6806 (ppc2-close-structured-lambda seg whole req opt rest keys auxen))))
6807
6808(defppc2 ppc2-multiple-value-prog1 multiple-value-prog1 (seg vreg xfer forms)
6809 (if (or (not (ppc2-mv-p xfer)) (ppc2-single-valued-form-p (%car forms)))
6810 (ppc2-use-operator (%nx1-operator prog1) seg vreg xfer forms)
6811 (if (null (cdr forms))
6812 (ppc2-form seg vreg xfer(car forms))
6813 (progn
6814 (let* ((*ppc2-vstack* *ppc2-vstack*)
6815 (*ppc2-top-vstack-lcell* *ppc2-top-vstack-lcell*))
6816 (ppc2-multiple-value-body seg (%car forms))
6817 (ppc2-open-undo $undostkblk)
6818 (! save-values))
6819 (dolist (form (cdr forms))
6820 (ppc2-form seg nil nil form))
6821 (ppc2-set-nargs seg 0)
6822 (! recover-values)
6823 (ppc2-close-undo)
6824 (let* ((*ppc2-returning-values* t))
6825 (^))))))
6826
6827(defppc2 ppc2-not not (seg vreg xfer cc form)
6828 (multiple-value-bind (cr-bit true-p) (acode-condition-to-ppc-cr-bit cc)
6829 (ppc2-compare-register-to-nil
6830 seg
6831 vreg
6832 xfer
6833 (ppc2-one-untargeted-reg-form seg form ppc::arg_z)
6834 cr-bit
6835 true-p)))
6836
6837
6838(defppc2 ppc2-%alloc-misc %make-uvector (seg vreg xfer element-count st &optional initval)
6839 (if (null vreg)
6840 (progn
6841 (ppc2-form seg nil nil element-count)
6842 (ppc2-form seg nil xfer st))
6843 (let* ((subtag (acode-fixnum-form-p st))
6844 (nelements (acode-fixnum-form-p element-count))
6845 (nbytes (if (and subtag nelements) (ppc2-misc-byte-count subtag nelements))))
6846 (if (and nbytes (null initval)
6847 (< (logand
6848 (lognot (1- (* 2 *ppc2-target-node-size*)))
6849 (+ nbytes *ppc2-target-node-size*
6850 (1- (* 2 *ppc2-target-node-size*)))) #x8000))
6851 (with-imm-temps () (header)
6852 (ppc2-lri seg header (arch::make-vheader nelements subtag))
6853 (ensuring-node-target (target vreg)
6854 (! %alloc-misc-fixed target header nbytes)))
6855 (progn
6856 (if initval
6857 (progn
6858 (ppc2-three-targeted-reg-forms seg element-count ($ ppc::arg_x) st ($ ppc::arg_y) initval ($ ppc::arg_z))
6859 (! misc-alloc-init)
6860 (<- ($ ppc::arg_z)))
6861 (progn
6862 (ppc2-two-targeted-reg-forms seg element-count ($ ppc::arg_y) st ($ ppc::arg_z))
6863 (! misc-alloc)
6864 (<- ($ ppc::arg_z))))))
6865 (^))))
6866
6867(defppc2 ppc2-%iasr %iasr (seg vreg xfer form1 form2)
6868 (if (null vreg)
6869 (progn
6870 (ppc2-form seg nil nil form1)
6871 (ppc2-form seg vreg xfer form2))
6872 (let* ((count (acode-fixnum-form-p form1))
6873 (max (target-arch-case (:ppc32 31) (:ppc64 63))))
6874 (declare (fixnum max))
6875 (ensuring-node-target (target vreg)
6876 (if count
6877 (! %iasr-c target (if (> count max) max count)
6878 (ppc2-one-untargeted-reg-form seg form2 ppc::arg_z))
6879 (multiple-value-bind (cnt src) (ppc2-two-targeted-reg-forms seg form1 ($ ppc::arg_y) form2 ($ ppc::arg_z))
6880 (! %iasr target cnt src))))
6881 (^))))
6882
6883(defppc2 ppc2-%ilsr %ilsr (seg vreg xfer form1 form2)
6884 (if (null vreg)
6885 (progn
6886 (ppc2-form seg nil nil form1)
6887 (ppc2-form seg vreg xfer form2))
6888 (let* ((count (acode-fixnum-form-p form1)))
6889 (ensuring-node-target (target vreg)
6890 (if count
6891 (let ((src (ppc2-one-untargeted-reg-form seg form2 ($ ppc::arg_z))))
6892 (if (<= count 31)
6893 (! %ilsr-c target count src)
6894 (! lri target 0)))
6895 (multiple-value-bind (cnt src) (ppc2-two-targeted-reg-forms seg form1 ($ ppc::arg_y) form2 ($ ppc::arg_z))
6896 (! %ilsr target cnt src))))
6897 (^))))
6898
6899
6900(defppc2 ppc2-%i<> %i<> (seg vreg xfer cc form1 form2)
6901 (multiple-value-bind (cr-bit true-p) (acode-condition-to-ppc-cr-bit cc)
6902 (ppc2-compare seg vreg xfer form1 form2 cr-bit true-p)))
6903
6904(defppc2 ppc2-%natural<> %natural<> (seg vreg xfer cc form1 form2)
6905 (multiple-value-bind (cr-bit true-p) (acode-condition-to-ppc-cr-bit cc)
6906 (ppc2-natural-compare seg vreg xfer form1 form2 cr-bit true-p)))
6907
6908(defppc2 ppc2-double-float-compare double-float-compare (seg vreg xfer cc form1 form2)
6909 (multiple-value-bind (cr-bit true-p) (acode-condition-to-ppc-cr-bit cc)
6910 (with-fp-target () (r1 :double-float)
6911 (with-fp-target (r1) (r2 :double-float)
6912 (multiple-value-bind (r1 r2) (ppc2-two-untargeted-reg-forms seg form1 r1 form2 r2)
6913 (ppc2-compare-double-float-registers seg vreg xfer r1 r2 cr-bit true-p))))))
6914
6915(defppc2 ppc2-short-float-compare short-float-compare (seg vreg xfer cc form1 form2)
6916 (multiple-value-bind (cr-bit true-p) (acode-condition-to-ppc-cr-bit cc)
6917 (with-fp-target () (r1 :single-float)
6918 (with-fp-target (r1) (r2 :single-float)
6919 (multiple-value-bind (r1 r2) (ppc2-two-untargeted-reg-forms seg form1 r1 form2 r2)
6920 (ppc2-compare-double-float-registers seg vreg xfer r1 r2 cr-bit true-p))))))
6921
6922(eval-when (:compile-toplevel :execute)
6923 (defmacro defppc2-df-op (fname opname vinsn)
6924 `(defppc2 ,fname ,opname (seg vreg xfer f0 f1)
6925 (if (null vreg)
6926 (progn
6927 (ppc2-form seg nil nil f0)
6928 (ppc2-form seg vreg xfer f1))
6929 (with-fp-target () (r1 :double-float)
6930 (with-fp-target (r1) (r2 :double-float)
6931 (multiple-value-bind (r1 r2) (ppc2-two-untargeted-reg-forms seg f0 r1 f1 r2)
6932 (if (= (hard-regspec-class vreg) hard-reg-class-fpr)
6933 (! ,vinsn vreg r1 r2)
6934 (with-fp-target (r1 r2) (result :double-float)
6935 (! ,vinsn result r1 r2)
6936 (ensuring-node-target (target vreg)
6937 (ppc2-copy-register seg target result))))
6938 (^)))))))
6939
6940 (defmacro defppc2-sf-op (fname opname vinsn)
6941 `(defppc2 ,fname ,opname (seg vreg xfer f0 f1)
6942 (if (null vreg)
6943 (progn
6944 (ppc2-form seg nil nil f0)
6945 (ppc2-form seg vreg xfer f1))
6946 (with-fp-target () (r1 :single-float)
6947 (with-fp-target (r1) (r2 :single-float)
6948 (multiple-value-bind (r1 r2) (ppc2-two-untargeted-reg-forms seg f0 r1 f1 r2)
6949 (if (= (hard-regspec-class vreg) hard-reg-class-fpr)
6950 (! ,vinsn vreg r1 r2)
6951 (with-fp-target (r1 r2) (result :single-float)
6952 (! ,vinsn result r1 r2)
6953 (ensuring-node-target (target vreg)
6954 (ppc2-copy-register seg target result))))
6955 (^)))))))
6956)
6957
6958(defppc2-df-op ppc2-%double-float+-2 %double-float+-2 double-float+-2)
6959(defppc2-df-op ppc2-%double-float--2 %double-float--2 double-float--2)
6960(defppc2-df-op ppc2-%double-float*-2 %double-float*-2 double-float*-2)
6961(defppc2-df-op ppc2-%double-float/-2 %double-float/-2 double-float/-2)
6962
6963(defppc2-sf-op ppc2-%short-float+-2 %short-float+-2 single-float+-2)
6964(defppc2-sf-op ppc2-%short-float--2 %short-float--2 single-float--2)
6965(defppc2-sf-op ppc2-%short-float*-2 %short-float*-2 single-float*-2)
6966(defppc2-sf-op ppc2-%short-float/-2 %short-float/-2 single-float/-2)
6967
6968(defun ppc2-get-float (seg vreg xfer ptr offset double-p fp-reg)
6969 (with-ppc-local-vinsn-macros (seg vreg xfer)
6970 (cond ((null vreg)
6971 (ppc2-form seg nil nil ptr)
6972 (ppc2-form seg nil xfer offset))
6973 (t
6974 (let* ((fixoffset (acode-fixnum-form-p offset)))
6975 (if (typep fixoffset '(unsigned-byte 15))
6976 (with-imm-target () (ptrreg :address)
6977 (ppc2-form seg ptrreg nil ptr)
6978 (if double-p
6979 (! mem-ref-c-double-float fp-reg ptrreg fixoffset)
6980 (! mem-ref-c-single-float fp-reg ptrreg fixoffset)))
6981 (with-imm-target () (ptrreg :address)
6982 (with-imm-target (ptrreg) (offsetreg :s32)
6983 (ppc2-two-targeted-reg-forms seg
6984 ptr ptrreg
6985 offset ($ ppc::arg_z))
6986 (! fixnum->signed-natural offsetreg ppc::arg_z)
6987 (if double-p
6988 (! mem-ref-double-float fp-reg ptrreg offsetreg)
6989 (! mem-ref-single-float fp-reg ptrreg offsetreg)))))
6990 (<- fp-reg))
6991 (^)))))
6992
6993
6994(defppc2 ppc2-%get-double-float %get-double-float (seg vreg xfer ptr offset)
6995 (with-fp-target () (fp-reg :double-float)
6996 (ppc2-get-float seg vreg xfer ptr offset t fp-reg)))
6997
6998(defppc2 ppc2-%get-single-float %get-single-float (seg vreg xfer ptr offset)
6999 (with-fp-target () (fp-reg :single-float)
7000 (ppc2-get-float seg vreg xfer ptr offset nil fp-reg)))
7001
7002(defun ppc2-set-float (seg vreg xfer ptr offset newval double-p fp-reg)
7003 (with-ppc-local-vinsn-macros (seg vreg xfer)
7004 (let* ((fixoffset (acode-fixnum-form-p offset))
7005 (immoffset (typep fixoffset '(unsigned-byte 15))))
7006 (with-imm-target () (ptr-reg :address)
7007 (cond ((or (null vreg)
7008 (= (hard-regspec-class vreg) hard-reg-class-fpr))
7009 (cond (immoffset
7010 (ppc2-push-register
7011 seg
7012 (ppc2-one-untargeted-reg-form seg
7013 ptr
7014 ptr-reg))
7015 (ppc2-one-targeted-reg-form seg newval fp-reg)
7016 (ppc2-pop-register seg ptr-reg)
7017 (if double-p
7018 (! mem-set-c-double-float fp-reg ptr-reg fixoffset)
7019 (! mem-set-c-single-float fp-reg ptr-reg fixoffset)))
7020 (t
7021 (with-imm-target (ptr-reg) (offset-reg :s32)
7022 (ppc2-push-register
7023 seg
7024 (ppc2-one-untargeted-reg-form seg
7025 ptr
7026 ptr-reg))
7027 (ppc2-push-register
7028 seg
7029 (ppc2-one-untargeted-reg-form seg
7030 offset
7031 ppc::arg_z))
7032 (ppc2-one-targeted-reg-form seg newval fp-reg)
7033 (ppc2-pop-register seg ppc::arg_z)
7034 (ppc2-pop-register seg ptr-reg)
7035 (! fixnum->signed-natural offset-reg ppc::arg_z)
7036 (if double-p
7037 (! mem-set-double-float fp-reg ptr-reg offset-reg)
7038 (! mem-set-single-float fp-reg ptr-reg offset-reg)))))
7039 (<- fp-reg))
7040 (t
7041 (cond (immoffset
7042 (let* ((rnew ($ ppc::arg_z)))
7043 (ppc2-push-register
7044 seg
7045 (ppc2-one-untargeted-reg-form seg
7046 ptr
7047 ptr-reg))
7048 (ppc2-one-targeted-reg-form seg newval rnew)
7049 (ppc2-pop-register seg ptr-reg)
7050 (with-imm-temps (ptr-reg) ()
7051 (ppc2-copy-register seg fp-reg rnew)
7052 (if double-p
7053 (! mem-set-c-double-float fp-reg ptr-reg fixoffset)
7054 (! mem-set-c-single-float fp-reg ptr-reg fixoffset)))))
7055 (t
7056 (let* ((roffset ($ ppc::arg_y))
7057 (rnew ($ ppc::arg_z)))
7058 (ppc2-push-register
7059 seg
7060 (ppc2-one-untargeted-reg-form
7061 seg
7062 ptr ptr-reg))
7063 (ppc2-two-targeted-reg-forms seg
7064 offset roffset
7065 newval rnew)
7066 (ppc2-pop-register seg ptr-reg)
7067 (with-imm-target (ptr-reg) (offset-reg :s32)
7068 (with-imm-temps (ptr-reg offset-reg) ()
7069 (! fixnum->signed-natural offset-reg roffset)
7070 (ppc2-copy-register seg fp-reg rnew))
7071 (if double-p
7072 (! mem-set-double-float fp-reg ptr-reg offset-reg)
7073 (! mem-set-single-float fp-reg ptr-reg offset-reg))))))
7074 (<- ppc::arg_z)))
7075 (^)))))
7076
7077(defppc2 ppc2-%set-double-float %set-double-float (seg vreg xfer ptr offset newval)
7078 (with-fp-target () (fp-reg :double-float)
7079 (ppc2-set-float seg vreg xfer ptr offset newval t fp-reg)))
7080
7081(defppc2 ppc2-%set-single-float %set-single-float (seg vreg xfer ptr offset newval)
7082 (with-fp-target () (fp-reg :single-float)
7083 (ppc2-set-float seg vreg xfer ptr offset newval nil fp-reg)))
7084
7085(defppc2 ppc2-immediate-get-ptr immediate-get-ptr (seg vreg xfer ptr offset)
7086 (let* ((absptr (acode-absolute-ptr-p ptr))
7087 (triv-p (ppc2-trivial-p offset))
7088 (dest vreg)
7089 (offval (acode-fixnum-form-p offset)))
7090 (cond ((not vreg)
7091 (ppc2-form seg nil nil ptr)
7092 (ppc2-form seg nil xfer offset))
7093 (t
7094 (if (and absptr offval)
7095 (setq absptr (+ absptr offval) offval 0)
7096 (setq absptr nil))
7097 (and offval (%i> (integer-length offval) 15) (setq offval nil))
7098 (and absptr (%i> (integer-length absptr) 15) (setq absptr nil))
7099 (target-arch-case
7100 (:ppc32 (progn))
7101 (:ppc64 (progn
7102 (and offval (logtest 3 offval) (setq offval nil))
7103 (and absptr (logtest 3 absptr) (setq absptr nil)))))
7104 (if absptr
7105 (! mem-ref-c-natural dest ppc::rzero absptr)
7106 (if offval
7107 (let* ((src (ppc2-macptr-arg-to-reg seg ptr ($ ppc::imm0 :mode :address))))
7108 (! mem-ref-c-natural dest src offval))
7109 (let* ((src (ppc2-macptr-arg-to-reg seg ptr ($ ppc::imm0 :mode :address))))
7110 (if triv-p
7111 (with-imm-temps (src) (x)
7112 (if (acode-fixnum-form-p offset)
7113 (ppc2-lri seg x (acode-fixnum-form-p offset))
7114 (! fixnum->signed-natural x (ppc2-one-untargeted-reg-form seg offset ppc::arg_z)))
7115 (! mem-ref-natural dest src x))
7116 (progn
7117 (! temp-push-unboxed-word src)
7118 (ppc2-open-undo $undostkblk)
7119 (let* ((oreg (ppc2-one-untargeted-reg-form seg offset ppc::arg_z)))
7120 (with-imm-temps () (src x)
7121 (! temp-pop-unboxed-word src)
7122 (ppc2-close-undo)
7123 (! fixnum->signed-natural x oreg)
7124 (! mem-ref-natural dest src x))))))))
7125 (^)))))
7126
7127(defppc2 ppc2-get-bit %get-bit (seg vreg xfer ptr offset)
7128 (if (null vreg)
7129 (progn
7130 (ppc2-form seg nil nil ptr)
7131 (ppc2-form seg nil ptr nil))
7132 (let* ((offval (acode-fixnum-form-p offset))
7133 (byte-index (if offval (ash offval -3)))
7134 (bit-shift (if (and byte-index (< byte-index #x8000))
7135 (logand 31 (+ 25 (logand offval 7))))))
7136 (if bit-shift
7137 (with-imm-target ()
7138 (src-reg :address)
7139 (ppc2-one-targeted-reg-form seg ptr src-reg)
7140 (if (node-reg-p vreg)
7141 (! mem-ref-c-bit-fixnum vreg src-reg byte-index (logand 31 (+ bit-shift
7142 *ppc2-target-fixnum-shift*)))
7143 (with-imm-target () ;OK if src-reg & dest overlap
7144 (dest :u8)
7145 (! mem-ref-c-bit dest src-reg byte-index bit-shift)
7146 (<- dest))))
7147 (let* ((triv-p (ppc2-trivial-p offset))
7148 (offset-reg nil))
7149 (with-imm-target ()
7150 (src-reg :address)
7151 (ppc2-one-targeted-reg-form seg ptr src-reg)
7152 (unless triv-p
7153 (! temp-push-unboxed-word src-reg)
7154 (ppc2-open-undo $undostkblk))
7155 (setq offset-reg (ppc2-one-untargeted-reg-form seg offset ppc::arg_z))
7156 (unless triv-p
7157 (! temp-pop-unboxed-word src-reg)
7158 (ppc2-close-undo))
7159 (if (node-reg-p vreg)
7160 (! mem-ref-bit-fixnum vreg src-reg offset-reg)
7161 (with-imm-target ()
7162 (dest :u8)
7163 (! mem-ref-bit dest src-reg offset-reg)
7164 (<- dest))))))))
7165 (^))
7166
7167
7168
7169;;; This returns an unboxed object, unless the caller wants to box it.
7170(defppc2 ppc2-immediate-get-xxx immediate-get-xxx (seg vreg xfer bits ptr offset)
7171 (declare (fixnum bits))
7172 (let* ((fixnump (logbitp 6 bits))
7173 (signed (logbitp 5 bits))
7174 (size (logand 15 bits))
7175 (absptr (acode-absolute-ptr-p ptr))
7176 (triv-p (ppc2-trivial-p offset))
7177 (offval (acode-fixnum-form-p offset)))
7178 (declare (fixnum size))
7179 (cond ((null vreg)
7180 (ppc2-form seg nil nil ptr)
7181 (ppc2-form seg nil xfer offset))
7182 (t
7183 (if (and absptr offval)
7184 (setq absptr (+ absptr offval) offval 0)
7185 (setq absptr nil))
7186 (and offval (%i> (integer-length offval) 15) (setq offval nil))
7187 (and absptr (%i> (integer-length absptr) 15) (setq absptr nil))
7188 (target-arch-case
7189 (:ppc32 (progn))
7190 (:ppc64 (when (or fixnump (eql size 8) (and (eql size 8) signed))
7191 (and offval (logtest 3 offval) (setq offval nil))
7192 (and absptr (logtest 3 absptr) (setq absptr nil)))))
7193 (cond
7194 (fixnump
7195 (with-imm-target () (dest :signed-natural)
7196 (cond
7197 (absptr
7198 (target-arch-case
7199 (:ppc32 (! mem-ref-c-fullword dest ppc::rzero absptr))
7200 (:ppc64 (! mem-ref-c-doubleword dest ppc::rzero absptr))))
7201 (offval
7202 (with-imm-target () (src-reg :address)
7203 (ppc2-one-targeted-reg-form seg ptr src-reg)
7204 (target-arch-case
7205 (:ppc32 (! mem-ref-c-fullword dest src-reg offval))
7206 (:ppc64 (! mem-ref-c-doubleword dest src-reg offval)))))
7207 (t
7208 (with-imm-target () (src-reg :address)
7209 (with-imm-target (src-reg) (offset-reg :signed-natural)
7210 (ppc2-one-targeted-reg-form seg ptr src-reg)
7211 (if triv-p
7212 (if (acode-fixnum-form-p offset)
7213 (ppc2-lri seg offset-reg (acode-fixnum-form-p offset))
7214 (! fixnum->signed-natural offset-reg (ppc2-one-untargeted-reg-form seg offset ppc::arg_z)))
7215 (progn
7216 (! temp-push-unboxed-word src-reg)
7217 (ppc2-open-undo $undostkblk)
7218 (! fixnum->signed-natural offset-reg (ppc2-one-untargeted-reg-form seg offset ppc::arg_z))
7219 (! temp-pop-unboxed-word src-reg)
7220 (ppc2-close-undo)))
7221 (target-arch-case
7222 (:ppc32 (! mem-ref-fullword dest src-reg offset-reg))
7223 (:ppc64 (! mem-ref-doubleword dest src-reg offset-reg)))))))
7224 (if (node-reg-p vreg)
7225 (! box-fixnum vreg dest)
7226 (<- dest))))
7227 (signed
7228 (with-imm-target () (dest :signed-natural)
7229 (cond
7230 (absptr
7231 (case size
7232 (8 (! mem-ref-c-signed-doubleword dest ppc::rzero absptr))
7233 (4 (! mem-ref-c-signed-fullword dest ppc::rzero absptr))
7234 (2 (! mem-ref-c-s16 dest ppc::rzero absptr))
7235 (1 (! mem-ref-c-s8 dest ppc::rzero absptr))))
7236 (offval
7237 (with-imm-target (dest) (src-reg :address)
7238 (ppc2-one-targeted-reg-form seg ptr src-reg)
7239 (case size
7240 (8 (! mem-ref-c-signed-doubleword dest src-reg offval))
7241 (4 (! mem-ref-c-signed-fullword dest src-reg offval))
7242 (2 (! mem-ref-c-s16 dest src-reg offval))
7243 (1 (! mem-ref-c-s8 dest src-reg offval)))))
7244 (t
7245 (with-imm-target () (src-reg :address)
7246 (with-imm-target (src-reg) (offset-reg :signed-natural)
7247 (ppc2-one-targeted-reg-form seg ptr src-reg)
7248 (if triv-p
7249 (if (acode-fixnum-form-p offset)
7250 (ppc2-lri seg offset-reg (acode-fixnum-form-p offset))
7251 (! fixnum->signed-natural offset-reg (ppc2-one-untargeted-reg-form seg offset ppc::arg_z)))
7252 (progn
7253 (! temp-push-unboxed-word src-reg)
7254 (ppc2-open-undo $undostkblk)
7255 (! fixnum->signed-natural offset-reg (ppc2-one-untargeted-reg-form seg offset ppc::arg_z))
7256 (! temp-pop-unboxed-word src-reg)
7257 (ppc2-close-undo)))
7258 (case size
7259 (8 (! mem-ref-signed-doubleword dest src-reg offset-reg))
7260 (4 (! mem-ref-signed-fullword dest src-reg offset-reg))
7261 (2 (! mem-ref-s16 dest src-reg offset-reg))
7262 (1 (! mem-ref-s8 dest src-reg offset-reg)))))))
7263 (if (node-reg-p vreg)
7264 (case size
7265 ((1 2) (! box-fixnum vreg dest))
7266 (4 (target-arch-case
7267 (:ppc32
7268 (<- dest))
7269 (:ppc64 (! box-fixnum vreg dest))))
7270 (8 (<- dest)))
7271 (<- dest))))
7272 (t
7273 (with-imm-target () (dest :natural)
7274 (cond
7275 (absptr
7276 (case size
7277 (8 (! mem-ref-c-doubleword dest ppc::rzero absptr))
7278 (4 (! mem-ref-c-fullword dest ppc::rzero absptr))
7279 (2 (! mem-ref-c-u16 dest ppc::rzero absptr))
7280 (1 (! mem-ref-c-u8 dest ppc::rzero absptr))))
7281 (offval
7282 (with-imm-target (dest) (src-reg :address)
7283 (ppc2-one-targeted-reg-form seg ptr src-reg)
7284 (case size
7285 (8 (! mem-ref-c-doubleword dest src-reg offval))
7286 (4 (! mem-ref-c-fullword dest src-reg offval))
7287 (2 (! mem-ref-c-u16 dest src-reg offval))
7288 (1 (! mem-ref-c-u8 dest src-reg offval)))))
7289 (t
7290 (with-imm-target () (src-reg :address)
7291 (with-imm-target (src-reg) (offset-reg :signed-natural)
7292 (ppc2-one-targeted-reg-form seg ptr src-reg)
7293 (if triv-p
7294 (if (acode-fixnum-form-p offset)
7295 (ppc2-lri seg offset-reg (acode-fixnum-form-p offset))
7296 (! fixnum->signed-natural offset-reg (ppc2-one-untargeted-reg-form seg offset ppc::arg_z)))
7297 (progn
7298 (! temp-push-unboxed-word src-reg)
7299 (ppc2-open-undo $undostkblk)
7300 (! fixnum->signed-natural offset-reg (ppc2-one-untargeted-reg-form seg offset ppc::arg_z))
7301 (! temp-pop-unboxed-word src-reg)
7302 (ppc2-close-undo)))
7303 (case size
7304 (8 (! mem-ref-doubleword dest src-reg offset-reg))
7305 (4 (! mem-ref-fullword dest src-reg offset-reg))
7306 (2 (! mem-ref-u16 dest src-reg offset-reg))
7307 (1 (! mem-ref-u8 dest src-reg offset-reg)))))))
7308 (<- (set-regspec-mode
7309 dest
7310 (gpr-mode-name-value
7311 (case size
7312 (8 :u64)
7313 (4 :u32)
7314 (2 :u16)
7315 (1 :u8))))))))
7316 (^)))))
7317
7318(defppc2 ppc2-let let (seg vreg xfer vars vals body p2decls)
7319 (let* ((old-stack (ppc2-encode-stack))
7320 (val nil)
7321 (bits nil)
7322 (valcopy vals))
7323 (with-ppc-p2-declarations p2decls
7324 (dolist (var vars)
7325 (setq val (%car valcopy))
7326 (cond ((or (%ilogbitp $vbitspecial (setq bits (nx-var-bits var)))
7327 (and (%ilogbitp $vbitreg bits)
7328 (dolist (val (%cdr valcopy))
7329 (unless (ppc2-trivial-p val) (return t)))))
7330 (let* ((pair (cons (ppc2-vloc-ea *ppc2-vstack*) nil)))
7331 (%rplaca valcopy pair)
7332 (if (and (%ilogbitp $vbitdynamicextent bits)
7333 (progn
7334 (setq val
7335 (ppc2-dynamic-extent-form seg (ppc2-encode-stack) val))
7336 (ppc2-load-ea-p val)))
7337 (progn
7338 (%rplaca pair (ppc2-vloc-ea *ppc2-vstack*))
7339 (ppc2-vpush-register seg val :reserved))
7340 (ppc2-vpush-register seg (ppc2-one-untargeted-reg-form seg val ppc::arg_z) :reserved))
7341 (%rplacd pair *ppc2-top-vstack-lcell*)))
7342 (t (ppc2-seq-bind-var seg var val)
7343 (%rplaca valcopy nil)))
7344 (setq valcopy (%cdr valcopy)))
7345 (dolist (var vars)
7346 (declare (list val))
7347 (when (setq val (pop vals))
7348 (if (%ilogbitp $vbitspecial (nx-var-bits var))
7349 (progn
7350 (ppc2-dbind seg (car val) (var-name var))
7351 (ppc2-set-var-ea seg var (ppc2-vloc-ea (- *ppc2-vstack* *ppc2-target-node-size*))))
7352 (ppc2-seq-bind-var seg var (car val)))))
7353 (ppc2-undo-body seg vreg xfer body old-stack)
7354 (dolist (var vars)
7355 (ppc2-close-var seg var)))))
7356
7357(defppc2 ppc2-closed-function closed-function (seg vreg xfer afunc)
7358 (ppc2-make-closure seg afunc nil)
7359 (when vreg (<- ppc::arg_z))
7360 (^))
7361
7362(defppc2 ppc2-flet flet (seg vreg xfer vars afuncs body p2decls)
7363 (ppc2-seq-fbind seg vreg xfer vars afuncs body p2decls))
7364
7365(defppc2 ppc2-labels labels (seg vreg xfer vars afuncs body p2decls)
7366 (let* ((fwd-refs nil)
7367 (func nil)
7368 (togo vars)
7369 (real-vars ())
7370 (real-funcs ())
7371 (funs afuncs))
7372 (dolist (v vars)
7373 (when (neq 0 (afunc-fn-refcount (setq func (pop funs))))
7374 (push v real-vars)
7375 (push func real-funcs)
7376 (let* ((i 2)
7377 (our-var nil)
7378 (item nil))
7379 (declare (fixnum i))
7380 (dolist (ref (afunc-inherited-vars func))
7381 (when (memq (setq our-var (var-bits ref)) togo)
7382 (setq item (cons i our-var))
7383 (let* ((refs (assq v fwd-refs)))
7384 (if refs
7385 (push item (cdr refs))
7386 (push (list v item) fwd-refs))))
7387 (incf i)))
7388 (setq togo (%cdr togo))))
7389 (if (null fwd-refs)
7390 (ppc2-seq-fbind seg vreg xfer (nreverse real-vars) (nreverse real-funcs) body p2decls)
7391 (let* ((old-stack (ppc2-encode-stack)))
7392 (setq real-vars (nreverse real-vars) real-funcs (nreverse real-funcs))
7393 (with-ppc-p2-declarations p2decls
7394 (dolist (var real-vars)
7395 (ppc2-seq-bind-var seg var (nx1-afunc-ref (pop real-funcs))))
7396 (dolist (ref fwd-refs)
7397 (let ((ea (var-ea (pop ref))))
7398 (ppc2-addrspec-to-reg seg ea ppc::temp0)
7399 (dolist (r ref)
7400 (let* ((v-ea (var-ea (cdr r))))
7401 (let* ((val-reg (if (eq v-ea ea)
7402 ppc::temp0
7403 (progn
7404 (ppc2-addrspec-to-reg seg v-ea ppc::temp1)
7405 ppc::temp1))))
7406 (! misc-set-c-node val-reg ppc::temp0 (car r)))))))
7407 (ppc2-undo-body seg vreg xfer body old-stack)
7408 (dolist (var real-vars)
7409 (ppc2-close-var seg var)))))))
7410
7411;;; Make a function call (e.g., to mapcar) with some of the toplevel arguments
7412;;; stack-consed (downward) closures. Bind temporaries to these closures so
7413;;; that tail-recursion/non-local exits work right.
7414;;; (all of the closures are distinct: FLET and LABELS establish dynamic extent themselves.)
7415(defppc2 ppc2-with-downward-closures with-downward-closures (seg vreg xfer tempvars closures callform)
7416 (let* ((old-stack (ppc2-encode-stack)))
7417 (ppc2-seq-bind seg tempvars closures)
7418 (ppc2-undo-body seg vreg xfer callform old-stack)
7419 (dolist (v tempvars) (ppc2-close-var seg v))))
7420
7421
7422(defppc2 ppc2-local-return-from local-return-from (seg vreg xfer blocktag value)
7423 (declare (ignorable vreg xfer))
7424 (let* ((*ppc2-undo-count* *ppc2-undo-count*)
7425 (tagdata (car blocktag))
7426 (cur-stack (ppc2-encode-stack))
7427 (dest-vd (caar tagdata))
7428 (dest-cd (cdar tagdata))
7429 (mv-p (ppc2-mvpass-p dest-cd))
7430 (dest-stack (cdr tagdata))
7431 (need-break (neq cur-stack dest-stack)))
7432 (let* ((*ppc2-vstack* *ppc2-vstack*)
7433 (*ppc2-top-vstack-lcell* *ppc2-top-vstack-lcell*)
7434 (*ppc2-cstack* *ppc2-cstack*))
7435 (if
7436 (or
7437 (eq dest-cd $backend-return)
7438 (and mv-p
7439 (eq (ppc2-encoding-undo-count cur-stack)
7440 (ppc2-encoding-undo-count dest-stack))
7441 (eq (ppc2-encoding-cstack-depth cur-stack)
7442 (ppc2-encoding-cstack-depth dest-stack))))
7443 (ppc2-form seg dest-vd dest-cd value)
7444 (if mv-p
7445 (progn
7446 (ppc2-multiple-value-body seg value)
7447 (let* ((*ppc2-returning-values* :pass))
7448 (ppc2-nlexit seg dest-cd (%i- *ppc2-undo-count* (ppc2-encoding-undo-count dest-stack)))
7449 (ppc2-branch seg dest-cd vreg)))
7450 (progn
7451 (ppc2-form
7452 seg
7453 (if need-break (if dest-vd ppc::arg_z) dest-vd)
7454 (if need-break nil dest-cd)
7455 value)
7456 (when need-break
7457 (ppc2-unwind-set seg dest-cd dest-stack)
7458 (when dest-vd (ppc2-copy-register seg dest-vd ppc::arg_z))
7459 (ppc2-branch seg dest-cd dest-vd))))))
7460 (ppc2-unreachable-store)))
7461
7462(defppc2 ppc2-inherited-arg inherited-arg (seg vreg xfer arg)
7463 (when vreg
7464 (ppc2-addrspec-to-reg seg (ppc2-ea-open (var-ea arg)) vreg))
7465 (^))
7466
7467
7468(defppc2 ppc2-%lisp-word-ref %lisp-word-ref (seg vreg xfer base offset)
7469 (let* ((fixoffset (acode-fixnum-form-p offset)))
7470 (cond ((null vreg)
7471 (ppc2-form seg nil nil base)
7472 (ppc2-form seg nil xfer offset))
7473 ((target-arch-case
7474 (:ppc32 (typep fixoffset '(signed-byte 14)))
7475 (:ppc64 (typep fixoffset '(signed-byte 13))))
7476 (ensuring-node-target (target vreg)
7477 (! lisp-word-ref-c target
7478 (ppc2-one-untargeted-reg-form seg base ppc::arg_z)
7479 (ash fixoffset *ppc2-target-fixnum-shift*)))
7480 (^))
7481 (t (multiple-value-bind (breg oreg)
7482 (ppc2-two-untargeted-reg-forms seg base ppc::arg_y offset ppc::arg_z)
7483 (ensuring-node-target (target vreg)
7484 (! lisp-word-ref target breg oreg))
7485 (^))))))
7486
7487(defppc2 ppc2-%fixnum-ref %fixnum-ref (seg vreg xfer base offset)
7488 (let* ((fixoffset (acode-fixnum-form-p offset)))
7489 (cond ((null vreg)
7490 (ppc2-form seg nil nil base)
7491 (ppc2-form seg nil xfer offset))
7492 ((typep fixoffset '(signed-byte 16))
7493 (ensuring-node-target (target vreg)
7494 (! lisp-word-ref-c target
7495 (ppc2-one-untargeted-reg-form seg base ppc::arg_z)
7496 fixoffset))
7497 (^))
7498 (t (multiple-value-bind (breg oreg)
7499 (ppc2-two-untargeted-reg-forms seg base ppc::arg_y offset ppc::arg_z)
7500 (with-imm-target () (otemp :s32)
7501 (! fixnum->signed-natural otemp oreg)
7502 (ensuring-node-target (target vreg)
7503 (! lisp-word-ref target breg otemp)))
7504 (^))))))
7505
7506(defppc2 ppc2-%fixnum-ref-natural %fixnum-ref-natural (seg vreg xfer base offset)
7507 (let* ((fixoffset (acode-fixnum-form-p offset)))
7508 (cond ((null vreg)
7509 (ppc2-form seg nil nil base)
7510 (ppc2-form seg nil xfer offset))
7511 ((typep fixoffset '(signed-byte 16))
7512 (with-imm-target () (val :natural)
7513 (! lisp-word-ref-c val
7514 (ppc2-one-untargeted-reg-form seg base ppc::arg_z)
7515 fixoffset)
7516 (<- val))
7517 (^))
7518 (t (multiple-value-bind (breg oreg)
7519 (ppc2-two-untargeted-reg-forms seg base ppc::arg_y offset ppc::arg_z)
7520 (with-imm-target () (otemp :s32)
7521 (! fixnum->signed-natural otemp oreg)
7522 (with-imm-target () (val :natural)
7523 (! lisp-word-ref val breg otemp)
7524 (<- val)))
7525 (^))))))
7526
7527(defppc2 ppc2-int>0-p int>0-p (seg vreg xfer cc form)
7528 (multiple-value-bind (cr-bit true-p) (acode-condition-to-ppc-cr-bit cc)
7529 (ppc2-one-targeted-reg-form seg form ($ ppc::arg_z))
7530 (! integer-sign)
7531 (ppc2-test-reg-%izerop seg vreg xfer ppc::imm0 cr-bit true-p 0)))
7532
7533
7534(defppc2 ppc2-throw throw (seg vreg xfer tag valform )
7535 (declare (ignorable vreg xfer))
7536 (let* ((*ppc2-vstack* *ppc2-vstack*)
7537 (*ppc2-top-vstack-lcell* *ppc2-top-vstack-lcell*))
7538 (ppc2-vpush-register seg (ppc2-one-untargeted-reg-form seg tag ppc::arg_z))
7539 (if (ppc2-trivial-p valform)
7540 (progn
7541 (ppc2-vpush-register seg (ppc2-one-untargeted-reg-form seg valform ppc::arg_z))
7542 (ppc2-set-nargs seg 1))
7543 (ppc2-multiple-value-body seg valform))
7544 (! throw)))
7545
7546;;; This (and unwind-protect and things like that) are a little funky in that
7547;;; they have no good way of specifying the exit-point. The bad way is to
7548;;; follow the call to the catch-frame-creating subprim with a branch to that
7549;;; exit-point; the subprim returns to the following instruction.
7550;;; If the compiler ever gets smart about eliminating dead code, it has to
7551;;; be careful not to consider the block following the jump to be dead.
7552;;; Use a vinsn other than JUMP to reference the label.
7553(defppc2 ppc2-catch catch (seg vreg xfer tag valform)
7554 (let* ((tag-label (backend-get-next-label))
7555 (mv-pass (ppc2-mv-p xfer)))
7556 (ppc2-one-targeted-reg-form seg tag ($ ppc::arg_z))
7557 (if mv-pass
7558 (! mkcatchmv)
7559 (! mkcatch1v))
7560 (! non-barrier-jump (aref *backend-labels* tag-label))
7561 (ppc2-open-undo)
7562 (if mv-pass
7563 (ppc2-multiple-value-body seg valform)
7564 (ppc2-one-targeted-reg-form seg valform ($ ppc::arg_z)))
7565 (ppc2-lri seg ppc::imm0 (ash 1 *ppc2-target-fixnum-shift*))
7566 (if mv-pass
7567 (! nthrowvalues)
7568 (! nthrow1value))
7569 (ppc2-close-undo)
7570 (@ tag-label)
7571 (unless mv-pass (if vreg (<- ppc::arg_z)))
7572 (let* ((*ppc2-returning-values* mv-pass)) ; nlexit keeps values on stack
7573 (^))))
7574
7575
7576(defppc2 ppc2-fixnum-overflow fixnum-overflow (seg vreg xfer form)
7577 (destructuring-bind (op n0 n1) (acode-unwrapped-form form)
7578 (ppc2-use-operator op seg vreg xfer n0 n1 *nx-t*)))
7579
7580
7581
7582(defppc2 ppc2-%aref2 simple-typed-aref2 (seg vreg xfer typename arr i j &optional dim0 dim1)
7583 (if (null vreg)
7584 (progn
7585 (ppc2-form seg nil nil arr)
7586 (ppc2-form seg nil nil i)
7587 (ppc2-form seg nil xfer j))
7588 (let* ((type-keyword (ppc2-immediate-operand typename))
7589 (fixtype (nx-lookup-target-uvector-subtag type-keyword ))
7590 (safe (unless *ppc2-reckless* fixtype))
7591 (dim0 (acode-fixnum-form-p dim0))
7592 (dim1 (acode-fixnum-form-p dim1)))
7593 (ppc2-aref2 seg vreg xfer arr i j safe type-keyword dim0 dim1))))
7594
7595
7596(defppc2 ppc2-general-aref2 general-aref2 (seg vreg xfer arr i j)
7597 (let* ((atype0 (acode-form-type arr t))
7598 (ctype (if atype0 (specifier-type atype0)))
7599 (atype (if (array-ctype-p ctype) ctype))
7600 (keyword (and atype
7601 (let* ((dims (array-ctype-dimensions atype)))
7602 (and (typep dims 'list)
7603 (= 2 (length dims))))
7604 (not (array-ctype-complexp atype))
7605 (funcall
7606 (arch::target-array-type-name-from-ctype-function
7607 (backend-target-arch *target-backend*))
7608 atype))))
7609 (cond (keyword
7610 (let* ((dims (array-ctype-dimensions atype))
7611 (dim0 (car dims))
7612 (dim1 (cadr dims)))
7613 (ppc2-aref2 seg
7614 vreg
7615 xfer
7616 arr
7617 i
7618 j
7619 (if *ppc2-reckless*
7620 *nx-nil*
7621 (nx-lookup-target-uvector-subtag keyword ))
7622 keyword ;(make-acode (%nx1-operator immediate) )
7623 (if (typep dim0 'fixnum) dim0) (if (typep dim1 'fixnum) dim1))))
7624 (t
7625 (ppc2-three-targeted-reg-forms seg
7626 arr ($ ppc::arg_x)
7627 i ($ ppc::arg_y)
7628 j ($ ppc::arg_z))
7629 (ppc2-fixed-call-builtin seg vreg xfer nil (subprim-name->offset '.SParef2))))) )
7630
7631
7632(defppc2 ppc2-%aref3 simple-typed-aref3 (seg vreg xfer typename arr i j k &optional dim0 dim1 dim2)
7633 (if (null vreg)
7634 (progn
7635 (ppc2-form seg nil nil arr)
7636 (ppc2-form seg nil nil i)
7637 (ppc2-form seg nil nil j)
7638 (ppc2-form seg nil xfer k)))
7639 (let* ((type-keyword (ppc2-immediate-operand typename))
7640 (fixtype (nx-lookup-target-uvector-subtag type-keyword ))
7641 (safe (unless *ppc2-reckless* fixtype))
7642 (dim0 (acode-fixnum-form-p dim0))
7643 (dim1 (acode-fixnum-form-p dim1))
7644 (dim2 (acode-fixnum-form-p dim2)))
7645 (ppc2-aref3 seg vreg xfer arr i j k safe type-keyword dim0 dim1 dim2)))
7646
7647(defppc2 ppc2-general-aref3 general-aref3 (seg vreg xfer arr i j k)
7648 (let* ((atype0 (acode-form-type arr t))
7649 (ctype (if atype0 (specifier-type atype0)))
7650 (atype (if (array-ctype-p ctype) ctype))
7651 (keyword (and atype
7652 (let* ((dims (array-ctype-dimensions atype)))
7653 (and (typep dims 'list)
7654 (= 3 (length dims))))
7655 (not (array-ctype-complexp atype))
7656 (funcall
7657 (arch::target-array-type-name-from-ctype-function
7658 (backend-target-arch *target-backend*))
7659 atype))))
7660 (cond (keyword
7661 (let* ((dims (array-ctype-dimensions atype))
7662 (dim0 (car dims))
7663 (dim1 (cadr dims))
7664 (dim2 (caddr dims)))
7665 (ppc2-aref3 seg
7666 vreg
7667 xfer
7668 arr
7669 i
7670 j
7671 k
7672 (if *ppc2-reckless*
7673 *nx-nil*
7674 (nx-lookup-target-uvector-subtag keyword ))
7675 keyword ;(make-acode (%nx1-operator immediate) )
7676 (if (typep dim0 'fixnum) dim0)
7677 (if (typep dim1 'fixnum) dim1)
7678 (if (typep dim2 'fixnum) dim2))))
7679 (t
7680 (ppc2-four-targeted-reg-forms seg
7681 arr ($ ppc::temp0)
7682 i ($ ppc::arg_x)
7683 j ($ ppc::arg_y)
7684 k ($ ppc::arg_z))
7685 (ppc2-fixed-call-builtin seg vreg xfer nil (subprim-name->offset '.SParef3))))))
7686
7687(defppc2 ppc2-%aset2 simple-typed-aset2 (seg vreg xfer typename arr i j new &optional dim0 dim1)
7688 (let* ((type-keyword (ppc2-immediate-operand typename))
7689 (fixtype (nx-lookup-target-uvector-subtag type-keyword ))
7690 (safe (unless *ppc2-reckless* fixtype))
7691 (dim0 (acode-fixnum-form-p dim0))
7692 (dim1 (acode-fixnum-form-p dim1)))
7693 (ppc2-aset2 seg vreg xfer arr i j new safe type-keyword dim0 dim1))
7694)
7695
7696(defppc2 ppc2-general-aset2 general-aset2 (seg vreg xfer arr i j new)
7697 (let* ((atype0 (acode-form-type arr t))
7698 (ctype (if atype0 (specifier-type atype0)))
7699 (atype (if (array-ctype-p ctype) ctype))
7700 (keyword (and atype
7701 (let* ((dims (array-ctype-dimensions atype)))
7702 (and (typep dims 'list)
7703 (= 2 (length dims))))
7704 (not (array-ctype-complexp atype))
7705 (funcall
7706 (arch::target-array-type-name-from-ctype-function
7707 (backend-target-arch *target-backend*))
7708 atype))))
7709 (cond (keyword
7710 (let* ((dims (array-ctype-dimensions atype))
7711 (dim0 (car dims))
7712 (dim1 (cadr dims)))
7713 (ppc2-aset2 seg
7714 vreg
7715 xfer
7716 arr
7717 i
7718 j
7719 new
7720 (unless *ppc2-reckless*
7721 (nx-lookup-target-uvector-subtag keyword ))
7722 keyword
7723 (if (typep dim0 'fixnum) dim0)
7724 (if (typep dim1 'fixnum) dim1))))
7725 (t
7726 (ppc2-four-targeted-reg-forms seg
7727 arr ($ ppc::temp0)
7728 i ($ ppc::arg_x)
7729 j ($ ppc::arg_y)
7730 new ($ ppc::arg_z))
7731 (ppc2-fixed-call-builtin seg vreg xfer nil (subprim-name->offset '.SPaset2))))))
7732
7733
7734(defppc2 ppc2-general-aset3 general-aset3 (seg vreg xfer arr i j k new)
7735 (let* ((atype0 (acode-form-type arr t))
7736 (ctype (if atype0 (specifier-type atype0)))
7737 (atype (if (array-ctype-p ctype) ctype))
7738 (keyword (and atype
7739 (let* ((dims (array-ctype-dimensions atype)))
7740 (unless (atom dims)
7741 (= 3 (length dims))))
7742 (not (array-ctype-complexp atype))
7743 (funcall
7744 (arch::target-array-type-name-from-ctype-function
7745 (backend-target-arch *target-backend*))
7746 atype))))
7747 (cond (keyword
7748 (let* ((dims (array-ctype-dimensions atype))
7749 (dim0 (car dims))
7750 (dim1 (cadr dims))
7751 (dim2 (caddr dims)))
7752 (ppc2-aset3 seg
7753 vreg
7754 xfer
7755 arr
7756 i
7757 j
7758 k
7759 new
7760 (unless *ppc2-reckless*
7761 (nx-lookup-target-uvector-subtag keyword ))
7762 keyword
7763 (if (typep dim0 'fixnum) dim0)
7764 (if (typep dim1 'fixnum) dim1)
7765 (if (typep dim2 'fixnum) dim2))))
7766 (t
7767 (ppc2-push-register seg (ppc2-one-untargeted-reg-form seg arr ($ ppc::arg_z)))
7768 (ppc2-four-targeted-reg-forms seg
7769 i ($ ppc::temp0)
7770 j ($ ppc::arg_x)
7771 k ($ ppc::arg_y)
7772 new ($ ppc::arg_z))
7773 (ppc2-pop-register seg ($ ppc::temp1))
7774 (ppc2-fixed-call-builtin seg vreg xfer nil (subprim-name->offset '.SPaset3))))))
7775
7776(defppc2 ppc2-%aset3 simple-typed-aset3 (seg vreg xfer typename arr i j k new &optional dim0 dim1 dim2)
7777 (let* ((type-keyword (ppc2-immediate-operand typename))
7778 (fixtype (nx-lookup-target-uvector-subtag type-keyword))
7779 (safe (unless *ppc2-reckless* fixtype))
7780 (dim0 (acode-fixnum-form-p dim0))
7781 (dim1 (acode-fixnum-form-p dim1))
7782 (dim2 (acode-fixnum-form-p dim2)))
7783 (ppc2-aset3 seg vreg xfer arr i j k new safe type-keyword dim0 dim1 dim2)))
7784
7785
7786
7787(defppc2 ppc2-%typed-uvref %typed-uvref (seg vreg xfer subtag uvector index)
7788 (let* ((type-keyword
7789 (let* ((fixtype (acode-fixnum-form-p subtag)))
7790 (if fixtype
7791 (nx-target-uvector-subtag-name fixtype)
7792 (ppc2-immediate-operand subtag)))))
7793 (if type-keyword
7794 (ppc2-vref seg vreg xfer type-keyword uvector index (unless *ppc2-reckless* (nx-lookup-target-uvector-subtag type-keyword)))
7795 (progn
7796 (ppc2-three-targeted-reg-forms seg subtag ($ ppc::arg_x) uvector ($ ppc::arg_y) index ($ ppc::arg_z))
7797 (! subtag-misc-ref)
7798 (when vreg (<- ($ ppc::arg_z)))
7799 (^)) )))
7800
7801(defppc2 ppc2-%typed-uvset %typed-uvset (seg vreg xfer subtag uvector index newval)
7802 (let* ((type-keyword
7803 (let* ((fixtype (acode-fixnum-form-p subtag)))
7804 (if fixtype
7805 (nx-target-uvector-subtag-name fixtype)
7806 (ppc2-immediate-operand subtag)))))
7807 (if type-keyword
7808 (ppc2-vset seg vreg xfer type-keyword uvector index newval (unless *ppc2-reckless* (nx-lookup-target-uvector-subtag type-keyword)))
7809 (progn
7810 (ppc2-four-targeted-reg-forms seg
7811 subtag ($ ppc::temp0)
7812 uvector ($ ppc::arg_x)
7813 index ($ ppc::arg_y)
7814 newval ($ ppc::arg_z))
7815
7816 (! subtag-misc-set)
7817 (when vreg (<- ($ ppc::arg_z)))
7818 (^)))))
7819
7820(defppc2 ppc2-%macptrptr% %macptrptr% (seg vreg xfer form)
7821 (with-imm-target () (target :address)
7822 (ppc2-one-targeted-reg-form seg form (or vreg target)))
7823 (^))
7824
7825
7826;;; cons a macptr, unless "vreg" is an immediate register of mode :address.
7827(defppc2 ppc2-%consmacptr% %consmacptr% (seg vreg xfer form)
7828 (cond ((null vreg) (ppc2-form seg nil xfer form))
7829 ((eql (get-regspec-mode vreg) hard-reg-class-gpr-mode-address)
7830 (ppc2-form seg vreg xfer form))
7831 (t
7832 (with-imm-target () (temp :address)
7833 (<- (ppc2-one-targeted-reg-form seg form temp))
7834 (^)))))
7835
7836(defppc2 ppc2-%immediate-ptr-to-int %immediate-ptr-to-int (seg vreg xfer form)
7837 (if (null vreg)
7838 (ppc2-form seg nil xfer form)
7839 (with-imm-target () (address-reg :address)
7840 (ppc2-form seg address-reg nil form)
7841 (<- (set-regspec-mode address-reg (gpr-mode-name-value :natural)))
7842 (^))))
7843
7844(defppc2 ppc2-%immediate-int-to-ptr %immediate-int-to-ptr (seg vreg xfer form)
7845 (if (null vreg)
7846 (ppc2-form seg nil xfer form)
7847 (progn
7848 (unless (logbitp (hard-regspec-value vreg) ppc-imm-regs)
7849 (error "I give up. When will I get this right ?"))
7850 (let* ((natural-reg (ppc2-one-targeted-reg-form seg
7851 form
7852 ($ vreg :mode :natural))))
7853 (<- natural-reg)
7854 (^)))))
7855
7856
7857(defppc2 ppc2-%function %function (seg vreg xfer sym)
7858 (when vreg
7859 (let* ((symreg (ppc2-one-untargeted-reg-form seg (make-acode (%nx1-operator immediate)
7860 (ppc2-symbol-entry-locative sym)) ppc::arg_z)))
7861 (with-node-temps (vreg symreg) (val)
7862 (! symbol-function val symreg)
7863 (<- val))))
7864 (^))
7865
7866(defppc2 ppc2-%unbound-marker %unbound-marker (seg vreg xfer)
7867 (when vreg
7868 (ensuring-node-target (target vreg)
7869 (ppc2-lri seg target (target-arch-case
7870 (:ppc32 ppc32::unbound-marker)
7871 (:ppc64 ppc64::unbound-marker)))))
7872 (^))
7873
7874(defppc2 ppc2-slot-unbound-marker %slot-unbound-marker (seg vreg xfer)
7875 (when vreg
7876 (ensuring-node-target (target vreg)
7877 (ppc2-lri seg target (target-arch-case
7878 (:ppc32 ppc32::slot-unbound-marker)
7879 (:ppc64 ppc64::slot-unbound-marker)))))
7880 (^))
7881
7882(defppc2 ppc2-illegal-marker %illegal-marker (seg vreg xfer)
7883 (when vreg
7884 (ensuring-node-target (target vreg)
7885 (ppc2-lri seg target (target-arch-case
7886 (:ppc32 ppc32::illegal-marker)
7887 (:ppc64 ppc64::illegal-marker)))))
7888 (^))
7889
7890(defppc2 ppc2-lambda-bind lambda-bind (seg vreg xfer vals req rest keys-p auxen body p2decls)
7891 (let* ((old-stack (ppc2-encode-stack))
7892 (nreq (list-length req))
7893 (rest-arg (nthcdr nreq vals))
7894 (apply-body (ppc2-eliminate-&rest body rest keys-p auxen rest-arg)))
7895 (ppc2-seq-bind seg req vals)
7896 (when apply-body (setq rest nil body apply-body))
7897 (let*
7898 ((vloc *ppc2-vstack*)
7899 (restloc vloc)
7900 (nvloc (progn (if (or rest keys-p) (ppc2-formlist seg rest-arg)) *ppc2-vstack*)))
7901 (with-ppc-p2-declarations p2decls
7902 (when rest
7903 (when keys-p
7904 (until (eq restloc nvloc)
7905 (with-node-temps () (temp)
7906 (ppc2-stack-to-register seg (ppc2-vloc-ea restloc) temp)
7907 (ppc2-vpush-register seg temp))
7908 (setq restloc (%i+ restloc *ppc2-target-node-size*))))
7909 (ppc2-set-nargs seg (length rest-arg))
7910 (ppc2-set-vstack restloc)
7911 (if (%ilogbitp $vbitdynamicextent (nx-var-bits rest))
7912 (progn
7913 (! stack-cons-list)
7914 (ppc2-open-undo $undostkblk))
7915 (! list))
7916 (ppc2-vpush-register seg ppc::arg_z))
7917 (when rest (ppc2-bind-var seg rest restloc))
7918 (destructuring-bind (vars inits) auxen
7919 (while vars
7920 (let ((val (%car inits)))
7921 (if (fixnump val)
7922 (progn
7923 (when rest (setq val (%i+ (%i+ val val) 1)))
7924 (ppc2-bind-var seg (%car vars) (%i+ vloc (* val *ppc2-target-node-size*))))
7925 (ppc2-seq-bind-var seg (%car vars) val)))
7926 (setq vars (%cdr vars) inits (%cdr inits))))
7927 (ppc2-undo-body seg vreg xfer body old-stack)
7928 (dolist (var req) (ppc2-close-var seg var))
7929 (when rest (ppc2-close-var seg rest))
7930 (dolist (var (%car auxen)) (ppc2-close-var seg var))))))
7931
7932(macrolet
7933 ((def-ppc2-require (function op &optional (vinsn op))
7934 `(defppc2 ,function ,op (seg vreg xfer val)
7935 (let* ((val-reg (ppc2-one-untargeted-reg-form
7936 seg
7937 val
7938 (if (eq vreg ppc::arg_z) ppc::arg_y ppc::arg_z))))
7939 (! ,vinsn val-reg)
7940 (when vreg (<- val-reg))
7941 (^)))))
7942 (def-ppc2-require ppc2-require-simple-vector require-simple-vector)
7943 (def-ppc2-require ppc2-require-simple-string require-simple-string)
7944 (def-ppc2-require ppc2-require-integer require-integer)
7945 (def-ppc2-require ppc2-require-fixnum require-fixnum)
7946 (def-ppc2-require ppc2-require-real require-real)
7947 (def-ppc2-require ppc2-require-list require-list)
7948 (def-ppc2-require ppc2-require-character require-character)
7949 (def-ppc2-require ppc2-require-number require-number)
7950 (def-ppc2-require ppc2-require-symbol require-symbol)
7951 (def-ppc2-require ppc2-require-s8 require-s8)
7952 (def-ppc2-require ppc2-require-s8 require-u8)
7953 (def-ppc2-require ppc2-require-s8 require-s16)
7954 (def-ppc2-require ppc2-require-s8 require-u16)
7955 (def-ppc2-require ppc2-require-s8 require-s32)
7956 (def-ppc2-require ppc2-require-s8 require-u32)
7957 (def-ppc2-require ppc2-require-s8 require-s64)
7958 (def-ppc2-require ppc2-require-s8 require-u64))
7959
7960(defppc2 ppc2-%badarg2 %badarg2 (seg vreg xfer badthing goodthing)
7961 (ppc2-two-targeted-reg-forms seg badthing ($ ppc::arg_y) goodthing ($ ppc::arg_z))
7962 (ppc2-lri seg ($ ppc::arg_x) (ash $XWRONGTYPE *ppc2-target-fixnum-shift*))
7963 (ppc2-set-nargs seg 3)
7964 (! ksignalerr)
7965 (<- nil)
7966 (^))
7967
7968(defppc2 ppc2-%set-sbchar %set-sbchar (seg vreg xfer string index value)
7969 (ppc2-vset
7970 seg
7971 vreg
7972 xfer
7973 :simple-string
7974 string
7975 index
7976 value
7977 (unless *ppc2-reckless* (nx-lookup-target-uvector-subtag :simple-string))))
7978
7979
7980;;; If we didn't use this for stack consing, turn it into a call. Ugh.
7981
7982(defppc2 ppc2-make-list make-list (seg vreg xfer size initial-element)
7983 (ppc2-form seg vreg xfer (make-acode (%nx1-operator call)
7984 (make-acode (%nx1-operator immediate) 'make-list)
7985 (list nil
7986 (list initial-element
7987 (make-acode (%nx1-operator immediate)
7988 :initial-element)
7989 size)))))
7990
7991
7992(defppc2 ppc2-setq-free setq-free (seg vreg xfer sym val)
7993 (let* ((rsym ($ ppc::arg_y))
7994 (rval ($ ppc::arg_z)))
7995 (ppc2-one-targeted-reg-form seg val rval)
7996 (ppc2-immediate seg rsym nil (ppc2-symbol-value-cell sym))
7997 (! setqsym)
7998 (<- rval)
7999 (^)))
8000
8001(defppc2 ppc2-%setf-macptr %setf-macptr (seg vreg xfer x y)
8002 (ppc2-vpush-register seg (ppc2-one-untargeted-reg-form seg x ppc::arg_z))
8003 (with-imm-target () (src-reg :address)
8004 (ppc2-one-targeted-reg-form seg y src-reg)
8005 (ppc2-vpop-register seg ppc::arg_z)
8006 (unless (or *ppc2-reckless* (ppc2-form-typep x 'macptr))
8007 (with-imm-temps (src-reg) ()
8008 (! trap-unless-macptr ppc::arg_z)))
8009 (! set-macptr-address src-reg ppc::arg_z)
8010 (<- ppc::arg_z)
8011 (^)))
8012
8013(defppc2 ppc2-%setf-double-float %setf-double-float (seg vref xfer fnode fval)
8014 (ppc2-vpush-register seg (ppc2-one-untargeted-reg-form seg fnode ppc::arg_z))
8015 (let* ((target ($ ppc::fp1 :class :fpr :mode :double-float))
8016 (node ($ ppc::arg_z)))
8017 (ppc2-one-targeted-reg-form seg fval target)
8018 (ppc2-vpop-register seg node)
8019 (unless (or *ppc2-reckless* (ppc2-form-typep fnode 'double-float))
8020 (! trap-unless-double-float node))
8021 (! store-double node target)
8022 (<- node)
8023 (^)))
8024
8025(defppc2 ppc2-%setf-short-float %setf-short-float (seg vreg xfer fnode fval)
8026 (ppc2-vpush-register seg (ppc2-one-untargeted-reg-form seg fnode ppc::arg_z))
8027 (let* ((target ($ ppc::fp1 :class :fpr :mode :single-float))
8028 (freg ($ ppc::arg_z)))
8029 (ppc2-one-targeted-reg-form seg fval target)
8030 (ppc2-vpop-register seg freg)
8031 (unless (or *ppc2-reckless* (ppc2-form-typep fnode 'short-float))
8032 (! trap-unless-single-float freg))
8033 (! store-single freg target)
8034 (<- freg)
8035 (^)))
8036
8037
8038
8039(defppc2 ppc2-unwind-protect unwind-protect (seg vreg xfer protected-form cleanup-form)
8040 (let* ((cleanup-label (backend-get-next-label))
8041 (protform-label (backend-get-next-label))
8042 (old-stack (ppc2-encode-stack))
8043 (ilevel '*interrupt-level*))
8044 (! nmkunwind)
8045 (ppc2-open-undo $undointerruptlevel)
8046 (ppc2-new-vstack-lcell :special-value *ppc2-target-lcell-size* 0 ilevel)
8047 (ppc2-new-vstack-lcell :special *ppc2-target-lcell-size* (ash 1 $vbitspecial) ilevel)
8048 (ppc2-new-vstack-lcell :special-link *ppc2-target-lcell-size* 0 ilevel)
8049 (ppc2-adjust-vstack (* 3 *ppc2-target-node-size*))
8050 (! non-barrier-jump (aref *backend-labels* cleanup-label))
8051 (-> protform-label)
8052 (@ cleanup-label)
8053 (let* ((*ppc2-vstack* *ppc2-vstack*)
8054 (*ppc2-top-vstack-lcell* *ppc2-top-vstack-lcell*)
8055 (*ppc2-cstack* (%i+ *ppc2-cstack* (target-arch-case
8056 (:ppc32 ppc32::lisp-frame.size)
8057 (:ppc64 ppc64::lisp-frame.size)))))
8058 (ppc2-open-undo $undostkblk) ; tsp frame created by nthrow.
8059 (! save-cleanup-context)
8060 (setq *ppc2-cstack* (%i+ *ppc2-cstack*
8061 (target-arch-case
8062 (:ppc32 ppc32::lisp-frame.size)
8063 (:ppc64 ppc64::lisp-frame.size)))) ; the frame we just pushed
8064 (ppc2-form seg nil nil cleanup-form)
8065 (ppc2-close-undo)
8066 (! restore-cleanup-context)
8067 (! jump-return-pc)) ; blr
8068 (ppc2-open-undo)
8069 (@ protform-label)
8070 (ppc2-new-vstack-lcell :special-value *ppc2-target-lcell-size* 0 ilevel)
8071 (ppc2-new-vstack-lcell :special *ppc2-target-lcell-size* (ash 1 $vbitspecial) ilevel)
8072 (ppc2-new-vstack-lcell :special-link *ppc2-target-lcell-size* 0 ilevel)
8073 (ppc2-adjust-vstack (* 3 *ppc2-target-node-size*))
8074
8075 (ppc2-undo-body seg vreg xfer protected-form old-stack)))
8076
8077(defppc2 ppc2-progv progv (seg vreg xfer symbols values body)
8078 (let* ((cleanup-label (backend-get-next-label))
8079 (protform-label (backend-get-next-label))
8080 (old-stack (ppc2-encode-stack)))
8081 (ppc2-two-targeted-reg-forms seg symbols ($ ppc::arg_y) values ($ ppc::arg_z))
8082 (! progvsave)
8083 (ppc2-open-undo $undostkblk)
8084 (! mkunwind)
8085 (! non-barrier-jump (aref *backend-labels* cleanup-label))
8086 (-> protform-label)
8087 (@ cleanup-label)
8088 (! progvrestore)
8089 (ppc2-open-undo)
8090 (@ protform-label)
8091 (ppc2-undo-body seg vreg xfer body old-stack)))
8092
8093(defppc2 ppc2-%ptr-eql %ptr-eql (seg vreg xfer cc x y )
8094 (if (null vreg)
8095 (progn
8096 (ppc2-form seg nil nil x)
8097 (ppc2-form seg nil xfer y))
8098 (let* ((x-abs (acode-absolute-ptr-p x t))
8099 (y-abs (acode-absolute-ptr-p y t))
8100 (abs (or x-abs y-abs))
8101 (other (if abs (if x-abs y x))))
8102 (multiple-value-bind (cr-bit true-p) (acode-condition-to-ppc-cr-bit cc)
8103 (if other
8104 (with-imm-target () (other-target :address)
8105 (ppc2-one-targeted-reg-form seg other other-target)
8106 (if (typep abs '(signed-byte 16))
8107 (ppc2-test-reg-%izerop seg vreg xfer other-target cr-bit true-p abs)
8108 (with-imm-temps (other-target) ((abs-target :address))
8109 (use-imm-temp other-target)
8110 (ppc2-lri seg abs-target abs)
8111 (ppc2-compare-registers seg vreg xfer other-target abs-target cr-bit true-p))))
8112 ; Neither expression is obviously a constant-valued macptr.
8113 (with-imm-target () (target-a :address)
8114 (ppc2-one-targeted-reg-form seg x target-a)
8115 (! temp-push-unboxed-word target-a)
8116 (ppc2-open-undo $undostkblk)
8117 (ppc2-one-targeted-reg-form seg y target-a)
8118 (with-imm-target (target-a) (target-b :address)
8119 (! temp-pop-unboxed-word target-b)
8120 (ppc2-close-undo)
8121 (ppc2-compare-registers seg vreg xfer target-b target-a cr-bit true-p))))))))
8122
8123(defppc2 ppc2-set-bit %set-bit (seg vreg xfer ptr offset newval)
8124 (let* ((offval (acode-fixnum-form-p offset))
8125 (byte-index (if offval (ash offval -3)))
8126 (bit-index (if (and byte-index (< byte-index #x8000))
8127 (logand offval #x7)))
8128 (triv-offset (ppc2-trivial-p offset))
8129 (triv-val (ppc2-trivial-p newval)))
8130 (with-imm-target ()
8131 (src :address)
8132 (ppc2-one-targeted-reg-form seg ptr src)
8133 (if bit-index
8134 (let* ((mask-start (logand 31 (+ bit-index 25)))
8135 (mask-end (logand 31 (+ bit-index 23)))
8136 (mask (ash #x80 (- bit-index)))
8137 (constval (acode-fixnum-form-p newval)))
8138 (if constval
8139 (progn
8140 (if (eql constval 0)
8141 (! mem-set-c-bit-0 src byte-index mask-start mask-end)
8142 (! mem-set-c-bit-1 src byte-index mask))
8143 (when vreg
8144 (ppc2-form seg vreg nil newval)))
8145 (progn
8146 (unless triv-val
8147 (! temp-push-unboxed-word src)
8148 (ppc2-open-undo $undostkblk))
8149 (let* ((target (ppc2-one-untargeted-reg-form seg newval ppc::arg_z)))
8150 (unless triv-val
8151 (! temp-pop-unboxed-word src)
8152 (ppc2-close-undo))
8153 (! mem-set-c-bit src byte-index (+ 24 bit-index) target)
8154 (<- target)))))
8155 (progn
8156 (unless (and triv-val triv-offset)
8157 (! temp-push-unboxed-word src)
8158 (ppc2-open-undo $undostkblk))
8159 (multiple-value-bind (idx-reg val-reg)
8160 (ppc2-two-untargeted-reg-forms seg offset ppc::arg_y newval ppc::arg_z)
8161 (unless (and triv-val triv-offset)
8162 (! temp-pop-unboxed-word src)
8163 (ppc2-close-undo ))
8164 (! mem-set-bit src idx-reg val-reg)
8165 (<- val-reg)))))
8166 (^)))
8167
8168(defppc2 ppc2-%immediate-set-xxx %immediate-set-xxx (seg vreg xfer bits ptr offset val)
8169 (ppc2-%immediate-store seg vreg xfer bits ptr offset val))
8170
8171
8172
8173(defppc2 ppc2-%immediate-inc-ptr %immediate-inc-ptr (seg vreg xfer ptr by)
8174 (let* ((triv-by (ppc2-trivial-p by))
8175 (fixnum-by (acode-fixnum-form-p by)))
8176 (if (and fixnum-by (eql 0 fixnum-by))
8177 (ppc2-form seg vreg xfer ptr)
8178 (with-imm-target (vreg) (ptr-reg :address)
8179 (ppc2-one-targeted-reg-form seg ptr ptr-reg)
8180 (if fixnum-by
8181 (with-imm-target (vreg ptr-reg) (result :address)
8182 (let* ((high (ldb (byte 16 16) fixnum-by))
8183 (low (ldb (byte 16 0) fixnum-by)))
8184 (declare (type (unsigned-byte 16) high low))
8185 (if (logbitp 15 low) (incf high))
8186 (! add-immediate result ptr-reg high low)
8187 (<- result)))
8188 (progn
8189 (unless triv-by
8190 (! temp-push-unboxed-word ptr-reg)
8191 (ppc2-open-undo $undostkblk))
8192 (with-imm-target (vreg ptr-reg) (by-reg :s32)
8193 (ppc2-one-targeted-reg-form seg by by-reg)
8194 (unless triv-by
8195 (! temp-pop-unboxed-word ptr-reg)
8196 (ppc2-close-undo))
8197 (with-imm-target (vreg ptr-reg by-reg) (result :address)
8198 (! fixnum-add result ptr-reg by-reg)
8199 (<- result)))))
8200 (^)))))
8201
8202
8203
8204(defppc2 ppc2-multiple-value-call multiple-value-call (seg vreg xfer fn arglist)
8205 (ppc2-mvcall seg vreg xfer fn arglist))
8206
8207
8208
8209(defppc2 ppc2-eabi-syscall eabi-syscall (seg vreg xfer idx argspecs argvals resultspec &optional monitor-exception-ports)
8210 (declare (ignore monitor-exception-ports))
8211 (let* ((*ppc2-vstack* *ppc2-vstack*)
8212 (*ppc2-top-vstack-lcell* *ppc2-top-vstack-lcell*)
8213 (*ppc2-cstack* *ppc2-cstack*)
8214 (nextarg 0))
8215 (declare (fixnum nextarg))
8216 (! alloc-eabi-c-frame (the fixnum (length argvals)))
8217 (ppc2-open-undo $undo-ppc-c-frame)
8218 ;; Evaluate each form into the C frame, according to the matching argspec.
8219 (do* ((specs argspecs (cdr specs))
8220 (vals argvals (cdr vals)))
8221 ((null specs))
8222 (declare (list specs vals))
8223 (let* ((valform (car vals))
8224 (spec (car specs))
8225 (absptr (acode-absolute-ptr-p valform)))
8226 (case spec
8227 (:address
8228 (with-imm-target ()
8229 (ptr :address)
8230 (if absptr
8231 (ppc2-lri seg ptr absptr)
8232 (ppc2-one-targeted-reg-form seg valform ptr))
8233 (! set-eabi-c-arg ptr nextarg)))
8234 (t
8235 (! set-eabi-c-arg
8236 (with-imm-target ()
8237 (valreg :natural)
8238 (ppc2-unboxed-integer-arg-to-reg seg valform valreg spec))
8239 nextarg)))
8240 (incf nextarg)))
8241 (ppc2-form seg ppc::arg_z nil idx)
8242 (! eabi-syscall)
8243 (ppc2-close-undo)
8244 (when vreg
8245 (if (eq resultspec :void)
8246 (<- nil)
8247 (<- (set-regspec-mode ppc::imm0 (gpr-mode-name-value
8248 (case resultspec
8249 (:address :address)
8250 (:signed-byte :s8)
8251 (:unsigned-byte :u8)
8252 (:signed-halfword :s16)
8253 (:unsigned-halfword :u16)
8254 (:signed-fullword :s32)
8255 (t :u32)))))))
8256 (^)))
8257
8258
8259;;; Caller has allocated poweropen stack frame.
8260(defun ppc2-poweropen-foreign-args (seg argspecs argvals)
8261 (with-ppc-local-vinsn-macros (seg)
8262 (let* ((fp-loads ())
8263 (nextarg 0)
8264 (return-registers nil))
8265 ;; Evaluate each form into the C frame, according to the matching
8266 ;; argspec. Remember type and arg offset of any FP args, since FP
8267 ;; regs will have to be loaded later.
8268 (do* ((specs argspecs (cdr specs))
8269 (vals argvals (cdr vals)))
8270 ((null specs) (if return-registers (ppc2-pop-register seg ($ ppc::arg_y))))
8271 (declare (list specs vals))
8272 (let* ((valform (car vals))
8273 (spec (car specs))
8274 (longval (ppc2-long-constant-p valform))
8275 (absptr (acode-absolute-ptr-p valform)))
8276 (case spec
8277 (:registers
8278 (setq return-registers t)
8279 (ppc2-push-register seg (ppc2-one-untargeted-reg-form seg valform ppc::arg_z)))
8280 ((:signed-doubleword :unsigned-doubleword :hybrid-int-float :hybrid-float-float :hybrid-float-int)
8281
8282 (ppc2-one-targeted-reg-form seg valform ($ ppc::arg_z))
8283 (if (eq spec :signed-doubleword)
8284 (! gets64)
8285 (! getu64))
8286 (! set-c-arg ($ ppc::imm0) nextarg)
8287 (target-arch-case
8288 (:ppc32
8289 (incf nextarg)
8290 (! set-c-arg ($ ppc::imm1) nextarg))
8291 (:ppc64
8292 (case spec
8293 (:hybrid-int-float (push (cons :single-float nextarg) fp-loads))
8294 (:hybrid-float-int (push (cons :single-float-high nextarg) fp-loads))
8295 (:hybrid-float-float
8296 (push (cons :single-float-high nextarg) fp-loads)
8297 (push (cons :single-float nextarg) fp-loads))))))
8298 (:double-float
8299 (let* ((df ($ ppc::fp1 :class :fpr :mode :double-float)))
8300 (ppc2-one-targeted-reg-form seg valform df)
8301 (! set-double-c-arg df nextarg)
8302 (push (cons :double-float nextarg) fp-loads)
8303 (target-word-size-case
8304 (32 (incf nextarg))
8305 (64))))
8306 (:single-float
8307 (let* ((sf ($ ppc::fp1 :class :fpr :mode :single-float)))
8308 (ppc2-one-targeted-reg-form seg valform sf)
8309 (! set-single-c-arg sf nextarg)
8310 (push (cons :single-float nextarg) fp-loads)))
8311 (:address
8312 (with-imm-target ()
8313 (ptr :address)
8314 (if absptr
8315 (ppc2-lri seg ptr absptr)
8316 (ppc2-one-targeted-reg-form seg valform ptr))
8317 (! set-c-arg ptr nextarg)))
8318 (t
8319 (if (typep spec 'unsigned-byte)
8320 (progn
8321 (with-imm-target () (ptr :address)
8322 (ppc2-one-targeted-reg-form seg valform ptr)
8323 (with-imm-temps (ptr) (r)
8324 (dotimes (i spec)
8325 (target-arch-case
8326 (:ppc32
8327 (! mem-ref-c-fullword r ptr (ash i ppc32::word-shift)))
8328 (:ppc64
8329 (! mem-ref-c-doubleword r ptr (ash i ppc64::word-shift))))
8330 (! set-c-arg r nextarg)
8331 (incf nextarg))))
8332 (decf nextarg))
8333 (with-imm-target ()
8334 (valreg :natural)
8335 (let* ((reg valreg))
8336 (if longval
8337 (ppc2-lri seg valreg longval)
8338 (setq reg (ppc2-unboxed-integer-arg-to-reg seg valform valreg spec)))
8339 (! set-c-arg reg nextarg))))))
8340 (unless (eq spec :registers)(incf nextarg))))
8341 (do* ((fpreg ppc::fp1 (1+ fpreg))
8342 (reloads (nreverse fp-loads) (cdr reloads)))
8343 ((or (null reloads) (= fpreg ppc::fp14)))
8344 (declare (list reloads) (fixnum fpreg))
8345 (let* ((reload (car reloads))
8346 (size (car reload))
8347 (from (cdr reload)))
8348 (if (eq size :double-float)
8349 (! reload-double-c-arg fpreg from)
8350 (if (eq size :single-float-high)
8351 (! reload-single-c-arg-high fpreg from)
8352 (! reload-single-c-arg fpreg from)))))
8353 return-registers)))
8354
8355(defun ppc2-poweropen-foreign-return (seg vreg xfer resultspec)
8356 (with-ppc-local-vinsn-macros (seg vreg xfer)
8357 (when vreg
8358 (cond ((eq resultspec :void) (<- nil))
8359 ((eq resultspec :double-float)
8360 (<- ($ ppc::fp1 :class :fpr :mode :double-float)))
8361 ((eq resultspec :single-float)
8362 (<- ($ ppc::fp1 :class :fpr :mode :single-float)))
8363 ((eq resultspec :unsigned-doubleword)
8364 (ensuring-node-target
8365 (target vreg)
8366 (! makeu64)
8367 (ppc2-copy-register seg target ppc::arg_z)))
8368 ((eq resultspec :signed-doubleword)
8369 (ensuring-node-target
8370 (target vreg)
8371 (! makes64)
8372 (ppc2-copy-register seg target ppc::arg_z)))
8373 (t
8374 (<- (make-wired-lreg ppc::imm0
8375 :mode
8376 (gpr-mode-name-value
8377 (case resultspec
8378 (:address :address)
8379 (:signed-byte :s8)
8380 (:unsigned-byte :u8)
8381 (:signed-halfword :s16)
8382 (:unsigned-halfword :u16)
8383 (:signed-fullword :s32)
8384 (t :u32))))))))
8385
8386 (^)))
8387
8388(defppc2 ppc2-poweropen-syscall poweropen-syscall (seg vreg xfer idx argspecs argvals resultspec &optional monitor-exception-ports)
8389 (declare (ignore monitor-exception-ports))
8390 (let* ((*ppc2-vstack* *ppc2-vstack*)
8391 (*ppc2-top-vstack-lcell* *ppc2-top-vstack-lcell*)
8392 (*ppc2-cstack* *ppc2-cstack*))
8393 (declare (fixnum nextarg))
8394 (! alloc-c-frame (the fixnum
8395 (+ (the fixnum (length argvals))
8396 (the fixnnum
8397 (let* ((n 0))
8398 (declare (fixnum n))
8399 (dolist (spec argspecs n)
8400 (if (typep spec 'unsigned-byte)
8401 (incf n (the fixnum
8402 (1- (the fixnum spec))))))))
8403 (the fixnum
8404 (count-if
8405 #'(lambda (x)
8406 (member x
8407 '(:double-float
8408 :unsigned-doubleword
8409 :signed-doubleword)))
8410 argspecs)))))
8411 (ppc2-open-undo $undo-ppc-c-frame)
8412 (ppc2-poweropen-foreign-args seg argspecs argvals)
8413 (ppc2-form seg ppc::arg_z nil idx)
8414 (if (eq resultspec :signed-doubleword)
8415 (! poweropen-syscall-s64)
8416 (! poweropen-syscall))
8417 (ppc2-close-undo)
8418 (ppc2-poweropen-foreign-return seg vreg xfer resultspec)))
8419
8420(defun ppc2-identity (seg vreg xfer arg)
8421 (with-ppc-local-vinsn-macros (seg vreg xfer)
8422 (if (null vreg)
8423 (ppc2-form seg vreg xfer arg)
8424 (progn
8425 (ensuring-node-target (target vreg)
8426 (ppc2-one-targeted-reg-form seg arg target))
8427 (^)))))
8428
8429;;; Outgoing C stack frame will look like:
8430;;; backptr
8431;;; NIL ; marker to keep GC happy, make GDB unhappy.
8432;;; 8 words of GPR arg vals - will be loaded & popped by subprim
8433;;; N words of "other" (overflow) arguments
8434;;; F words of single-float values, to be loaded into FPR before subprim call
8435;;; D aligned doublewords of double-float values, to be loaded into FPR before call.
8436(defppc2 ppc2-eabi-ff-call eabi-ff-call (seg vreg xfer address argspecs argvals resultspec &optional monitor)
8437 (declare (ignore monitor))
8438 (let* ((*ppc2-vstack* *ppc2-vstack*)
8439 (*ppc2-top-vstack-lcell* *ppc2-top-vstack-lcell*)
8440 (*ppc2-cstack* *ppc2-cstack*)
8441 (gpr-offset 0)
8442 (other-offset 8)
8443 (single-float-offset 8)
8444 (double-float-offset 8)
8445 (nsingle-floats 0) ; F
8446 (ndouble-floats 0) ; D
8447 (nother-words 0)
8448 (nfpr-args 0)
8449 (ngpr-args 0)
8450 (fp-loads ()))
8451 (declare (fixnum nshort-floats ndouble-floats nfpr-args ngpr-args narg-words
8452 gpr-offset other-offset single-float-offset double-float-offset))
8453 (dolist (argspec argspecs)
8454 (case argspec
8455 (:double-float (incf nfpr-args)
8456 (if (<= nfpr-args 8)
8457 (incf ndouble-floats)
8458 (progn
8459 (if (oddp nother-words)
8460 (incf nother-words))
8461 (incf nother-words 2))))
8462 (:single-float (incf nfpr-args)
8463 (if (<= nfpr-args 8)
8464 (incf nsingle-floats)
8465 (progn
8466 (if (oddp nother-words)
8467 (incf nother-words))
8468 (incf nother-words 2))))
8469 ((:unsigned-doubleword :signed-doubleword)
8470 (setq ngpr-args (logior 1 ngpr-args))
8471 (incf ngpr-args 2)
8472 (when (> ngpr-args 9)
8473 (if (oddp nother-words)
8474 (incf nother-words))
8475 (incf nother-words 2)))
8476 (t (incf ngpr-args)
8477 (if (> ngpr-args 8)
8478 (incf nother-words)))))
8479 (let* ((single-words (+ 8 nother-words nsingle-floats))
8480 (total-words (if (zerop ndouble-floats)
8481 single-words
8482 (+ (the fixnum (+ ndouble-floats ndouble-floats))
8483 (the fixnum (logand (lognot 1) (the fixnum (1+ single-words))))))))
8484
8485 (! alloc-eabi-c-frame total-words))
8486 (setq single-float-offset (+ other-offset nother-words))
8487 (setq double-float-offset
8488 (logand (lognot 1)
8489 (the fixnum (1+ (the fixnum (+ single-float-offset nsingle-floats))))))
8490 (setq ngpr-args 0 nfpr-args 0)
8491 (ppc2-open-undo $undo-ppc-c-frame)
8492 (ppc2-vpush-register seg (ppc2-one-untargeted-reg-form seg address ppc::arg_z))
8493 ;; Evaluate each form into the C frame, according to the
8494 ;; matching argspec.
8495 ;; Remember type and arg offset of any FP args, since FP regs
8496 ;; will have to be loaded later.
8497 (do* ((specs argspecs (cdr specs))
8498 (vals argvals (cdr vals)))
8499 ((null specs))
8500 (declare (list specs vals))
8501 (let* ((valform (car vals))
8502 (spec (car specs))
8503 (absptr (acode-absolute-ptr-p valform)))
8504 (case spec
8505 (:double-float
8506 (let* ((df ($ ppc::fp1 :class :fpr :mode :double-float)))
8507 (incf nfpr-args)
8508 (ppc2-one-targeted-reg-form seg valform df )
8509 (cond ((<= nfpr-args 8)
8510 (! set-double-eabi-c-arg df double-float-offset)
8511 (push (cons :double-float double-float-offset) fp-loads)
8512 (incf double-float-offset 2))
8513 (t
8514 (setq other-offset (logand (lognot 1) (the fixnum (1+ other-offset))))
8515 (! set-double-eabi-c-arg df other-offset)
8516 (incf other-offset 2)))))
8517 (:single-float
8518 (let* ((sf ($ ppc::fp1 :class :fpr :mode :single-float)))
8519 (incf nfpr-args)
8520 (ppc2-one-targeted-reg-form
8521 seg valform sf)
8522 (cond ((<= nfpr-args 8)
8523 (! set-single-eabi-c-arg sf single-float-offset)
8524 (push (cons :single-float single-float-offset) fp-loads)
8525 (incf single-float-offset))
8526 (t
8527 (setq other-offset (logand (lognot 1) (the fixnum (1+ other-offset))))
8528 (! set-double-eabi-c-arg sf other-offset)
8529 (incf other-offset 2)))))
8530 ((:signed-doubleword :unsigned-doubleword)
8531 (ppc2-one-targeted-reg-form seg valform ($ ppc::arg_z))
8532 (if (eq spec :signed-doubleword)
8533 (! gets64)
8534 (! getu64))
8535 (if (oddp ngpr-args)
8536 (incf ngpr-args))
8537 (incf ngpr-args 2)
8538 (if (oddp gpr-offset)
8539 (incf gpr-offset))
8540 (cond ((<= ngpr-args 8)
8541 (! set-eabi-c-arg ($ ppc::imm0) gpr-offset)
8542 (incf gpr-offset)
8543 (! set-eabi-c-arg ($ ppc::imm1) gpr-offset)
8544 (incf gpr-offset))
8545 (t
8546 (if (oddp other-offset)
8547 (incf other-offset))
8548 (! set-eabi-c-arg ($ ppc::imm0) other-offset)
8549 (incf other-offset)
8550 (! set-eabi-c-arg ($ ppc::imm1) other-offset)
8551 (incf other-offset))))
8552 (:address
8553 (with-imm-target () (ptr :address)
8554 (if absptr
8555 (ppc2-lri seg ptr absptr)
8556 (ppc2-form seg ptr nil valform))
8557 (incf ngpr-args)
8558 (cond ((<= ngpr-args 8)
8559 (! set-eabi-c-arg ptr gpr-offset)
8560 (incf gpr-offset))
8561 (t
8562 (! set-eabi-c-arg ptr other-offset)
8563 (incf other-offset)))))
8564 (t
8565 (with-imm-target () (valreg :natural)
8566 (let* ((reg (ppc2-unboxed-integer-arg-to-reg seg valform valreg spec)))
8567 (incf ngpr-args)
8568 (cond ((<= ngpr-args 8)
8569 (! set-eabi-c-arg reg gpr-offset)
8570 (incf gpr-offset))
8571 (t
8572 (! set-eabi-c-arg reg other-offset)
8573 (incf other-offset)))))))))
8574 (do* ((fpreg ppc::fp1 (1+ fpreg))
8575 (reloads (nreverse fp-loads) (cdr reloads)))
8576 ((or (null reloads) (= fpreg ppc::fp14)))
8577 (declare (list reloads) (fixnum fpreg))
8578 (let* ((reload (car reloads))
8579 (size (car reload))
8580 (from (cdr reload)))
8581 (if (eq size :double-float)
8582 (! reload-double-eabi-c-arg ($ fpreg :class :fpr :mode :double-float) from)
8583 (! reload-single-eabi-c-arg ($ fpreg :class :fpr :mode :single-float) from))))
8584 (ppc2-vpop-register seg ($ ppc::arg_z))
8585 (! eabi-ff-call)
8586 (ppc2-close-undo)
8587 (when vreg
8588 (cond ((eq resultspec :void) (<- nil))
8589 ((eq resultspec :double-float)
8590 (<- ($ ppc::fp1 :class :fpr :mode :double-float)))
8591 ((eq resultspec :single-float)
8592 (<- ($ ppc::fp1 :class :fpr :mode :single-float)))
8593 ((eq resultspec :unsigned-doubleword)
8594 (ensuring-node-target (target vreg)
8595 (! makeu64)
8596 (ppc2-copy-register seg target ppc::arg_z)))
8597 ((eq resultspec :signed-doubleword)
8598 (ensuring-node-target (target vreg)
8599 (! makes64)
8600 (ppc2-copy-register seg target ppc::arg_z)))
8601 (t
8602 (<- (make-wired-lreg ppc::imm0
8603 :mode
8604 (gpr-mode-name-value
8605 (case resultspec
8606 (:address :address)
8607 (:signed-byte :s8)
8608 (:unsigned-byte :u8)
8609 (:signed-halfword :s16)
8610 (:unsigned-halfword :u16)
8611 (:signed-fullword :s32)
8612 (t :u32))))))))
8613 (^)))
8614
8615(defppc2 ppc2-poweropen-ff-call poweropen-ff-call (seg vreg xfer address argspecs argvals resultspec &optional monitor-exception-ports)
8616 (let* ((*ppc2-vstack* *ppc2-vstack*)
8617 (*ppc2-top-vstack-lcell* *ppc2-top-vstack-lcell*)
8618 (*ppc2-cstack* *ppc2-cstack*)
8619 (return-registers nil))
8620 (declare (fixnum nextarg))
8621 (! alloc-c-frame (the fixnum
8622 (+ (the fixnum (length argvals))
8623 (the fixnnum
8624 (let* ((n 0))
8625 (declare (fixnum n))
8626 (dolist (spec argspecs n)
8627 (if (typep spec 'unsigned-byte)
8628 (incf n (the fixnum
8629 (1- (the fixnum spec))))))))
8630 (the fixnum
8631 (count-if
8632 #'(lambda (x)
8633 (member x
8634 '(:double-float
8635 :unsigned-doubleword
8636 :signed-doubleword)))
8637 argspecs)))))
8638 (ppc2-open-undo $undo-ppc-c-frame)
8639 (ppc2-vpush-register seg (ppc2-one-untargeted-reg-form seg address ppc::arg_z))
8640 (setq return-registers (ppc2-poweropen-foreign-args seg argspecs argvals))
8641 (ppc2-vpop-register seg ppc::arg_z)
8642 (if return-registers
8643 (! poweropen-ff-call-regs)
8644 (if monitor-exception-ports
8645 (! poweropen-ff-callX)
8646 (! poweropen-ff-call)))
8647 (ppc2-close-undo)
8648 (when vreg
8649 (cond ((eq resultspec :void) (<- nil))
8650 ((eq resultspec :double-float)
8651 (<- (make-hard-fp-reg ppc::fp1 hard-reg-class-fpr-mode-double)))
8652 ((eq resultspec :single-float)
8653 (<- (make-hard-fp-reg ppc::fp1 hard-reg-class-fpr-mode-single)))
8654 ((eq resultspec :unsigned-doubleword)
8655 (ensuring-node-target
8656 (target vreg)
8657 (! makeu64)
8658 (ppc2-copy-register seg target ppc::arg_z)))
8659 ((eq resultspec :signed-doubleword)
8660 (ensuring-node-target
8661 (target vreg)
8662 (! makes64)
8663 (ppc2-copy-register seg target ppc::arg_z)))
8664 (t
8665 (<- (set-regspec-mode ppc::imm0 (gpr-mode-name-value
8666 (case resultspec
8667 (:address :address)
8668 (:signed-byte :s8)
8669 (:unsigned-byte :u8)
8670 (:signed-halfword :s16)
8671 (:unsigned-halfword :u16)
8672 (:signed-fullword :s32)
8673 (t :u32))))))))
8674 (^)))
8675
8676
8677
8678
8679(defppc2 ppc2-%temp-list %temp-list (seg vreg xfer arglist)
8680 (ppc2-use-operator (%nx1-operator list) seg vreg xfer arglist))
8681
8682(defppc2 ppc2-%temp-cons %temp-cons (seg vreg xfer car cdr)
8683 (ppc2-use-operator (%nx1-operator cons) seg vreg xfer car cdr))
8684
8685
8686;;; Under MacsBug 5.3 (and some others ?), this'll do a low-level user
8687;;; break. If the debugger doesn't recognize the trap instruction,
8688;;; you'll have to manually advance the PC past it. "arg" winds up in the
8689;;; arg_z register; whatever's in arg_z on return is returned by
8690;;; the %debug-trap construct.
8691
8692(defppc2 ppc2-%debug-trap %debug-trap (seg vreg xfer arg)
8693 (ppc2-one-targeted-reg-form seg arg ($ ppc::arg_z))
8694 (! %debug-trap)
8695 (<- ($ ppc::arg_z))
8696 (^))
8697
8698(defppc2 ppc2-%reference-external-entry-point %reference-external-entry-point
8699 (seg vreg xfer arg)
8700 (ensuring-node-target (target vreg)
8701 (let* ((reg (if (eq (hard-regspec-value target) ppc::arg_z) ($ ppc::arg_y) ($ ppc::arg_z))))
8702 (ppc2-one-targeted-reg-form seg arg reg)
8703 (! eep.address target reg)))
8704 (^))
8705
8706(defppc2 ppc2-%natural+ %natural+ (seg vreg xfer x y)
8707 (if (null vreg)
8708 (progn
8709 (ppc2-form seg nil nil x)
8710 (ppc2-form seg nil xfer y))
8711 (let* ((fix-x (acode-fixnum-form-p x))
8712 (fix-y (acode-fixnum-form-p y)))
8713 (if (and fix-x fix-y)
8714 (ppc2-absolute-natural seg vreg xfer (+ fix-x fix-y))
8715 (let* ((u15x (and (typep fix-x '(unsigned-byte 15)) fix-x))
8716 (u15y (and (typep fix-y '(unsigned-byte 15)) fix-y)))
8717 (if (not (or u15x u15y))
8718 (with-imm-target () (xreg :natural)
8719 (with-imm-target (xreg) (yreg :natural)
8720 (ppc2-two-targeted-reg-forms seg x xreg y yreg)
8721 (! %natural+ xreg xreg yreg))
8722 (<- xreg))
8723 (let* ((other (if u15x y x)))
8724 (with-imm-target () (other-reg :natural)
8725 (ppc2-one-targeted-reg-form seg other other-reg)
8726 (! %natural+-c other-reg other-reg (or u15x u15y))
8727 (<- other-reg))))
8728 (^))))))
8729
8730(defppc2 ppc2-%natural- %natural- (seg vreg xfer x y)
8731 (if (null vreg)
8732 (progn
8733 (ppc2-form seg nil nil x)
8734 (ppc2-form seg nil xfer y))
8735 (let* ((fix-x (acode-fixnum-form-p x))
8736 (fix-y (acode-fixnum-form-p y)))
8737 (if (and fix-x fix-y)
8738 (ppc2-absolute-natural seg vreg xfer (- fix-x fix-y))
8739 (let* ((u15y (and (typep fix-y '(unsigned-byte 15)) fix-y)))
8740 (if (not u15y)
8741 (with-imm-target () (xreg :natural)
8742 (with-imm-target (xreg) (yreg :natural)
8743 (ppc2-two-targeted-reg-forms seg x xreg y yreg)
8744 (! %natural- xreg xreg yreg))
8745 (<- xreg))
8746 (progn
8747 (with-imm-target () (xreg :natural)
8748 (ppc2-one-targeted-reg-form seg x xreg)
8749 (! %natural--c xreg xreg u15y)
8750 (<- xreg))))
8751 (^))))))
8752
8753(defppc2 ppc2-%natural-logior %natural-logior (seg vreg xfer x y)
8754 (if (null vreg)
8755 (progn
8756 (ppc2-form seg nil nil x)
8757 (ppc2-form seg nil xfer y))
8758 (let* ((naturalx (nx-natural-constant-p x))
8759 (naturaly (nx-natural-constant-p y)))
8760 (if (and naturalx naturaly)
8761 (ppc2-absolute-natural seg vreg xfer (logior naturalx naturaly))
8762 (let* ((u32x (nx-u32-constant-p x))
8763 (u32y (nx-u32-constant-p y))
8764 (constant (or u32x u32y)))
8765 (if (not constant)
8766 (with-imm-target () (xreg :natural)
8767 (with-imm-target (xreg) (yreg :natural)
8768 (ppc2-two-targeted-reg-forms seg x xreg y yreg)
8769 (! %natural-logior xreg xreg yreg))
8770 (<- xreg))
8771 (let* ((other (if u32x y x))
8772 (high (ldb (byte 16 16) constant))
8773 (low (ldb (byte 16 0) constant)))
8774 (with-imm-target () (other-reg :natural)
8775 (ppc2-one-targeted-reg-form seg other other-reg)
8776 (! %natural-logior-c other-reg other-reg high low)
8777 (<- other-reg))))
8778 (^))))))
8779
8780(defppc2 ppc2-%natural-logxor %natural-logxor (seg vreg xfer x y)
8781 (if (null vreg)
8782 (progn
8783 (ppc2-form seg nil nil x)
8784 (ppc2-form seg nil xfer y))
8785 (let* ((naturalx (nx-natural-constant-p x))
8786 (naturaly (nx-natural-constant-p y)))
8787 (if (and naturalx naturaly)
8788 (ppc2-absolute-natural seg vreg xfer (logxor naturalx naturaly))
8789 (let* ((u32x (nx-u32-constant-p x))
8790 (u32y (nx-u32-constant-p y))
8791 (constant (or u32x u32y)))
8792 (if (not constant)
8793 (with-imm-target () (xreg :natural)
8794 (with-imm-target (xreg) (yreg :natural)
8795 (ppc2-two-targeted-reg-forms seg x xreg y yreg)
8796 (! %natural-logxor xreg xreg yreg))
8797 (<- xreg))
8798 (let* ((other (if u32x y x))
8799 (high (ldb (byte 16 16) constant))
8800 (low (ldb (byte 16 0) constant)))
8801 (with-imm-target () (other-reg :natural)
8802 (ppc2-one-targeted-reg-form seg other other-reg)
8803 (! %natural-logxor-c other-reg other-reg high low)
8804 (<- other-reg))))
8805 (^))))))
8806
8807(defppc2 ppc2-%natural-logand %natural-logand (seg vreg xfer x y)
8808 (if (null vreg)
8809 (progn
8810 (ppc2-form seg nil nil x)
8811 (ppc2-form seg nil xfer y))
8812 (let* ((naturalx (nx-natural-constant-p x))
8813 (naturaly (nx-natural-constant-p y)))
8814 (if (and naturalx naturaly)
8815 (ppc2-absolute-natural seg vreg xfer (logand naturalx naturaly))
8816 (let* ((u32x (nx-u32-constant-p x))
8817 (u32y (nx-u32-constant-p y))
8818 (constant (or u32x u32y)))
8819 (if (not constant)
8820 (with-imm-target () (xreg :natural)
8821 (with-imm-target (xreg) (yreg :natural)
8822 (ppc2-two-targeted-reg-forms seg x xreg y yreg)
8823 (! %natural-logand xreg xreg yreg))
8824 (<- xreg))
8825 (let* ((other (if u32x y x)))
8826 (with-imm-target () (other-reg :natural)
8827 (ppc2-one-targeted-reg-form seg other other-reg)
8828 (multiple-value-bind (start-bit stop-bit)
8829 (ppc2-mask-bits constant)
8830 (if start-bit
8831 (! %natural-logand-mask-c other-reg other-reg start-bit stop-bit)
8832 (let* ((high (ldb (byte 16 16) constant))
8833 (low (ldb (byte 16 0) constant)))
8834 (declare (type (unsigned-byte 16) high low))
8835 (unless (and (= high #xffff)
8836 (= low high))
8837 (if (= low 0)
8838 (! %natural-logand-high-c other-reg other-reg high)
8839 (if (= high 0)
8840 (! %natural-logand-low-c other-reg other-reg low)
8841 (with-imm-target (other-reg) (const-reg :natural)
8842 (ppc2-absolute-natural seg const-reg nil constant)
8843 (! %natural-logand other-reg other-reg const-reg))))))))
8844 (<- other-reg))))
8845 (^))))))
8846
8847(defppc2 ppc2-natural-shift-right natural-shift-right (seg vreg xfer num amt)
8848 (with-imm-target () (dest :natural)
8849 (ppc2-one-targeted-reg-form seg num dest)
8850 (! natural-shift-right dest dest (acode-fixnum-form-p amt))
8851 (<- dest)
8852 (^)))
8853
8854(defppc2 ppc2-natural-shift-left natural-shift-left (seg vreg xfer num amt)
8855 (with-imm-target () (dest :natural)
8856 (ppc2-one-targeted-reg-form seg num dest)
8857 (! natural-shift-left dest dest (acode-fixnum-form-p amt))
8858 (<- dest)
8859 (^)))
8860
8861;;; This assumes that "global" variables are always boundp.
8862(defppc2 ppc2-global-ref global-ref (seg vreg xfer sym)
8863 (when vreg
8864 (ensuring-node-target (target vreg)
8865 (with-node-temps () (symreg)
8866 (setq symreg (or (ppc2-register-constant-p sym)
8867 (ppc2-store-immediate seg sym symreg)))
8868 (! node-slot-ref target symreg (target-arch-case
8869 (:ppc32 ppc32::symbol.vcell-cell)
8870 (:ppc64 ppc64::symbol.vcell-cell))))))
8871 (^))
8872
8873(defppc2 ppc2-global-setq global-setq (seg vreg xfer sym val)
8874 (ppc2-vset seg
8875 vreg
8876 xfer
8877 :symbol
8878 (make-acode (%nx1-operator immediate) sym)
8879 (make-acode (%nx1-operator fixnum)
8880 (target-arch-case (:ppc32 ppc32::symbol.vcell-cell)
8881 (:ppc64 ppc64::symbol.vcell-cell)))
8882 val
8883 nil))
8884
8885(defppc2 ppc2-%current-frame-ptr %current-frame-ptr (seg vreg xfer)
8886 (cond ((ppc2-tailcallok xfer)
8887 (ppc2-restore-nvrs seg *ppc2-register-restore-ea* *ppc2-register-restore-count*)
8888 (ppc2-restore-full-lisp-context seg)
8889 (! %current-frame-ptr ($ ppc::arg_z))
8890 (! jump-return-pc))
8891 (t
8892 (when vreg
8893 (ensuring-node-target (target vreg)
8894 (! %current-frame-ptr target)))
8895 (^))))
8896
8897(defppc2 ppc2-%foreign-stack-pointer %foreign-stack-pointer (seg vreg xfer)
8898 (when vreg
8899 (ensuring-node-target (target vreg)
8900 (! %current-frame-ptr target)))
8901 (^))
8902
8903(defppc2 ppc2-%current-tcr %current-tcr (seg vreg xfer)
8904 (when vreg
8905 (ensuring-node-target (target vreg)
8906 (! %current-tcr target)))
8907 (^))
8908
8909
8910
8911(defppc2 ppc2-%interrupt-poll %interrupt-poll (seg vreg xfer)
8912 (! event-poll)
8913 (ppc2-nil seg vreg xfer))
8914
8915
8916(defppc2 ppc2-with-c-frame with-c-frame (seg vreg xfer body &aux
8917 (old-stack (ppc2-encode-stack)))
8918 (ecase (backend-name *target-backend*)
8919 (:linuxppc32 (! alloc-eabi-c-frame 0))
8920 ((:darwinppc32 :darwinppc64 :linuxppc64) (! alloc-c-frame 0)))
8921 (ppc2-open-undo $undo-ppc-c-frame)
8922 (ppc2-undo-body seg vreg xfer body old-stack))
8923
8924(defppc2 ppc2-with-variable-c-frame with-variable-c-frame (seg vreg xfer size body &aux
8925 (old-stack (ppc2-encode-stack)))
8926 (let* ((reg (ppc2-one-untargeted-reg-form seg size ppc::arg_z)))
8927 (ecase (backend-name *target-backend*)
8928 (:linuxppc32 (! alloc-variable-eabi-c-frame reg))
8929 ((:darwinppc32 :darwinppc64 :linuxppc64) (! alloc-variable-c-frame reg)))
8930 (ppc2-open-undo $undo-ppc-c-frame)
8931 (ppc2-undo-body seg vreg xfer body old-stack)))
8932
8933(defppc2 ppc2-%symbol->symptr %symbol->symptr (seg vreg xfer sym)
8934 (let* ((src (ppc2-one-untargeted-reg-form seg sym ppc::arg_z)))
8935 (ensuring-node-target (target vreg)
8936 (! %symbol->symptr target src))
8937 (^)))
8938
8939(defppc2 ppc2-%double-to-single %double-to-single (seg vreg xfer arg)
8940 (if (null vreg)
8941 (ppc2-form seg vreg xfer arg)
8942 (if (and (= (hard-regspec-class vreg) hard-reg-class-fpr)
8943 (= (get-regspec-mode vreg) hard-reg-class-fpr-mode-single))
8944 (let* ((dreg (ppc2-one-untargeted-reg-form
8945 seg arg
8946 (make-wired-lreg (hard-regspec-value vreg)
8947 :class hard-reg-class-fpr
8948 :mode hard-reg-class-fpr-mode-double))))
8949 (! double-to-single vreg dreg)
8950 (^))
8951 (with-fp-target () (argreg :double-float)
8952 (ppc2-one-targeted-reg-form seg arg argreg)
8953 (with-fp-target () (sreg :single-float)
8954 (! double-to-single sreg argreg)
8955 (<- sreg)
8956 (^))))))
8957
8958(defppc2 ppc2-%single-to-double %single-to-double (seg vreg xfer arg)
8959 (if (null vreg)
8960 (ppc2-form seg vreg xfer arg)
8961 (if (and (= (hard-regspec-class vreg) hard-reg-class-fpr)
8962 (= (get-regspec-mode vreg) hard-reg-class-fpr-mode-double))
8963 (progn
8964 (ppc2-one-untargeted-reg-form
8965 seg arg
8966 (make-wired-lreg (hard-regspec-value vreg)
8967 :class hard-reg-class-fpr
8968 :mode hard-reg-class-fpr-mode-single))
8969 (^))
8970 (with-fp-target () (sreg :single-float)
8971 (ppc2-one-targeted-reg-form seg arg sreg)
8972 (<- (set-regspec-mode sreg hard-reg-class-fpr-mode-double))
8973 (^)))))
8974
8975(defppc2 ppc2-%symptr->symvector %symptr->symvector (seg vreg xfer arg)
8976 (ppc2-identity seg vreg xfer arg))
8977
8978(defppc2 ppc2-%symvector->symptr %symvector->symptr (seg vreg xfer arg)
8979 (ppc2-identity seg vreg xfer arg))
8980
8981(defppc2 ppc2-%fixnum-to-double %fixnum-to-double (seg vreg xfer arg)
8982 (with-fp-target () (dreg :double-float)
8983 (let* ((r (ppc2-one-untargeted-reg-form seg arg ppc::arg_z)))
8984 (unless (or (acode-fixnum-form-p arg)
8985 *ppc2-reckless*)
8986 (! trap-unless-fixnum r))
8987 (! fixnum->fpr dreg r)
8988 (<- dreg)
8989 (^))))
8990
8991(defppc2 ppc2-%fixnum-to-single %fixnum-to-single (seg vreg xfer arg)
8992 (with-fp-target () (dreg :double-float)
8993 (let* ((r (ppc2-one-untargeted-reg-form seg arg ppc::arg_z)))
8994 (unless (or (acode-fixnum-form-p arg)
8995 *ppc2-reckless*)
8996 (! trap-unless-fixnum r))
8997 (! fixnum->fpr dreg r)
8998 (<- (set-regspec-mode dreg hard-reg-class-fpr-mode-single))
8999 (^))))
9000
9001(defppc2 ppc2-%double-float %double-float (seg vreg xfer arg)
9002 (let* ((real (or (acode-fixnum-form-p arg)
9003 (let* ((form (acode-unwrapped-form arg)))
9004 (if (and (acode-p form)
9005 (eq (acode-operator form)
9006 (%nx1-operator immediate))
9007 (typep (cadr form) 'real))
9008 (cadr form))))))
9009 (if real
9010 (ppc2-immediate seg vreg xfer (float real 0.0d0))
9011 (if (ppc2-form-typep arg 'single-float)
9012 (ppc2-use-operator (%nx1-operator %single-to-double)
9013 seg
9014 vreg
9015 xfer
9016 arg)
9017 (if (ppc2-form-typep arg 'fixnum)
9018 (ppc2-use-operator (%nx1-operator %fixnum-to-double)
9019 seg
9020 vreg
9021 xfer
9022 arg)
9023 (ppc2-use-operator (%nx1-operator call)
9024 seg
9025 vreg
9026 xfer
9027 (make-acode (%nx1-operator immediate)
9028 '%double-float)
9029 (list nil (list arg))))))))
9030
9031(defppc2 ppc2-%single-float %single-float (seg vreg xfer arg)
9032 (let* ((real (or (acode-fixnum-form-p arg)
9033 (let* ((form (acode-unwrapped-form arg)))
9034 (if (and (acode-p form)
9035 (eq (acode-operator form)
9036 (%nx1-operator immediate))
9037 (typep (cadr form) 'real))
9038 (cadr form))))))
9039 (if real
9040 (ppc2-immediate seg vreg xfer (float real 0.0f0))
9041 (if (ppc2-form-typep arg 'double-float)
9042 (ppc2-use-operator (%nx1-operator %double-to-single)
9043 seg
9044 vreg
9045 xfer
9046 arg)
9047 (if (ppc2-form-typep arg 'fixnum)
9048 (ppc2-use-operator (%nx1-operator %fixnum-to-single)
9049 seg
9050 vreg
9051 xfer
9052 arg)
9053 (ppc2-use-operator (%nx1-operator call)
9054 seg
9055 vreg
9056 xfer
9057 (make-acode (%nx1-operator immediate)
9058 '%short-float)
9059 (list nil (list arg))))))))
9060
9061;------
9062
9063#+not-yet
9064(progn
9065
9066
9067;Make a gcable macptr.
9068(defppc2 ppc2-%new-ptr %new-ptr (b vreg xfer size clear-p )
9069 (declare (ignore b vreg xfer size clear-p))
9070 (error "%New-ptr is a waste of precious silicon."))
9071
9072
9073
9074)
Note: See TracBrowser for help on using the repository browser.