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