0.8.18.20:
[sbcl.git] / src / compiler / ppc / alloc.lisp
1 ;;;
2 ;;; Written by William Lott.
3 ;;; 
4
5 (in-package "SB!VM")
6
7 \f
8 ;;;; LIST and LIST*
9
10 (define-vop (list-or-list*)
11   (:args (things :more t))
12   (:temporary (:scs (descriptor-reg) :type list) ptr)
13   (:temporary (:scs (descriptor-reg)) temp)
14   (:temporary (:scs (descriptor-reg) :type list :to (:result 0) :target result)
15               res)
16   (:temporary (:sc non-descriptor-reg :offset nl3-offset) pa-flag)
17   (:info num)
18   (:results (result :scs (descriptor-reg)))
19   (:variant-vars star)
20   (:policy :safe)
21   (:generator 0
22     (cond ((zerop num)
23            (move result null-tn))
24           ((and star (= num 1))
25            (move result (tn-ref-tn things)))
26           (t
27            (macrolet
28                ((maybe-load (tn)
29                   (once-only ((tn tn))
30                     `(sc-case ,tn
31                        ((any-reg descriptor-reg zero null)
32                         ,tn)
33                        (control-stack
34                         (load-stack-tn temp ,tn)
35                         temp)))))
36              (let* ((cons-cells (if star (1- num) num))
37                     (alloc (* (pad-data-block cons-size) cons-cells)))
38                (pseudo-atomic (pa-flag :extra alloc)
39                  (inst clrrwi res alloc-tn n-lowtag-bits)
40                  (inst ori res res list-pointer-lowtag)
41                  (move ptr res)
42                  (dotimes (i (1- cons-cells))
43                    (storew (maybe-load (tn-ref-tn things)) ptr
44                            cons-car-slot list-pointer-lowtag)
45                    (setf things (tn-ref-across things))
46                    (inst addi ptr ptr (pad-data-block cons-size))
47                    (storew ptr ptr
48                            (- cons-cdr-slot cons-size)
49                            list-pointer-lowtag))
50                  (storew (maybe-load (tn-ref-tn things)) ptr
51                          cons-car-slot list-pointer-lowtag)
52                  (storew (if star
53                              (maybe-load (tn-ref-tn (tn-ref-across things)))
54                              null-tn)
55                          ptr cons-cdr-slot list-pointer-lowtag))
56                (move result res)))))))
57
58 (define-vop (list list-or-list*)
59   (:variant nil))
60
61 (define-vop (list* list-or-list*)
62   (:variant t))
63
64 \f
65 ;;;; Special purpose inline allocators.
66
67 (define-vop (allocate-code-object)
68   (:args (boxed-arg :scs (any-reg))
69          (unboxed-arg :scs (any-reg)))
70   (:results (result :scs (descriptor-reg)))
71   (:temporary (:scs (non-descriptor-reg)) ndescr)
72   (:temporary (:scs (any-reg) :from (:argument 0)) boxed)
73   (:temporary (:scs (non-descriptor-reg) :from (:argument 1)) unboxed)
74   (:temporary (:sc non-descriptor-reg :offset nl3-offset) pa-flag)
75   (:generator 100
76     (inst addi boxed boxed-arg (fixnumize (1+ code-trace-table-offset-slot)))
77     (inst clrrwi boxed boxed n-lowtag-bits)
78     (inst srwi unboxed unboxed-arg word-shift)
79     (inst addi unboxed unboxed lowtag-mask)
80     (inst clrrwi unboxed unboxed n-lowtag-bits)
81     (pseudo-atomic (pa-flag)
82       ;; Note: we don't have to subtract off the 4 that was added by
83       ;; pseudo-atomic, because oring in other-pointer-lowtag just adds
84       ;; it right back.
85       (inst ori result alloc-tn other-pointer-lowtag)
86       (inst add alloc-tn alloc-tn boxed)
87       (inst add alloc-tn alloc-tn unboxed)
88       (inst slwi ndescr boxed (- n-widetag-bits word-shift))
89       (inst ori ndescr ndescr code-header-widetag)
90       (storew ndescr result 0 other-pointer-lowtag)
91       (storew unboxed result code-code-size-slot other-pointer-lowtag)
92       (storew null-tn result code-entry-points-slot other-pointer-lowtag)
93       (storew null-tn result code-debug-info-slot other-pointer-lowtag))))
94
95 (define-vop (make-fdefn)
96   (:args (name :scs (descriptor-reg) :to :eval))
97   (:temporary (:scs (non-descriptor-reg)) temp)
98   (:temporary (:sc non-descriptor-reg :offset nl3-offset) pa-flag)
99   (:results (result :scs (descriptor-reg) :from :argument))
100   (:policy :fast-safe)
101   (:translate make-fdefn)
102   (:generator 37
103     (with-fixed-allocation (result pa-flag temp fdefn-widetag fdefn-size)
104       (inst lr temp  (make-fixup (extern-alien-name "undefined_tramp") :foreign))
105       (storew name result fdefn-name-slot other-pointer-lowtag)
106       (storew null-tn result fdefn-fun-slot other-pointer-lowtag)
107       (storew temp result fdefn-raw-addr-slot other-pointer-lowtag))))
108
109
110 (define-vop (make-closure)
111   (:args (function :to :save :scs (descriptor-reg)))
112   (:info length stack-allocate-p)
113   (:ignore stack-allocate-p)
114   (:temporary (:scs (non-descriptor-reg)) temp)
115   (:temporary (:sc non-descriptor-reg :offset nl3-offset) pa-flag)
116   (:results (result :scs (descriptor-reg)))
117   (:generator 10
118     (let ((size (+ length closure-info-offset)))
119       (pseudo-atomic (pa-flag :extra (pad-data-block size))
120         (inst clrrwi. result alloc-tn n-lowtag-bits)
121         (inst ori result result fun-pointer-lowtag)
122         (inst lr temp (logior (ash (1- size) n-widetag-bits) closure-header-widetag))
123         (storew temp result 0 fun-pointer-lowtag)))
124     ;(inst lis temp (ash 18 10))
125     ;(storew temp result closure-jump-insn-slot function-pointer-type)
126     (storew function result closure-fun-slot fun-pointer-lowtag)))
127
128 ;;; The compiler likes to be able to directly make value cells.
129 ;;; 
130 (define-vop (make-value-cell)
131   (:args (value :to :save :scs (descriptor-reg any-reg)))
132   (:temporary (:scs (non-descriptor-reg)) temp)
133   (:temporary (:sc non-descriptor-reg :offset nl3-offset) pa-flag)
134   (:results (result :scs (descriptor-reg)))
135   (:generator 10
136     (with-fixed-allocation
137         (result pa-flag temp value-cell-header-widetag value-cell-size))
138     (storew value result value-cell-value-slot other-pointer-lowtag)))
139
140
141 \f
142 ;;;; Automatic allocators for primitive objects.
143
144 (define-vop (make-unbound-marker)
145   (:args)
146   (:results (result :scs (any-reg)))
147   (:generator 1
148     (inst li result unbound-marker-widetag)))
149
150 (define-vop (fixed-alloc)
151   (:args)
152   (:info name words type lowtag)
153   (:ignore name)
154   (:results (result :scs (descriptor-reg)))
155   (:temporary (:scs (non-descriptor-reg)) temp)
156   (:temporary (:sc non-descriptor-reg :offset nl3-offset) pa-flag)
157   (:generator 4
158     (pseudo-atomic (pa-flag :extra (pad-data-block words))
159       (cond ((logbitp 2 lowtag)
160              (inst ori result alloc-tn lowtag))
161             (t
162              (inst clrrwi result alloc-tn n-lowtag-bits)
163              (inst ori result  result lowtag)))
164       (when type
165         (inst lr temp (logior (ash (1- words) n-widetag-bits) type))
166         (storew temp result 0 lowtag)))))
167
168 (define-vop (var-alloc)
169   (:args (extra :scs (any-reg)))
170   (:arg-types positive-fixnum)
171   (:info name words type lowtag)
172   (:ignore name)
173   (:results (result :scs (descriptor-reg)))
174   (:temporary (:scs (any-reg)) bytes)
175   (:temporary (:scs (non-descriptor-reg)) header)
176   (:temporary (:sc non-descriptor-reg :offset nl3-offset) pa-flag)
177   (:generator 6
178     (inst addi bytes extra (* (1+ words) n-word-bytes))
179     (inst slwi header bytes (- n-widetag-bits 2))
180     (inst addi header header (+ (ash -2 n-widetag-bits) type))
181     (inst clrrwi bytes bytes n-lowtag-bits)
182     (pseudo-atomic (pa-flag)
183       (cond ((logbitp 2 lowtag)
184              (inst ori result alloc-tn lowtag))
185             (t
186              (inst clrrwi result alloc-tn n-lowtag-bits)
187              (inst ori result result lowtag)))
188       (storew header result 0 lowtag)
189       (inst add alloc-tn alloc-tn bytes))))