Explorar o código

MIPS procinfo improvements:
- Removed TMIPSProcInfo.needs_frame_pointer, it duplicates pi_needs_stackframe flag.
- Don't save RA for leaf procedures.
* GP is caller-saved register, it does not need saving/restoring as nonvolatile registers. Handle its restore position as a "normal" temp, whose offset is known before secondpass. This allows to handle PIC calls without involving GAS macro processing.

git-svn-id: trunk@23885 -

sergei %!s(int64=12) %!d(string=hai) anos
pai
achega
1c652eb8f9
Modificáronse 3 ficheiros con 52 adicións e 51 borrados
  1. 11 23
      compiler/mips/cgcpu.pas
  2. 1 1
      compiler/mips/cpupara.pas
  3. 40 27
      compiler/mips/cpupi.pas

+ 11 - 23
compiler/mips/cgcpu.pas

@@ -1203,7 +1203,7 @@ begin
   if nostackframe then
   if nostackframe then
     exit;
     exit;
 
 
-  if (TMIPSProcinfo(current_procinfo).needs_frame_pointer) or (pi_needs_stackframe in current_procinfo.flags) then
+  if (pi_needs_stackframe in current_procinfo.flags) then
     a_reg_alloc(list,NR_FRAME_POINTER_REG);
     a_reg_alloc(list,NR_FRAME_POINTER_REG);
 
 
   helplist:=TAsmList.Create;
   helplist:=TAsmList.Create;
@@ -1236,15 +1236,12 @@ begin
   mask:=0;
   mask:=0;
   nextoffset:=TMIPSProcInfo(current_procinfo).intregstart;
   nextoffset:=TMIPSProcInfo(current_procinfo).intregstart;
   saveregs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(pocall_stdcall);
   saveregs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(pocall_stdcall);
-  include(saveregs,RS_R31);
-  if (TMIPSProcinfo(current_procinfo).needs_frame_pointer) or (pi_needs_stackframe in current_procinfo.flags) then
+  if (current_procinfo.flags*[pi_do_call,pi_is_assembler]<>[]) then
+    include(saveregs,RS_R31);
+  if (pi_needs_stackframe in current_procinfo.flags) then
     include(saveregs,RS_FRAME_POINTER_REG);
     include(saveregs,RS_FRAME_POINTER_REG);
-  if (cs_create_pic in current_settings.moduleswitches) and
-     (pi_needs_got in current_procinfo.flags) then
-    include(saveregs,RS_GP);
   lastintoffset:=LocalSize;
   lastintoffset:=LocalSize;
   framesave:=nil;
   framesave:=nil;
-  gp_save:=nil;
   ra_save:=nil;
   ra_save:=nil;
 
 
   for reg:=RS_R1 to RS_R31 do
   for reg:=RS_R1 to RS_R31 do
@@ -1258,10 +1255,6 @@ begin
             framesave:=taicpu.op_reg_ref(A_SW,newreg(R_INTREGISTER,reg,R_SUBWHOLE),href)
             framesave:=taicpu.op_reg_ref(A_SW,newreg(R_INTREGISTER,reg,R_SUBWHOLE),href)
           else if (reg=RS_R31) then
           else if (reg=RS_R31) then
             ra_save:=taicpu.op_reg_ref(A_SW,newreg(R_INTREGISTER,reg,R_SUBWHOLE),href)
             ra_save:=taicpu.op_reg_ref(A_SW,newreg(R_INTREGISTER,reg,R_SUBWHOLE),href)
-          else if (reg=RS_GP) and
-                  (cs_create_pic in current_settings.moduleswitches) and
-                  (pi_needs_got in current_procinfo.flags) then
-            gp_save:=taicpu.op_const(A_P_CPRESTORE,nextoffset)
           else
           else
             helplist.concat(taicpu.op_reg_ref(A_SW,newreg(R_INTREGISTER,reg,R_SUBWHOLE),href));
             helplist.concat(taicpu.op_reg_ref(A_SW,newreg(R_INTREGISTER,reg,R_SUBWHOLE),href));
           inc(nextoffset,4);
           inc(nextoffset,4);
@@ -1311,10 +1304,11 @@ begin
         even use AT register, which is why we use R9 instead of AT here for -LocalSize }
         even use AT register, which is why we use R9 instead of AT here for -LocalSize }
       list.concat(Taicpu.op_none(A_P_SET_NOMACRO));
       list.concat(Taicpu.op_none(A_P_SET_NOMACRO));
     end;
     end;
-  if assigned(gp_save) then
+  if (cs_create_pic in current_settings.moduleswitches) and
+     (pi_needs_got in current_procinfo.flags) then
     begin
     begin
       list.concat(Taicpu.op_none(A_P_SET_MACRO));
       list.concat(Taicpu.op_none(A_P_SET_MACRO));
-      list.concat(gp_save);
+      list.concat(Taicpu.op_const(A_P_CPRESTORE,TMIPSProcinfo(current_procinfo).save_gp_ref.offset));
       list.concat(Taicpu.op_none(A_P_SET_NOMACRO));
       list.concat(Taicpu.op_none(A_P_SET_NOMACRO));
     end;
     end;
 
 
@@ -1338,11 +1332,6 @@ begin
             list.concat(taicpu.op_reg_ref(A_SW, newreg(R_INTREGISTER,reg,R_SUBWHOLE), href));
             list.concat(taicpu.op_reg_ref(A_SW, newreg(R_INTREGISTER,reg,R_SUBWHOLE), href));
         end;
         end;
     end;
     end;
-  if (cs_create_pic in current_settings.moduleswitches) and
-     (pi_needs_got in current_procinfo.flags) then
-    begin
-      current_procinfo.got := NR_GP;
-    end;
   list.concatList(helplist);
   list.concatList(helplist);
   helplist.Free;
   helplist.Free;
 end;
 end;
@@ -1382,12 +1371,11 @@ begin
 
 
        nextoffset:=TMIPSProcInfo(current_procinfo).intregstart;
        nextoffset:=TMIPSProcInfo(current_procinfo).intregstart;
        saveregs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(pocall_stdcall);
        saveregs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(pocall_stdcall);
-       include(saveregs,RS_R31);
-       if (TMIPSProcinfo(current_procinfo).needs_frame_pointer) or (pi_needs_stackframe in current_procinfo.flags) then
+       if (current_procinfo.flags*[pi_do_call,pi_is_assembler]<>[]) then
+         include(saveregs,RS_R31);
+       if (pi_needs_stackframe in current_procinfo.flags) then
          include(saveregs,RS_FRAME_POINTER_REG);
          include(saveregs,RS_FRAME_POINTER_REG);
-       if (cs_create_pic in current_settings.moduleswitches) and
-          (pi_needs_got in current_procinfo.flags) then
-         include(saveregs,RS_GP);
+       // GP does not need to be restored on exit
        for reg:=RS_R1 to RS_R31 do
        for reg:=RS_R1 to RS_R31 do
          begin
          begin
            if reg in saveregs then
            if reg in saveregs then

+ 1 - 1
compiler/mips/cpupara.pas

@@ -450,7 +450,7 @@ implementation
                           begin
                           begin
                             paraloc^.reference.index := NR_FRAME_POINTER_REG;
                             paraloc^.reference.index := NR_FRAME_POINTER_REG;
                             if assigned(current_procinfo) then
                             if assigned(current_procinfo) then
-                              TMIPSProcinfo(current_procinfo).needs_frame_pointer := true;
+                              include(current_procinfo.flags,pi_needs_stackframe);
                           end;
                           end;
                         paraloc^.reference.offset:=intparasize;
                         paraloc^.reference.offset:=intparasize;
 
 

+ 40 - 27
compiler/mips/cpupi.pas

@@ -29,7 +29,7 @@ interface
     cutils,
     cutils,
     globtype,symdef,
     globtype,symdef,
     procinfo,cpuinfo,cpupara,
     procinfo,cpuinfo,cpupara,
-    psub;
+    psub,aasmdata,cgutils;
 
 
   type
   type
 
 
@@ -40,17 +40,18 @@ interface
       floatregstart : aint;
       floatregstart : aint;
       intregssave,
       intregssave,
       floatregssave : byte;
       floatregssave : byte;
-      needs_frame_pointer: boolean;
       register_used : tparasupregsused;
       register_used : tparasupregsused;
       register_size : tparasupregsize;
       register_size : tparasupregsize;
       register_name : tparasuprename;
       register_name : tparasuprename;
       register_offset : tparasupregsoffset;
       register_offset : tparasupregsoffset;
       computed_local_size : longint;
       computed_local_size : longint;
+      save_gp_ref: treference;
       //intparareg,
       //intparareg,
       //parasize : longint;
       //parasize : longint;
       constructor create(aparent:tprocinfo);override;
       constructor create(aparent:tprocinfo);override;
       function calc_stackframe_size:longint;override;
       function calc_stackframe_size:longint;override;
       procedure set_first_temp_offset;override;
       procedure set_first_temp_offset;override;
+      procedure allocate_got_register(list:tasmlist);override;
     end;
     end;
 
 
    { Used by Stabs debug info generator }
    { Used by Stabs debug info generator }
@@ -61,7 +62,7 @@ implementation
 
 
     uses
     uses
       systems,globals,verbose,
       systems,globals,verbose,
-      cpubase,cgbase,cgutils,cgobj,
+      cpubase,cgbase,cgobj,
       tgobj,paramgr,symconst;
       tgobj,paramgr,symconst;
 
 
     constructor TMIPSProcInfo.create(aparent: tprocinfo);
     constructor TMIPSProcInfo.create(aparent: tprocinfo);
@@ -69,9 +70,9 @@ implementation
         i : longint;
         i : longint;
       begin
       begin
         inherited create(aparent);
         inherited create(aparent);
-        { will call _mcount if profiling }
-        if cs_profile in current_settings.moduleswitches then
-          include(flags,pi_do_call);
+        { if (cs_generate_stackframes in current_settings.localswitches) or
+           not (cs_opt_stackframe in current_settings.optimizerswitches) then }
+          include(flags,pi_needs_stackframe);
         for i:=low(tparasupregs)  to high(tparasupregs) do
         for i:=low(tparasupregs)  to high(tparasupregs) do
           begin
           begin
             register_used[i]:=false;
             register_used[i]:=false;
@@ -80,9 +81,7 @@ implementation
             register_offset[i]:=-1;
             register_offset[i]:=-1;
           end;
           end;
         floatregssave:=12; { f20-f31 }
         floatregssave:=12; { f20-f31 }
-        intregssave:=12;   { r16-r23,r28-r31 }
-        { for testing }
-        needs_frame_pointer := true;//false;
+        intregssave:=10;   { r16-r23,r30,r31 }
         computed_local_size:=-1;
         computed_local_size:=-1;
         { pi_needs_got is not yet set correctly
         { pi_needs_got is not yet set correctly
           so include it always if creating PIC code }
           so include it always if creating PIC code }
@@ -98,28 +97,42 @@ implementation
 
 
     procedure TMIPSProcInfo.set_first_temp_offset;
     procedure TMIPSProcInfo.set_first_temp_offset;
       begin
       begin
+        { MIPS stack frame is always "optimized" }
+        framepointer:=NR_STACK_POINTER_REG;
+        tg.direction:=1;
+
         { We allocate enough space to save all registers because we can't determine
         { We allocate enough space to save all registers because we can't determine
           the necessary space because the used registers aren't known before
           the necessary space because the used registers aren't known before
           secondpass is run. }
           secondpass is run. }
-        if tg.direction = -1 then
-          tg.setfirsttemp(0)
+
+        { will call _mcount if profiling }
+        if (cs_profile in current_settings.moduleswitches) and
+           not (po_nostackframe in procdef.procoptions) then
+          include(flags,pi_do_call);
+
+        { Fixes the case when there are calls done by low-level means
+          (cg.a_call_name) but no child callnode. !!For assembler procedure
+          there is no clean way to determine what it calls, unless it is
+          also declared as nostackframe and everything is managed manually. }
+        if (pi_do_call in flags) or
+           ((pi_is_assembler in flags) and not (po_nostackframe in procdef.procoptions)) then
+          allocate_push_parasize(mips_nb_used_registers*sizeof(aint));
+
+        if not (po_nostackframe in procdef.procoptions) then
+          tg.setfirsttemp(Align(maxpushedparasize+
+            floatregssave*sizeof(aint)+intregssave*sizeof(aint)
+            ,max(current_settings.alignment.localalignmin,8)))
         else
         else
-          begin
-            { Fixes the case when there are calls done by low-level means
-              (cg.a_call_name) but no child callnode. !!For assembler procedure
-              there is no clean way to determine what it calls, unless it is
-              also declared as nostackframe and everything is managed manually. }
-            if (pi_do_call in flags) or
-               ((pi_is_assembler in flags) and not (po_nostackframe in procdef.procoptions)) then
-              allocate_push_parasize(mips_nb_used_registers*sizeof(aint));
-
-            if not (po_nostackframe in procdef.procoptions) then
-              tg.setfirsttemp(Align(maxpushedparasize+
-                floatregssave*sizeof(aint)+intregssave*sizeof(aint)
-                ,max(current_settings.alignment.localalignmin,8)))
-            else
-              tg.setfirsttemp(align(maxpushedparasize,max(current_settings.alignment.localalignmin,8)));
-          end;
+          tg.setfirsttemp(align(maxpushedparasize,max(current_settings.alignment.localalignmin,8)));
+      end;
+
+
+    procedure TMIPSProcInfo.allocate_got_register(list:tasmlist);
+      begin
+        if (cs_create_pic in current_settings.moduleswitches) and
+           (pi_needs_got in flags) and
+           not (po_nostackframe in procdef.procoptions) then
+          tg.gettemp(list,sizeof(aint),sizeof(aint),tt_noreuse,save_gp_ref);
       end;
       end;