1a4573ee63932084c039c63456293f257f505ee0
[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)
113   (:temporary (:scs (non-descriptor-reg)) temp)
114   (:temporary (:sc non-descriptor-reg :offset nl3-offset) pa-flag)
115   (:results (result :scs (descriptor-reg)))
116   (:generator 10
117     (let ((size (+ length closure-info-offset)))
118       (pseudo-atomic (pa-flag :extra (pad-data-block size))
119         (inst clrrwi. result alloc-tn n-lowtag-bits)
120         (inst ori result result fun-pointer-lowtag)
121         (inst lr temp (logior (ash (1- size) n-widetag-bits) closure-header-widetag))
122         (storew temp result 0 fun-pointer-lowtag)))
123     ;(inst lis temp (ash 18 10))
124     ;(storew temp result closure-jump-insn-slot function-pointer-type)
125     (storew function result closure-fun-slot fun-pointer-lowtag)))
126
127 ;;; The compiler likes to be able to directly make value cells.
128 ;;; 
129 (define-vop (make-value-cell)
130   (:args (value :to :save :scs (descriptor-reg any-reg)))
131   (:temporary (:scs (non-descriptor-reg)) temp)
132   (:temporary (:sc non-descriptor-reg :offset nl3-offset) pa-flag)
133   (:results (result :scs (descriptor-reg)))
134   (:generator 10
135     (with-fixed-allocation
136         (result pa-flag temp value-cell-header-widetag value-cell-size))
137     (storew value result value-cell-value-slot other-pointer-lowtag)))
138
139
140 \f
141 ;;;; Automatic allocators for primitive objects.
142
143 (define-vop (make-unbound-marker)
144   (:args)
145   (:results (result :scs (any-reg)))
146   (:generator 1
147     (inst li result unbound-marker-widetag)))
148
149 (define-vop (fixed-alloc)
150   (:args)
151   (:info name words type lowtag)
152   (:ignore name)
153   (:results (result :scs (descriptor-reg)))
154   (:temporary (:scs (non-descriptor-reg)) temp)
155   (:temporary (:sc non-descriptor-reg :offset nl3-offset) pa-flag)
156   (:generator 4
157     (pseudo-atomic (pa-flag :extra (pad-data-block words))
158       (cond ((logbitp 2 lowtag)
159              (inst ori result alloc-tn lowtag))
160             (t
161              (inst clrrwi result alloc-tn n-lowtag-bits)
162              (inst ori result  result lowtag)))
163       (when type
164         (inst lr temp (logior (ash (1- words) n-widetag-bits) type))
165         (storew temp result 0 lowtag)))))
166
167 (define-vop (var-alloc)
168   (:args (extra :scs (any-reg)))
169   (:arg-types positive-fixnum)
170   (:info name words type lowtag)
171   (:ignore name)
172   (:results (result :scs (descriptor-reg)))
173   (:temporary (:scs (any-reg)) bytes)
174   (:temporary (:scs (non-descriptor-reg)) header)
175   (:temporary (:sc non-descriptor-reg :offset nl3-offset) pa-flag)
176   (:generator 6
177     (inst addi bytes extra (* (1+ words) n-word-bytes))
178     (inst slwi header bytes (- n-widetag-bits 2))
179     (inst addi header header (+ (ash -2 n-widetag-bits) type))
180     (inst clrrwi bytes bytes n-lowtag-bits)
181     (pseudo-atomic (pa-flag)
182       (cond ((logbitp 2 lowtag)
183              (inst ori result alloc-tn lowtag))
184             (t
185              (inst clrrwi result alloc-tn n-lowtag-bits)
186              (inst ori result result lowtag)))
187       (storew header result 0 lowtag)
188       (inst add alloc-tn alloc-tn bytes))))