longlong2str-x86.s 4.75 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
# Copyright (C) 2000 MySQL AB
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
unknown's avatar
unknown committed
15

16 17
# Optimized longlong2str function for Intel 80x86  (gcc/gas syntax) 
# Some set sequences are optimized for pentuimpro II 
unknown's avatar
unknown committed
18

19 20
	.file	"longlong2str-x86.s"
	.version "1.02"
unknown's avatar
unknown committed
21 22 23 24

.text
	.align 4

25 26
.globl	longlong2str_with_dig_vector
	.type	 longlong2str_with_dig_vector,@function
unknown's avatar
unknown committed
27
	
28
longlong2str_with_dig_vector:
unknown's avatar
unknown committed
29 30 31 32 33
	subl $80,%esp
	pushl %ebp
	pushl %esi
	pushl %edi
	pushl %ebx
34 35
	movl 100(%esp),%esi	# Lower part of val 
	movl 112(%esp),%ebx	# Radix 
36
	movl 104(%esp),%ebp	# Higher part of val 
unknown's avatar
unknown committed
37
	movl %ebx,%eax
38
	movl 108(%esp),%edi	# get dst 
unknown's avatar
unknown committed
39 40 41 42 43
	testl %eax,%eax
	jge .L144

	addl $36,%eax
	cmpl $34,%eax
44
	ja .Lerror		# Wrong radix 
unknown's avatar
unknown committed
45 46
	testl %ebp,%ebp
	jge .L146
47 48
	movb $45,(%edi)		# Add sign 
	incl %edi		# Change sign of val 
unknown's avatar
unknown committed
49 50 51 52
	negl %esi
	adcl $0,%ebp
	negl %ebp
.L146:
53
	negl %ebx		# Change radix to positive 
unknown's avatar
unknown committed
54
	jmp .L148
55
	.align 4
unknown's avatar
unknown committed
56 57 58
.L144:
	addl $-2,%eax
	cmpl $34,%eax
59
	ja .Lerror		# Radix in range 
unknown's avatar
unknown committed
60 61

.L148:
62
	movl %esi,%eax		# Test if zero (for easy loop) 
unknown's avatar
unknown committed
63 64 65 66
	orl %ebp,%eax
	jne .L150
	movb $48,(%edi)
	incl %edi
67
	jmp .L10_end
68
	.align 4
unknown's avatar
unknown committed
69 70

.L150:
71
	leal 92(%esp),%ecx	# End of buffer 
72 73
	movl %edi, 108(%esp)    # Store possible modified dest
	movl 116(%esp), %edi    # dig_vec_upper
unknown's avatar
unknown committed
74
	jmp  .L155
75
	.align 4
unknown's avatar
unknown committed
76 77

.L153:
78
	# val is stored in in ebp:esi 
unknown's avatar
unknown committed
79

80
	movl %ebp,%eax		# High part of value 
unknown's avatar
unknown committed
81 82 83 84 85
	xorl %edx,%edx
	divl %ebx
	movl %eax,%ebp
	movl %esi,%eax
	divl %ebx
86
	decl %ecx
87
	movl %eax,%esi		# quotent in ebp:esi 
88
	movb (%edx,%edi),%al    # al is faster than dl 
89 90
	movb %al,(%ecx)		# store value in buff 
	.align 4
unknown's avatar
unknown committed
91 92 93
.L155:
	testl %ebp,%ebp
	ja .L153
94
	testl %esi,%esi		# rest value 
unknown's avatar
unknown committed
95
	jl .L153
96
	je .L160		# Ready 
unknown's avatar
unknown committed
97
	movl %esi,%eax
98
	.align 4
unknown's avatar
unknown committed
99

100
.L154:				# Do rest with integer precision 
unknown's avatar
unknown committed
101 102 103
	cltd
	divl %ebx
	decl %ecx
104
	movb (%edx,%edi),%dl	# bh is always zero as ebx=radix < 36 
unknown's avatar
unknown committed
105 106 107 108
	testl %eax,%eax
	movb %dl,(%ecx)
	jne .L154

109 110 111
.L160:
	movl 108(%esp),%edi	# get dst 
	
112
.L10_mov:
unknown's avatar
unknown committed
113
	movl %ecx,%esi
114
	leal 92(%esp),%ecx	# End of buffer 
unknown's avatar
unknown committed
115 116 117 118
	subl %esi,%ecx
	rep
	movsb

119
.L10_end:
120 121
	movl %edi,%eax		# Pointer to end null 
	movb $0,(%edi)		# Store the end null 
unknown's avatar
unknown committed
122 123 124 125 126 127 128 129 130 131

.L165:
	popl %ebx
	popl %edi
	popl %esi
	popl %ebp
	addl $80,%esp
	ret

.Lerror:
132
	xorl %eax,%eax		# Wrong radix 
unknown's avatar
unknown committed
133 134 135
	jmp .L165

.Lfe3:
136
	.size	 longlong2str_with_dig_vector,.Lfe3-longlong2str_with_dig_vector
unknown's avatar
unknown committed
137

138 139 140 141 142 143 144
#
# This is almost equal to the above, except that we can do the final
# loop much more efficient	
#	

	.align 4
	
unknown's avatar
unknown committed
145
.globl	longlong10_to_str
146
	.type	 longlong10_to_str,@function
unknown's avatar
unknown committed
147
longlong10_to_str:
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
	subl $80,%esp
	pushl %ebp
	pushl %esi
	pushl %edi
	pushl %ebx
	movl 100(%esp),%esi	# Lower part of val 
	movl 104(%esp),%ebp	# Higher part of val 
	movl 108(%esp),%edi	# get dst 
	movl 112(%esp),%ebx	# Radix (10 or -10)
	testl %ebx,%ebx
	jge .L10_10		# Positive radix

	negl %ebx		# Change radix to positive (= 10)

	testl %ebp,%ebp		# Test if negative value
	jge .L10_10
	movb $45,(%edi)		# Add sign 
	incl %edi
	negl %esi		# Change sign of val (ebp:esi)
	adcl $0,%ebp
	negl %ebp
	.align 4

.L10_10:
	leal 92(%esp),%ecx	# End of buffer 
	movl %esi,%eax		# Test if zero (for easy loop) 
	orl %ebp,%eax
	jne .L10_30		# Not zero

	# Here when value is zero
	movb $48,(%edi)
	incl %edi
	jmp .L10_end
	.align 4

.L10_20:
	# val is stored in in ebp:esi 
	movl %ebp,%eax		# High part of value 
	xorl %edx,%edx
	divl %ebx		# Divide by 10
	movl %eax,%ebp
	movl %esi,%eax
	divl %ebx		# Divide by 10
	decl %ecx
	movl %eax,%esi		# quotent in ebp:esi 
	addl $48,%edx		# Convert to ascii
	movb %dl,(%ecx)		# store value in buff 

.L10_30:
	testl %ebp,%ebp
	ja .L10_20
	testl %esi,%esi		# rest value 
	jl .L10_20		# Unsigned, do ulonglong div once more
	je .L10_mov		# Ready
	movl %esi,%ebx		# Move val to %ebx

	# The following code uses some tricks to change division by 10 to
	# multiplication and shifts
206 207
	movl $0xcccccccd,%esi
		
208 209 210 211 212 213 214 215 216 217 218 219 220 221
.L10_40:
        movl %ebx,%eax
        mull %esi
        decl %ecx
        shrl $3,%edx
        leal (%edx,%edx,4),%eax
        addl %eax,%eax
        subb %al,%bl		# %bl now contains val % 10
        addb $48,%bl
        movb %bl,(%ecx)
        movl %edx,%ebx
        testl %ebx,%ebx
	jne .L10_40
	jmp .L10_mov		# Shared end with longlong10_to_str
unknown's avatar
unknown committed
222 223 224

.L10end:
	.size	 longlong10_to_str,.L10end-longlong10_to_str