~linuxjedi/drizzle/trunk-bug-667053

« back to all changes in this revision

Viewing changes to strings/longlong2str-x86.s

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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