~drizzle-trunk/drizzle/development

1 by brian
clean slate
1
# Copyright (C) 2000 MySQL AB
2
# This program is free software; you can redistribute it and/or modify
3
# it under the terms of the GNU General Public License as published by
4
# the Free Software Foundation; version 2 of the License.
5
#
6
# This program is distributed in the hope that it will be useful,
7
# but WITHOUT ANY WARRANTY; without even the implied warranty of
8
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9
# GNU General Public License for more details.
10
#
11
# You should have received a copy of the GNU General Public License
12
# along with this program; if not, write to the Free Software
13
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
14
15
# Optimized longlong2str function for Intel 80x86  (gcc/gas syntax) 
16
# Some set sequences are optimized for pentuimpro II 
17
18
	.file	"longlong2str-x86.s"
19
	.version "1.02"
20
21
.text
22
	.align 4
23
24
.globl	longlong2str_with_dig_vector
25
	.type	 longlong2str_with_dig_vector,@function
26
	
27
longlong2str_with_dig_vector:
28
	subl  $80,%esp          # Temporary buffer for up to 64 radix-2 digits
29
	pushl %ebp
30
	pushl %esi
31
	pushl %edi
32
	pushl %ebx
33
	movl 100(%esp),%esi	# esi = Lower part of val 
34
	movl 112(%esp),%ebx	# ebx = Radix 
35
	movl 104(%esp),%ebp	# ebp = Higher part of val 
36
	movl 108(%esp),%edi	# edi = dst
37
38
	testl %ebx,%ebx
39
	jge .L144		# Radix was positive
40
	negl %ebx		# Change radix to positive 
41
	testl %ebp,%ebp		# Test if given value is negative
42
	jge .L144
43
	movb $45,(%edi)		# Add sign 
44
	incl %edi		# Change sign of val 
45
	negl %esi
46
	adcl $0,%ebp
47
	negl %ebp
48
	
49
.L144:	# Test that radix is between 2 and 36
50
	movl %ebx, %eax
51
	addl $-2,%eax		# Test that radix is between 2 and 36
52
	cmpl $34,%eax
53
	ja .Lerror		# Radix was not in range
54
55
	leal 92(%esp),%ecx	# End of buffer 
56
	movl %edi, 108(%esp)    # Store possible modified dest
57
	movl 116(%esp), %edi    # dig_vec_upper
58
	testl %ebp,%ebp		# Test if value > 0xFFFFFFFF
59
	jne .Llongdiv
60
	cmpl %ebx, %esi		# Test if <= radix, for easy loop
61
	movl %esi, %eax		# Value in eax (for Llow)
62
	jae .Llow
63
64
	# Value is one digit (negative or positive)
65
	movb (%eax,%edi),%bl
66
	movl 108(%esp),%edi	# get dst
67
	movb %bl,(%edi)
68
	incl %edi		# End null here
69
	jmp .L10_end
70
71
.Llongdiv:
72
	# Value in ebp:esi. div the high part by the radix,
73
        # then div remainder + low part by the radix.
74
	movl %ebp,%eax		# edx=0,eax=high(from ebp)
75
	xorl %edx,%edx
76
	decl %ecx
77
	divl %ebx
78
	movl %eax,%ebp		# edx=result of last, eax=low(from esi)
79
	movl %esi,%eax
80
	divl %ebx
81
	movl %eax,%esi		# ebp:esi = quotient
82
	movb (%edx,%edi),%dl	# Store result number in temporary buffer
83
	testl %ebp,%ebp
84
	movb %dl,(%ecx)		# store value in buff 
85
	ja .Llongdiv		# (Higher part of val still > 0)
86
	
87
	.align 4
88
.Llow:				# Do rest with integer precision 
89
	# Value in 0:eax. div 0 + low part by the radix.
90
	xorl  %edx,%edx
91
	decl %ecx
92
	divl %ebx
93
	movb (%edx,%edi),%dl	# bh is always zero as ebx=radix < 36 
94
	testl %eax,%eax
95
	movb %dl,(%ecx)
96
	jne .Llow
97
98
.L160:
99
	movl 108(%esp),%edi	# get dst 
100
101
.Lcopy_end:	
102
	leal 92(%esp),%esi	# End of buffer 
103
.Lmov:				# mov temporary buffer to result (%ecx -> %edi)
104
	movb (%ecx), %al
105
	movb %al, (%edi)
106
	incl %ecx
107
	incl %edi
108
	cmpl  %ecx,%esi
109
	jne  .Lmov
110
111
.L10_end:
112
	movl %edi,%eax		# Pointer to end null 
113
	movb $0,(%edi)		# Store the end null 
114
115
.L165:
116
	popl %ebx
117
	popl %edi
118
	popl %esi
119
	popl %ebp
120
	addl $80,%esp
121
	ret
122
123
.Lerror:
124
	xorl %eax,%eax		# Wrong radix 
125
	jmp .L165
126
127
.Lfe3:
128
	.size	 longlong2str_with_dig_vector,.Lfe3-longlong2str_with_dig_vector
129
130
#
131
# This is almost equal to the above, except that we can do the final
132
# loop much more efficient	
133
#	
134
135
	.align 4
136
	
137
.globl	longlong10_to_str
138
	.type	 longlong10_to_str,@function
139
longlong10_to_str:
140
	subl $80,%esp
141
	pushl %ebp
142
	pushl %esi
143
	pushl %edi
144
	pushl %ebx
145
	movl 100(%esp),%esi	# Lower part of val 
146
	movl 104(%esp),%ebp	# Higher part of val 
147
	movl 108(%esp),%edi	# get dst 
148
	movl 112(%esp),%ebx	# Radix (10 or -10)
149
	testl %ebx,%ebx
150
	jge .L10_10		# Positive radix
151
152
	negl %ebx		# Change radix to positive (= 10)
153
154
	testl %ebp,%ebp		# Test if negative value
155
	jge .L10_10
156
	movb $45,(%edi)		# Add sign 
157
	incl %edi
158
	negl %esi		# Change sign of val (ebp:esi)
159
	adcl $0,%ebp
160
	negl %ebp
161
162
.L10_10:
163
	leal 92(%esp),%ecx	# End of buffer 
164
	testl %ebp,%ebp		# Test if value > 0xFFFFFFFF
165
	jne .L10_longdiv
166
	cmpl $10, %esi		# Test if <= radix, for easy loop
167
	movl %esi, %ebx		# Value in eax (for L10_low)
168
	jae .L10_low
169
170
	# Value is one digit (negative or positive)
171
	addb $48, %bl
172
	movb %bl,(%edi)
173
	incl %edi
174
	jmp .L10_end
175
	.align 4
176
177
.L10_longdiv:
178
	# val is stored in in ebp:esi 
179
	movl %ebp,%eax		# High part of value 
180
	xorl %edx,%edx
181
	divl %ebx		# Divide by 10
182
	movl %eax,%ebp
183
	movl %esi,%eax
184
	divl %ebx		# Divide by 10
185
	decl %ecx
186
	movl %eax,%esi		# quotent in ebp:esi 
187
	addl $48,%edx		# Convert to ascii
188
	movb %dl,(%ecx)		# store value in buff 
189
190
.L10_30:
191
	testl %ebp,%ebp
192
	ja .L10_longdiv
193
	movl %esi,%ebx		# Move val to %ebx
194
195
.L10_low:
196
	# The following code uses some tricks to change division by 10 to
197
	# multiplication and shifts
198
	movl $0xcccccccd,%esi
199
		
200
.L10_40:			# Divide %ebx with 10
201
        movl %ebx,%eax
202
        mull %esi
203
        decl %ecx
204
        shrl $3,%edx
205
        leal (%edx,%edx,4),%eax
206
        addl %eax,%eax
207
        subb %al,%bl		# %bl now contains val % 10
208
        addb $48,%bl
209
        movb %bl,(%ecx)
210
        movl %edx,%ebx
211
        testl %ebx,%ebx
212
	jne .L10_40
213
	jmp .Lcopy_end		# Shared end with longlong2str
214
215
.L10end:
216
	.size	 longlong10_to_str,.L10end-longlong10_to_str