--- mysql-4.0.25/strings/strings-x86.s 2005-06-29 19:06:44.000000000 +0200 +++ mysql/strings/strings-x86.s 2005-07-19 15:41:31.000000000 +0200 @@ -403,3 +403,5 @@ ret .strxmov_end: .size strxmov,.strxmov_end-strxmov + + .section .note.GNU-stack,"",@progbits --- mysql-4.0.25/strings/longlong2str-x86.s 2005-06-29 19:06:43.000000000 +0200 +++ mysql/strings/longlong2str-x86.s 2005-07-19 15:41:31.000000000 +0200 @@ -13,8 +13,9 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# Optimized longlong2str function for Intel 80x86 (gcc/gas syntax) -# Some set sequences are optimized for pentuimpro II +# longlong2str function for Intel 80x86 (gcc/gas syntax) + +# See longlong2str(dst,radix,val) description in longlong2str.c. .file "longlong2str.s" .version "1.01" @@ -24,8 +25,123 @@ .globl longlong2str .type longlong2str,@function - + longlong2str: + subl $80,%esp # Temporary buffer for up to 64 radix-2 digits + pushl %ebp + pushl %esi + pushl %edi + pushl %ebx + + movl 100(%esp),%esi # esi = Lower part of val + movl 112(%esp),%ebx # ebx = Radix + movl 104(%esp),%ebp # ebp = Higher part of val + movl 108(%esp),%edi # edi -> dst + + testl %ebx,%ebx + jge .L144 # (Radix >= 0) + + testl %ebp,%ebp + jge .L146 # (Higher part of val >= 0) + movb $45,(%edi) # Add '-' sign + incl %edi + negl %esi # Change val to positive + adcl $0,%ebp + negl %ebp +.L146: + negl %ebx # Change radix to positive +.L144: + cmpl $36,%ebx # Radix must be between 2 and 36 + ja .Lerror # (Radix not in range) + cmpl $2,%ebx + jb .Lerror # (Radix not in range) + + movl %esi,%eax # eax = lower part of val ... + orl %ebp,%eax # and it stays thus if ebp=0 + je Lzero # (Treat zero as special case) + + leal 92(%esp),%ecx # ecx -> End of temporary buffer + + testl %ebp,%ebp + je Llow # (Higher part of val = 0) + +Lhigh: + #val in ebp:esi. div the high part by the radix, + #then div remainder + low part by the radix. + movl %ebp,%eax # edx=0,eax=high(from ebp) + xorl %edx,%edx + decl %ecx + divl %ebx + movl %eax,%ebp # edx=result of last, eax=low(from esi) + movl %esi,%eax + divl %ebx + movl %eax,%esi # ebp:esi = quotient + movb %dl,(%ecx) # store byte in temporary buffer + testl %ebp,%ebp + jne Lhigh # (Higher part of val still > 0) + +Llow: + #val in 0:eax. div 0 + low part by the radix. + xorl %edx,%edx + decl %ecx + divl %ebx + movb %dl,(%ecx) # store byte in temporary buffer + testl %eax,%eax + jne Llow # (Lower part of val still <> 0) + + leal 92(%esp),%esi # esi -> End of temporary buffer + +Lmov: + movb (%ecx),%dl # dl = byte from temporary buffer + movb $-1,%bl + cmpb $10,%dl # add 7 if dl > '9' + adcb $0,%bl + addb $48,%dl # add '0' + andb $7,%bl + addb %bl,%dl + incl %ecx + movb %dl,(%edi) # put dl in dst + incl %edi + cmpl %ecx,%esi + ja Lmov # (more bytes exist in temporary buffer) + movb $0,(%edi) # trailing '\0' in dst + movl %edi,%eax # eax = return value = pointer to '\0' +.Lret: + popl %ebx + popl %edi + popl %esi + popl %ebp + addl $80,%esp + ret + +.Lerror: + xorl %eax,%eax # Wrong radix + jmp .Lret + +Lzero: + # Treat 0 as a special case. Unnecessary but we + # expect 0 will be frequent. + movl 108(%esp),%eax # eax = dst + popl %ebx + movb $48,(%eax) # '0' + popl %edi + incl %eax + popl %esi + popl %ebp + addl $80,%esp + movb $0,(%eax) # '\0' + ret + +# +# This is almost equal to the above, except that we can do the final +# loop much more efficient +# + + .align 4 + +.globl longlong10_to_str + .type longlong10_to_str,@function +longlong10_to_str: subl $80,%esp pushl %ebp pushl %esi @@ -34,85 +150,82 @@ 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 - movl %ebx,%eax - testl %eax,%eax - jge .L144 - - addl $36,%eax - cmpl $34,%eax - ja .Lerror # Wrong radix - testl %ebp,%ebp - jge .L146 + 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 # Change sign of val - negl %esi + incl %edi + negl %esi # Change sign of val (ebp:esi) adcl $0,%ebp negl %ebp -.L146: - negl %ebx # Change radix to positive - jmp .L148 .align 4 -.L144: - addl $-2,%eax - cmpl $34,%eax - ja .Lerror # Radix in range -.L148: +.L10_10: + leal 92(%esp),%ecx # End of buffer movl %esi,%eax # Test if zero (for easy loop) orl %ebp,%eax - jne .L150 + jne .L10_30 # Not zero + + # Here when value is zero movb $48,(%edi) incl %edi - jmp .L164 - .align 4 - -.L150: - leal 92(%esp),%ecx # End of buffer - jmp .L155 + jmp .L10_end .align 4 -.L153: +.L10_20: # val is stored in in ebp:esi - movl %ebp,%eax # High part of value xorl %edx,%edx - divl %ebx + divl %ebx # Divide by 10 movl %eax,%ebp movl %esi,%eax - divl %ebx - movl %eax,%esi # quotent in ebp:esi - movb _dig_vec(%edx),%al # al is faster than dl + divl %ebx # Divide by 10 decl %ecx - movb %al,(%ecx) # store value in buff - .align 4 -.L155: + 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 .L153 + ja .L10_20 testl %esi,%esi # rest value - jl .L153 - je .L160 # Ready - movl %esi,%eax - movl $_dig_vec,%ebp - .align 4 + 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 + movl $0xcccccccd,%esi # set %esi to 0xcccccccd + +.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 -.L154: # Do rest with integer precision - cltd - divl %ebx - decl %ecx - movb (%edx,%ebp),%dl # bh is always zero as ebx=radix < 36 - testl %eax,%eax - movb %dl,(%ecx) - jne .L154 -.L160: +.L10_mov: movl %ecx,%esi leal 92(%esp),%ecx # End of buffer subl %esi,%ecx rep movsb -.L164: +.L10_end: movl %edi,%eax # Pointer to end null movb $0,(%edi) # Store the end null @@ -123,18 +236,8 @@ popl %ebp addl $80,%esp ret - -.Lerror: - xorl %eax,%eax # Wrong radix - jmp .L165 - -.Lfe3: - .size longlong2str,.Lfe3-longlong2str - -.globl longlong10_to_str - .type longlong10_to_str,@function -longlong10_to_str: - jmp longlong2str - + .L10end: .size longlong10_to_str,.L10end-longlong10_to_str + + .section .note.GNU-stack,"",@progbits