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