浏览代码

* shortstr compare with empty string fixed
* removed special i386 code

peter 21 年之前
父节点
当前提交
f80f3fc0fa
共有 5 个文件被更改,包括 93 次插入122 次删除
  1. 5 2
      compiler/i386/n386add.pas
  2. 10 4
      compiler/nadd.pas
  3. 6 1
      compiler/options.pas
  4. 7 114
      compiler/x86/nx86add.pas
  5. 65 1
      rtl/i386/i386.inc

+ 5 - 2
compiler/i386/n386add.pas

@@ -45,7 +45,6 @@ interface
     uses
     uses
       globtype,systems,
       globtype,systems,
       cutils,verbose,globals,
       cutils,verbose,globals,
-      cpuinfo,
       symconst,symdef,paramgr,
       symconst,symdef,paramgr,
       aasmbase,aasmtai,aasmcpu,
       aasmbase,aasmtai,aasmcpu,
       cgbase,
       cgbase,
@@ -654,7 +653,11 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.100  2004-10-31 21:45:03  peter
+  Revision 1.101  2004-11-01 12:43:29  peter
+    * shortstr compare with empty string fixed
+    * removed special i386 code
+
+  Revision 1.100  2004/10/31 21:45:03  peter
     * generic tlocation
     * generic tlocation
     * move tlocation to cgutils
     * move tlocation to cgutils
 
 

+ 10 - 4
compiler/nadd.pas

@@ -1360,8 +1360,9 @@ implementation
             end;
             end;
           ltn,lten,gtn,gten,equaln,unequaln :
           ltn,lten,gtn,gten,equaln,unequaln :
             begin
             begin
-              { generate better code for s='' and s<>'' }
-              if (nodetype in [equaln,unequaln]) and
+              { generate better code for comparison with empty string, we
+                only need to compare the length with 0 }
+              if (nodetype in [equaln,unequaln,gtn,gten,ltn,lten]) and
                  (((left.nodetype=stringconstn) and (str_length(left)=0)) or
                  (((left.nodetype=stringconstn) and (str_length(left)=0)) or
                   ((right.nodetype=stringconstn) and (str_length(right)=0))) then
                   ((right.nodetype=stringconstn) and (str_length(right)=0))) then
                 begin
                 begin
@@ -1372,7 +1373,8 @@ implementation
                       left := right;
                       left := right;
                       right := p;
                       right := p;
                     end;
                     end;
-                  if is_shortstring(left.resulttype.def) then
+                  if is_shortstring(left.resulttype.def) or
+                     (nodetype in [gtn,gten,ltn,lten]) then
                     { compare the length with 0 }
                     { compare the length with 0 }
                     result := caddnode.create(nodetype,
                     result := caddnode.create(nodetype,
                       cinlinenode.create(in_length_x,false,left),
                       cinlinenode.create(in_length_x,false,left),
@@ -2030,7 +2032,11 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.129  2004-09-21 17:25:12  peter
+  Revision 1.130  2004-11-01 12:43:28  peter
+    * shortstr compare with empty string fixed
+    * removed special i386 code
+
+  Revision 1.129  2004/09/21 17:25:12  peter
     * paraloc branch merged
     * paraloc branch merged
 
 
   Revision 1.128  2004/09/13 20:32:53  peter
   Revision 1.128  2004/09/13 20:32:53  peter

+ 6 - 1
compiler/options.pas

@@ -1748,6 +1748,7 @@ begin
   def_symbol('HAS_INTERNAL_INTTYPES');
   def_symbol('HAS_INTERNAL_INTTYPES');
   def_symbol('STR_USES_VALINT');
   def_symbol('STR_USES_VALINT');
   def_symbol('NOSAVEREGISTERS');
   def_symbol('NOSAVEREGISTERS');
+  def_symbol('SHORTSTRCOMPAREINREG');
 
 
 { using a case is pretty useless here (FK) }
 { using a case is pretty useless here (FK) }
 { some stuff for TP compatibility }
 { some stuff for TP compatibility }
@@ -2088,7 +2089,11 @@ finalization
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.151  2004-10-31 19:09:54  peter
+  Revision 1.152  2004-11-01 12:43:28  peter
+    * shortstr compare with empty string fixed
+    * removed special i386 code
+
+  Revision 1.151  2004/10/31 19:09:54  peter
     * default paths fixed
     * default paths fixed
 
 
   Revision 1.150  2004/10/26 15:11:01  peter
   Revision 1.150  2004/10/26 15:11:01  peter

+ 7 - 114
compiler/x86/nx86add.pas

@@ -44,10 +44,6 @@ unit nx86add;
         procedure second_addfloatsse;
         procedure second_addfloatsse;
         procedure second_mul;virtual;abstract;
         procedure second_mul;virtual;abstract;
       public
       public
-{$ifdef i386}
-        function  first_addstring : tnode; override;
-        procedure second_addstring;override;
-{$endif i386}
         procedure second_addfloat;override;
         procedure second_addfloat;override;
         procedure second_addsmallset;override;
         procedure second_addsmallset;override;
         procedure second_add64bit;override;
         procedure second_add64bit;override;
@@ -66,11 +62,9 @@ unit nx86add;
       verbose,cutils,
       verbose,cutils,
       cpuinfo,
       cpuinfo,
       aasmbase,aasmtai,aasmcpu,
       aasmbase,aasmtai,aasmcpu,
-      symconst,symdef,
+      symconst,
       cgobj,cgx86,cga,cgutils,
       cgobj,cgx86,cga,cgutils,
-      paramgr,parabase,
-      htypechk,tgobj,
-      pass_2,ncgutil,
+      paramgr,tgobj,ncgutil,
       ncon,nset,
       ncon,nset,
       defutil;
       defutil;
 
 
@@ -683,111 +677,6 @@ unit nx86add;
       end;
       end;
 
 
 
 
-{*****************************************************************************
-                                Addstring
-*****************************************************************************}
-
-{$ifdef i386}
-    { note: if you implemented an fpc_shortstr_concat similar to the    }
-    { one in i386.inc, you have to override first_addstring like in     }
-    { ti386addnode.first_string and implement the shortstring concat    }
-    { manually! The generic routine is different from the i386 one (JM) }
-    function tx86addnode.first_addstring : tnode;
-      begin
-        { special cases for shortstrings, handled in pass_2 (JM) }
-        { can't handle fpc_shortstr_compare with compilerproc either because it }
-        { returns its results in the flags instead of in eax                    }
-        if (nodetype in [ltn,lten,gtn,gten,equaln,unequaln]) and
-           is_shortstring(left.resulttype.def) and
-           not(((left.nodetype=stringconstn) and (str_length(left)=0)) or
-              ((right.nodetype=stringconstn) and (str_length(right)=0))) then
-         begin
-           expectloc:=LOC_FLAGS;
-           calcregisters(self,0,0,0);
-           result := nil;
-           exit;
-         end;
-        { otherwise, use the generic code }
-        result := inherited first_addstring;
-      end;
-
-
-    procedure tx86addnode.second_addstring;
-      var
-        paraloc1,
-        paraloc2   : tcgpara;
-        hregister1,
-        hregister2 : tregister;
-      begin
-        { string operations are not commutative }
-        if nf_swaped in flags then
-          swapleftright;
-        case tstringdef(left.resulttype.def).string_typ of
-           st_shortstring:
-             begin
-                case nodetype of
-                   ltn,lten,gtn,gten,equaln,unequaln :
-                     begin
-                       paraloc1.init;
-                       paraloc2.init;
-                       paramanager.getintparaloc(pocall_default,1,paraloc1);
-                       paramanager.getintparaloc(pocall_default,2,paraloc2);
-                       { process parameters }
-                       secondpass(left);
-                       if paraloc2.location^.loc=LOC_REGISTER then
-                         begin
-                           hregister2:=cg.getaddressregister(exprasmlist);
-                           cg.a_loadaddr_ref_reg(exprasmlist,left.location.reference,hregister2);
-                         end
-                       else
-                         begin
-                           paramanager.allocparaloc(exprasmlist,paraloc2);
-                           cg.a_paramaddr_ref(exprasmlist,left.location.reference,paraloc2);
-                         end;
-                       secondpass(right);
-                       if paraloc1.location^.loc=LOC_REGISTER then
-                         begin
-                           hregister1:=cg.getaddressregister(exprasmlist);
-                           cg.a_loadaddr_ref_reg(exprasmlist,right.location.reference,hregister1);
-                         end
-                       else
-                         begin
-                           paramanager.allocparaloc(exprasmlist,paraloc1);
-                           cg.a_paramaddr_ref(exprasmlist,right.location.reference,paraloc1);
-                         end;
-                       { push parameters }
-                       if paraloc1.location^.loc=LOC_REGISTER then
-                         begin
-                           paramanager.allocparaloc(exprasmlist,paraloc2);
-                           cg.a_param_reg(exprasmlist,OS_ADDR,hregister2,paraloc2);
-                         end;
-                       if paraloc2.location^.loc=LOC_REGISTER then
-                         begin
-                           paramanager.allocparaloc(exprasmlist,paraloc1);
-                           cg.a_param_reg(exprasmlist,OS_ADDR,hregister1,paraloc1);
-                         end;
-                       paramanager.freeparaloc(exprasmlist,paraloc1);
-                       paramanager.freeparaloc(exprasmlist,paraloc2);
-                       cg.alloccpuregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
-                       cg.a_call_name(exprasmlist,'FPC_SHORTSTR_COMPARE');
-                       cg.dealloccpuregisters(exprasmlist,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
-                       location_freetemp(exprasmlist,left.location);
-                       location_freetemp(exprasmlist,right.location);
-                       paraloc1.done;
-                       paraloc2.done;
-                     end;
-                end;
-                location_reset(location,LOC_FLAGS,OS_NO);
-                location.resflags:=getresflags(true);
-             end;
-           else
-             { rest should be handled in first pass (JM) }
-             internalerror(200108303);
-       end;
-     end;
-{$endif i386}
-
-
 {*****************************************************************************
 {*****************************************************************************
                                   Add64bit
                                   Add64bit
 *****************************************************************************}
 *****************************************************************************}
@@ -906,7 +795,11 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.14  2004-10-31 21:45:04  peter
+  Revision 1.15  2004-11-01 12:43:29  peter
+    * shortstr compare with empty string fixed
+    * removed special i386 code
+
+  Revision 1.14  2004/10/31 21:45:04  peter
     * generic tlocation
     * generic tlocation
     * move tlocation to cgutils
     * move tlocation to cgutils
 
 

+ 65 - 1
rtl/i386/i386.inc

@@ -1119,6 +1119,64 @@ end;
 
 
 {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE}
 {$ifndef FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE}
 {$define FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE}
 {$define FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE}
+
+{$ifdef SHORTSTRCOMPAREINREG}
+function fpc_shortstr_compare(const left,right:shortstring): longint;assembler; [public,alias:'FPC_SHORTSTR_COMPARE']; compilerproc;
+var
+  saveesi,saveedi,saveebx : longint;
+asm
+        movl    %edi,saveedi
+        movl    %esi,saveesi
+        movl    %ebx,saveebx
+        cld
+        movl    right,%esi
+        movl    left,%edi
+        movzbl  (%esi),%eax
+        movzbl  (%edi),%ebx
+        movl    %eax,%edx
+        incl    %esi
+        incl    %edi
+        cmpl    %ebx,%eax
+        jbe     .LStrCmp1
+        movl    %ebx,%eax
+.LStrCmp1:
+        cmpl    $7,%eax
+        jl      .LStrCmp2
+        movl    %edi,%ecx       { Align on 32bits }
+        negl    %ecx
+        andl    $3,%ecx
+        subl    %ecx,%eax
+        orl     %ecx,%ecx
+        rep
+        cmpsb
+        jne     .LStrCmp3
+        movl    %eax,%ecx
+        andl    $3,%eax
+        shrl    $2,%ecx
+        orl     %ecx,%ecx
+        rep
+        cmpsl
+        je      .LStrCmp2
+        movl    $4,%eax
+        subl    %eax,%esi
+        subl    %eax,%edi
+.LStrCmp2:
+        movl    %eax,%ecx
+        orl     %eax,%eax
+        rep
+        cmpsb
+        je      .LStrCmp4
+.LStrCmp3:
+        movzbl  -1(%esi),%edx      // Compare failing (or equal) position
+        movzbl  -1(%edi),%ebx
+.LStrCmp4:
+        movl    %ebx,%eax          // Compare length or position
+        subl    %edx,%eax
+        movl    saveedi,%edi
+        movl    saveesi,%esi
+        movl    saveebx,%ebx
+end;
+{$else SHORTSTRCOMPAREINREG}
 function fpc_shortstr_compare(const left,right:shortstring): longint; [public,alias:'FPC_SHORTSTR_COMPARE']; {$ifdef hascompilerproc} compilerproc; {$endif}
 function fpc_shortstr_compare(const left,right:shortstring): longint; [public,alias:'FPC_SHORTSTR_COMPARE']; {$ifdef hascompilerproc} compilerproc; {$endif}
 begin
 begin
   asm
   asm
@@ -1166,6 +1224,8 @@ begin
 .LStrCmp3:
 .LStrCmp3:
   end ['EDX','ECX','EBX','EAX','ESI','EDI'];
   end ['EDX','ECX','EBX','EAX','ESI','EDI'];
 end;
 end;
+{$endif SHORTSTRCOMPAREINREG}
+
 {$endif FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE}
 {$endif FPC_SYSTEM_HAS_FPC_SHORTSTR_COMPARE}
 
 
 
 
@@ -1450,7 +1510,11 @@ end;
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.64  2004-07-18 20:21:44  florian
+  Revision 1.65  2004-11-01 12:43:29  peter
+    * shortstr compare with empty string fixed
+    * removed special i386 code
+
+  Revision 1.64  2004/07/18 20:21:44  florian
     + several unicode (to/from utf-8 conversion) stuff added
     + several unicode (to/from utf-8 conversion) stuff added
     * some longint -> SizeInt changes
     * some longint -> SizeInt changes