Browse Source

+ default code now preserves mm registers
* save|restore_standard_registers => save|restore_registers

git-svn-id: trunk@8954 -

florian 18 years ago
parent
commit
00d6a03b2c

+ 4 - 4
compiler/arm/cgcpu.pas

@@ -98,8 +98,8 @@ unit cgcpu;
         procedure g_overflowcheck(list: TAsmList; const l: tlocation; def: tdef); override;
         procedure g_overflowCheck_loc(List:TAsmList;const Loc:TLocation;def:TDef;ovloc : tlocation);override;
 
-        procedure g_save_standard_registers(list : TAsmList);override;
-        procedure g_restore_standard_registers(list : TAsmList);override;
+        procedure g_save_registers(list : TAsmList);override;
+        procedure g_restore_registers(list : TAsmList);override;
 
         procedure a_jmp_cond(list : TAsmList;cond : TOpCmp;l: tasmlabel);
         procedure fixref(list : TAsmList;var ref : treference);
@@ -1842,13 +1842,13 @@ unit cgcpu;
       end;
 
 
-    procedure tcgarm.g_save_standard_registers(list : TAsmList);
+    procedure tcgarm.g_save_registers(list : TAsmList);
       begin
         { this work is done in g_proc_entry }
       end;
 
 
-    procedure tcgarm.g_restore_standard_registers(list : TAsmList);
+    procedure tcgarm.g_restore_registers(list : TAsmList);
       begin
         { this work is done in g_proc_exit }
       end;

+ 4 - 0
compiler/arm/cpubase.pas

@@ -339,6 +339,10 @@ unit cpubase;
       }
       saved_standard_registers : array[0..6] of tsuperregister =
         (RS_R4,RS_R5,RS_R6,RS_R7,RS_R8,RS_R9,RS_R10);
+
+      { this is only for the generic code which is not used for this architecture }
+      saved_mm_registers : array[0..0] of tsuperregister = (RS_NO);
+
       { Required parameter alignment when calling a routine declared as
         stdcall and cdecl. The alignment value should be the one defined
         by GCC or the target ABI.

+ 44 - 8
compiler/cgobj.pas

@@ -39,7 +39,7 @@ unit cgobj;
        cclasses,globtype,constexp,
        cpubase,cgbase,cgutils,parabase,
        aasmbase,aasmtai,aasmdata,aasmcpu,
-       symconst,symbase,symtype,symdef,symtable,rgobj
+       symconst,symtype,symdef,rgobj
        ;
 
     type
@@ -462,24 +462,25 @@ unit cgobj;
 
              @param(usedinproc Registers which are used in the code of this routine)
           }
-          procedure g_save_standard_registers(list:TAsmList);virtual;
+          procedure g_save_registers(list:TAsmList);virtual;
           {# This routine is called when generating the code for the exit point
              of a routine. It should restore all registers which were previously
              saved in @var(g_save_standard_registers).
 
              @param(usedinproc Registers which are used in the code of this routine)
           }
-          procedure g_restore_standard_registers(list:TAsmList);virtual;
+          procedure g_restore_registers(list:TAsmList);virtual;
+                    
           procedure g_intf_wrapper(list: TAsmList; procdef: tprocdef; const labelname: string; ioffset: longint);virtual;abstract;
           procedure g_adjust_self_value(list:TAsmList;procdef: tprocdef;ioffset: aint);virtual;
 
           function g_indirect_sym_load(list:TAsmList;const symname: string): tregister;virtual;
-          { generate a stub which only purpose is to pass control the given external method, 
+          { generate a stub which only purpose is to pass control the given external method,
           setting up any additional environment before doing so (if required).
 
           The default implementation issues a jump instruction to the external name. }
           procedure g_external_wrapper(list : TAsmList; procdef: tprocdef; const externalname: string); virtual;
-          
+
           { initialize the pic/got register }
           procedure g_maybe_got_init(list: TAsmList); virtual;
         protected
@@ -3594,17 +3595,26 @@ implementation
       end;
 
 
-    procedure tcg.g_save_standard_registers(list:TAsmList);
+    procedure tcg.g_save_registers(list:TAsmList);
       var
         href : treference;
         size : longint;
         r : integer;
       begin
-        { Get temp }
+        { calculate temp. size }
         size:=0;
         for r:=low(saved_standard_registers) to high(saved_standard_registers) do
           if saved_standard_registers[r] in rg[R_INTREGISTER].used_in_proc then
             inc(size,sizeof(aint));
+
+        { mm registers }
+        if uses_registers(R_MMREGISTER) then
+          for r:=low(saved_mm_registers) to high(saved_mm_registers) do
+            if saved_mm_registers[r] in rg[R_MMREGISTER].used_in_proc then
+              inc(size,tcgsize2size[OS_VECTOR]);
+
+        tg.GetTemp(list,size,tt_noreuse,current_procinfo.save_regs_ref);
+
         if size>0 then
           begin
             tg.GetTemp(list,size,tt_noreuse,current_procinfo.save_regs_ref);
@@ -3620,11 +3630,22 @@ implementation
                   end;
                 include(rg[R_INTREGISTER].preserved_by_proc,saved_standard_registers[r]);
               end;
+
+            if uses_registers(R_MMREGISTER) then
+              for r:=low(saved_mm_registers) to high(saved_mm_registers) do
+                begin
+                  if saved_mm_registers[r] in rg[R_MMREGISTER].used_in_proc then
+                    begin
+                      a_loadmm_reg_ref(list,OS_VECTOR,OS_VECTOR,newreg(R_MMREGISTER,saved_mm_registers[r],R_SUBNONE),href,nil);
+                      inc(href.offset,tcgsize2size[OS_VECTOR]);
+                    end;
+                  include(rg[R_MMREGISTER].preserved_by_proc,saved_mm_registers[r]);
+                end;
           end;
       end;
 
 
-    procedure tcg.g_restore_standard_registers(list:TAsmList);
+    procedure tcg.g_restore_registers(list:TAsmList);
       var
         href     : treference;
         r        : integer;
@@ -3644,6 +3665,21 @@ implementation
               inc(href.offset,sizeof(aint));
               freetemp:=true;
             end;
+
+        if uses_registers(R_MMREGISTER) then
+          for r:=low(saved_mm_registers) to high(saved_mm_registers) do
+            begin
+              if saved_mm_registers[r] in rg[R_MMREGISTER].used_in_proc then
+                begin
+                  hreg:=newreg(R_MMREGISTER,saved_mm_registers[r],R_SUBNONE);
+                  { Allocate register so the optimizer does not remove the load }
+                  a_reg_alloc(list,hreg);
+                  a_loadmm_ref_reg(list,OS_VECTOR,OS_VECTOR,href,hreg,nil);
+                  inc(href.offset,tcgsize2size[OS_VECTOR]);
+                  freetemp:=true;
+                end;
+            end;
+
         if freetemp then
           tg.UnGetTemp(list,current_procinfo.save_regs_ref);
       end;

+ 2 - 0
compiler/i386/cpubase.inc

@@ -159,6 +159,8 @@
          GCC source.
       }
       saved_standard_registers : array[0..2] of tsuperregister = (RS_EBX,RS_ESI,RS_EDI);
+
+      saved_mm_registers : array[0..0] of tsuperregister = (RS_INVALID);
       {# Required parameter alignment when calling a routine declared as
          stdcall and cdecl. The alignment value should be the one defined
          by GCC or the target ABI.

+ 4 - 4
compiler/m68k/cgcpu.pas

@@ -86,8 +86,8 @@ unit cgcpu;
 
 //        procedure g_restore_frame_pointer(list : TAsmList);override;
 //        procedure g_return_from_proc(list : TAsmList;parasize : aint);override;
-        procedure g_restore_standard_registers(list:TAsmList);override;
-        procedure g_save_standard_registers(list:TAsmList);override;
+        procedure g_restore_registers(list:TAsmList);override;
+        procedure g_save_registers(list:TAsmList);override;
 
 //        procedure g_save_all_registers(list : TAsmList);override;
 //        procedure g_restore_all_registers(list : TAsmList;const funcretparaloc:TCGPara);override;
@@ -1410,7 +1410,7 @@ unit cgcpu;
       end;
 
 
-    procedure Tcg68k.g_save_standard_registers(list:TAsmList);
+    procedure Tcg68k.g_save_registers(list:TAsmList);
       var
         tosave : tcpuregisterset;
         ref : treference;
@@ -1427,7 +1427,7 @@ unit cgcpu;
       end;
 
 
-    procedure Tcg68k.g_restore_standard_registers(list:TAsmList);
+    procedure Tcg68k.g_restore_registers(list:TAsmList);
       var
         torestore : tcpuregisterset;
         r:Tregister;

+ 3 - 0
compiler/m68k/cpubase.pas

@@ -300,6 +300,9 @@ unit cpubase;
       }
       saved_standard_registers : array[0..5] of tsuperregister = (RS_D2,RS_D3,RS_D4,RS_D5,RS_D6,RS_D7);
       saved_standard_address_registers : array[0..3] of tsuperregister = (RS_A2,RS_A3,RS_A4,RS_A5);
+      
+      { this is only for the generic code which is not used for this architecture }
+      saved_mm_registers : array[0..0] of tsuperregister = (RS_NO);
 
       {# Required parameter alignment when calling a routine declared as
          stdcall and cdecl. The alignment value should be the one defined

+ 4 - 0
compiler/mips/cpubase.pas

@@ -353,6 +353,10 @@ unit cpubase;
       }
       saved_standard_registers : array[0..8] of tsuperregister =
         (RS_R16,RS_R17,RS_R18,RS_R19,RS_R20,RS_R21,RS_R22,RS_R23,RS_R30);
+        
+      { this is only for the generic code which is not used for this architecture }
+      saved_mm_registers : array[0..0] of tsuperregister = (RS_NO);
+      
       { Required parameter alignment when calling a routine declared as
         stdcall and cdecl. The alignment value should be the one defined
         by GCC or the target ABI.

+ 2 - 2
compiler/ncgutil.pas

@@ -2090,7 +2090,7 @@ implementation
 
         { oldfpccall expects all registers to be destroyed }
         if current_procinfo.procdef.proccalloption<>pocall_oldfpccall then
-          cg.g_save_standard_registers(list);
+            cg.g_save_registers(list);
       end;
 
 
@@ -2102,7 +2102,7 @@ implementation
 
         { oldfpccall expects all registers to be destroyed }
         if current_procinfo.procdef.proccalloption<>pocall_oldfpccall then
-          cg.g_restore_standard_registers(list);
+          cg.g_restore_registers(list);
       end;
 
 

+ 4 - 4
compiler/powerpc/cgcpu.pas

@@ -78,8 +78,8 @@ unit cgcpu;
 
         procedure g_proc_entry(list : TAsmList;localsize : longint;nostackframe:boolean);override;
         procedure g_proc_exit(list : TAsmList;parasize : longint;nostackframe:boolean); override;
-        procedure g_save_standard_registers(list:TAsmList); override;
-        procedure g_restore_standard_registers(list:TAsmList); override;
+        procedure g_save_registers(list:TAsmList); override;
+        procedure g_restore_registers(list:TAsmList); override;
 
         procedure g_concatcopy(list : TAsmList;const source,dest : treference;len : aint);override;
 
@@ -857,13 +857,13 @@ const
 
 { *********** entry/exit code and address loading ************ }
 
-    procedure tcgppc.g_save_standard_registers(list:TAsmList);
+    procedure tcgppc.g_save_registers(list:TAsmList);
       begin
         { this work is done in g_proc_entry }
       end;
 
 
-    procedure tcgppc.g_restore_standard_registers(list:TAsmList);
+    procedure tcgppc.g_restore_registers(list:TAsmList);
       begin
         { this work is done in g_proc_exit }
       end;

+ 3 - 0
compiler/powerpc/cpubase.pas

@@ -348,6 +348,9 @@ uses
         RS_R30,RS_R31
       );
 
+      { this is only for the generic code which is not used for this architecture }
+      saved_mm_registers : array[0..0] of tsuperregister = (RS_NO);
+
       {# Required parameter alignment when calling a routine declared as
          stdcall and cdecl. The alignment value should be the one defined
          by GCC or the target ABI.

+ 4 - 4
compiler/powerpc64/cgcpu.pas

@@ -90,8 +90,8 @@ type
       boolean); override;
     procedure g_proc_exit(list: TAsmList; parasize: longint; nostackframe:
       boolean); override;
-    procedure g_save_standard_registers(list: TAsmList); override;
-    procedure g_restore_standard_registers(list: TAsmList); override;
+    procedure g_save_registers(list: TAsmList); override;
+    procedure g_restore_registers(list: TAsmList); override;
 
     procedure a_loadaddr_ref_reg(list: TAsmList; const ref: treference; r:
       tregister); override;
@@ -1275,13 +1275,13 @@ end;
 
 { *********** entry/exit code and address loading ************ }
 
-procedure tcgppc.g_save_standard_registers(list: TAsmList);
+procedure tcgppc.g_save_registers(list: TAsmList);
 begin
   { this work is done in g_proc_entry; additionally it is not safe
   to use it because it is called at some weird time }
 end;
 
-procedure tcgppc.g_restore_standard_registers(list: TAsmList);
+procedure tcgppc.g_restore_registers(list: TAsmList);
 begin
   { this work is done in g_proc_exit; mainly because it is not safe to
   put the register restore code here because it is called at some weird time }

+ 3 - 0
compiler/powerpc64/cpubase.pas

@@ -348,6 +348,9 @@ const
     RS_R26, RS_R27, RS_R28, RS_R29, RS_R30, RS_R31
     );
 
+  { this is only for the generic code which is not used for this architecture }
+  saved_mm_registers : array[0..0] of tsuperregister = (RS_NO);  
+  
   {# Required parameter alignment when calling a routine declared as
      stdcall and cdecl. The alignment value should be the one defined
      by GCC or the target ABI.

+ 4 - 4
compiler/sparc/cgcpu.pas

@@ -84,8 +84,8 @@ interface
         procedure g_overflowCheck_loc(List:TAsmList;const Loc:TLocation;def:TDef;ovloc : tlocation);override;
         procedure g_proc_entry(list : TAsmList;localsize : longint;nostackframe:boolean);override;
         procedure g_proc_exit(list : TAsmList;parasize:longint;nostackframe:boolean);override;
-        procedure g_restore_standard_registers(list:TAsmList);override;
-        procedure g_save_standard_registers(list : TAsmList);override;
+        procedure g_restore_registers(list:TAsmList);override;
+        procedure g_save_registers(list : TAsmList);override;
         procedure g_concatcopy(list : TAsmList;const source,dest : treference;len : aint);override;
         procedure g_concatcopy_unaligned(list : TAsmList;const source,dest : treference;len : aint);override;
         procedure g_concatcopy_move(list : TAsmList;const source,dest : treference;len : aint);
@@ -1065,7 +1065,7 @@ implementation
       end;
 
 
-    procedure TCgSparc.g_restore_standard_registers(list:TAsmList);
+    procedure TCgSparc.g_restore_registers(list:TAsmList);
       begin
         { The sparc port uses the sparc standard calling convetions so this function has no used }
       end;
@@ -1114,7 +1114,7 @@ implementation
       end;
 
 
-    procedure TCgSparc.g_save_standard_registers(list : TAsmList);
+    procedure TCgSparc.g_save_registers(list : TAsmList);
       begin
         { The sparc port uses the sparc standard calling convetions so this function has no used }
       end;

+ 3 - 0
compiler/sparc/cpubase.pas

@@ -304,6 +304,9 @@ uses
       }
       saved_standard_registers : array[0..0] of tsuperregister = (RS_NO);
 
+      { this is only for the generic code which is not used for this architecture }
+      saved_mm_registers : array[0..0] of tsuperregister = (RS_NO);
+      
       {# Required parameter alignment when calling a routine declared as
          stdcall and cdecl. The alignment value should be the one defined
          by GCC or the target ABI.

+ 4 - 4
compiler/x86_64/cgcpu.pas

@@ -65,24 +65,24 @@ unit cgcpu;
         if target_info.system=system_x86_64_win64 then
           begin
             SetLength(saved_standard_registers,Length(win64_saved_std_regs));
-            SetLength(saved_xmm_registers,Length(win64_saved_xmm_regs));
+            SetLength(saved_mm_registers,Length(win64_saved_xmm_regs));
 
             for i:=low(win64_saved_std_regs) to high(win64_saved_std_regs) do
               saved_standard_registers[i]:=win64_saved_std_regs[i];
 
             for i:=low(win64_saved_xmm_regs) to high(win64_saved_xmm_regs) do
-              saved_xmm_registers[i]:=win64_saved_xmm_regs[i];
+              saved_mm_registers[i]:=win64_saved_xmm_regs[i];
           end
         else
           begin
             SetLength(saved_standard_registers,Length(others_saved_std_regs));
-            SetLength(saved_xmm_registers,0);
+            SetLength(saved_mm_registers,0);
 
             for i:=low(others_saved_std_regs) to high(others_saved_std_regs) do
               saved_standard_registers[i]:=others_saved_std_regs[i];
           end;
         if assigned(current_procinfo) then
-          framepointer:=getsupreg(current_procinfo.framepointer) 
+          framepointer:=getsupreg(current_procinfo.framepointer)
         else
           { in intf. wrapper code generation }
           framepointer:=RS_FRAME_POINTER_REG;

+ 1 - 2
compiler/x86_64/cpubase.inc

@@ -123,7 +123,7 @@ const
     const
       { these arrays differ between unix and win64 }
       saved_standard_registers : array of tsuperregister = nil;
-      saved_xmm_registers : array of tsuperregister = nil;
+      saved_mm_registers : array of tsuperregister = nil;
       { Required parameter alignment when calling a routine declared as
         stdcall and cdecl. The alignment value should be the one defined
         by GCC or the target ABI.
@@ -132,4 +132,3 @@ const
          PARM_BOUNDARY / BITS_PER_UNIT in the GCC source.
       }
       std_param_align = 8;
-