~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to strings/my_strtoll10-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) 2003 MySQL AB
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; version 2 of the License.
 
6
#
 
7
# This program is distributed in the hope that it will be useful,
 
8
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
# GNU General Public License for more details.
 
11
#
 
12
# You should have received a copy of the GNU General Public License
 
13
# along with this program; if not, write to the Free Software
 
14
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
 
 
16
# Implemention of my_strtoll():  Converting a string to a 64 bit integer.
 
17
# For documentation, check my_strtoll.c
 
18
        
 
19
        .file   "my_strtoll10-x86.s"
 
20
        .version "01.02"
 
21
        
 
22
.text
 
23
        .align 4
 
24
        
 
25
.globl my_strtoll10
 
26
        .type    my_strtoll10,@function
 
27
 
 
28
 
 
29
        # Used stack variables
 
30
        # ebp-4         dummy for storing endptr if endptr = 0
 
31
        # ebp-8         First 9 digits of return values
 
32
        # ebp-12        Pointer to first digit of second part
 
33
        # ebp-16        Store lowest 2 digits
 
34
        # ebp-20        != 0 if value was negative
 
35
        # ebp-24        High max value
 
36
        # ebp-28        Middle max value
 
37
        # ebp-32        Low max value
 
38
        # ebp-36        Temp value
 
39
 
 
40
        # esi           Pointer to input string
 
41
        # ebx           End of string
 
42
        
 
43
my_strtoll10:
 
44
        pushl %ebp
 
45
        movl %esp,%ebp
 
46
        subl $48,%esp
 
47
        pushl %esi
 
48
        pushl %edi
 
49
        pushl %ebx
 
50
        movl 8(%ebp),%esi       # esi= nptr
 
51
        movl 16(%ebp),%ecx      # ecx= error (Will be overwritten later)
 
52
        movl 12(%ebp),%eax      # eax= endptr
 
53
        cmpl $0,%eax            # if (endptr)
 
54
        je .L110
 
55
 
 
56
# Fixed length string
 
57
        movl (%eax),%ebx        # bx= end-of-string
 
58
        .p2align 4,,7
 
59
.L100:
 
60
        cmpl %ebx,%esi
 
61
        je .Lno_conv
 
62
        movb (%esi), %al        # al= next byte
 
63
        incl %esi
 
64
        cmpb $32,%al            # Skip space
 
65
        je .L100
 
66
        cmpb $9,%al             # Skip tab
 
67
        je .L100
 
68
        jmp .L130
 
69
 
 
70
# String that ends with \0
 
71
 
 
72
.L110:
 
73
        leal -4(%ebp),%edi
 
74
        movl %edi,12(%ebp)      # endptr= &dummy, for easier end check
 
75
        .p2align 4,,7
 
76
.L120:
 
77
        movb (%esi), %al        # al= next byte
 
78
        incl %esi
 
79
        cmpb $32,%al
 
80
        je .L120
 
81
        cmpb $9,%al
 
82
        je .L120
 
83
        testb %al,%al           # Test if we found end \0
 
84
        je .Lno_conv
 
85
        leal 65535(%esi),%ebx   # ebx = end-of-string
 
86
 
 
87
.L130:
 
88
        cmpb $45,%al            # Test if '-'
 
89
        jne .Lpositive
 
90
 
 
91
        # negative number
 
92
        movl $-1,(%ecx)         # error = -1 (mark that number is negative)
 
93
        movl $1,-20(%ebp)       # negative= 1
 
94
        movl $92233720,-24(%ebp)
 
95
        movl $368547758,-28(%ebp)
 
96
        movl $8,-32(%ebp)
 
97
        jmp .L460
 
98
 
 
99
        .p2align 4,,7
 
100
.Lpositive:
 
101
        movl $0,(%ecx)          # error=0
 
102
        movl $0,-20(%ebp)       # negative= 0
 
103
        movl $184467440,-24(%ebp)
 
104
        movl $737095516,-28(%ebp)
 
105
        movl $15,-32(%ebp)
 
106
        cmpb $43,%al            # Check if '+'
 
107
        jne .L462
 
108
 
 
109
.L460:
 
110
        cmpl %ebx,%esi          # Check if overflow
 
111
        je .Lno_conv
 
112
        movb (%esi), %al        # al= next byte after sign
 
113
        incl %esi
 
114
                
 
115
        # Remove pre zero to be able to handle a lot of pre-zero
 
116
.L462:
 
117
        cmpb $48,%al
 
118
        jne .L475               # Number doesn't start with 0
 
119
        decl %esi
 
120
        .p2align 4,,7
 
121
 
 
122
        # Skip pre zeros
 
123
.L481:  
 
124
        incl %esi               # Skip processed byte
 
125
        cmpl %ebx,%esi
 
126
        je .Lms_return_zero
 
127
        cmpb (%esi),%al         # Test if next byte is also zero
 
128
        je .L481
 
129
        leal 9(%esi),%ecx       # ecx = end-of-current-part
 
130
        xorl %edi,%edi          # Store first 9 digits in edi
 
131
        jmp .L482
 
132
        .p2align 4,,7
 
133
 
 
134
        # Check if first char is a valid number
 
135
.L475:
 
136
        addb $-48,%al
 
137
        cmpb $9,%al
 
138
        ja .Lno_conv
 
139
.L477:  
 
140
        movzbl %al,%edi         # edi = first digit
 
141
        leal 8(%esi),%ecx       # ecx = end-of-current-part
 
142
 
 
143
        # Handle first 8/9 digits and store them in edi
 
144
.L482:
 
145
        cmpl %ebx,%ecx
 
146
        jbe .L522
 
147
        movl %ebx,%ecx          # ecx = min(end-of-current-part, end-of-string)
 
148
        jmp .L522
 
149
 
 
150
        .p2align 4,,7
 
151
.L488:
 
152
        movb (%esi), %al        # al= next byte
 
153
        incl %esi
 
154
        addb $-48,%al
 
155
        cmpb $9,%al
 
156
        ja .Lend_i_dec_esi
 
157
 
 
158
        # Calculate edi= edi*10 + al
 
159
        leal (%edi,%edi,4),%edx
 
160
        movzbl %al,%eax
 
161
        leal (%eax,%edx,2),%edi
 
162
.L522:
 
163
        cmpl %ecx,%esi          # If more digits at this level
 
164
        jne .L488
 
165
        cmpl %ebx,%esi          # If end of string
 
166
        je .Lend_i
 
167
 
 
168
        movl %edi,-8(%ebp)      # Store first 9 digits
 
169
        movl %esi,-12(%ebp)     # store pos to first digit of second part
 
170
 
 
171
        # Calculate next 9 digits and store them in edi
 
172
 
 
173
        xorl %edi,%edi
 
174
        leal 9(%esi),%ecx       # ecx= end-of-current-part
 
175
        movl %ecx,-36(%ebp)     # Store max length
 
176
        cmpl %ebx,%ecx
 
177
        jbe .L498
 
178
        movl %ebx,%ecx          # ecx = min(end-of-current-part, end-of-string)
 
179
 
 
180
        .p2align 4,,7
 
181
.L498:
 
182
        movb (%esi), %al        # al= next byte
 
183
        incl %esi
 
184
        addb $-48,%al
 
185
        cmpb $9,%al
 
186
        ja .Lend_i_and_j_decl_esi
 
187
 
 
188
        # Calculate edi= edi*10 + al
 
189
        leal (%edi,%edi,4),%edx
 
190
        movzbl %al,%eax
 
191
        leal (%eax,%edx,2),%edi
 
192
 
 
193
        cmpl %ecx,%esi          # If end of current part
 
194
        jne .L498
 
195
        cmpl %ebx,%esi          # If end of string
 
196
        jne .L500
 
197
        cmpl -36(%ebp),%esi     # Test if string is less than 18 digits
 
198
        jne .Lend_i_and_j
 
199
.L499:  
 
200
        movl $1000000000,%eax   
 
201
        jmp .Lgot_factor        # 18 digit string
 
202
 
 
203
        # Handle the possible next to last digit and store in ecx
 
204
.L500:
 
205
        movb (%esi),%al
 
206
        addb $-48,%al
 
207
        cmpb $9,%al
 
208
        ja .L499                # 18 digit string
 
209
 
 
210
        incl %esi
 
211
        movzbl %al,%ecx
 
212
        cmpl %ebx,%esi          # If end of string
 
213
        je .Lend4
 
214
 
 
215
        movb (%esi),%al         # Read last digit
 
216
        addb $-48,%al
 
217
        cmpb $9,%al
 
218
        ja .Lend4
 
219
 
 
220
        # ecx= ecx*10 + al
 
221
        leal (%ecx,%ecx,4),%edx
 
222
        movzbl %al,%eax
 
223
        leal (%eax,%edx,2),%ecx
 
224
 
 
225
        movl 12(%ebp),%eax      # eax = endptr
 
226
        incl %esi
 
227
        movl %esi,(%eax)        # *endptr = end-of-string
 
228
        cmpl %ebx,%esi
 
229
        je .L505                # At end of string
 
230
 
 
231
        movb (%esi),%al         # check if extra digits
 
232
        addb $-48,%al
 
233
        cmpb $9,%al
 
234
        jbe .Loverflow
 
235
 
 
236
        # At this point we have:
 
237
        # -8(%ebp)      First 9 digits
 
238
        # edi           Next 9 digits
 
239
        # ecx           Last 2 digits
 
240
        # *endpos       end-of-string
 
241
        
 
242
.L505:  # Check that we are not going to get overflow for unsigned long long
 
243
        movl -8(%ebp),%eax      # First 9 digits
 
244
        cmpl -24(%ebp),%eax
 
245
        ja .Loverflow
 
246
        jne .L507
 
247
        cmpl -28(%ebp),%edi
 
248
        ja .Loverflow
 
249
        jne .L507
 
250
        cmpl -32(%ebp),%ecx
 
251
        ja .Loverflow
 
252
 
 
253
.L507:
 
254
        movl %edi,-4(%ebp)      # Save middle bytes
 
255
        movl %ecx,%esi          # esi = 2 last digits
 
256
        movl $1215752192,%ecx   # %ecx= lower_32_bits(100000000000)
 
257
        mull %ecx
 
258
        imull $23,-8(%ebp),%ecx
 
259
        movl $0,-36(%ebp)
 
260
        movl %eax,%ebx
 
261
        imull $1215752192,-36(%ebp),%eax
 
262
        movl %edx,%edi
 
263
        addl %ecx,%edi
 
264
        addl %eax,%edi          # Temp in edi:ebx
 
265
 
 
266
        movl $100,%eax          # j= j*100
 
267
        mull -4(%ebp)
 
268
        addl %ebx,%eax          # edx:eax+= edi:ebx
 
269
        adcl %edi,%edx
 
270
        addl %esi,%eax
 
271
        adcl $0,%edx
 
272
        jmp .Lms_return
 
273
 
 
274
.Loverflow:
 
275
        # When we come here, *endptr is already updated
 
276
 
 
277
        movl 16(%ebp),%edx      # edx= error
 
278
        movl $34,(%edx)         # *error = 34
 
279
        movl $-1,%eax
 
280
        movl %eax,%edx
 
281
        cmpl $0,-20(%ebp)       # If negative
 
282
        je .Lms_return
 
283
        xor %eax,%eax           # edx:eax = LONGLONG_LMIN
 
284
        movl $-2147483648,%edx
 
285
        jmp .Lms_return
 
286
 
 
287
        # Return value that is in %edi as long long
 
288
        .p2align 4,,7
 
289
.Lend_i_dec_esi:
 
290
        decl %esi               # Fix so that it points at last digit
 
291
.Lend_i:
 
292
        xorl %edx,%edx
 
293
        movl %edi,%eax
 
294
        cmpl $0,-20(%ebp)
 
295
        je .Lreturn_save_endptr # Positive number
 
296
        negl %eax
 
297
        cltd                    # Neg result in edx:eax
 
298
        jmp .Lreturn_save_endptr
 
299
 
 
300
        # Return value (%ebp-8) * lfactor[(uint) (edx-start)] + edi
 
301
        .p2align 4,,7
 
302
.Lend_i_and_j_decl_esi:
 
303
        decl %esi               # Fix so that it points at last digit
 
304
.Lend_i_and_j:
 
305
        movl %esi,%ecx
 
306
        subl -12(%ebp),%ecx     # ecx= number of digits in second part
 
307
 
 
308
        # Calculate %eax= 10 ** %cl, where %cl <= 8
 
309
        # With an array one could do this with:
 
310
        # movl 10_factor_table(,%ecx,4),%eax
 
311
        # We calculate the table here to avoid problems in
 
312
        # position independent code (gcc -pic)
 
313
 
 
314
        cmpb  $3,%cl
 
315
        ja    .L4_to_8
 
316
        movl  $1000, %eax
 
317
        je    .Lgot_factor      # %cl=3, eax= 1000
 
318
        movl  $10, %eax
 
319
        cmpb  $1,%cl            # %cl is here 0 - 2
 
320
        je    .Lgot_factor      # %cl=1, eax= 10
 
321
        movl  $100, %eax        
 
322
        ja    .Lgot_factor      # %cl=2, eax=100
 
323
        movl  $1, %eax          
 
324
        jmp   .Lgot_factor      # %cl=0, eax=1
 
325
 
 
326
.L4_to_8:                       # %cl is here 4-8
 
327
        cmpb  $5,%cl
 
328
        movl  $100000, %eax
 
329
        je   .Lgot_factor       # %cl=5, eax=100000
 
330
        movl  $10000, %eax
 
331
        jbe  .Lgot_factor       # %cl=4, eax=10000
 
332
        movl  $10000000, %eax
 
333
        cmpb  $7,%cl
 
334
        je   .Lgot_factor       # %cl=7, eax=10000000
 
335
        movl  $100000000, %eax  
 
336
        ja   .Lgot_factor       # %cl=8, eax=100000000
 
337
        movl  $1000000, %eax    # %cl=6, eax=1000000
 
338
 
 
339
        # Return -8(%ebp) * %eax + edi
 
340
        .p2align 4,,7
 
341
.Lgot_factor:
 
342
        mull -8(%ebp)
 
343
        addl %edi,%eax
 
344
        adcl $0,%edx
 
345
        cmpl $0,-20(%ebp)       # if negative
 
346
        je .Lreturn_save_endptr
 
347
        negl %eax               # Neg edx:%eax
 
348
        adcl $0,%edx
 
349
        negl %edx
 
350
        jmp .Lreturn_save_endptr
 
351
 
 
352
        # Return -8(%ebp) * $10000000000 + edi*10 + ecx
 
353
        .p2align 4,,7
 
354
.Lend4:
 
355
        movl %ecx,-16(%ebp)     # store lowest digits
 
356
        movl 12(%ebp),%ebx
 
357
        movl %esi,(%ebx)        # *endpos = end-of-string
 
358
        movl -8(%ebp),%eax      # First 9 digits
 
359
        movl $1410065408,%ecx   # ecx= lower_32_bits(10000000000)
 
360
        mull %ecx
 
361
        movl $0,-36(%ebp)
 
362
        movl %eax,%ebx          # Store lowest 32 byte from multiplication
 
363
        imull $1410065408,-36(%ebp),%eax
 
364
        movl -8(%ebp),%ecx      # First 9 digits
 
365
        movl %edx,%esi
 
366
        addl %ecx,%ecx
 
367
        addl %ecx,%esi
 
368
        addl %eax,%esi          # %esi:%ebx now has -8(%ebp) * $10000000000
 
369
 
 
370
        movl $10,%eax           # Calc edi*10
 
371
        mull %edi
 
372
        addl %ebx,%eax          # And add to result
 
373
        adcl %esi,%edx
 
374
        addl -16(%ebp),%eax     # Add lowest digit
 
375
        adcl $0,%edx
 
376
        cmpl $0,-20(%ebp)       # if negative
 
377
        je .Lms_return
 
378
 
 
379
        cmpl $-2147483648,%edx  # Test if too big signed integer
 
380
        ja .Loverflow
 
381
        jne .L516
 
382
        testl %eax,%eax
 
383
        ja .Loverflow
 
384
 
 
385
.L516:  
 
386
        negl %eax
 
387
        adcl $0,%edx
 
388
        negl %edx
 
389
        jmp .Lms_return
 
390
 
 
391
        .p2align 4,,7
 
392
.Lno_conv:                      # Not a legal number
 
393
        movl 16(%ebp),%eax
 
394
        movl $33,(%eax)         # error= edom
 
395
 
 
396
.Lms_return_zero:
 
397
        xorl %eax,%eax          # Return zero
 
398
        xorl %edx,%edx
 
399
 
 
400
        .p2align 4,,7
 
401
.Lreturn_save_endptr:
 
402
        movl 12(%ebp),%ecx      # endptr= end-of-string
 
403
        movl %esi,(%ecx)        # *endptr= end-of-string
 
404
 
 
405
.Lms_return:
 
406
        popl %ebx
 
407
        popl %edi
 
408
        popl %esi
 
409
        movl %ebp,%esp
 
410
        popl %ebp
 
411
        ret
 
412
 
 
413
.my_strtoll10_end:
 
414
        .size   my_strtoll10,.my_strtoll10_end-my_strtoll10
 
415
        .comm   res,240,32
 
416
        .comm   end_ptr,120,32
 
417
        .comm   error,120,32
 
418
        .ident  "Monty"