source: release/1.11/source/level-0/X86/X8632/x8632-numbers.lisp

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

Merge copyright/license header changes to 1.11 release branch.

File size: 10.8 KB
RevLine 
[16688]1;;;
[13067]2;;; Copyright 2009 Clozure Associates
3;;;
[16688]4;;; Licensed under the Apache License, Version 2.0 (the "License");
5;;; you may not use this file except in compliance with the License.
6;;; You may obtain a copy of the License at
[13067]7;;;
[16688]8;;; http://www.apache.org/licenses/LICENSE-2.0
[13067]9;;;
[16688]10;;; Unless required by applicable law or agreed to in writing, software
11;;; distributed under the License is distributed on an "AS IS" BASIS,
12;;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13;;; See the License for the specific language governing permissions and
14;;; limitations under the License.
[13067]15
[7998]16(in-package "CCL")
17
18(defx8632lapfunction %fixnum-signum ((number arg_z))
19 (mov ($ '-1) (% temp0))
20 (mov ($ '1) (% temp1))
21 (test (% number) (% number))
22 (cmovs (% temp0) (% arg_z))
23 (cmovns (% temp1) (% arg_z))
24 (single-value-return))
25
26;;; see %logcount.
27(defx86lapfunction %ilogcount ((number arg_z))
28 (mark-as-imm temp0)
29 (let ((rshift imm0)
30 (temp temp0))
31 (unbox-fixnum number rshift)
32 (xor (% arg_z) (% arg_z))
33 (test (% rshift) (% rshift))
34 (jmp @test)
35 @next
36 (lea (@ -1 (% rshift)) (% temp))
37 (and (% temp) (% rshift)) ;sets flags
38 (lea (@ '1 (% arg_z)) (% arg_z)) ;doesn't set flags
39 @test
40 (jne @next))
41 (mark-as-node temp0)
42 (single-value-return))
43
44;;; might be able to get away with not marking ecx as imm.
45(defx8632lapfunction %iash ((number arg_y) (count arg_z))
46 (mark-as-imm ecx) ;aka temp0
47 (unbox-fixnum count ecx)
48 (test (% count) (% count))
49 (jge @left)
50 (negb (% cl))
51 (unbox-fixnum number imm0)
52 (sar (% cl) (% imm0))
53 (box-fixnum imm0 arg_z)
54 (mark-as-node ecx)
55 (single-value-return)
56 @left
57 (shl (% cl) (% number))
58 (movl (% number) (% arg_z))
59 (mark-as-node ecx)
60 (single-value-return))
61
62(defparameter *double-float-zero* 0.0d0)
63(defparameter *short-float-zero* 0.0s0)
64
65(defx8632lapfunction %sfloat-hwords ((sfloat arg_z))
66 (movl (% esp) (% temp0))
67 (movzwl (@ (+ 2 x8632::misc-data-offset) (% sfloat)) (% imm0))
68 (box-fixnum imm0 temp1)
69 (pushl (% temp1)) ;high
70 (movzwl (@ x8632::misc-data-offset (% sfloat)) (% imm0))
71 (box-fixnum imm0 temp1)
72 (pushl (% temp1)) ;low
73 (set-nargs 2)
74 (jmp-subprim .SPvalues))
75
76(defx8632lapfunction %fixnum-intlen ((number arg_z))
77 (mark-as-imm temp0)
78 (let ((imm1 temp0))
79 (unbox-fixnum arg_z imm0)
80 (mov (% imm0) (% imm1))
81 (not (% imm1))
82 (test (% imm0) (% imm0))
83 (cmovs (% imm1) (% imm0))
84 (bsrl (% imm0) (% imm0))
85 (setne (%b imm1))
86 (addb (%b imm1) (%b imm0))
87 (box-fixnum imm0 arg_z))
88 (mark-as-node temp0)
89 (single-value-return))
90
91;;; Caller guarantees that result fits in a fixnum.
92(defx8632lapfunction %truncate-double-float->fixnum ((arg arg_z))
93 (get-double-float arg fp1)
94 (cvttsd2si (% fp1) (% imm0))
95 (box-fixnum imm0 arg_z)
96 (single-value-return))
97
98(defx8632lapfunction %truncate-short-float->fixnum ((arg arg_z))
99 (get-single-float arg fp1)
100 (cvttss2si (% fp1) (% imm0))
101 (box-fixnum imm0 arg_z)
102 (single-value-return))
103
104;;; DOES round to even
105(defx8632lapfunction %round-nearest-double-float->fixnum ((arg arg_z))
106 (get-double-float arg fp1)
107 (cvtsd2si (% fp1) (% imm0))
108 (box-fixnum imm0 arg_z)
109 (single-value-return))
110
111(defx8632lapfunction %round-nearest-short-float->fixnum ((arg arg_z))
112 (get-single-float arg fp1)
113 (cvtss2si (% fp1) (% imm0))
114 (box-fixnum imm0 arg_z)
115 (single-value-return))
116
[13531]117
118
[7998]119;;; We'll get a SIGFPE if divisor is 0.
120(defx8632lapfunction %fixnum-truncate ((dividend arg_y) (divisor arg_z))
[13531]121 (cmpl ($ '-1) (% divisor))
122 (je @neg)
[7998]123 (mark-as-imm temp0)
124 (mark-as-imm temp1)
125 (let ((imm2 temp0)
126 (imm1 temp1)) ;edx
127 (unbox-fixnum dividend imm0)
128 (unbox-fixnum divisor imm2)
129 (cltd) ;edx:eax = sign_extend(eax)
130 (idivl (% imm2))
131 (box-fixnum imm0 arg_z) ;quotient
132 (box-fixnum imm1 arg_y)) ;remainder
133 (mark-as-node temp0)
134 (mark-as-node temp1)
135 (movl (% esp) (% temp0))
136 (push (% arg_z))
137 (push (% arg_y))
138 (set-nargs 2)
[13531]139 (jmp-subprim .SPvalues)
140 @neg
141 (negl (% dividend))
142 (load-constant *least-positive-bignum* arg_z)
143 (cmovol (@ x8632::symbol.vcell (% arg_z)) (% dividend))
144 (movl (% esp) (% temp0))
145 (pushl (% dividend))
146 (pushl ($ 0))
147 (set-nargs 2)
[7998]148 (jmp-subprim .SPvalues))
149
150(defx8632lapfunction called-for-mv-p ()
151 (movl (@ x8632::lisp-frame.return-address (% ebp)) (% imm0))
[10959]152 (cmpl (% imm0) (@ (+ (target-nil-value) (x8632::kernel-global ret1valaddr))))
153 (movl ($ (target-t-value)) (% imm0))
154 (movl ($ (target-nil-value)) (% arg_z))
[7998]155 (cmove (% imm0) (% arg_z))
156 (single-value-return))
[8975]157
[7998]158;;; n1 and n2 must be positive (esp non zero)
159(defx86lapfunction %fixnum-gcd ((boxed-u arg_y) (boxed-v arg_z))
160 (mark-as-imm temp0)
161 (mark-as-imm temp1)
162 (let ((u imm0)
163 (v temp1)
164 (k temp0)) ;temp0 = ecx
165 (xorl (% k) (% k))
166 (bsfl (% boxed-u) (% u))
167 (bsfl (% boxed-v) (% v))
168 (rcmp (% u) (% v))
169 (cmovlel (%l u) (%l k))
170 (cmovgl (%l v) (%l k))
171 (unbox-fixnum boxed-u u)
172 (unbox-fixnum boxed-v v)
173 (subb ($ x8632::fixnumshift) (%b k))
174 (jz @start)
175 (shrl (% cl) (% u))
176 (shrl (% cl) (% v))
177 @start
178 ;; At least one of u or v is odd at this point
179 @loop
180 ;; if u is even, shift it right one bit
181 (testb ($ 1) (%b u))
182 (jne @u-odd)
183 (shrl ($ 1) (% u))
184 (jmp @test)
185 @u-odd
186 ;; if v is even, shift it right one bit
187 (testb ($ 1) (%b v))
188 (jne @both-odd)
189 (shrl ($ 1) (% v))
190 (jmp @test-u)
191 @both-odd
192 (cmpl (% v) (% u))
193 (jb @v>u)
194 (subl (% v) (% u))
195 (shrl ($ 1) (% u))
196 (jmp @test)
197 @v>u
198 (subl (% u) (% v))
199 (shrl ($ 1) (% v))
200 @test-u
201 (testl (% u) (% u))
202 @test
203 (ja @loop)
204 (shll (% cl) (% v))
205 (movb ($ 0) (% cl))
206 (box-fixnum v arg_z))
207 (mark-as-node temp0)
208 (mark-as-node temp1)
209 (single-value-return))
210
[13327]211(defx8632lapfunction %mrg31k3p ((state arg_z))
212 (let ((seed temp0)
213 (m1 #x7fffffff)
214 (m2 #x7fffadb3)
215 (negative-m1 #x80000001)
216 (negative-m2 #x8000524d)
217 (imm1 temp1))
218 (mark-as-imm temp1)
219 (svref state 1 seed)
220 (movl (@ (+ x8632::misc-data-offset (* 4 1)) (% seed)) (% imm0))
221 (andl ($ #x1ff) (% imm0))
222 (shll ($ 22) (% imm0))
223 (movl (@ (+ x8632::misc-data-offset (* 4 1)) (% seed)) (% imm1))
224 (shrl ($ 9) (% imm1))
225 (addl (% imm1) (% imm0))
226
227 (movl (@ (+ x8632::misc-data-offset (* 4 2)) (% seed)) (% imm1))
228 (andl ($ #xffffff) (% imm1))
229 (shll ($ 7) (% imm1))
230 (addl (% imm1) (% imm0))
231 (movl (@ (+ x8632::misc-data-offset (* 4 2)) (% seed)) (% imm1))
232 (shrl ($ 24) (% imm1))
233
234 (addl (% imm1) (% imm0))
235 (leal (@ negative-m1 (% imm0)) (% imm1))
236 (cmpl ($ m1) (% imm0))
237 (cmovael (% imm1) (% imm0))
238
239 (addl (@ (+ x8632::misc-data-offset (* 4 2)) (% seed)) (% imm0))
240 (leal (@ negative-m1 (% imm0)) (% imm1))
241 (cmpl ($ m1) (% imm0))
242 (cmovael (% imm1) (% imm0))
243
244 ;; update state
245 (movl (@ (+ x8632::misc-data-offset (* 4 1)) (% seed)) (% imm1))
246 (movl (% imm1) (@ (+ x8632::misc-data-offset (* 4 2)) (% seed)))
247 (movl (@ (+ x8632::misc-data-offset (* 4 0)) (% seed)) (% imm1))
248 (movl (% imm1) (@ (+ x8632::misc-data-offset (* 4 1)) (% seed)))
249 (movl (% imm0) (@ (+ x8632::misc-data-offset (* 4 0)) (% seed)))
250
251 ;; second component
252 (movzwl (@ (+ x8632::misc-data-offset (* 4 3)) (% seed)) (% imm0))
253 ;(andl ($ #xffff) (% imm0))
254 (shll ($ 15) (% imm0))
255 (movl (@ (+ x8632::misc-data-offset (* 4 3)) (% seed)) (% imm1))
256 (shrl ($ 16) (% imm1))
257 (imull ($ 21069) (% imm1) (% imm1))
258
259 (addl (% imm1) (% imm0))
260 (leal (@ negative-m2 (% imm0)) (% imm1))
261 (cmpl ($ m2) (% imm0))
262 (cmovael (% imm1) (% imm0))
263 (movl (% imm0) (:rcontext x8632::tcr.unboxed0)) ;stash t1
264
265 (movzwl (@ (+ x8632::misc-data-offset (* 4 5)) (% seed)) (% imm0))
266 ;(andl ($ #xffff) (% imm0))
267 (shll ($ 15) (% imm0))
268 (movl (@ (+ x8632::misc-data-offset (* 4 5)) (% seed)) (% imm1))
269 (shrl ($ 16) (% imm1))
270 (imull ($ 21069) (% imm1) (% imm1))
271
272 (addl (% imm1) (% imm0))
273 (leal (@ negative-m2 (% imm0)) (% imm1))
274 (cmpl ($ m2) (% imm0))
275 (cmovael (% imm1) (% imm0))
276
277 (addl (@ (+ x8632::misc-data-offset (* 4 5)) (% seed)) (% imm0))
278 (leal (@ negative-m2 (% imm0)) (% imm1))
279 (cmpl ($ m2) (% imm0))
280 (cmovael (% imm1) (% imm0))
281
282 (addl (:rcontext x8632::tcr.unboxed0) (% imm0)) ;add in t1
283 (leal (@ negative-m2 (% imm0)) (% imm1))
284 (cmpl ($ m2) (% imm0))
285 (cmovael (% imm1) (% imm0))
286
287 ;; update state
288 (movl (@ (+ x8632::misc-data-offset (* 4 4)) (% seed)) (% imm1))
289 (movl (% imm1) (@ (+ x8632::misc-data-offset (* 4 5)) (% seed)))
290 (movl (@ (+ x8632::misc-data-offset (* 4 3)) (% seed)) (% imm1))
291 (movl (% imm1) (@ (+ x8632::misc-data-offset (* 4 4)) (% seed)))
292 (movl (% imm0) (@ (+ x8632::misc-data-offset (* 4 3)) (% seed)))
293
294 ;; combination
295 (movl (@ (+ x8632::misc-data-offset (* 4 0)) (% seed)) (% imm1))
296 (xchgl (% imm1) (% imm0)) ;for sanity
297 (rcmpl (% imm0) (% imm1))
298 (ja @ok)
299 (subl (% imm1) (% imm0))
300 (mark-as-node temp1)
301 (addl ($ m1) (% imm0))
302 (box-fixnum imm0 arg_z)
303 (andl ($ #x7fffffff) (% arg_z))
304 (single-value-return)
305 @ok
306 (subl (% imm1) (% imm0))
307 (mark-as-node temp1)
308 (box-fixnum imm0 arg_z)
309 (andl ($ #x7fffffff) (% arg_z))
310 (single-value-return)))
[16085]311
312(defx8632lapfunction %make-complex-double-float ((r arg_y) (i arg_z))
313 (movsd (@ target::misc-dfloat-offset (% r)) (% xmm0))
314 (movsd (@ target::misc-dfloat-offset (% i)) (% xmm1))
315 (unpcklpd (% xmm1) (% xmm0))
316 (movl ($ (logior (ash 5 x8632::num-subtag-bits) x8632::subtag-complex-double-float)) (%l imm0))
317 (movd (% imm0) (% mm0))
318 (movl ($ (- (* 2 8) x8632::fulltag-misc)) (%l imm0))
319 (subl (% imm0) (:rcontext x8632::tcr.save-allocptr))
320 (movl (:rcontext x8632::tcr.save-allocptr) (% allocptr))
321 (cmpl (:rcontext x8632::tcr.save-allocbase) (% allocptr))
322 (ja @no-trap)
323 (uuo-alloc)
324 @no-trap
325 (movd (% mm0) (@ x8632::misc-header-offset (% temp0)))
326 (andb ($ (lognot x8632::fulltagmask)) (:rcontext x8632::tcr.save-allocptr))
327 (movl (% allocptr) (% arg_z))
328 (movdqu (% xmm0) (@ x8632::complex-double-float.realpart (% arg_z)))
329 (single-value-return))
330
331(defx8632lapfunction %make-complex-single-float ((r arg_y) (i arg_z))
332 (movsd (@ target::misc-data-offset (% r)) (% xmm0))
333 (movsd (@ target::misc-data-offset (% i)) (% xmm1))
334 (unpcklps (% xmm1) (% xmm0))
335 (movl ($ (logior (ash 3 x8632::num-subtag-bits) x8632::subtag-complex-single-float)) (%l imm0))
336 (movd (% imm0) (% mm0))
337 (movl ($ (- (* 2 8) x8632::fulltag-misc)) (%l imm0))
338 (subl (% imm0) (:rcontext x8632::tcr.save-allocptr))
339 (movl (:rcontext x8632::tcr.save-allocptr) (% allocptr))
340 (cmpl (:rcontext x8632::tcr.save-allocbase) (% allocptr))
341 (ja @no-trap)
342 (uuo-alloc)
343 @no-trap
344 (movq (% mm0) (@ x8632::misc-header-offset (% temp0)))
345 (andb ($ (lognot x8632::fulltagmask)) (:rcontext x8632::tcr.save-allocptr))
346 (movl (% allocptr) (% arg_z))
347 (movq (% xmm0) (@ x8632::complex-single-float.realpart (% arg_z)))
[16688]348 (single-value-return))
Note: See TracBrowser for help on using the repository browser.