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

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

Merge r13529 through r13532 (special-case divisor of -1 in %fixnum-truncate)
from trunk to 1.4 branch. Fixes ticket:666.

File size: 6.3 KB
RevLine 
[13075]1;;; Copyright 2009 Clozure Associates
2;;; This file is part of Clozure CL.
3;;;
4;;; Clozure CL is licensed under the terms of the Lisp Lesser GNU
5;;; Public License , known as the LLGPL and distributed with Clozure
6;;; CL as the file "LICENSE". The LLGPL consists of a preamble and
7;;; the LGPL, which is distributed with Clozure CL as the file "LGPL".
8;;; Where these conflict, the preamble takes precedence.
9;;;
10;;; Clozure CL is referenced in the preamble as the "LIBRARY."
11;;;
12;;; The LLGPL is also available online at
13;;; http://opensource.franz.com/preamble.html
14
[7998]15(in-package "CCL")
16
17(defx8632lapfunction %fixnum-signum ((number arg_z))
18 (mov ($ '-1) (% temp0))
19 (mov ($ '1) (% temp1))
20 (test (% number) (% number))
21 (cmovs (% temp0) (% arg_z))
22 (cmovns (% temp1) (% arg_z))
23 (single-value-return))
24
25;;; see %logcount.
26(defx86lapfunction %ilogcount ((number arg_z))
27 (mark-as-imm temp0)
28 (let ((rshift imm0)
29 (temp temp0))
30 (unbox-fixnum number rshift)
31 (xor (% arg_z) (% arg_z))
32 (test (% rshift) (% rshift))
33 (jmp @test)
34 @next
35 (lea (@ -1 (% rshift)) (% temp))
36 (and (% temp) (% rshift)) ;sets flags
37 (lea (@ '1 (% arg_z)) (% arg_z)) ;doesn't set flags
38 @test
39 (jne @next))
40 (mark-as-node temp0)
41 (single-value-return))
42
43;;; might be able to get away with not marking ecx as imm.
44(defx8632lapfunction %iash ((number arg_y) (count arg_z))
45 (mark-as-imm ecx) ;aka temp0
46 (unbox-fixnum count ecx)
47 (test (% count) (% count))
48 (jge @left)
49 (negb (% cl))
50 (unbox-fixnum number imm0)
51 (sar (% cl) (% imm0))
52 (box-fixnum imm0 arg_z)
53 (mark-as-node ecx)
54 (single-value-return)
55 @left
56 (shl (% cl) (% number))
57 (movl (% number) (% arg_z))
58 (mark-as-node ecx)
59 (single-value-return))
60
61(defparameter *double-float-zero* 0.0d0)
62(defparameter *short-float-zero* 0.0s0)
63
64(defx8632lapfunction %sfloat-hwords ((sfloat arg_z))
65 (movl (% esp) (% temp0))
66 (movzwl (@ (+ 2 x8632::misc-data-offset) (% sfloat)) (% imm0))
67 (box-fixnum imm0 temp1)
68 (pushl (% temp1)) ;high
69 (movzwl (@ x8632::misc-data-offset (% sfloat)) (% imm0))
70 (box-fixnum imm0 temp1)
71 (pushl (% temp1)) ;low
72 (set-nargs 2)
73 (jmp-subprim .SPvalues))
74
75(defx8632lapfunction %fixnum-intlen ((number arg_z))
76 (mark-as-imm temp0)
77 (let ((imm1 temp0))
78 (unbox-fixnum arg_z imm0)
79 (mov (% imm0) (% imm1))
80 (not (% imm1))
81 (test (% imm0) (% imm0))
82 (cmovs (% imm1) (% imm0))
83 (bsrl (% imm0) (% imm0))
84 (setne (%b imm1))
85 (addb (%b imm1) (%b imm0))
86 (box-fixnum imm0 arg_z))
87 (mark-as-node temp0)
88 (single-value-return))
89
90;;; Caller guarantees that result fits in a fixnum.
91(defx8632lapfunction %truncate-double-float->fixnum ((arg arg_z))
92 (get-double-float arg fp1)
93 (cvttsd2si (% fp1) (% imm0))
94 (box-fixnum imm0 arg_z)
95 (single-value-return))
96
97(defx8632lapfunction %truncate-short-float->fixnum ((arg arg_z))
98 (get-single-float arg fp1)
99 (cvttss2si (% fp1) (% imm0))
100 (box-fixnum imm0 arg_z)
101 (single-value-return))
102
103;;; DOES round to even
104(defx8632lapfunction %round-nearest-double-float->fixnum ((arg arg_z))
105 (get-double-float arg fp1)
106 (cvtsd2si (% fp1) (% imm0))
107 (box-fixnum imm0 arg_z)
108 (single-value-return))
109
110(defx8632lapfunction %round-nearest-short-float->fixnum ((arg arg_z))
111 (get-single-float arg fp1)
112 (cvtss2si (% fp1) (% imm0))
113 (box-fixnum imm0 arg_z)
114 (single-value-return))
115
[13535]116
117
[7998]118;;; We'll get a SIGFPE if divisor is 0.
119(defx8632lapfunction %fixnum-truncate ((dividend arg_y) (divisor arg_z))
[13535]120 (cmpl ($ '-1) (% divisor))
121 (je @neg)
[7998]122 (mark-as-imm temp0)
123 (mark-as-imm temp1)
124 (let ((imm2 temp0)
125 (imm1 temp1)) ;edx
126 (unbox-fixnum dividend imm0)
127 (unbox-fixnum divisor imm2)
128 (cltd) ;edx:eax = sign_extend(eax)
129 (idivl (% imm2))
130 (box-fixnum imm0 arg_z) ;quotient
131 (box-fixnum imm1 arg_y)) ;remainder
132 (mark-as-node temp0)
133 (mark-as-node temp1)
134 (movl (% esp) (% temp0))
135 (push (% arg_z))
136 (push (% arg_y))
137 (set-nargs 2)
[13535]138 (jmp-subprim .SPvalues)
139 @neg
140 (negl (% dividend))
141 (load-constant *least-positive-bignum* arg_z)
142 (cmovol (@ x8632::symbol.vcell (% arg_z)) (% dividend))
143 (movl (% esp) (% temp0))
144 (pushl (% dividend))
145 (pushl ($ 0))
146 (set-nargs 2)
[7998]147 (jmp-subprim .SPvalues))
148
149(defx8632lapfunction called-for-mv-p ()
150 (movl (@ x8632::lisp-frame.return-address (% ebp)) (% imm0))
[10959]151 (cmpl (% imm0) (@ (+ (target-nil-value) (x8632::kernel-global ret1valaddr))))
152 (movl ($ (target-t-value)) (% imm0))
153 (movl ($ (target-nil-value)) (% arg_z))
[7998]154 (cmove (% imm0) (% arg_z))
155 (single-value-return))
156
[8975]157(defx8632lapfunction %next-random-pair ((high arg_y) (low arg_z))
158 ;; high: (unsigned-byte 15)
159 ;; low: (unsigned-byte 16)
160 (unbox-fixnum low imm0)
161 ;; clear most significant bit
162 (shll ($ (1+ (- 16 x8632::fixnumshift))) (% high))
163 (shrl ($ 1) (% high))
164 (orl (% high) (% imm0))
165 (mark-as-imm edx)
166 (movl ($ 48271) (% edx))
167 (mul (% edx))
168 (mark-as-node edx)
169 (movl ($ (- #x10000)) (% high)) ;#xffff0000
170 (andl (% imm0) (% high))
171 (shrl ($ (- 16 x8632::fixnumshift)) (% high))
172 (shll ($ 16) (% imm0))
173 (shrl ($ (- 16 x8632::fixnumshift)) (% imm0))
174 (movl (% imm0) (% low))
175 (movl (% esp) (% temp0))
176 (push (% high))
177 (push (% low))
178 (set-nargs 2)
179 (jmp-subprim .SPvalues))
180
[7998]181;;; n1 and n2 must be positive (esp non zero)
182(defx86lapfunction %fixnum-gcd ((boxed-u arg_y) (boxed-v arg_z))
183 (mark-as-imm temp0)
184 (mark-as-imm temp1)
185 (let ((u imm0)
186 (v temp1)
187 (k temp0)) ;temp0 = ecx
188 (xorl (% k) (% k))
189 (bsfl (% boxed-u) (% u))
190 (bsfl (% boxed-v) (% v))
191 (rcmp (% u) (% v))
192 (cmovlel (%l u) (%l k))
193 (cmovgl (%l v) (%l k))
194 (unbox-fixnum boxed-u u)
195 (unbox-fixnum boxed-v v)
196 (subb ($ x8632::fixnumshift) (%b k))
197 (jz @start)
198 (shrl (% cl) (% u))
199 (shrl (% cl) (% v))
200 @start
201 ;; At least one of u or v is odd at this point
202 @loop
203 ;; if u is even, shift it right one bit
204 (testb ($ 1) (%b u))
205 (jne @u-odd)
206 (shrl ($ 1) (% u))
207 (jmp @test)
208 @u-odd
209 ;; if v is even, shift it right one bit
210 (testb ($ 1) (%b v))
211 (jne @both-odd)
212 (shrl ($ 1) (% v))
213 (jmp @test-u)
214 @both-odd
215 (cmpl (% v) (% u))
216 (jb @v>u)
217 (subl (% v) (% u))
218 (shrl ($ 1) (% u))
219 (jmp @test)
220 @v>u
221 (subl (% u) (% v))
222 (shrl ($ 1) (% v))
223 @test-u
224 (testl (% u) (% u))
225 @test
226 (ja @loop)
227 (shll (% cl) (% v))
228 (movb ($ 0) (% cl))
229 (box-fixnum v arg_z))
230 (mark-as-node temp0)
231 (mark-as-node temp1)
232 (single-value-return))
233
Note: See TracBrowser for help on using the repository browser.