close Warning: Can't use blame annotator:
No changeset 1633 in the repository

source: release/1.4/source/level-0/PPC/PPC64/ppc64-bignum.lisp

Last change on this file was 13075, checked in by R. Matthew Emerson, 15 years ago

Merge trunk changes r13066 through r13067.
(copyright notices)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.5 KB
RevLine 
1;;-*- Mode: Lisp; Package: CCL -*-
2;;;
3;;; Copyright (C) 2009 Clozure Associates
4;;; Copyright (C) 1994-2001 Digitool, Inc
5;;; This file is part of Clozure CL.
6;;;
7;;; Clozure CL is licensed under the terms of the Lisp Lesser GNU Public
8;;; License , known as the LLGPL and distributed with Clozure CL as the
9;;; file "LICENSE". The LLGPL consists of a preamble and the LGPL,
10;;; which is distributed with Clozure CL as the file "LGPL". Where these
11;;; conflict, the preamble takes precedence.
12;;;
13;;; Clozure CL is referenced in the preamble as the "LIBRARY."
14;;;
15;;; The LLGPL is also available online at
16;;; http://opensource.franz.com/preamble.html
17
18
19(in-package "CCL")
20
21;;; The caller has allocated a two-digit bignum (quite likely on the stack).
22;;; If we can fit in a single digit (if the high word is just a sign
23;;; extension of the low word), truncate the bignum in place (the
24;;; trailing words should already be zeroed.
25(defppclapfunction %fixnum-to-bignum-set ((bignum arg_y) (fixnum arg_z))
26 (unbox-fixnum imm0 fixnum)
27 (srdi imm1 imm0 32)
28 (srawi imm2 imm0 31)
29 (cmpw imm2 imm1)
30 (stw imm0 ppc64::misc-data-offset bignum)
31 (li imm2 ppc64::one-digit-bignum-header)
32 (beq @chop)
33 (stw imm1 (+ ppc64::misc-data-offset 4) bignum)
34 (blr)
35 @chop
36 (std imm2 ppc64::misc-header-offset bignum)
37 (blr))
38
39(defppclapfunction %multiply-and-add-loop
40 ((x 8) (y 0) (r arg_x) (idx arg_y) (ylen arg_z))
41 (let ((cc nargs)
42 (xx imm2)
43 (yy imm3)
44 (rr imm4)
45 (i imm0)
46 (j imm1))
47 (srdi i idx 1)
48 (la i ppc64::misc-data-offset i)
49 (ld temp0 x vsp)
50 (lwzx xx temp0 i) ;x[i]
51 (ld temp0 y vsp)
52 (mr temp1 r)
53 (li cc 0)
54 (li j ppc64::misc-data-offset)
55 @loop
56 (lwzx yy temp0 j)
57 (mulld yy xx yy)
58 ;; 64-bit product now in %yy
59 (lwzx rr temp1 i)
60 ;; add in digit from r[i]
61 (add rr rr yy)
62 ;; add in carry
63 (add rr rr cc)
64 (stwx rr temp1 i)
65 (srdi cc rr 32) ;get carry digit into low word
66 (cmpdi ylen '1)
67 (la i 4 i)
68 (la j 4 j)
69 (subi ylen ylen '1)
70 (bne @loop)
71 (stwx cc temp1 i)
72 (set-nargs 0)
73 (la vsp 16 vsp)
74 (blr)))
75
76(defppclapfunction %multiply-and-add-loop64
77 ((x 8) (y 0) (r arg_x) (idx arg_y) (ylen arg_z))
78 (let ((i imm0)
79 (j imm1)
80 (xx imm2)
81 (yy imm3)
82 (rr imm4)
83 (dd imm5)
84 (cc nargs))
85 (ld temp0 x vsp)
86 (la i ppc64::misc-data-offset idx)
87 (ldx xx temp0 i) ;x[i]
88 (rotldi xx xx 32)
89 (ld temp0 y vsp)
90 (li cc 0)
91 (li j ppc64::misc-data-offset)
92 @loop
93 (ldx yy temp0 j) ;y[j]
94 (rotldi yy yy 32)
95 (mulld dd xx yy) ;low
96 (ldx rr r i) ;r[i]
97 (rotldi rr rr 32)
98 (addc rr rr dd) ;r[i] = r[i] + low
99 (mulhdu dd xx yy) ;high
100 (addze dd dd) ;carry from addding in low
101 (addc rr rr cc) ;add in carry digit
102 (addze cc dd)
103 (rotldi rr rr 32)
104 (stdx rr r i) ;update r[i]
105 (cmpdi ylen '1)
106 (la i 8 i)
107 (la j 8 j)
108 (subi ylen ylen '1)
109 (bne @loop)
110 (rotldi cc cc 32)
111 (stdx cc r i)
112 (set-nargs 0)
113 (la vsp 16 vsp)
114 (blr)))
115
116;;; Multiply the (32-bit) digits X and Y, producing a 64-bit result.
117;;; Add the 32-bit "prev" digit and the 32-bit carry-in digit to that 64-bit
118;;; result; return the halves as (VALUES high low).
119(defppclapfunction %multiply-and-add4 ((x 0) (y arg_x) (prev arg_y) (carry-in arg_z))
120 (let ((unboxed-x imm0)
121 (unboxed-y imm1)
122 (unboxed-prev imm2)
123 (unboxed-carry-in imm3)
124 (result64 imm4)
125 (high arg_y)
126 (low arg_z))
127 (ld temp0 x vsp)
128 (unbox-fixnum unboxed-x temp0)
129 (unbox-fixnum unboxed-y y)
130 (unbox-fixnum unboxed-prev prev)
131 (unbox-fixnum unboxed-carry-in carry-in)
132 (mulld result64 unboxed-x unboxed-y)
133 (add result64 result64 unboxed-prev)
134 (add result64 result64 unboxed-carry-in)
135 (clrlsldi low result64 32 ppc64::fixnumshift)
136 (clrrdi high result64 32)
137 (srdi high high (- 32 ppc64::fixnumshift))
138 (std high 0 vsp)
139 (set-nargs 2)
140 (vpush low)
141 (la temp0 '2 vsp)
142 (ba .SPvalues)))
143
144(defppclapfunction %multiply-and-add3 ((x arg_x) (y arg_y) (carry-in arg_z))
145 (let ((unboxed-x imm0)
146 (unboxed-y imm1)
147 (unboxed-carry-in imm2)
148 (result64 imm3)
149 (high arg_y)
150 (low arg_z))
151 (unbox-fixnum unboxed-x arg_x)
152 (unbox-fixnum unboxed-y y)
153 (unbox-fixnum unboxed-carry-in carry-in)
154 (mulld result64 unboxed-x unboxed-y)
155 (add result64 result64 unboxed-carry-in)
156 (clrlsldi low result64 32 ppc64::fixnumshift)
157 (clrrdi high result64 32)
158 (srdi high high (- 32 ppc64::fixnumshift))
159 (vpush high)
160 (set-nargs 2)
161 (vpush low)
162 (la temp0 '2 vsp)
163 (ba .SPvalues)))
164
165;;; Return the (possibly truncated) 32-bit quotient and remainder
166;;; resulting from dividing hi:low by divisor.
167(defppclapfunction %floor ((num-high arg_x) (num-low arg_y) (divisor arg_z))
168 (let ((unboxed-num imm0)
169 (unboxed-low imm1)
170 (unboxed-divisor imm2)
171 (unboxed-quo imm3)
172 (unboxed-rem imm4))
173 (sldi unboxed-num num-high (- 32 ppc64::fixnumshift))
174 (unbox-fixnum unboxed-low num-low)
175 (unbox-fixnum unboxed-divisor divisor)
176 (or unboxed-num unboxed-low unboxed-num)
177 (divdu unboxed-quo unboxed-num unboxed-divisor)
178 (mulld unboxed-rem unboxed-quo unboxed-divisor)
179 (sub unboxed-rem unboxed-num unboxed-rem)
180 (clrlsldi arg_y unboxed-quo 32 ppc64::fixnumshift)
181 (clrlsldi arg_z unboxed-rem 32 ppc64::fixnumshift)
182 (mr temp0 vsp)
183 (vpush arg_y)
184 (vpush arg_z)
185 (set-nargs 2)
186 (ba .SPvalues)))
187
188;;; Multiply two (UNSIGNED-BYTE 32) arguments, return the high and
189;;; low halves of the 64-bit result
190(defppclapfunction %multiply ((x arg_y) (y arg_z))
191 (let ((unboxed-x imm0)
192 (unboxed-y imm1)
193 (unboxed-high imm2)
194 (unboxed-low imm3))
195 (unbox-fixnum unboxed-x x)
196 (unbox-fixnum unboxed-y y)
197 (mulld imm2 unboxed-x unboxed-y)
198 (clrlsldi arg_y imm2 32 ppc64::fixnumshift) ; arg_y = low32
199 (srdi imm2 imm2 32)
200 (box-fixnum arg_z imm2) ; arg_z = high32
201 (mr temp0 vsp)
202 (vpush arg_z)
203 (set-nargs 2)
204 (vpush arg_y)
205 (ba .SPvalues)))
206
207;;; Any words in the "tail" of the bignum should have been
208;;; zeroed by the caller.
209(defppclapfunction %set-bignum-length ((newlen arg_y) (bignum arg_z))
210 (sldi imm0 newlen (- ppc64::num-subtag-bits ppc64::fixnumshift))
211 (ori imm0 imm0 ppc64::subtag-bignum)
212 (std imm0 ppc64::misc-header-offset bignum)
213 (blr))
214
215;;; Count the sign bits in the most significant digit of bignum;
216;;; return fixnum count.
217(defppclapfunction %bignum-sign-bits ((bignum arg_z))
218 (vector-size imm0 bignum imm0)
219 (sldi imm0 imm0 2)
220 (la imm0 (- ppc64::misc-data-offset 4) imm0) ; Reference last (most significant) digit
221 (lwzx imm0 bignum imm0)
222 (cmpwi imm0 0)
223 (not imm0 imm0)
224 (blt @wasneg)
225 (not imm0 imm0)
226 @wasneg
227 (cntlzw imm0 imm0)
228 (box-fixnum arg_z imm0)
229 (blr))
230
231(defppclapfunction %signed-bignum-ref ((bignum arg_y) (index arg_z))
232 (srdi imm0 index 1)
233 (la imm0 ppc64::misc-data-offset imm0)
234 (lwax imm0 bignum imm0)
235 (box-fixnum arg_z imm0)
236 (blr))
237
238
239;;; If the bignum is a one-digit bignum, return the value of the
240;;; single digit as a fixnum. Otherwise, if it's a two-digit-bignum
241;;; and the two words of the bignum can be represented in a fixnum,
242;;; return that fixnum; else return nil.
243(defppclapfunction %maybe-fixnum-from-one-or-two-digit-bignum ((bignum arg_z))
244 (ld imm1 ppc64::misc-header-offset bignum)
245 (cmpdi cr1 imm1 ppc64::one-digit-bignum-header)
246 (cmpdi cr2 imm1 ppc64::two-digit-bignum-header)
247 (beq cr1 @one)
248 (bne cr2 @no)
249 (ld imm0 ppc64::misc-data-offset bignum)
250 (rotldi imm0 imm0 32)
251 (box-fixnum arg_z imm0)
252 (unbox-fixnum imm1 arg_z)
253 (cmpd imm0 imm1)
254 (beqlr)
255 @no
256 (li arg_z nil)
257 (blr)
258 @one
259 (lwa imm0 ppc64::misc-data-offset bignum)
260 (box-fixnum arg_z imm0)
261 (blr))
262
263
264(defppclapfunction %digit-logical-shift-right ((digit arg_y) (count arg_z))
265 (unbox-fixnum imm0 digit)
266 (unbox-fixnum imm1 count)
267 (srw imm0 imm0 imm1)
268 (box-fixnum arg_z imm0)
269 (blr))
270
271(defppclapfunction %ashr ((digit arg_y) (count arg_z))
272 (unbox-fixnum imm0 digit)
273 (unbox-fixnum imm1 count)
274 (sraw imm0 imm0 imm1)
275 (box-fixnum arg_z imm0)
276 (blr))
277
278(defppclapfunction %ashl ((digit arg_y) (count arg_z))
279 (unbox-fixnum imm0 digit)
280 (unbox-fixnum imm1 count)
281 (slw imm0 imm0 imm1)
282 (clrlsldi arg_z imm0 32 ppc64::fixnumshift)
283 (blr))
284
285(defppclapfunction macptr->fixnum ((ptr arg_z))
286 (macptr-ptr imm0 ptr)
287 (andi. imm1 imm0 7)
288 (li arg_z nil)
289 (bne @done)
290 (mr arg_z imm0)
291 @done
292 (blr))
293
294(defppclapfunction fix-digit-logand ((fix arg_x) (big arg_y) (dest arg_z)) ; index 0
295 (let ((w1 imm0)
296 (w2 imm1))
297 (ld w2 ppc64::misc-data-offset big)
298 (unbox-fixnum w1 fix)
299 (rotldi w2 w2 32)
300 (cmpdi dest nil)
301 (and w1 w1 w2)
302 (bne @store)
303 (box-fixnum arg_z w1)
304 (blr)
305 @store
306 (rotldi w1 w1 32)
307 (std w1 ppc64::misc-data-offset dest)
308 (blr)))
309
310
311
312(defppclapfunction fix-digit-logandc2 ((fix arg_x) (big arg_y) (dest arg_z))
313 (cmpdi dest nil)
314 (ld imm1 ppc64::misc-data-offset big)
315 (unbox-fixnum imm0 fix)
316 (rotldi imm1 imm1 32)
317 (andc imm1 imm0 imm1)
318 (bne @store)
319 (box-fixnum arg_z imm1)
320 (blr)
321 @store
322 (rotldi imm1 imm1 32)
323 (std imm1 ppc64::misc-data-offset dest)
324 (blr))
325
326(defppclapfunction fix-digit-logandc1 ((fix arg_x) (big arg_y) (dest arg_z))
327 (cmpdi dest nil)
328 (ld imm1 ppc64::misc-data-offset big)
329 (unbox-fixnum imm0 fix)
330 (rotldi imm1 imm1 32)
331 (andc imm1 imm1 imm0)
332 (bne @store)
333 (box-fixnum arg_z imm1)
334 (blr)
335 @store
336 (rotldi imm1 imm1 32)
337 (std imm1 ppc64::misc-data-offset dest)
338 (blr))
339
340
Note: See TracBrowser for help on using the repository browser.