Browse Source

* fix register allocation initalization for arm thumb
* avoid that the register allocator creates code which writes to frame/stack pointer

git-svn-id: trunk@24190 -

florian 12 years ago
parent
commit
f25a905904
2 changed files with 43 additions and 14 deletions
  1. 5 14
      compiler/arm/cgcpu.pas
  2. 38 0
      compiler/arm/rgcpu.pas

+ 5 - 14
compiler/arm/cgcpu.pas

@@ -3337,20 +3337,12 @@ unit cgcpu;
     procedure tthumbcgarm.init_register_allocators;
     procedure tthumbcgarm.init_register_allocators;
       begin
       begin
         inherited init_register_allocators;
         inherited init_register_allocators;
-          rg[R_INTREGISTER]:=trgintcputhumb2.create(R_INTREGISTER,R_SUBWHOLE,
-              [RS_R0,RS_R1,RS_R2,RS_R3,RS_R4,RS_R5,RS_R6,RS_R7],first_int_imreg,[]);
-{          rg[R_FPUREGISTER]:=trgcpu.create(R_FPUREGISTER,R_SUBNONE,
-            [RS_F0,RS_F1,RS_F2,RS_F3,RS_F4,RS_F5,RS_F6,RS_F7],first_fpu_imreg,[]);
-
-        if current_settings.fputype=fpu_fpv4_s16 then
-          rg[R_MMREGISTER]:=trgcpu.create(R_MMREGISTER,R_SUBFD,
-              [RS_D0,RS_D1,RS_D2,RS_D3,RS_D4,RS_D5,RS_D6,RS_D7,
-               RS_D8,RS_D9,RS_D10,RS_D11,RS_D12,RS_D13,RS_D14,RS_D15
-              ],first_mm_imreg,[])
+        if assigned(current_procinfo) and (current_procinfo.framepointer=NR_R7) then
+          rg[R_INTREGISTER]:=trgintcputhumb.create(R_INTREGISTER,R_SUBWHOLE,
+              [RS_R0,RS_R1,RS_R2,RS_R3,RS_R4,RS_R5,RS_R6],first_int_imreg,[])
         else
         else
-          rg[R_MMREGISTER]:=trgcpu.create(R_MMREGISTER,R_SUBNONE,
-              [RS_S0,RS_S1,RS_R2,RS_R3,RS_R4,RS_S31],first_mm_imreg,[]);
-}
+          rg[R_INTREGISTER]:=trgintcputhumb.create(R_INTREGISTER,R_SUBWHOLE,
+              [RS_R0,RS_R1,RS_R2,RS_R3,RS_R4,RS_R5,RS_R6,RS_R7],first_int_imreg,[]);
       end;
       end;
 
 
 
 
@@ -3394,7 +3386,6 @@ unit cgcpu;
             ref.addressmode:=AM_PREINDEXED;
             ref.addressmode:=AM_PREINDEXED;
             regs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(pocall_stdcall);
             regs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(pocall_stdcall);
 
 
-            a_reg_alloc(list,NR_STACK_POINTER_REG);
             if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
             if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
               begin
               begin
                 //!!!! a_reg_alloc(list,NR_R12);
                 //!!!! a_reg_alloc(list,NR_R12);

+ 38 - 0
compiler/arm/rgcpu.pas

@@ -63,6 +63,14 @@ unit rgcpu;
          procedure add_cpu_interferences(p : tai);override;
          procedure add_cpu_interferences(p : tai);override;
        end;
        end;
 
 
+       trgcputhumb = class(trgcpu)
+       end;
+
+       trgintcputhumb = class(trgcputhumb)
+         procedure add_cpu_interferences(p: tai);override;
+       end;
+
+
   implementation
   implementation
 
 
     uses
     uses
@@ -494,4 +502,34 @@ unit rgcpu;
       end;
       end;
 
 
 
 
+    procedure trgintcputhumb.add_cpu_interferences(p: tai);
+      var
+        r : tregister;
+        hr : longint;
+      begin
+        if p.typ=ait_instruction then
+          begin
+            { prevent that the register allocator merges registers with frame/stack pointer
+              if an instruction writes to the register }
+            if (taicpu(p).ops>=1) and (taicpu(p).oper[0]^.typ=top_reg) and
+              (taicpu(p).spilling_get_operation_type(0) in [operand_write,operand_readwrite]) then
+              begin
+                { FIXME: temp variable r is needed here to avoid Internal error 20060521 }
+                {        while compiling the compiler. }
+                r:=NR_STACK_POINTER_REG;
+                add_edge(getsupreg(taicpu(p).oper[0]^.reg),getsupreg(r));
+                add_edge(getsupreg(taicpu(p).oper[0]^.reg),getsupreg(current_procinfo.framepointer));
+              end;
+            if (taicpu(p).ops>=2) and (taicpu(p).oper[1]^.typ=top_reg) and
+              (taicpu(p).spilling_get_operation_type(1) in [operand_write,operand_readwrite]) then
+              begin
+                { FIXME: temp variable r is needed here to avoid Internal error 20060521 }
+                {        while compiling the compiler. }
+                r:=NR_STACK_POINTER_REG;
+                add_edge(getsupreg(taicpu(p).oper[1]^.reg),getsupreg(r));
+                add_edge(getsupreg(taicpu(p).oper[1]^.reg),getsupreg(current_procinfo.framepointer));
+              end;
+          end;
+      end;
+
 end.
 end.