Browse Source

+ inline abs(<longint>) on x86

git-svn-id: trunk@9333 -
florian 17 years ago
parent
commit
fb8bbd5ff0
7 changed files with 89 additions and 5 deletions
  1. 1 0
      compiler/compinnr.inc
  2. 9 1
      compiler/ncginl.pas
  3. 32 4
      compiler/ninl.pas
  4. 1 0
      compiler/options.pas
  5. 40 0
      compiler/x86/nx86inl.pas
  6. 1 0
      rtl/inc/innr.inc
  7. 5 0
      rtl/inc/systemh.inc

+ 1 - 0
compiler/compinnr.inc

@@ -71,6 +71,7 @@ const
    in_bitsizeof_x       = 61;
    in_bitsizeof_x       = 61;
    in_writestr_x        = 62;
    in_writestr_x        = 62;
    in_readstr_x         = 63;
    in_readstr_x         = 63;
+   in_abs_long          = 64;
 
 
 { Internal constant functions }
 { Internal constant functions }
    in_const_sqr        = 100;
    in_const_sqr        = 100;

+ 9 - 1
compiler/ncginl.pas

@@ -53,6 +53,7 @@ interface
           procedure second_prefetch; virtual;
           procedure second_prefetch; virtual;
           procedure second_round_real; virtual;
           procedure second_round_real; virtual;
           procedure second_trunc_real; virtual;
           procedure second_trunc_real; virtual;
+          procedure second_abs_long; virtual;
        end;
        end;
 
 
 implementation
 implementation
@@ -109,6 +110,8 @@ implementation
               second_arctan_real;
               second_arctan_real;
             in_abs_real:
             in_abs_real:
               second_abs_real;
               second_abs_real;
+            in_abs_long:
+              second_abs_long;
             in_round_real:
             in_round_real:
               second_round_real;
               second_round_real;
             in_trunc_real:
             in_trunc_real:
@@ -596,6 +599,11 @@ implementation
       begin
       begin
       end;
       end;
 
 
+    procedure tcginlinenode.second_abs_long;
+      begin
+        internalerror(200711251);
+      end;
+
 
 
 {*****************************************************************************
 {*****************************************************************************
                          ASSIGNED GENERIC HANDLING
                          ASSIGNED GENERIC HANDLING
@@ -630,7 +638,7 @@ implementation
 
 
     procedure Tcginlinenode.second_get_caller_frame;
     procedure Tcginlinenode.second_get_caller_frame;
 
 
-    var 
+    var
       frame_reg:Tregister;
       frame_reg:Tregister;
       use_frame_pointer:boolean;
       use_frame_pointer:boolean;
 
 

+ 32 - 4
compiler/ninl.pas

@@ -62,6 +62,7 @@ interface
           function first_round_real: tnode; virtual;
           function first_round_real: tnode; virtual;
           function first_trunc_real: tnode; virtual;
           function first_trunc_real: tnode; virtual;
           function first_int_real: tnode; virtual;
           function first_int_real: tnode; virtual;
+          function first_abs_long: tnode; virtual;
         private
         private
           function handle_str: tnode;
           function handle_str: tnode;
           function handle_reset_rewrite_typed: tnode;
           function handle_reset_rewrite_typed: tnode;
@@ -1618,7 +1619,6 @@ implementation
                   end;
                   end;
                 end;
                 end;
 
 
-
               in_sizeof_x:
               in_sizeof_x:
                 begin
                 begin
                   set_varstate(left,vs_read,[]);
                   set_varstate(left,vs_read,[]);
@@ -2281,12 +2281,30 @@ implementation
               in_abs_real :
               in_abs_real :
                 begin
                 begin
                   if left.nodetype in [ordconstn,realconstn] then
                   if left.nodetype in [ordconstn,realconstn] then
-                   setconstrealvalue(abs(getconstrealvalue))
+                    setconstrealvalue(abs(getconstrealvalue))
                   else
                   else
+                    begin
+                      set_varstate(left,vs_read,[vsf_must_be_valid]);
+                      inserttypeconv(left,pbestrealtype^);
+                      resultdef:=pbestrealtype^;
+                    end;
+                end;
+
+              in_abs_long:
+                begin
+                 if left.nodetype=ordconstn then
+                   begin
+                     if tordconstnode(left).value<0 then
+                       result:=cordconstnode.create((-tordconstnode(left).value),s32inttype,false)
+                     else
+                       result:=cordconstnode.create((tordconstnode(left).value),s32inttype,false);
+                     left:=nil
+                   end
+                 else
                    begin
                    begin
                      set_varstate(left,vs_read,[vsf_must_be_valid]);
                      set_varstate(left,vs_read,[vsf_must_be_valid]);
-                     inserttypeconv(left,pbestrealtype^);
-                     resultdef:=pbestrealtype^;
+                     inserttypeconv(left,s32inttype);
+                     resultdef:=s32inttype;
                    end;
                    end;
                 end;
                 end;
 
 
@@ -2650,6 +2668,11 @@ implementation
              result := first_abs_real;
              result := first_abs_real;
            end;
            end;
 
 
+         in_abs_long:
+           begin
+             result := first_abs_long;
+           end;
+
          in_sqr_real:
          in_sqr_real:
            begin
            begin
              result := first_sqr_real;
              result := first_sqr_real;
@@ -2856,6 +2879,11 @@ implementation
         left := nil;
         left := nil;
       end;
       end;
 
 
+     function tinlinenode.first_abs_long : tnode;
+      begin
+        result:=nil;
+      end;
+
      function tinlinenode.first_pack_unpack: tnode;
      function tinlinenode.first_pack_unpack: tnode;
        var
        var
          loopstatement    : tstatementnode;
          loopstatement    : tstatementnode;

+ 1 - 0
compiler/options.pas

@@ -2141,6 +2141,7 @@ begin
   def_system_macro('FPC_STRTOCHARARRAYPROC');
   def_system_macro('FPC_STRTOCHARARRAYPROC');
   def_system_macro('FPC_NEW_BIGENDIAN_SETS');
   def_system_macro('FPC_NEW_BIGENDIAN_SETS');
   def_system_macro('FPC_STRTOSHORTSTRINGPROC');
   def_system_macro('FPC_STRTOSHORTSTRINGPROC');
+  def_system_macro('FPC_HAS_INTERNAL_ABS_LONG');
 
 
 {$ifdef SUPPORT_UNALIGNED}
 {$ifdef SUPPORT_UNALIGNED}
   def_system_macro('FPC_SUPPORTS_UNALIGNED');
   def_system_macro('FPC_SUPPORTS_UNALIGNED');

+ 40 - 0
compiler/x86/nx86inl.pas

@@ -58,6 +58,8 @@ interface
           procedure second_trunc_real; override;
           procedure second_trunc_real; override;
 
 
           procedure second_prefetch;override;
           procedure second_prefetch;override;
+
+          procedure second_abs_long;override;
        private
        private
           procedure load_fpu_location;
           procedure load_fpu_location;
        end;
        end;
@@ -415,6 +417,44 @@ implementation
            end;
            end;
        end;
        end;
 
 
+
+    procedure tx86inlinenode.second_abs_long;
+      var
+        hregister : tregister;
+        opsize : tcgsize;
+        hp : taicpu;
+      begin
+{$ifdef i386}
+        if current_settings.cputype<cpu_Pentium2 then
+          begin
+            opsize:=int_cgsize(tcallparanode(left).resultdef.size);
+            secondpass(left);
+            location_force_reg(current_asmdata.CurrAsmList,left.location,opsize,false);
+            location:=left.location;
+            location.register:=cg.getintregister(current_asmdata.CurrAsmList,opsize);
+            emit_reg_reg(A_MOV,S_L,left.location.register,location.register);
+            emit_const_reg(A_SAR,tcgsize2opsize[opsize],31,left.location.register);
+            emit_reg_reg(A_XOR,S_L,left.location.register,location.register);
+            emit_reg_reg(A_SUB,S_L,left.location.register,location.register);
+          end
+        else
+{$endif i386}
+          begin
+            opsize:=int_cgsize(tcallparanode(left).resultdef.size);
+            secondpass(left);
+            location_force_reg(current_asmdata.CurrAsmList,left.location,opsize,true);
+            hregister:=cg.getintregister(current_asmdata.CurrAsmList,opsize);
+            location:=left.location;
+            location.register:=cg.getintregister(current_asmdata.CurrAsmList,opsize);
+            cg.a_load_reg_reg(current_asmdata.CurrAsmList,opsize,opsize,left.location.register,hregister);
+            cg.a_load_reg_reg(current_asmdata.CurrAsmList,opsize,opsize,left.location.register,location.register);
+            emit_reg(A_NEG,tcgsize2opsize[opsize],hregister);
+            hp:=taicpu.op_reg_reg(A_CMOVcc,tcgsize2opsize[opsize],hregister,location.register);
+            hp.condition:=C_NS;
+            current_asmdata.CurrAsmList.concat(hp);
+          end;
+      end;
+
 {*****************************************************************************
 {*****************************************************************************
                      INCLUDE/EXCLUDE GENERIC HANDLING
                      INCLUDE/EXCLUDE GENERIC HANDLING
 *****************************************************************************}
 *****************************************************************************}

+ 1 - 0
rtl/inc/innr.inc

@@ -72,6 +72,7 @@ const
    fpc_in_bitsizeof_x       = 61;
    fpc_in_bitsizeof_x       = 61;
    fpc_in_writestr_x        = 62;
    fpc_in_writestr_x        = 62;
    fpc_in_readstr_x         = 63;
    fpc_in_readstr_x         = 63;
+   fpc_in_abs_long          = 64;
 
 
 { Internal constant functions }
 { Internal constant functions }
    fpc_in_const_sqr        = 100;
    fpc_in_const_sqr        = 100;

+ 5 - 0
rtl/inc/systemh.inc

@@ -481,7 +481,12 @@ Function  Random: extended;
 Procedure Randomize;
 Procedure Randomize;
 {$endif FPC_HAS_FEATURE_RANDOM}
 {$endif FPC_HAS_FEATURE_RANDOM}
 
 
+{$ifdef FPC_HAS_INTERNAL_ABS_LONG and (defined(cpui386) or defined(cpux86_64))}
+{$define FPC_SYSTEM_HAS_ABS_LONGINT}
+Function abs(l:longint):longint;[internproc:fpc_in_abs_long];
+{$else FPC_HAS_INTERNAL_ABS_LONG}
 Function abs(l:Longint):Longint;[internconst:fpc_in_const_abs];{$ifdef SYSTEMINLINE}inline;{$endif}
 Function abs(l:Longint):Longint;[internconst:fpc_in_const_abs];{$ifdef SYSTEMINLINE}inline;{$endif}
+{$endif FPC_HAS_INTERNAL_ABS_LONG}
 Function abs(l:Int64):Int64;[internconst:fpc_in_const_abs];{$ifdef SYSTEMINLINE}inline;{$endif}
 Function abs(l:Int64):Int64;[internconst:fpc_in_const_abs];{$ifdef SYSTEMINLINE}inline;{$endif}
 Function sqr(l:Longint):Longint;[internconst:fpc_in_const_sqr];{$ifdef SYSTEMINLINE}inline;{$endif}
 Function sqr(l:Longint):Longint;[internconst:fpc_in_const_sqr];{$ifdef SYSTEMINLINE}inline;{$endif}
 Function sqr(l:Int64):Int64;[internconst:fpc_in_const_sqr];{$ifdef SYSTEMINLINE}inline;{$endif}
 Function sqr(l:Int64):Int64;[internconst:fpc_in_const_sqr];{$ifdef SYSTEMINLINE}inline;{$endif}