cddfdc73c1a3026e1c1cdd9c12371905011dd42f
[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 stack-allocate-p)
108   (:ignore stack-allocate-p)
109   (:temporary (:scs (non-descriptor-reg)) temp)
110   (:results (result :scs (descriptor-reg)))
111   (:generator 10
112     (let ((size (+ length closure-info-offset)))
113       (pseudo-atomic (:extra (pad-data-block size))
114         (inst move alloc-tn result)
115         (inst dep fun-pointer-lowtag 31 3 result)
116         (inst li (logior (ash (1- size) n-widetag-bits) closure-header-widetag) temp)
117         (storew temp result 0 fun-pointer-lowtag)))
118     (storew function result closure-fun-slot fun-pointer-lowtag)))
119
120 ;;; The compiler likes to be able to directly make value cells.
121 ;;;
122 (define-vop (make-value-cell)
123   (:args (value :to :save :scs (descriptor-reg any-reg)))
124   (:temporary (:scs (non-descriptor-reg)) temp)
125   (:results (result :scs (descriptor-reg)))
126   (:generator 10
127     (with-fixed-allocation
128         (result temp value-cell-header-widetag value-cell-size))
129     (storew value result value-cell-value-slot other-pointer-lowtag)))
130
131
132 \f
133 ;;;; Automatic allocators for primitive objects.
134
135 (define-vop (make-unbound-marker)
136   (:args)
137   (:results (result :scs (any-reg)))
138   (:generator 1
139     (inst li unbound-marker-widetag result)))
140
141 (define-vop (fixed-alloc)
142   (:args)
143   (:info name words type lowtag)
144   (:ignore name)
145   (:results (result :scs (descriptor-reg)))
146   (:temporary (:scs (non-descriptor-reg)) temp)
147   (:generator 4
148     (pseudo-atomic (:extra (pad-data-block words))
149       (inst move alloc-tn result)
150       (inst dep lowtag 31 3 result)
151       (when type
152         (inst li (logior (ash (1- words) n-widetag-bits) type) temp)
153         (storew temp result 0 lowtag)))))
154
155 (define-vop (var-alloc)
156   (:args (extra :scs (any-reg)))
157   (:arg-types positive-fixnum)
158   (:info name words type lowtag)
159   (:ignore name)
160   (:results (result :scs (descriptor-reg)))
161   (:temporary (:scs (any-reg)) bytes)
162   (:temporary (:scs (non-descriptor-reg)) header)
163   (:generator 6
164     (inst addi (* (1+ words) n-word-bytes) extra bytes)
165     (inst sll bytes (- n-widetag-bits 2) header)
166     (inst addi (+ (ash -2 n-widetag-bits) type) header header)
167     (inst dep 0 31 3 bytes)
168     (pseudo-atomic ()
169       (inst move alloc-tn result)
170       (inst dep lowtag 31 3 result)
171       (storew header result 0 lowtag)
172       (inst add alloc-tn bytes alloc-tn))))