0.7.1.20:
[sbcl.git] / src / compiler / sparc / values.lisp
1 ;;;; the sparc implementation of unknown-values VOPs
2
3 ;;;; This software is part of the SBCL system. See the README file for
4 ;;;; more information.
5 ;;;;
6 ;;;; This software is derived from the CMU CL system, which was
7 ;;;; written at Carnegie Mellon University and released into the
8 ;;;; public domain. The software is in the public domain and is
9 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
10 ;;;; files for more information.
11
12 (in-package "SB!VM")
13
14 (define-vop (reset-stack-pointer)
15   (:args (ptr :scs (any-reg)))
16   (:generator 1
17     (move csp-tn ptr)))
18
19
20 ;;; Push some values onto the stack, returning the start and number of
21 ;;; values pushed as results.  It is assumed that the Vals are wired
22 ;;; to the standard argument locations.  Nvals is the number of values
23 ;;; to push.
24 ;;;
25 ;;; The generator cost is pseudo-random.  We could get it right by
26 ;;; defining a bogus SC that reflects the costs of the
27 ;;; memory-to-memory moves for each operand, but this seems
28 ;;; unworthwhile.
29 (define-vop (push-values)
30   (:args (vals :more t))
31   (:results (start :scs (any-reg) :from :load)
32             (count :scs (any-reg)))
33   (:info nvals)
34   (:temporary (:scs (descriptor-reg)) temp)
35   (:generator 20
36     (inst move start csp-tn)
37     (inst add csp-tn csp-tn (* nvals n-word-bytes))
38     (do ((val vals (tn-ref-across val))
39          (i 0 (1+ i)))
40         ((null val))
41       (let ((tn (tn-ref-tn val)))
42         (sc-case tn
43           (descriptor-reg
44            (storew tn start i))
45           (control-stack
46            (load-stack-tn temp tn)
47            (storew temp start i)))))
48     (inst li count (fixnumize nvals))))
49
50 ;;; Push a list of values on the stack, returning Start and Count as
51 ;;; used in unknown values continuations.
52 (define-vop (values-list)
53   (:args (arg :scs (descriptor-reg) :target list))
54   (:arg-types list)
55   (:policy :fast-safe)
56   (:results (start :scs (any-reg))
57             (count :scs (any-reg)))
58   (:temporary (:scs (descriptor-reg) :type list :from (:argument 0)) list)
59   (:temporary (:scs (descriptor-reg)) temp)
60   (:temporary (:scs (non-descriptor-reg)) ndescr)
61   (:vop-var vop)
62   (:save-p :compute-only)
63   (:generator 0
64     (let ((loop (gen-label))
65           (done (gen-label)))
66
67       (move list arg)
68       (move start csp-tn)
69
70       (emit-label loop)
71       (inst cmp list null-tn)
72       (inst b :eq done)
73       (loadw temp list cons-car-slot list-pointer-lowtag)
74       (loadw list list cons-cdr-slot list-pointer-lowtag)
75       (inst add csp-tn csp-tn n-word-bytes)
76       (storew temp csp-tn -1)
77       (test-type list ndescr loop nil list-pointer-lowtag)
78       (error-call vop bogus-arg-to-values-list-error list)
79
80       (emit-label done)
81       (inst sub count csp-tn start))))
82
83
84
85 ;;; Copy the more arg block to the top of the stack so we can use them
86 ;;; as function arguments.
87 (define-vop (%more-arg-values)
88   (:args (context :scs (descriptor-reg any-reg) :target src)
89          (skip :scs (any-reg zero immediate))
90          (num :scs (any-reg) :target count))
91   (:arg-types * positive-fixnum positive-fixnum)
92   (:temporary (:sc any-reg :from (:argument 0)) src)
93   (:temporary (:sc any-reg :from (:argument 2)) dst)
94   (:temporary (:sc descriptor-reg :from (:argument 1)) temp)
95   (:temporary (:sc any-reg) i)
96   (:results (start :scs (any-reg))
97             (count :scs (any-reg)))
98   (:generator 20
99     (sc-case skip
100       (zero
101        (move src context))
102       (immediate
103        (inst add src context (* (tn-value skip) n-word-bytes)))
104       (any-reg
105        (inst add src context skip)))
106     (inst orcc count zero-tn num)
107     (inst b :eq done)
108     (inst move start csp-tn)
109     (inst move dst csp-tn)
110     (inst add csp-tn count)
111     (inst move i count)
112     LOOP
113     (inst subcc i 4)
114     (inst ld temp src i)
115     (inst b :ne loop)
116     (inst st temp dst i)
117     DONE))