Browse Source

* faster int_str
* removed i386 int_str since the generic implementation is faster

git-svn-id: trunk@2646 -

peter 19 years ago
parent
commit
340cf721b5
2 changed files with 86 additions and 155 deletions
  1. 1 89
      rtl/i386/i386.inc
  2. 85 66
      rtl/inc/generic.inc

+ 1 - 89
rtl/i386/i386.inc

@@ -979,94 +979,6 @@ asm
 end;
 end;
 
 
 
 
-{****************************************************************************
-                                 Str()
-****************************************************************************}
-
-{$define FPC_SYSTEM_HAS_INT_STR_LONGINT}
-procedure int_str(l : longint;var s : string);
-var
-  buffer : array[0..15] of byte;
-  isneg  : byte;
-begin
-  { Workaround: }
-  if l=longint($80000000) then
-   begin
-     s:='-2147483648';
-     exit;
-   end;
-  asm
-        movl    l,%eax          // load Integer
-        xorl    %ecx,%ecx       // String length=0
-        leal    buffer,%ebx
-        movl    $0x0a,%esi      // load 10 as dividing constant.
-        movb    $0,isneg
-        orl     %eax,%eax       // Sign ?
-        jns     .LM2
-        movb    $1,isneg
-        negl    %eax
-.LM2:
-        cltd
-        idivl   %esi
-        addb    $0x30,%dl       // convert Rest to ASCII.
-        movb    %dl,(%ebx)
-        incl    %ecx
-        incl    %ebx
-        cmpl    $0,%eax
-        jnz     .LM2
-        { now copy the string }
-        movl    s,%edi          // Load String address
-        cmpb    $0,isneg
-        je      .LM3
-        movb    $0x2d,(%ebx)
-        incl    %ecx
-        incl    %ebx
-.LM3:
-        movb    %cl,(%edi)      // Copy String length
-        incl    %edi
-.LM4:
-        decl    %ebx
-        movb    (%ebx),%al
-        stosb
-        decl    %ecx
-        jnz     .LM4
-  end ['eax','ecx','edx','ebx','esi','edi'];
-end;
-
-
-{$define FPC_SYSTEM_HAS_INT_STR_LONGWORD}
-procedure int_str(c : longword;var s : string);
-var
-  buffer : array[0..15] of byte;
-begin
-  asm
-        movl    c,%eax          // load CARDINAL
-        xorl    %ecx,%ecx       // String length=0
-        leal    buffer,%ebx
-        movl    $0x0a,%esi      // load 10 as dividing constant.
-.LM4:
-        xorl    %edx,%edx
-        divl    %esi
-        addb    $0x30,%dl       // convert Rest to ASCII.
-        movb    %dl,(%ebx)
-        incl    %ecx
-        incl    %ebx
-        cmpl    $0,%eax
-        jnz     .LM4
-        { now copy the string }
-        movl    s,%edi          // Load String address
-        movb    %cl,(%edi)      // Copy String length
-        incl    %edi
-.LM5:
-        decl    %ebx
-        movb    (%ebx),%al
-        stosb
-        decl    %ecx
-        jnz     .LM5
-  end ['eax','ecx','edx','ebx','esi','edi'];
-end;
-
-
 {****************************************************************************
 {****************************************************************************
                                Bounds Check
                                Bounds Check
 ****************************************************************************}
 ****************************************************************************}
@@ -1207,7 +1119,7 @@ asm
 	testl	%eax,%eax
 	testl	%eax,%eax
 	je	.Lj4031
 	je	.Lj4031
 .Lj4036:
 .Lj4036:
-// [440] if PAnsiRec(Pointer(S)-Firstoff)^.Ref<>1 then	
+// [440] if PAnsiRec(Pointer(S)-Firstoff)^.Ref<>1 then
 	movl	-8(%eax),%ecx
 	movl	-8(%eax),%ecx
 	cmpl	$1,%ecx
 	cmpl	$1,%ecx
 	je	.Lj4038
 	je	.Lj4038

+ 85 - 66
rtl/inc/generic.inc

@@ -1013,26 +1013,34 @@ function align(addr : Pointer;alignment : PtrInt) : Pointer;{$ifdef SYSTEMINLINE
 {$ifndef FPC_SYSTEM_HAS_INT_STR_LONGINT}
 {$ifndef FPC_SYSTEM_HAS_INT_STR_LONGINT}
 
 
 procedure int_str(l:longint;out s:string);
 procedure int_str(l:longint;out s:string);
-
-var m:cardinal;
-    p:byte;
-
+var
+  m,m1 : longword;
+  pc,pc2 : pchar;
+  hs : string[32];
 begin
 begin
-  s[1]:='-';     {Will be overwritten if positive.}
-  p:=byte(l<0);  {Number of characters to start with.}
-  {Count number of characters.}
-  m:=abs(l);
-  repeat
-    inc(p);
-    l:=l div 10;
-  until l=0;
-  {Generate string.}
-  s[0]:=char(p);
+  pc2:=@s[1];
+  if (l<0) then
+    begin
+      pc2^:='-';
+      inc(pc2);
+      m:=longword(-l);
+    end
+  else
+    m:=longword(l);
+  pc:=@hs[0];
   repeat
   repeat
-    s[p]:=char(m mod 10+byte('0'));
-    m:=m div 10;
-    dec(p);
+    inc(pc);
+    m1:=m div 10;
+    pc^:=char(m-(m1*10)+byte('0'));
+    m:=m1;
   until m=0;
   until m=0;
+  while (pc>pchar(@hs[0])) do
+    begin
+      pc2^:=pc^;
+      dec(pc);
+      inc(pc2);
+    end;
+  s[0]:=char(pc2-pchar(@s[1]));
 end;
 end;
 
 
 {$endif ndef FPC_SYSTEM_HAS_INT_STR_LONGINT}
 {$endif ndef FPC_SYSTEM_HAS_INT_STR_LONGINT}
@@ -1040,25 +1048,26 @@ end;
 {$ifndef FPC_SYSTEM_HAS_INT_STR_LONGWORD}
 {$ifndef FPC_SYSTEM_HAS_INT_STR_LONGWORD}
 
 
 procedure int_str(l:longword;out s:string);
 procedure int_str(l:longword;out s:string);
-
-var m:longword;
-    p:byte;
-
+var
+  m1 : longword;
+  pc,pc2 : pchar;
+  hs : string[32];
 begin
 begin
-  p:=0;
-  {Count number of characters.}
-  m:=l;
+  pc2:=@s[1];
+  pc:=@hs[0];
   repeat
   repeat
-    inc(p);
-    m:=m div 10;
-  until m=0;
-  {Generate string.}
-  s[0]:=char(p);
-  repeat
-    s[p]:=char((l mod 10)+byte('0'));
-    l:=l div 10;
-    dec(p);
+    inc(pc);
+    m1:=l div 10;
+    pc^:=char(l-(m1*10)+byte('0'));
+    l:=m1;
   until l=0;
   until l=0;
+  while (pc>pchar(@hs[0])) do
+    begin
+      pc2^:=pc^;
+      dec(pc);
+      inc(pc2);
+    end;
+  s[0]:=char(pc2-pchar(@s[1]));
 end;
 end;
 
 
 {$endif ndef FPC_SYSTEM_HAS_INT_STR_LONGWORD}
 {$endif ndef FPC_SYSTEM_HAS_INT_STR_LONGWORD}
@@ -1066,51 +1075,61 @@ end;
 {$ifndef FPC_SYSTEM_HAS_INT_STR_INT64}
 {$ifndef FPC_SYSTEM_HAS_INT_STR_INT64}
 
 
 procedure int_str(l:int64;out s:string);
 procedure int_str(l:int64;out s:string);
-
-var m:qword;
-    p:byte;
-
+var
+  m,m1 : qword;
+  pc,pc2 : pchar;
+  hs : string[64];
 begin
 begin
-  s[1]:='-';     {Will be overwritten if positive.}
-  p:=byte(l<0);  {Number of characters to start with.}
-  {Count number of characters.}
-  m:=abs(l);
-  repeat
-    inc(p);
-    l:=l div 10;
-  until l=0;
-  {Generate string.}
-  s[0]:=char(p);
+  pc2:=@s[1];
+  if (l<0) then
+    begin
+      pc2^:='-';
+      inc(pc2);
+      m:=qword(-l);
+    end
+  else
+    m:=qword(l);
+  pc:=@hs[0];
   repeat
   repeat
-    s[p]:=char(m mod 10+byte('0'));
-    m:=m div 10;
-    dec(p);
+    inc(pc);
+    m1:=m div 10;
+    pc^:=char(m-(m1*10)+byte('0'));
+    m:=m1;
   until m=0;
   until m=0;
+  while (pc>pchar(@hs[0])) do
+    begin
+      pc2^:=pc^;
+      dec(pc);
+      inc(pc2);
+    end;
+  s[0]:=char(pc2-pchar(@s[1]));
 end;
 end;
+
 {$endif ndef FPC_SYSTEM_HAS_INT_STR_INT64}
 {$endif ndef FPC_SYSTEM_HAS_INT_STR_INT64}
 
 
 {$ifndef FPC_SYSTEM_HAS_INT_STR_QWORD}
 {$ifndef FPC_SYSTEM_HAS_INT_STR_QWORD}
 
 
 procedure int_str(l:qword;out s:string);
 procedure int_str(l:qword;out s:string);
-
-var m:qword;
-    p:byte;
-
+var
+  m1 : qword;
+  pc,pc2 : pchar;
+  hs : string[64];
 begin
 begin
-  p:=0;
-  {Count number of characters.}
-  m:=l;
+  pc2:=@s[1];
+  pc:=@hs[0];
   repeat
   repeat
-    inc(p);
-    m:=m div 10;
-  until m=0;
-  {Generate string.}
-  s[0]:=char(p);
-  repeat
-    s[p]:=char((l mod 10)+byte('0'));
-    l:=l div 10;
-    dec(p);
+    inc(pc);
+    m1:=l div 10;
+    pc^:=char(l-(m1*10)+byte('0'));
+    l:=m1;
   until l=0;
   until l=0;
+  while (pc>pchar(@hs[0])) do
+    begin
+      pc2^:=pc^;
+      dec(pc);
+      inc(pc2);
+    end;
+  s[0]:=char(pc2-pchar(@s[1]));
 end;
 end;
 
 
 {$endif ndef FPC_SYSTEM_HAS_INT_STR_QWORD}
 {$endif ndef FPC_SYSTEM_HAS_INT_STR_QWORD}