Prechádzať zdrojové kódy

+ fpu<->mm register conversion

florian 21 rokov pred
rodič
commit
3d8e1ab1fb

+ 28 - 1
compiler/ncgcnv.pas

@@ -272,6 +272,14 @@ interface
               begin
                 location_copy(location,left.location);
                 location.size:=def_cgsize(resulttype.def);
+                case expectloc of
+                  LOC_FPUREGISTER:
+                    ;
+                  LOC_MMREGISTER:
+                    location_force_mmregscalar(exprasmlist,location,false);
+                  else
+                    internalerror(2003012262);
+                end;
                 exit
               end;
             LOC_CREFERENCE,
@@ -282,6 +290,22 @@ interface
                  cg.a_loadfpu_loc_reg(exprasmlist,left.location,location.register);
                  location_freetemp(exprasmlist,left.location);
               end;
+            LOC_MMREGISTER,
+            LOC_CMMREGISTER:
+              begin
+                location_copy(location,left.location);
+                case expectloc of
+                  LOC_FPUREGISTER:
+                    begin
+                      location_force_fpureg(exprasmlist,location,false);
+                      location.size:=def_cgsize(resulttype.def);
+                    end;
+                  LOC_MMREGISTER:
+                    ;
+                  else
+                    internalerror(2003012261);
+                end;
+              end;
             else
               internalerror(2002032215);
          end;
@@ -511,7 +535,10 @@ end.
 
 {
   $Log$
-  Revision 1.51  2003-12-22 23:08:59  peter
+  Revision 1.52  2003-12-26 00:32:21  florian
+    + fpu<->mm register conversion
+
+  Revision 1.51  2003/12/22 23:08:59  peter
     * removed unused checkobject method
 
   Revision 1.50  2003/11/04 22:30:15  florian

+ 24 - 1
compiler/ncgutil.pas

@@ -605,10 +605,20 @@ implementation
     procedure location_force_fpureg(list:TAAsmoutput;var l: tlocation;maybeconst:boolean);
       var
         reg : tregister;
+        href : treference;
       begin
         if (l.loc<>LOC_FPUREGISTER)  and
            ((l.loc<>LOC_CFPUREGISTER) or (not maybeconst)) then
           begin
+            { if it's in an mm register, store to memory first }
+            if (l.loc in [LOC_MMREGISTER,LOC_CMMREGISTER]) then
+              begin
+                tg.GetTemp(list,tcgsize2size[l.size],tt_normal,href);
+                cg.a_loadmm_reg_ref(list,l.size,l.size,l.register,href,mms_movescalar);
+                location_release(list,l);
+                location_reset(l,LOC_REFERENCE,l.size);
+                l.reference:=href;
+              end;
             reg:=cg.getfpuregister(list,l.size);
             cg.a_loadfpu_loc_reg(list,l,reg);
             location_freetemp(list,l);
@@ -622,10 +632,20 @@ implementation
     procedure location_force_mmregscalar(list:TAAsmoutput;var l: tlocation;maybeconst:boolean);
       var
         reg : tregister;
+        href : treference;
       begin
         if (l.loc<>LOC_MMREGISTER)  and
            ((l.loc<>LOC_CMMREGISTER) or (not maybeconst)) then
           begin
+            { if it's in an fpu register, store to memory first }
+            if (l.loc in [LOC_FPUREGISTER,LOC_CFPUREGISTER]) then
+              begin
+                tg.GetTemp(list,tcgsize2size[l.size],tt_normal,href);
+                cg.a_loadfpu_reg_ref(list,l.size,l.register,href);
+                location_release(list,l);
+                location_reset(l,LOC_REFERENCE,l.size);
+                l.reference:=href;
+              end;
             reg:=cg.getmmregister(list,l.size);
             cg.a_loadmm_loc_reg(list,l.size,l,reg,mms_movescalar);
             location_freetemp(list,l);
@@ -2019,7 +2039,10 @@ implementation
 end.
 {
   $Log$
-  Revision 1.177  2003-12-24 00:10:02  florian
+  Revision 1.178  2003-12-26 00:32:21  florian
+    + fpu<->mm register conversion
+
+  Revision 1.177  2003/12/24 00:10:02  florian
     - delete parameter in cg64 methods removed
 
   Revision 1.176  2003/12/23 14:38:07  florian

+ 4 - 9
compiler/ncnv.pas

@@ -1571,18 +1571,10 @@ implementation
       end;
 
 
-
-
     function ttypeconvnode.first_real_to_real : tnode;
       begin
          first_real_to_real:=nil;
         { comp isn't a floating type }
-{$ifdef i386}
-         if (tfloatdef(resulttype.def).typ=s64comp) and
-            (tfloatdef(left.resulttype.def).typ<>s64comp) and
-            not (nf_explicit in flags) then
-           CGMessage(type_w_convert_real_2_comp);
-{$endif}
          if registersfpu<1 then
            registersfpu:=1;
          expectloc:=LOC_FPUREGISTER;
@@ -2413,7 +2405,10 @@ begin
 end.
 {
   $Log$
-  Revision 1.133  2003-12-22 23:11:15  peter
+  Revision 1.134  2003-12-26 00:32:21  florian
+    + fpu<->mm register conversion
+
+  Revision 1.133  2003/12/22 23:11:15  peter
     * fix rangecheck error
 
   Revision 1.132  2003/12/08 22:35:28  peter

+ 6 - 3
compiler/node.pas

@@ -274,9 +274,9 @@ interface
           flags : tnodeflags;
           ppuidx : longint;
           { the number of registers needed to evalute the node }
-          registers32,registersfpu : longint;  { must be longint !!!! }
+          registers32,registersfpu,registersmm : longint;  { must be longint !!!! }
 {$ifdef SUPPORT_MMX}
-          registersmmx,registerskni : longint;
+          registersmmx : longint;
 {$endif SUPPORT_MMX}
           resulttype : ttype;
           fileinfo : tfileposinfo;
@@ -1087,7 +1087,10 @@ implementation
 end.
 {
   $Log$
-  Revision 1.78  2003-12-01 18:44:15  peter
+  Revision 1.79  2003-12-26 00:32:22  florian
+    + fpu<->mm register conversion
+
+  Revision 1.78  2003/12/01 18:44:15  peter
     * fixed some crashes
     * fixed varargs and register calling probs
 

+ 13 - 2
compiler/x86/cgx86.pas

@@ -146,6 +146,8 @@ unit cgx86;
         procedure floatstoreops(t : tcgsize;var op : tasmop;var s : topsize);
       end;
 
+    function use_sse(def : tdef) : boolean;
+
    const
 {$ifdef x86_64}
       TCGSize2OpSize: Array[tcgsize] of topsize =
@@ -164,7 +166,7 @@ unit cgx86;
 
     uses
        globtype,globals,verbose,systems,cutils,
-       symdef,paramgr,tgobj,procinfo;
+       symdef,defutil,paramgr,tgobj,procinfo;
 
 {$ifndef NOTARGETWIN32}
     const
@@ -178,6 +180,12 @@ unit cgx86;
       TOpCmp2AsmCond: Array[topcmp] of TAsmCond = (C_NONE,
           C_E,C_G,C_L,C_GE,C_LE,C_NE,C_BE,C_B,C_AE,C_A);
 
+    function use_sse(def : tdef) : boolean;
+      begin
+        use_sse:=(is_single(def) and (aktfputype in sse_singlescalar)) or
+          (is_double(def) and (aktfputype in sse_doublescalar));
+      end;
+
 
     procedure Tcgx86.init_register_allocators;
       begin
@@ -1910,7 +1918,10 @@ unit cgx86;
 end.
 {
   $Log$
-  Revision 1.97  2003-12-25 12:01:35  florian
+  Revision 1.98  2003-12-26 00:32:22  florian
+    + fpu<->mm register conversion
+
+  Revision 1.97  2003/12/25 12:01:35  florian
     + possible sse2 unit usage for double calculations
     * some sse2 assembler issues fixed
 

+ 5 - 3
compiler/x86/nx86add.pas

@@ -81,8 +81,7 @@ unit nx86add;
         pushedfpu,
         cmpop      : boolean;
       begin
-        if (is_single(resulttype.def) and (aktfputype in sse_singlescalar)) or
-          (is_double(resulttype.def) and (aktfputype in sse_doublescalar)) then
+        if use_sse(resulttype.def) then
           begin
             second_addfloatsse;
             exit;
@@ -256,7 +255,10 @@ unit nx86add;
 end.
 {
   $Log$
-  Revision 1.3  2003-12-25 01:07:09  florian
+  Revision 1.4  2003-12-26 00:32:22  florian
+    + fpu<->mm register conversion
+
+  Revision 1.3  2003/12/25 01:07:09  florian
     + $fputype directive support
     + single data type operations with sse unit
     * fixed more x86-64 stuff

+ 30 - 2
compiler/x86/nx86cnv.pas

@@ -32,6 +32,7 @@ interface
     type
        tx86typeconvnode = class(tcgtypeconvnode)
          protected
+         function first_real_to_real : tnode;override;
          { procedure second_int_to_int;override; }
          { procedure second_string_to_string;override; }
          { procedure second_cstring_to_pchar;override; }
@@ -60,10 +61,34 @@ implementation
    uses
       verbose,systems,globals,
       aasmbase,aasmtai,
+      symconst,symdef,
       cgbase,pass_2,
       ncon,ncal,ncnv,
       cpubase,
-      cgobj,ncgutil;
+      cgobj,cgx86,ncgutil;
+
+
+    function tx86typeconvnode.first_real_to_real : tnode;
+      begin
+         first_real_to_real:=nil;
+        { comp isn't a floating type }
+         if (tfloatdef(resulttype.def).typ=s64comp) and
+            (tfloatdef(left.resulttype.def).typ<>s64comp) and
+            not (nf_explicit in flags) then
+           CGMessage(type_w_convert_real_2_comp);
+         if use_sse(resulttype.def) then
+           begin
+             if registersmm<1 then
+               registersmm:=1;
+             expectloc:=LOC_MMREGISTER;
+           end
+         else
+           begin
+             if registersfpu<1 then
+               registersfpu:=1;
+             expectloc:=LOC_FPUREGISTER;
+           end;
+      end;
 
 
     procedure tx86typeconvnode.second_int_to_bool;
@@ -166,7 +191,10 @@ implementation
 end.
 {
   $Log$
-  Revision 1.7  2003-10-10 17:48:14  peter
+  Revision 1.8  2003-12-26 00:32:22  florian
+    + fpu<->mm register conversion
+
+  Revision 1.7  2003/10/10 17:48:14  peter
     * old trgobj moved to x86/rgcpu and renamed to trgx86fpu
     * tregisteralloctor renamed to trgobj
     * removed rgobj from a lot of units