List:Internals« Previous MessageNext Message »
From:monty Date:August 8 2005 10:18am
Subject:bk commit into 4.1 tree (monty:1.2356) BUG#11642
View as plain text  
Below is the list of changes that have just been committed into a local
4.1 repository of monty. When monty does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.2356 05/08/08 13:18:18 monty@stripped +6 -0
  Fix for BUG #11642: [Patch]es x86 Assembler and text relocations
  Changed assembler functions to not access global variables or variables in text segement
  Added wrapper function in C to longlong2str() to pass _dig_vec_upper as an argument

  strings/longlong2str_asm.c
    1.1 05/08/08 13:18:12 monty@stripped +33 -0
    New BitKeeper file ``strings/longlong2str_asm.c''

  strings/my_strtoll10-x86.s
    1.4 05/08/08 13:18:12 monty@stripped +39 -23
    Removd array lfactor by calculating the value in code
    (this is to to make the code position independent)

  strings/longlong2str_asm.c
    1.0 05/08/08 13:18:12 monty@stripped +0 -0
    BitKeeper file /home/my/mysql-4.1/strings/longlong2str_asm.c

  strings/longlong2str-x86.s
    1.11 05/08/08 13:18:12 monty@stripped +18 -17
    Changed functions to not access variables in text segment
    Fixed this by adding global variable '_dig_vec_upper' as an argument to longlong2str_with_dig_vector()

  strings/Makefile.am
    1.43 05/08/08 13:18:12 monty@stripped +2 -2
    Added longlong2str_asm.c

  mysql-test/t/bigint.test
    1.24 05/08/08 13:18:11 monty@stripped +3 -0
    More tests for parsing of bigint's
    More tests for different values to conv()

  mysql-test/r/bigint.result
    1.25 05/08/08 13:18:11 monty@stripped +9 -0
    More tests for parsing of bigint's
    More tests for different values to conv()

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	monty
# Host:	mishka.local
# Root:	/home/my/mysql-4.1

--- 1.42/strings/Makefile.am	2005-07-03 04:29:13 +03:00
+++ 1.43/strings/Makefile.am	2005-08-08 13:18:12 +03:00
@@ -23,7 +23,7 @@
 # Exact one of ASSEMBLER_X
 if ASSEMBLER_x86
 ASRCS		= strings-x86.s longlong2str-x86.s my_strtoll10-x86.s
-CSRCS		= bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c ctype-extra.c
+CSRCS		= bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c ctype-extra.c longlong2str_asm.c
 else
 if ASSEMBLER_sparc32
 # These file MUST all be on the same line!! Otherwise automake
@@ -46,7 +46,7 @@
                         ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-utf8.c \
                         ctype-ucs2.c ctype-uca.c ctype-tis620.c ctype-ujis.c \
                         xml.c strto.c strings-x86.s \
-			longlong2str.c longlong2str-x86.s \
+			longlong2str.c longlong2str-x86.s longlong2str_asm.c \
 			my_strtoll10.c my_strtoll10-x86.s \
 			strxmov.c bmove_upp.c strappend.c strcont.c strend.c \
 			strfill.c strcend.c is_prefix.c strstr.c strinstr.c \

--- 1.10/strings/longlong2str-x86.s	2004-05-27 16:54:35 +03:00
+++ 1.11/strings/longlong2str-x86.s	2005-08-08 13:18:12 +03:00
@@ -16,26 +16,26 @@
 # Optimized longlong2str function for Intel 80x86  (gcc/gas syntax) 
 # Some set sequences are optimized for pentuimpro II 
 
-	.file	"longlong2str.s"
-	.version "1.01"
+	.file	"longlong2str-x86.s"
+	.version "1.02"
 
 .text
 	.align 4
 
-.globl	longlong2str
-	.type	 longlong2str,@function
+.globl	longlong2str_with_dig_vector
+	.type	 longlong2str_with_dig_vector,@function
 	
-longlong2str:
+longlong2str_with_dig_vector:
 	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 
+	movl 104(%esp),%ebp	# Higher part of val 
 	movl %ebx,%eax
+	movl 108(%esp),%edi	# get dst 
 	testl %eax,%eax
 	jge .L144
 
@@ -69,6 +69,8 @@
 
 .L150:
 	leal 92(%esp),%ecx	# End of buffer 
+	movl %edi, 108(%esp)    # Store possible modified dest
+	movl 116(%esp), %edi    # dig_vec_upper
 	jmp  .L155
 	.align 4
 
@@ -83,7 +85,7 @@
 	divl %ebx
 	decl %ecx
 	movl %eax,%esi		# quotent in ebp:esi 
-	movb _dig_vec_upper(%edx),%al   # al is faster than dl 
+	movb (%edx,%edi),%al    # al is faster than dl 
 	movb %al,(%ecx)		# store value in buff 
 	.align 4
 .L155:
@@ -91,20 +93,22 @@
 	ja .L153
 	testl %esi,%esi		# rest value 
 	jl .L153
-	je .L10_mov		# Ready 
+	je .L160		# Ready 
 	movl %esi,%eax
-	movl $_dig_vec_upper,%ebp
 	.align 4
 
 .L154:				# Do rest with integer precision 
 	cltd
 	divl %ebx
 	decl %ecx
-	movb (%edx,%ebp),%dl	# bh is always zero as ebx=radix < 36 
+	movb (%edx,%edi),%dl	# bh is always zero as ebx=radix < 36 
 	testl %eax,%eax
 	movb %dl,(%ecx)
 	jne .L154
 
+.L160:
+	movl 108(%esp),%edi	# get dst 
+	
 .L10_mov:
 	movl %ecx,%esi
 	leal 92(%esp),%ecx	# End of buffer 
@@ -129,7 +133,7 @@
 	jmp .L165
 
 .Lfe3:
-	.size	 longlong2str,.Lfe3-longlong2str
+	.size	 longlong2str_with_dig_vector,.Lfe3-longlong2str_with_dig_vector
 
 #
 # This is almost equal to the above, except that we can do the final
@@ -137,9 +141,6 @@
 #	
 
 	.align 4
-.Ltmp:
-        .long 0xcccccccd
-	.align 4
 	
 .globl	longlong10_to_str
 	.type	 longlong10_to_str,@function
@@ -202,8 +203,8 @@
 
 	# The following code uses some tricks to change division by 10 to
 	# multiplication and shifts
-	movl .Ltmp,%esi		# set %esi to 0xcccccccd
-	
+	movl $0xcccccccd,%esi
+		
 .L10_40:
         movl %ebx,%eax
         mull %esi

--- 1.24/mysql-test/r/bigint.result	2005-02-28 22:50:02 +02:00
+++ 1.25/mysql-test/r/bigint.result	2005-08-08 13:18:11 +03:00
@@ -17,6 +17,15 @@
 select -(0-3),round(-(0-3)), round(9999999999999999999);
 -(0-3)	round(-(0-3))	round(9999999999999999999)
 3	3	10000000000000000000
+select 1,11,101,1001,10001,100001,1000001,10000001,100000001,1000000001,10000000001,100000000001,1000000000001,10000000000001,100000000000001,1000000000000001,10000000000000001,100000000000000001,1000000000000000001,10000000000000000001;
+1	11	101	1001	10001	100001	1000001	10000001	100000001	1000000001	10000000001	100000000001	1000000000001	10000000000001	100000000000001	1000000000000001	10000000000000001	100000000000000001	1000000000000000001	10000000000000000001
+1	11	101	1001	10001	100001	1000001	10000001	100000001	1000000001	10000000001	100000000001	1000000000001	10000000000001	100000000000001	1000000000000001	10000000000000001	100000000000000001	1000000000000000001	10000000000000000001
+select -1,-11,-101,-1001,-10001,-100001,-1000001,-10000001,-100000001,-1000000001,-10000000001,-100000000001,-1000000000001,-10000000000001,-100000000000001,-1000000000000001,-10000000000000001,-100000000000000001,-1000000000000000001,-10000000000000000001;
+-1	-11	-101	-1001	-10001	-100001	-1000001	-10000001	-100000001	-1000000001	-10000000001	-100000000001	-1000000000001	-10000000000001	-100000000000001	-1000000000000001	-10000000000000001	-100000000000000001	-1000000000000000001	-10000000000000000001
+-1	-11	-101	-1001	-10001	-100001	-1000001	-10000001	-100000001	-1000000001	-10000000001	-100000000001	-1000000000001	-10000000000001	-100000000000001	-1000000000000001	-10000000000000001	-100000000000000001	-1000000000000000001	-10000000000000000000
+select conv(1,10,16),conv((1<<2)-1,10,16),conv((1<<10)-2,10,16),conv((1<<16)-3,10,16),conv((1<<25)-4,10,16),conv((1<<31)-5,10,16),conv((1<<36)-6,10,16),conv((1<<47)-7,10,16),conv((1<<48)-8,10,16),conv((1<<55)-9,10,16),conv((1<<56)-10,10,16),conv((1<<63)-11,10,16);
+conv(1,10,16)	conv((1<<2)-1,10,16)	conv((1<<10)-2,10,16)	conv((1<<16)-3,10,16)	conv((1<<25)-4,10,16)	conv((1<<31)-5,10,16)	conv((1<<36)-6,10,16)	conv((1<<47)-7,10,16)	conv((1<<48)-8,10,16)	conv((1<<55)-9,10,16)	conv((1<<56)-10,10,16)	conv((1<<63)-11,10,16)
+1	3	3FE	FFFD	1FFFFFC	7FFFFFFB	FFFFFFFFA	7FFFFFFFFFF9	FFFFFFFFFFF8	7FFFFFFFFFFFF7	FFFFFFFFFFFFF6	7FFFFFFFFFFFFFF5
 create table t1 (a bigint unsigned not null, primary key(a));
 insert into t1 values (18446744073709551615), (0xFFFFFFFFFFFFFFFE), (18446744073709551613), (18446744073709551612);
 select * from t1;

--- 1.23/mysql-test/t/bigint.test	2005-07-28 03:21:39 +03:00
+++ 1.24/mysql-test/t/bigint.test	2005-08-08 13:18:11 +03:00
@@ -14,6 +14,9 @@
 select cast(9223372036854775808 as unsigned)+1;
 select 9223372036854775808+1;
 select -(0-3),round(-(0-3)), round(9999999999999999999);
+select 1,11,101,1001,10001,100001,1000001,10000001,100000001,1000000001,10000000001,100000000001,1000000000001,10000000000001,100000000000001,1000000000000001,10000000000000001,100000000000000001,1000000000000000001,10000000000000000001;
+select -1,-11,-101,-1001,-10001,-100001,-1000001,-10000001,-100000001,-1000000001,-10000000001,-100000000001,-1000000000001,-10000000000001,-100000000000001,-1000000000000001,-10000000000000001,-100000000000000001,-1000000000000000001,-10000000000000000001;
+select conv(1,10,16),conv((1<<2)-1,10,16),conv((1<<10)-2,10,16),conv((1<<16)-3,10,16),conv((1<<25)-4,10,16),conv((1<<31)-5,10,16),conv((1<<36)-6,10,16),conv((1<<47)-7,10,16),conv((1<<48)-8,10,16),conv((1<<55)-9,10,16),conv((1<<56)-10,10,16),conv((1<<63)-11,10,16);
 
 #
 # In 3.23 we have to disable the test of column to bigint as

--- 1.3/strings/my_strtoll10-x86.s	2005-03-30 00:03:29 +03:00
+++ 1.4/strings/my_strtoll10-x86.s	2005-08-08 13:18:12 +03:00
@@ -17,21 +17,8 @@
 # For documentation, check my_strtoll.c
 	
 	.file	"my_strtoll10-x86.s"
-	.version "01.01"
-.data
-	.align 32
-	.type	 lfactor,@object
-	.size	 lfactor,36
-lfactor:
-	.long 1
-	.long 10
-	.long 100
-	.long 1000
-	.long 10000
-	.long 100000
-	.long 1000000
-	.long 10000000
-	.long 100000000
+	.version "01.02"
+	
 .text
 	.align 4
 	
@@ -209,14 +196,16 @@
 	jne .L500
 	cmpl -36(%ebp),%esi	# Test if string is less than 18 digits
 	jne .Lend_i_and_j
-	jmp .Lend3		# 18 digit string
+.L499:	
+	movl $1000000000,%eax	
+	jmp .Lgot_factor	# 18 digit string
 
 	# Handle the possible next to last digit and store in ecx
 .L500:
 	movb (%esi),%al
 	addb $-48,%al
 	cmpb $9,%al
-	ja .Lend3
+	ja .L499		# 18 digit string
 
 	incl %esi
 	movzbl %al,%ecx
@@ -315,14 +304,41 @@
 .Lend_i_and_j:
 	movl %esi,%ecx
 	subl -12(%ebp),%ecx	# ecx= number of digits in second part
-	movl lfactor(,%ecx,4),%eax
-	jmp .L523
 
-	# Return -8(%ebp) * $1000000000 + edi
+	# Calculate %eax= 10 ** %cl, where %cl <= 8
+	# With an array one could do this with:
+	# movl 10_factor_table(,%ecx,4),%eax
+	# We calculate the table here to avoid problems in
+	# position independent code (gcc -pic)
+
+	cmpb  $3,%cl
+	ja    .L4_to_8
+	movl  $1000, %eax
+	je    .Lgot_factor	# %cl=3, eax= 1000
+	movl  $10, %eax
+	cmpb  $1,%cl		# %cl is here 0 - 2
+	je    .Lgot_factor	# %cl=1, eax= 10
+	movl  $100, %eax	
+	ja    .Lgot_factor	# %cl=2, eax=100
+	movl  $1, %eax		
+	jmp   .Lgot_factor	# %cl=0, eax=1
+
+.L4_to_8:			# %cl is here 4-8
+	cmpb  $5,%cl
+	movl  $100000, %eax
+	je   .Lgot_factor	# %cl=5, eax=100000
+	movl  $10000, %eax
+	jbe  .Lgot_factor	# %cl=4, eax=10000
+	movl  $10000000, %eax
+	cmpb  $7,%cl
+	je   .Lgot_factor	# %cl=7, eax=10000000
+	movl  $100000000, %eax	
+	ja   .Lgot_factor	# %cl=8, eax=100000000
+	movl  $1000000, %eax	# %cl=6, eax=1000000
+
+	# Return -8(%ebp) * %eax + edi
 	.p2align 4,,7
-.Lend3:
-	movl $1000000000,%eax
-.L523:
+.Lgot_factor:
 	mull -8(%ebp)
 	addl %edi,%eax
 	adcl $0,%edx
--- New file ---
+++ strings/longlong2str_asm.c	05/08/08 13:18:12
/* 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 */

/*
  Wrapper for longlong2str.s

  We need this because the assembler code can't access the local variable
  _dig_vector in a portable manner.
*/

#include <my_global.h>
#include "m_string.h"

extern char *longlong2str_with_dig_vector(longlong val,char *dst,int radix,
                                          const char *dig_vector);

char *longlong2str(longlong val,char *dst,int radix)
{
  return longlong2str_with_dig_vector(val, dst, radix, _dig_vec_upper);
}

Thread
bk commit into 4.1 tree (monty:1.2356) BUG#11642monty8 Aug