5 ;;;; Addition and subtraction.
7 ;;; static-fun-offset returns the address of the raw_addr slot of
8 ;;; a static function's fdefn.
10 ;;; Note that there is only one use of static-fun-offset outside this
11 ;;; file (in genesis.lisp)
13 (define-assembly-routine (generic-+
15 (:return-style :full-call)
19 ((:arg x (descriptor-reg any-reg) a0-offset)
20 (:arg y (descriptor-reg any-reg) a1-offset)
22 (:res res (descriptor-reg any-reg) a0-offset)
24 (:temp temp non-descriptor-reg nl0-offset)
25 (:temp temp1 non-descriptor-reg nl1-offset)
26 (:temp temp2 non-descriptor-reg nl2-offset)
27 (:temp pa-flag non-descriptor-reg nl4-offset)
28 (:temp lip interior-reg lip-offset)
29 (:temp nargs any-reg nargs-offset)
30 (:temp ocfp any-reg ocfp-offset))
32 (inst and temp fixnum-tag-mask)
33 (inst beq temp DO-ADD)
34 (inst sra temp1 x n-fixnum-tag-bits)
37 (inst lw lip null-tn (static-fun-offset 'two-arg-+))
38 (inst li nargs (fixnumize 2))
41 (move cfp-tn csp-tn t)
44 (inst sra temp2 y n-fixnum-tag-bits)
45 (inst addu temp temp1 temp2)
47 (inst sra temp1 temp (- n-word-bits n-lowtag-bits))
48 (inst beq temp1 RETURN)
49 (inst nor temp1 temp1)
50 (inst beq temp1 RETURN)
52 (with-fixed-allocation (res pa-flag temp2 bignum-widetag (1+ bignum-digits-offset))
53 (storew temp res bignum-digits-offset other-pointer-lowtag))
58 (inst sll res temp n-fixnum-tag-bits)
63 (define-assembly-routine (generic--
65 (:return-style :full-call)
69 ((:arg x (descriptor-reg any-reg) a0-offset)
70 (:arg y (descriptor-reg any-reg) a1-offset)
72 (:res res (descriptor-reg any-reg) a0-offset)
74 (:temp temp non-descriptor-reg nl0-offset)
75 (:temp temp1 non-descriptor-reg nl1-offset)
76 (:temp temp2 non-descriptor-reg nl2-offset)
77 (:temp pa-flag non-descriptor-reg nl4-offset)
78 (:temp lip interior-reg lip-offset)
79 (:temp nargs any-reg nargs-offset)
80 (:temp ocfp any-reg ocfp-offset))
82 (inst and temp fixnum-tag-mask)
83 (inst beq temp DO-SUB)
84 (inst sra temp1 x n-fixnum-tag-bits)
87 (inst lw lip null-tn (static-fun-offset 'two-arg--))
88 (inst li nargs (fixnumize 2))
91 (move cfp-tn csp-tn t)
94 (inst sra temp2 y n-fixnum-tag-bits)
95 (inst subu temp temp1 temp2)
97 (inst sra temp1 temp (- n-word-bits n-lowtag-bits))
98 (inst beq temp1 RETURN)
99 (inst nor temp1 temp1)
100 (inst beq temp1 RETURN)
102 (with-fixed-allocation (res pa-flag temp2 bignum-widetag (1+ bignum-digits-offset))
103 (storew temp res bignum-digits-offset other-pointer-lowtag))
108 (inst sll res temp n-fixnum-tag-bits)
117 (define-assembly-routine (generic-*
119 (:return-style :full-call)
123 ((:arg x (descriptor-reg any-reg) a0-offset)
124 (:arg y (descriptor-reg any-reg) a1-offset)
126 (:res res (descriptor-reg any-reg) a0-offset)
128 (:temp temp non-descriptor-reg nl0-offset)
129 (:temp lo non-descriptor-reg nl1-offset)
130 (:temp hi non-descriptor-reg nl2-offset)
131 (:temp pa-flag non-descriptor-reg nl4-offset)
132 (:temp lip interior-reg lip-offset)
133 (:temp nargs any-reg nargs-offset)
134 (:temp ocfp any-reg ocfp-offset))
135 ;; If either arg is not a fixnum, call the static function.
137 (inst and temp fixnum-tag-mask)
138 (inst bne temp DO-STATIC-FUN)
139 ;; Remove the tag from one arg so that the result will have the correct
141 (inst sra temp x n-fixnum-tag-bits)
145 ;; Check to see if the result will fit in a fixnum. (I.e. the high word
146 ;; is just 32 copies of the sign bit of the low word).
147 (inst sra temp res 31)
148 (inst beq temp hi DONE)
149 ;; Shift the double word hi:res down two bits into hi:low to get rid of the
151 (inst srl lo res n-fixnum-tag-bits)
152 (inst sll temp hi (- n-word-bits n-fixnum-tag-bits))
154 (inst sra hi n-fixnum-tag-bits)
156 ;; Do we need one word or two? Assume two.
157 (inst sra temp lo 31)
158 (inst bne temp hi TWO-WORDS)
159 ;; Assume a two word header.
160 (inst li temp (logior (ash 2 n-widetag-bits) bignum-widetag))
162 ;; Only need one word, fix the header.
163 (inst li temp (logior (ash 1 n-widetag-bits) bignum-widetag))
165 (pseudo-atomic (pa-flag :extra (pad-data-block (+ 1 bignum-digits-offset)))
166 (inst or res alloc-tn other-pointer-lowtag)
167 (storew temp res 0 other-pointer-lowtag))
169 (storew lo res bignum-digits-offset other-pointer-lowtag)
172 (pseudo-atomic (pa-flag :extra (pad-data-block (+ 2 bignum-digits-offset)))
173 (inst or res alloc-tn other-pointer-lowtag)
174 (storew temp res 0 other-pointer-lowtag))
176 (storew lo res bignum-digits-offset other-pointer-lowtag)
178 (storew hi res (1+ bignum-digits-offset) other-pointer-lowtag)
181 (inst lw lip null-tn (static-fun-offset 'two-arg-*))
182 (inst li nargs (fixnumize 2))
185 (move cfp-tn csp-tn t)
191 ;;;; Comparison routines.
194 ((define-cond-assem-rtn (name translate static-fn cmp)
195 `(define-assembly-routine (,name
197 (:return-style :full-call)
199 (:translate ,translate)
201 ((:arg x (descriptor-reg any-reg) a0-offset)
202 (:arg y (descriptor-reg any-reg) a1-offset)
204 (:res res descriptor-reg a0-offset)
206 (:temp temp non-descriptor-reg nl0-offset)
207 (:temp lip interior-reg lip-offset)
208 (:temp nargs any-reg nargs-offset)
209 (:temp ocfp any-reg ocfp-offset))
211 (inst and temp fixnum-tag-mask)
212 (inst beq temp DO-COMPARE)
216 (inst lw lip null-tn (static-fun-offset ',static-fn))
217 (inst li nargs (fixnumize 2))
220 (move cfp-tn csp-tn t)
229 (define-cond-assem-rtn generic-< < two-arg-< (inst slt temp x y))
230 (define-cond-assem-rtn generic-> > two-arg-> (inst slt temp y x)))
233 (define-assembly-routine (generic-eql
235 (:return-style :full-call)
239 ((:arg x (descriptor-reg any-reg) a0-offset)
240 (:arg y (descriptor-reg any-reg) a1-offset)
242 (:res res descriptor-reg a0-offset)
244 (:temp temp non-descriptor-reg nl0-offset)
245 (:temp lip interior-reg lip-offset)
246 (:temp nargs any-reg nargs-offset)
247 (:temp ocfp any-reg ocfp-offset))
248 (inst beq x y RETURN-T)
250 (inst and temp fixnum-tag-mask)
251 (inst beq temp RETURN)
255 (inst lw lip null-tn (static-fun-offset 'eql))
256 (inst li nargs (fixnumize 2))
259 (move cfp-tn csp-tn t)
271 (define-assembly-routine (generic-=
273 (:return-style :full-call)
277 ((:arg x (descriptor-reg any-reg) a0-offset)
278 (:arg y (descriptor-reg any-reg) a1-offset)
280 (:res res descriptor-reg a0-offset)
282 (:temp temp non-descriptor-reg nl0-offset)
283 (:temp lip interior-reg lip-offset)
284 (:temp nargs any-reg nargs-offset)
285 (:temp ocfp any-reg ocfp-offset))
287 (inst and temp fixnum-tag-mask)
288 (inst beq temp RETURN)
292 (inst lw lip null-tn (static-fun-offset 'two-arg-=))
293 (inst li nargs (fixnumize 2))
296 (move cfp-tn csp-tn t)
306 (define-assembly-routine (generic-/=
308 (:return-style :full-call)
312 ((:arg x (descriptor-reg any-reg) a0-offset)
313 (:arg y (descriptor-reg any-reg) a1-offset)
315 (:res res descriptor-reg a0-offset)
317 (:temp temp non-descriptor-reg nl0-offset)
318 (:temp lip interior-reg lip-offset)
319 (:temp nargs any-reg nargs-offset)
320 (:temp ocfp any-reg ocfp-offset))
322 (inst and temp fixnum-tag-mask)
323 (inst beq temp RETURN)
327 (inst lw lip null-tn (static-fun-offset 'two-arg-/=))
328 (inst li nargs (fixnumize 2))
331 (move cfp-tn csp-tn t)